diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | io/ftw.c | 88 | ||||
-rw-r--r-- | linuxthreads/ChangeLog | 26 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sh/Makefile | 3 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sh/tcb-offsets.sym | 10 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sh/tls.h | 123 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c | 8 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h | 13 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S | 18 |
9 files changed, 231 insertions, 74 deletions
@@ -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 @@ -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 |