From c6481412ff19d5c551aba9330082a19a4a93260f Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 8 Nov 2002 02:20:41 +0000 Subject: * configure.in (ASM_ALPHA_NG_SYMBOL_PREFIX): Remove test. * configure: Regenerated. * config.h.in (ASM_ALPHA_NG_SYMBOL_PREFIX): Remove #undef. * sysdeps/alpha/dl-machine.h (TRAMPOLINE_TEMPLATE): Use !samegp. (RTLD_START): Likewise. Access _dl_skip_args, _rtld_local, and _dl_fini via gp-relative relocations. * sysdeps/alpha/fpu/e_sqrt.c: Use !samegp. * elf/tls-macros.h: Add alpha versions. * sysdeps/alpha/dl-machine.h (elf_machine_rela): Handle TLS relocs. * sysdeps/unix/alpha/sysdep.S: Support USE___THREAD. * sysdeps/unix/alpha/sysdep.h: Likewise. Add SYSCALL_ERROR_HANDLER. * sysdeps/unix/sysv/linux/alpha/brk.S: Use it. * sysdeps/unix/sysv/linux/alpha/clone.S: Likewise. * sysdeps/unix/sysv/linux/alpha/getitimer.S: Likewise. * sysdeps/unix/sysv/linux/alpha/getrusage.S: Likewise. * sysdeps/unix/sysv/linux/alpha/gettimeofday.S: Likewise. * sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S: Likewise. * sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S: Likewise. * sysdeps/unix/sysv/linux/alpha/rt_sigaction.S: Likewise. * sysdeps/unix/sysv/linux/alpha/select.S: Likewise. * sysdeps/unix/sysv/linux/alpha/setitimer.S: Likewise. * sysdeps/unix/sysv/linux/alpha/settimeofday.S: Likewise. * sysdeps/unix/sysv/linux/alpha/sigsuspend.S: Likewise. * sysdeps/unix/sysv/linux/alpha/syscall.S: Likewise. * sysdeps/unix/sysv/linux/alpha/utimes.S: Likewise. * sysdeps/unix/sysv/linux/alpha/wait4.S: Likewise. * sysdeps/unix/sysv/linux/alpha/sysdep.h: Re-include protect. Kill argument registers across the inline syscall. * sysdeps/unix/sysv/linux/alpha/clone.S: Add user_tid and tls args. * linuxthreads/sysdeps/alpha/tls.h: New file. * sysdeps/alpha/dl-tls.h: New file. --- sysdeps/alpha/dl-machine.h | 57 +++++++++++++++++++++++++++++++++++++++------- sysdeps/alpha/dl-tls.h | 29 +++++++++++++++++++++++ sysdeps/alpha/fpu/e_sqrt.c | 2 +- 3 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 sysdeps/alpha/dl-tls.h (limited to 'sysdeps/alpha') diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 05d988274b..711bf10fdd 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -228,7 +228,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) mov $26, $18 \n\ addq $17, $17, $17 \n\ /* Do the fixup */ \n\ - bsr $26, " ASM_ALPHA_NG_SYMBOL_PREFIX #fixup_name "..ng\n\ + bsr $26, " #fixup_name " !samegp \n\ /* Move the destination address into position. */ \n\ mov $0, $27 \n\ /* Restore program registers. */ \n\ @@ -308,7 +308,7 @@ _start: \n\ .prologue 0 \n\ /* Pass pointer to argument block to _dl_start. */ \n\ mov $sp, $16 \n\ - bsr $26, "ASM_ALPHA_NG_SYMBOL_PREFIX"_dl_start..ng \n\ + bsr $26, _dl_start !samegp \n\ .end _start \n\ /* FALLTHRU */ \n\ .globl _dl_start_user \n\ @@ -322,7 +322,7 @@ _dl_start_user: \n\ stq $30, __libc_stack_end \n\ /* See if we were run as a command with the executable \n\ file name as an extra leading argument. */ \n\ - ldl $1, _dl_skip_args \n\ + ldl $1, _dl_skip_args($gp) !gprel \n\ bne $1, $fixup_stack \n\ $fixup_stack_ret: \n\ /* The special initializer gets called with the stack \n\ @@ -332,14 +332,16 @@ $fixup_stack_ret: \n\ " RTLD_START_SPECIAL_INIT " \n\ /* Call _dl_init(_dl_loaded, argc, argv, envp) to run \n\ initializers. */ \n\ - ldq $16, _rtld_local \n\ + ldah $16, _rtld_local($gp) !gprelhigh \n\ + ldq $16, _rtld_local($16) !gprellow \n\ ldq $17, 0($sp) \n\ lda $18, 8($sp) \n\ s8addq $17, 8, $19 \n\ addq $19, $18, $19 \n\ - jsr $26, _dl_init_internal \n\ + bsr $26, _dl_init_internal !samegp \n\ /* Pass our finalizer function to the user in $0. */ \n\ - lda $0, _dl_fini \n\ + ldah $0, _dl_fini($gp) !gprelhigh \n\ + lda $0, _dl_fini($0) !gprellow \n\ /* Jump to the user's entry point. */ \n\ mov $9, $27 \n\ jmp ($9) \n\ @@ -541,10 +543,15 @@ elf_machine_rela (struct link_map *map, return; else { - Elf64_Addr loadbase, sym_value; + Elf64_Addr sym_value; - loadbase = RESOLVE (&sym, version, r_type); +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + sym_value = sym ? sym_map->l_addr + sym->st_value : 0; +#else + Elf64_Addr loadbase = RESOLVE (&sym, version, r_type); sym_value = sym ? loadbase + sym->st_value : 0; +#endif sym_value += reloc->r_addend; if (r_type == R_ALPHA_GLOB_DAT) @@ -575,6 +582,40 @@ elf_machine_rela (struct link_map *map, memcpy (reloc_addr_1, &sym_value, 8); } #endif +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) + else if (r_type == R_ALPHA_DTPMOD64) + { +#ifdef RTLD_BOOTSTRAP + /* During startup the dynamic linker is always index 1. */ + *reloc_addr = 1; +#else + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; +#endif + } + else if (r_type == R_ALPHA_DTPREL64) + { +#ifndef RTLD_BOOTSTRAP + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + *reloc_addr = sym_value; +#endif + } + else if (r_type == R_ALPHA_TPREL64) + { +#ifdef RTLD_BOOTSTRAP + *reloc_addr = sym_value - map->l_tls_offset; +#else + if (sym_map) + { + *reloc_addr = sym_value - sym_map->l_tls_offset; + CHECK_STATIC_TLS (map, sym_map); + } +#endif + } +#endif /* USE_TLS */ else _dl_reloc_bad_type (map, r_type, 0); } diff --git a/sysdeps/alpha/dl-tls.h b/sysdeps/alpha/dl-tls.h new file mode 100644 index 0000000000..f81f95d75e --- /dev/null +++ b/sysdeps/alpha/dl-tls.h @@ -0,0 +1,29 @@ +/* Thread-local storage handling in the ELF dynamic linker. Alpha version. + Copyright (C) 2002 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. */ + + +/* Type used for the representation of TLS information in the GOT. */ +typedef struct +{ + unsigned long int ti_module; + unsigned long int ti_offset; +} tls_index; + + +extern void *__tls_get_addr (tls_index *ti); diff --git a/sysdeps/alpha/fpu/e_sqrt.c b/sysdeps/alpha/fpu/e_sqrt.c index c6262c8f69..a371896765 100644 --- a/sysdeps/alpha/fpu/e_sqrt.c +++ b/sysdeps/alpha/fpu/e_sqrt.c @@ -153,7 +153,7 @@ __ieee754_sqrt: \n\ .align 4 \n\ $fixup: \n\ addq $sp, 16, $sp \n\ - br "ASM_ALPHA_NG_SYMBOL_PREFIX"__full_ieee754_sqrt..ng \n\ + br __full_ieee754_sqrt !samegp \n\ \n\ .end __ieee754_sqrt"); -- cgit v1.2.3