summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--io/ftw.c88
-rw-r--r--linuxthreads/ChangeLog26
-rw-r--r--linuxthreads/sysdeps/sh/Makefile3
-rw-r--r--linuxthreads/sysdeps/sh/tcb-offsets.sym10
-rw-r--r--linuxthreads/sysdeps/sh/tls.h123
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c8
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h13
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S18
9 files changed, 231 insertions, 74 deletions
diff --git a/ChangeLog b/ChangeLog
index a59468df95..183e5f95f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2003-02-07 Jim Meyering <jim@meyering.net>
+
+ * io/ftw.c: Add autoconf-recommended block of alloca-related code.
+ Include autoconf-recommended block of dirent/NAMELEN-related
+ definitions and includes. Use NAMELEN throughout, rather than
+ _D_EXACT_NAMLEN.
+ [_LIBC]: Define NAMELEN to _D_EXACT_NAMLEN.
+ [!_LIBC] (__getcwd): Define to xgetcwd and declare xgetcwd.
+ (stpcpy): Declare, if necessary.
+ (mempcpy): Define, if necessary.
+ [!_LIBC] (__stpcpy, __mempcpy): Define.
+ [!_LIBC] (LXSTAT, XSTAT): Define.
+ (lstat) [!LIBC && !LSTAT_FOLLOWS_SLASHED_SYMLINK]: Define to rpl_lstat.
+ (find_object): Don't use c99-style struct initializer.
+ Tweak wording in a couple comments.
+
2003-02-07 Kaz Kojima <kkojima@rr.iij4u.or.jp>
* elf/tls-macros.h: Add non-PIC TLS macros and fix clobber list
diff --git a/io/ftw.c b/io/ftw.c
index 45001d5b54..227f3f3b52 100644
--- a/io/ftw.c
+++ b/io/ftw.c
@@ -22,7 +22,42 @@
# include <config.h>
#endif
-#include <dirent.h>
+#if __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ # pragma alloca
+# else
+char *alloca ();
+# endif
+# endif
+#endif
+
+#if defined _LIBC
+# include <dirent.h>
+# define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
+#else
+# if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen ((dirent)->d_name)
+# else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+# endif
+#endif
+
#include <errno.h>
#include <ftw.h>
#include <limits.h>
@@ -39,6 +74,15 @@
# include <sys/stat.h>
#endif
+#if ! _LIBC && !HAVE_DECL_STPCPY && !defined stpcpy
+char *stpcpy ();
+#endif
+
+#if ! _LIBC && ! defined HAVE_MEMPCPY && ! defined mempcpy
+/* Be CAREFUL that there are no side effects in N. */
+# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
+#endif
+
/* #define NDEBUG 1 */
#include <assert.h>
@@ -50,11 +94,16 @@
# undef __fchdir
# define __fchdir fchdir
# undef __getcwd
-# define __getcwd getcwd
+# define __getcwd(P, N) xgetcwd ()
+extern char *xgetcwd (void);
+# undef __mempcpy
+# define __mempcpy mempcpy
# undef __opendir
# define __opendir opendir
# undef __readdir64
# define __readdir64 readdir
+# undef __stpcpy
+# define __stpcpy stpcpy
# undef __tdestroy
# define __tdestroy tdestroy
# undef __tfind
@@ -69,6 +118,15 @@
# define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
+/* Arrange to make lstat calls go through the wrapper function
+ on systems with an lstat function that does not dereference symlinks
+ that are specified with a trailing slash. */
+#if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK
+int rpl_lstat (const char *, struct stat *);
+# undef lstat
+# define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
+#endif
+
#ifndef __set_errno
# define __set_errno(Val) errno = (Val)
#endif
@@ -79,8 +137,13 @@
# define NFTW_NAME nftw
# define INO_T ino_t
# define STAT stat
-# define LXSTAT __lxstat
-# define XSTAT __xstat
+# ifdef _LIBC
+# define LXSTAT __lxstat
+# define XSTAT __xstat
+# else
+# define LXSTAT(V,f,sb) lstat (f,sb)
+# define XSTAT(V,f,sb) stat (f,sb)
+# endif
# define FTW_FUNC_T __ftw_func_t
# define NFTW_FUNC_T __nftw_func_t
#endif
@@ -124,7 +187,7 @@ struct ftw_data
int flags;
/* Conversion array for flag values. It is the identity mapping for
- `nftw' calls, otherwise it maps the values to those know by
+ `nftw' calls, otherwise it maps the values to those known by
`ftw'. */
const int *cvt_arr;
@@ -140,9 +203,8 @@ struct ftw_data
};
-/* Internally we use the FTW_* constants used for `nftw'. When the
- process called `ftw' we must reduce the flag to the known flags
- for `ftw'. */
+/* Internally we use the FTW_* constants used for `nftw'. When invoked
+ as `ftw', map each flag to the subset of values used by `ftw'. */
static const int nftw_arr[] =
{
FTW_F, FTW_D, FTW_DNR, FTW_NS, FTW_SL, FTW_DP, FTW_SLN
@@ -188,7 +250,9 @@ add_object (struct ftw_data *data, struct STAT *st)
static inline int
find_object (struct ftw_data *data, struct STAT *st)
{
- struct known_object obj = { .dev = st->st_dev, .ino = st->st_ino };
+ struct known_object obj;
+ obj.dev = st->st_dev;
+ obj.ino = st->st_ino;
return __tfind (&obj, &data->known_objects, object_compare) != NULL;
}
@@ -216,7 +280,7 @@ open_dir_stream (struct ftw_data *data, struct dir_data *dirp)
while ((d = __readdir64 (st)) != NULL)
{
- size_t this_len = _D_EXACT_NAMLEN (d);
+ size_t this_len = NAMLEN (d);
if (actsize + this_len + 2 >= bufsize)
{
char *newp;
@@ -354,7 +418,7 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
if (result == 0 && (data->flags & FTW_CHDIR))
{
- /* Change back to current directory. */
+ /* Change back to the parent directory. */
int done = 0;
if (dir->stream != NULL)
if (__fchdir (dirfd (dir->stream)) == 0)
@@ -452,7 +516,7 @@ ftw_dir (struct ftw_data *data, struct STAT *st)
while (dir.stream != NULL && (d = __readdir64 (dir.stream)) != NULL)
{
- result = process_entry (data, &dir, d->d_name, _D_EXACT_NAMLEN (d));
+ result = process_entry (data, &dir, d->d_name, NAMLEN (d));
if (result != 0)
break;
}
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 4cb52a1c9b..fe06a451bd 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,29 @@
+2003-02-07 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * sysdeps/sh/Makefile: New file.
+ * sysdeps/sh/tcb-offsets.sym: Likewise.
+ * sysdeps/sh/tls.h: Don't include sysdep.h. Move include
+ of linuxthreads/descr.h after the definition of THREAD_SELF.
+ (tcbhead_t): Use IA64 type tcbhead_t for TLS case.
+ (TLS_TCB_SIZE): Set size of tcbhead_t.
+ (TLS_PRE_TCB_SIZE): Define.
+ (INSTALL_NEW_DTV): Set dtv of tcbhead_t structure instead of
+ a member of thread structure.
+ (THREAD_DTV): Likewise.
+ (TLS_INIT_TP_EXPENSIVE): Remove.
+ (TLS_INIT_TP): Set gbr register only.
+ (THREAD_SELF): New.
+ (INIT_THREAD_SELF): Likewise.
+ (NONTLS_INIT_TP): New.
+ * sysdeps/unix/sysv/linux/sh/pt-initfini.c (__fpscr_values):
+ Remove.
+ * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (PSEUDO): Add
+ SYSCALL_INST_PAD macro after DO_CALL.
+ (SINGLE_THREAD_P): Fix non-PIC and TLS case so to read the
+ correct variable.
+ * sysdeps/unix/sysv/linux/sh/vfork.S (__vfork): Branch to __fork
+ whenever libpthread.so is loaded.
+
2003-02-08 Andreas Schwab <schwab@suse.de>
* sysdeps/unix/sysv/linux/m68k/vfork.S: Branch to __fork whenever
diff --git a/linuxthreads/sysdeps/sh/Makefile b/linuxthreads/sysdeps/sh/Makefile
new file mode 100644
index 0000000000..81bddf688c
--- /dev/null
+++ b/linuxthreads/sysdeps/sh/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/linuxthreads/sysdeps/sh/tcb-offsets.sym b/linuxthreads/sysdeps/sh/tcb-offsets.sym
new file mode 100644
index 0000000000..d74292b1c2
--- /dev/null
+++ b/linuxthreads/sysdeps/sh/tcb-offsets.sym
@@ -0,0 +1,10 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+#ifdef USE_TLS
+MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_header.data.multiple_threads)
+TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
+#else
+MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+#endif
diff --git a/linuxthreads/sysdeps/sh/tls.h b/linuxthreads/sysdeps/sh/tls.h
index de79aaed0a..af67a8eded 100644
--- a/linuxthreads/sysdeps/sh/tls.h
+++ b/linuxthreads/sysdeps/sh/tls.h
@@ -34,15 +34,6 @@ typedef union dtv
void *pointer;
} dtv_t;
-
-typedef struct
-{
- void *tcb; /* Pointer to the TCB. Not necessary the
- thread descriptor used by libpthread. */
- dtv_t *dtv;
- void *self; /* Pointer to the thread descriptor. */
- int multiple_threads;
-} tcbhead_t;
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
#endif /* __ASSEMBLER__ */
@@ -55,73 +46,101 @@ typedef struct
/* Signal that TLS support is available. */
# define USE_TLS 1
-#ifndef __ASSEMBLER__
-
-/* Get system call information. */
-# include <sysdep.h>
+# ifndef __ASSEMBLER__
-/* Get the thread descriptor definition. */
-# include <linuxthreads/descr.h>
+typedef struct
+{
+ dtv_t *dtv;
+ void *private;
+} tcbhead_t;
/* This is the size of the initial TCB. */
-# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
/* Alignment requirements for the initial TCB. */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
/* This is the size of the TCB. */
-# define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
+# define TLS_TCB_SIZE sizeof (tcbhead_t)
+
+/* This is the size we need before TCB. */
+# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
/* The TLS blocks start right after the TCB. */
-# define TLS_DTV_AT_TP 1
-
+# define TLS_DTV_AT_TP 1
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
-# define INSTALL_DTV(descr, dtvp) \
- ((tcbhead_t *) (descr))->dtv = dtvp + 1
+# define INSTALL_DTV(tcbp, dtvp) \
+ ((tcbhead_t *) (tcbp))->dtv = dtvp + 1
/* Install new dtv for current thread. */
-# define INSTALL_NEW_DTV(dtv) \
- ({ struct _pthread_descr_struct *__descr; \
- THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); })
+# define INSTALL_NEW_DTV(dtv) \
+ ({ tcbhead_t *__tcbp; \
+ __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
+ __tcbp->dtv = (dtv);})
/* Return dtv of given thread descriptor. */
-# define GET_DTV(descr) \
- (((tcbhead_t *) (descr))->dtv)
+# define GET_DTV(tcbp) \
+ (((tcbhead_t *) (tcbp))->dtv)
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
-# define TLS_INIT_TP(descr, secondcall) \
- ({ \
- void *_descr = (descr); \
- int result; \
- tcbhead_t *head = _descr; \
- \
- head->tcb = _descr; \
- /* For now the thread descriptor is at the same address. */ \
- head->self = _descr; \
- \
- asm ("ldc %0,gbr" : : "r" (_descr)); \
- \
- 0; \
- })
-
-/* Indicate that dynamic linker shouldn't try to initialize TLS even
- when no PT_TLS segments are found in the program and libraries
- it is linked against. */
-# define TLS_INIT_TP_EXPENSIVE 1
+# define TLS_INIT_TP(tcbp, secondcall) \
+ ({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; })
/* Return the address of the dtv for the current thread. */
-# define THREAD_DTV() \
- ({ struct _pthread_descr_struct *__descr; \
- THREAD_GETMEM (__descr, p_header.data.dtvp); })
+# define THREAD_DTV() \
+ ({ tcbhead_t *__tcbp; \
+ __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
+ __tcbp->dtv;})
-# endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
-#endif /* __ASSEMBLER__ */
+/* Return the thread descriptor for the current thread. */
+# undef THREAD_SELF
+# define THREAD_SELF \
+ ({ struct _pthread_descr_struct *__self; \
+ __asm ("stc gbr,%0" : "=r" (__self)); \
+ __self - 1;})
+
+# undef INIT_THREAD_SELF
+# define INIT_THREAD_SELF(descr, nr) \
+ ({ struct _pthread_descr_struct *__self = (void *) descr; \
+ __asm __volatile ("ldc %0,gbr" : : "r" (__self + 1)); \
+ 0; })
+
+/* Get the thread descriptor definition. This must be after the
+ the definition of THREAD_SELF for TLS. */
+# include <linuxthreads/descr.h>
+
+# endif /* __ASSEMBLER__ */
+
+#else
+
+# ifndef __ASSEMBLER__
+
+typedef struct
+{
+ void *tcb;
+ dtv_t *dtv;
+ void *self;
+ int multiple_threads;
+} tcbhead_t;
+
+/* Get the thread descriptor definition. */
+# include <linuxthreads/descr.h>
+
+# define NONTLS_INIT_TP \
+ do { \
+ static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 }; \
+ __asm __volatile ("ldc %0,gbr" : : "r" (&nontls_init_tp)); \
+ } while (0)
+
+# endif /* __ASSEMBLER__ */
+
+#endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
#endif /* tls.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c
index 1cf51a8e09..1cdb98f0f7 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c
@@ -1,5 +1,5 @@
/* Special .init and .fini section support for SH. Linuxthread version.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it
@@ -77,12 +77,6 @@ _init:\n\
.long __gmon_start__@PLT\n\
.L24:\n\
.long __pthread_initialize_minimal@PLT\n\
- .data\n\
- .global __fpscr_values\n\
-__fpscr_values:\n\
- .long 0\n\
- .long 0x80000\n\
- .previous\n\
1:\n\
ALIGN\n\
END_INIT\n\
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index b357eb4e88..57db351735 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -52,6 +52,7 @@
add _IMP16,r15; \
lds.l @r15+,pr; \
DO_CALL(syscall_name, args); \
+ SYSCALL_INST_PAD; \
sts.l pr,@-r15; \
mov.l r0,@-r15; \
CDISABLE; \
@@ -106,6 +107,7 @@
.align 2; \
1: .long __local_enable_asynccancel - 0b; \
2:
+
# define CDISABLE \
mov.l 1f,r0; \
bsrf r0; \
@@ -129,6 +131,7 @@ extern int __local_multiple_threads attribute_hidden;
# if !defined PIC
# define SINGLE_THREAD_P \
mov.l 1f,r0; \
+ mov.l @r0,r0; \
bra 2f; \
tst r0,r0; \
.align 2; \
@@ -136,7 +139,15 @@ extern int __local_multiple_threads attribute_hidden;
2:
# elif defined FLOATING_STACKS && USE___THREAD
# define SINGLE_THREAD_P \
- mov.l @(MULTIPLE_THREADS_OFFSET,gbr),r0; tst r0,r0
+ stc gbr,r0; \
+ mov.w 0f,r1; \
+ sub r1,r0; \
+ mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
+ bra 1f; \
+ tst r0,r0; \
+ 0: .word TLS_PRE_TCB_SIZE; \
+ 1:
+
# else
# define SINGLE_THREAD_P \
mov r12,r2; \
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
index f796e31088..b118ca34d7 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -26,8 +26,14 @@
and the process ID of the new process to the old process. */
ENTRY (__vfork)
- SINGLE_THREAD_P
- bf .Lhidden_fork
+#ifdef SHARED
+ mov.l .Lpthread_func, r0
+ mov.l @(r0,r12), r0
+#else
+ mov.l .Lpthread_fork, r0
+#endif
+ tst r0, r0
+ bf .Lhidden_fork
mov.w .L1, r3
trapa #0x10
@@ -42,6 +48,14 @@ ENTRY (__vfork)
rts
nop
.L1: .word __NR_vfork
+ .align 2
+#ifdef SHARED
+.Lpthread_func:
+ .long __libc_pthread_functions@GOTOFF
+#else
+.Lpthread_fork:
+ .long __pthread_fork
+#endif
.Lhidden_fork:
mov.l .L2, r1