From 0f0b799489b3b4df2c69c9a6844be6a8f294778d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 17 Jan 2003 19:57:05 +0000 Subject: [PATCH] Update. 2003-01-17 Richard Henderson * sysdeps/alpha/dl-machine.h (elf_machine_type_class): Add TLS relocs for class PLT. * sysdeps/alpha/libc-tls.c: New file. * sysdeps/unix/alpha/sysdep.S (EPILOGUE, GPSAVEREG): New. (LOADGP) [!PIC]: Rewrite to preserve caller's gp. 2003-01-17 Jakub Jelinek * sysdeps/unix/sysv/linux/ia64/dl-static.c (_dl_static_init): Use __libc_lock_{,un}lock_recursive instead of __libc_lock_{,un}lock on _dl_static_lock. --- ChangeLog | 14 +++++ linuxthreads/ChangeLog | 12 ++++ linuxthreads/sysdeps/alpha/tls.h | 65 +++++++++++++--------- linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S | 27 ++++++--- sysdeps/alpha/dl-machine.h | 21 +++++-- sysdeps/alpha/libc-tls.c | 37 ++++++++++++ sysdeps/unix/alpha/sysdep.S | 42 ++++++++++++-- 7 files changed, 172 insertions(+), 46 deletions(-) create mode 100644 sysdeps/alpha/libc-tls.c diff --git a/ChangeLog b/ChangeLog index 096f76c..1ac5cd8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2003-01-17 Richard Henderson + + * sysdeps/alpha/dl-machine.h (elf_machine_type_class): Add TLS + relocs for class PLT. + * sysdeps/alpha/libc-tls.c: New file. + * sysdeps/unix/alpha/sysdep.S (EPILOGUE, GPSAVEREG): New. + (LOADGP) [!PIC]: Rewrite to preserve caller's gp. + +2003-01-17 Jakub Jelinek + + * sysdeps/unix/sysv/linux/ia64/dl-static.c (_dl_static_init): Use + __libc_lock_{,un}lock_recursive instead of __libc_lock_{,un}lock + on _dl_static_lock. + 2003-01-17 Andreas Jaeger * stdio-common/bug14.c: Include stdlib.h for exit prototype. diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 93023e6..7b1fd74 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,15 @@ +2003-01-17 Richard Henderson + + * sysdeps/alpha/tls.h (tcbhead_t): Clarify second member. + (TLS_TCB_SIZE, TLS_TCB_ALIGN): Set for tcbhead_t. + (TLS_PRE_TCB_SIZE): New. + (TLS_INIT_TP, THREAD_SELF, INIT_THREAD_SELF): Update for + new ia64-style thread pointer layout. + (THREAD_GETMEM, THREAD_GETMEM_NC): New. + (THREAD_SETMEM, THREAD_SETMEM_NC): New. + * sysdeps/unix/sysv/linux/alpha/vfork.S: Don't tail-call to __fork + if !SHARED. + 2003-01-15 Jakub Jelinek * sysdeps/ia64/tls.h (tcbhead_t): Use the TLS ABI required layout diff --git a/linuxthreads/sysdeps/alpha/tls.h b/linuxthreads/sysdeps/alpha/tls.h index 98d0d9f..d93c91f 100644 --- a/linuxthreads/sysdeps/alpha/tls.h +++ b/linuxthreads/sysdeps/alpha/tls.h @@ -1,5 +1,5 @@ /* Definitions for thread-local data handling. linuxthreads/Alpha version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 and/or @@ -37,9 +37,8 @@ typedef struct { dtv_t *dtv; - /* Reserved for the thread implementation. In the case of LinuxThreads, - this is the thread descriptor. */ - void *tcb; + /* Reserved for the thread implementation. Unused in LinuxThreads. */ + void *private; } tcbhead_t; #endif @@ -53,58 +52,72 @@ typedef struct /* Get system call information. */ # include -/* Get the thread descriptor definition. */ -# include - /* 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) /* Alignment requirements for the TCB. */ -# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) +# define TLS_TCB_ALIGN __alignof__ (tcbhead_t) + +/* This is the size we need before TCB. */ +# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct) /* The DTV is allocated at the TP; the TCB is placed elsewhere. */ # 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) \ (((tcbhead_t *)__builtin_thread_pointer ())->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) \ - ({ \ - register tcbhead_t *__self = (void *)(descr); \ - __self->tcb = __self; \ - __builtin_set_thread_pointer(__self); \ - 0; \ - }) +# define TLS_INIT_TP(TCBP, SECONDCALL) \ + (__builtin_set_thread_pointer (TCBP), 0) /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ (((tcbhead_t *)__builtin_thread_pointer ())->dtv) /* Return the thread descriptor for the current thread. */ -#undef THREAD_SELF -#define THREAD_SELF \ - ((pthread_descr)(((tcbhead_t *)__builtin_thread_pointer ())->tcb)) +# undef THREAD_SELF +# define THREAD_SELF \ + ((pthread_descr)__builtin_thread_pointer () - 1) + +# undef INIT_THREAD_SELF +# define INIT_THREAD_SELF(DESCR, NR) \ + __builtin_set_thread_pointer ((struct _pthread_descr_struct *)(DESCR) + 1) + +/* Get the thread descriptor definition. */ +# include + +/* ??? Generic bits of LinuxThreads may call these macros with + DESCR set to NULL. We are expected to be able to reference + the "current" value. + + In our case, we'd really prefer to use DESCR, since lots of + PAL_code calls would be expensive. We can only trust that + the compiler does its job and unifies the multiple + __builtin_thread_pointer instances. */ -#undef INIT_THREAD_SELF +#define THREAD_GETMEM(descr, member) THREAD_SELF->member +#define THREAD_GETMEM_NC(descr, member) THREAD_SELF->member +#define THREAD_SETMEM(descr, member, value) (THREAD_SELF->member = (value)) +#define THREAD_SETMEM_NC(descr, member, value) (THREAD_SELF->member = (value)) # endif /* HAVE_TLS_SUPPORT */ #endif /* __ASSEMBLER__ */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S index 2481de9..e750724 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S @@ -26,26 +26,35 @@ __LABEL(__vfork) ldgp gp, 0(pv) .prologue 1 PSEUDO_PROF + SINGLE_THREAD_P(t0) #ifdef SHARED bne t0, HIDDEN_JUMPTARGET (__fork) !samegp #else - bne t0, $hidden_fork + bne t0, $do_fork #endif + lda v0, SYS_ify(vfork) call_pal PAL_callsys -#ifdef SHARED - bne a3, __syscall_error !samegp -#else - bne a3, $syscall_error -#endif + bne a3, SYSCALL_ERROR_LABEL ret + #ifndef SHARED -$hidden_fork: - jmp zero, HIDDEN_JUMPTARGET (__fork) + /* Can't tail-call due to possible mismatch between GP in + fork and vfork object files. */ +$do_fork: + subq sp, 16, sp + stq ra, 0(sp) + jsr ra, HIDDEN_JUMPTARGET (__fork) + ldgp gp, 0(ra) + ldq ra, 0(sp) + addq sp, 16, sp + ret + $syscall_error: - jmp zero, __syscall_error + SYSCALL_ERROR_HANDLER #endif + PSEUDO_END(__vfork) libc_hidden_def (__vfork) diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 5016f13..25359d8 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -387,13 +387,24 @@ $fixup_stack: \n\ #define RTLD_START_SPECIAL_INIT /* nothing */ #endif -/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so - PLT entries should not be allowed to define the value. - ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one - of the main executable's symbols, as for a COPY reloc, which we don't - use. */ +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry + or TLS variables, so undefined references should not be allowed + to define the value. + + ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve + to one of the main executable's symbols, as for a COPY reloc. + This is unused on Alpha. */ + +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#define elf_machine_type_class(type) \ + (((type) == R_ALPHA_JMP_SLOT \ + || (type) == R_ALPHA_DTPMOD64 \ + || (type) == R_ALPHA_DTPREL64 \ + || (type) == R_ALPHA_TPREL64) * ELF_RTYPE_CLASS_PLT) +#else #define elf_machine_type_class(type) \ (((type) == R_ALPHA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_ALPHA_JMP_SLOT diff --git a/sysdeps/alpha/libc-tls.c b/sysdeps/alpha/libc-tls.c new file mode 100644 index 0000000..434d5d9 --- /dev/null +++ b/sysdeps/alpha/libc-tls.c @@ -0,0 +1,37 @@ +/* Thread-local storage handling in the ELF dynamic linker. Alpha version. + Copyright (C) 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 and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +#if USE_TLS + +/* On Alpha, linker optimizations are not required, so __tls_get_addr + can be called even in statically linked binaries. In this case module + must be always 1 and PT_TLS segment exist in the binary, otherwise it + would not link. */ + +void * +__tls_get_addr (tls_index *ti) +{ + dtv_t *dtv = THREAD_DTV (); + return (char *) dtv[1].pointer + ti->ti_offset; +} + +#endif diff --git a/sysdeps/unix/alpha/sysdep.S b/sysdeps/unix/alpha/sysdep.S index c31508b..ce848f4 100644 --- a/sysdeps/unix/alpha/sysdep.S +++ b/sysdeps/unix/alpha/sysdep.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1998, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1996, 1998, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Brendan Kehoe (brendan@zen.org). @@ -35,9 +35,26 @@ have we loaded PV with our address. Do both. */ # define LOADGP br pv, 1f; 1: ldgp gp, 0(pv) # define PROLOGUE .prologue 0 +# define EPILOGUE #else -# define LOADGP ldgp gp, 0(pv) + /* When building the static library, we tail call here from + elsewhere, which might use a different GP. The entertaining + part is that we have to return with the GP of our caller + in place, so that linker relaxation works properly. */ + /* ??? This is so ugly. Consider always putting the errno + setting code with the syscall in the static case. */ +# define GPSAVEREG t10 +# define LOADGP ldah t11, 0(pv) !gpdisp!1; \ + br 1f; \ + .subsection 2; \ + 1: mov gp, GPSAVEREG; \ + lda gp, 0(t11) !gpdisp!1; \ + br 2f; \ + .previous; \ + mov gp, GPSAVEREG; \ + 2: # define PROLOGUE .prologue 1 +# define EPILOGUE mov GPSAVEREG, gp #endif .align 4 @@ -61,16 +78,20 @@ __syscall_error: addq v0, t1, v0 stl t0, 0(v0) lda v0, -1 + EPILOGUE ret #elif defined(_LIBC_REENTRANT) LOADGP - lda sp, -16(sp) - .frame sp, 16, ra, 0 + lda sp, -32(sp) + .frame sp, 32, ra, 0 stq ra, 0(sp) stq v0, 8(sp) - .mask 0x4000001, -16 +#ifdef GPSAVEREG + stq GPSAVEREG, 16(sp) +#endif + .mask 0x4000001, -32 PROLOGUE /* Find our per-thread errno address */ @@ -78,6 +99,9 @@ __syscall_error: bsr ra, __errno_location !samegp #else jsr ra, __errno_location +#ifndef GPSAVEREG + ldgp gp, 0(ra) +#endif #endif /* Store the error value. */ @@ -87,8 +111,12 @@ __syscall_error: /* And kick back a -1. */ ldi v0, -1 +#ifdef GPSAVEREG + ldq GPSAVEREG, 16(sp) +#endif ldq ra, 0(sp) - lda sp, 16(sp) + lda sp, 32(sp) + EPILOGUE ret #else @@ -97,8 +125,10 @@ __syscall_error: PROLOGUE stl v0, errno lda v0, -1 + EPILOGUE ret #endif + .subsection 3 .end __syscall_error -- 2.7.4