From c9ff0187a63b6bc535c9febd2c2eb1c5a843b2c1 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 13 May 2008 05:41:30 +0000 Subject: Introduce TLS descriptors for i386 and x86_64. * include/inline-hashtab.h: New file, copied from 2005's libiberty, with fix for memory leak imported afterwards by Glauber de Oliveira Costa. * elf/tlsdeschtab.h: New file. * elf/dl-reloc.c (_dl_try_allocate_static_tls): Extract from... (_dl_allocate_static_tls): ... here. Rearrange failure path. (CHECK_STATIC_TLS): Move to... * elf/dynamic-link.h: ... this file. (TRY_STATIC_TLS): New macro. * elf/dl-conflict.c (CHECK_STATIC_TLS, TRY_STATIC_TLS): Override. * elf/elf.h (R_386_TLS_GOTDESC, R_386_TLS_DESC_CALL, R_386_TLS_DESC): Define. (R_X86_64_PC64, R_X86_GOTOFF64, R_X86_64_GOTPC32): Merge from binutils. (R_X86_64_GOTPC32_TLSDESC, R_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC): Define. (R_386_NUM, R_X86_64_NUM): Adjust. * sysdeps/i386/Makefile (sysdep-dl-routines, sysdep_routines, systep-rtld-routines): Add tlsdesc and dl-tlsdesc for elf subdir. (gen-as-const-headers): Add tlsdesc.sym to csu subdir. * sysdeps/i386/dl-lookupcfg.h: New file. Introduce _dl_unmap to release tlsdesc_table. * sysdeps/i386/dl-machine.h: Include dl-tlsdesc.h. (elf_machine_type_class): Mark R_386_TLS_DESC as PLT class. (elf_machine_rel): Handle R_386_TLS_DESC. (elf_machine_rela): Likewise. (elf_machine_lazy_rel): Likewise. (elf_machine_lazy_rela): Likewise. * sysdeps/i386/dl-tls.h (struct dl_tls_index): Name it. * sysdeps/i386/dl-tlsdesc.S: New file. * sysdeps/i386/dl-tlsdesc.h: New file. * sysdeps/i386/tlsdesc.c: New file. * sysdeps/i386/tlsdesc.sym: New file. * sysdeps/i386/bits/linkmap.h (struct link_map_machine): Add tlsdesc_table. * sysdeps/x86_64/Makefile (sysdep-dl-routines, sysdep_routines, systep-rtld-routines): Add tlsdesc and dl-tlsdesc for elf subdir. (gen-as-const-headers): Add tlsdesc.sym to csu subdir. * sysdeps/x86_64/dl-lookupcfg.h: New file. Introduce _dl_unmap to release tlsdesc_table. * sysdeps/x86_64/dl-machine.h: Include dl-tlsdesc.h. (elf_machine_runtime_setup): Set up lazy TLSDESC GOT entry. (elf_machine_type_class): Mark R_X86_64_TLSDESC as PLT class. (elf_machine_rel): Handle R_X86_64_TLSDESC. (elf_machine_rela): Likewise. (elf_machine_lazy_rel): Likewise. * sysdeps/x86_64/dl-tls.h (struct dl_tls_index): Name it. (__tls_get_addr): Do not declare for non-shared compiles. * sysdeps/x86_64/dl-tlsdesc.S: New file. * sysdeps/x86_64/dl-tlsdesc.h: New file. * sysdeps/x86_64/tlsdesc.c: New file. * sysdeps/x86_64/tlsdesc.sym: New file. * sysdeps/x86_64/bits/linkmap.h (struct link_map_machine): Add tlsdesc_table for both 32- and 64-bit structs. --- elf/dl-reloc.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'elf/dl-reloc.c') diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index e9784c2..a303cb4 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -1,5 +1,5 @@ /* Relocate a shared object and resolve its references to other loaded objects. - Copyright (C) 1995-2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1995-2004, 2005, 2006, 2008 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 @@ -43,9 +43,9 @@ This function intentionally does not return any value but signals error directly, as static TLS should be rare and code handling it should not be inlined as much as possible. */ -void -internal_function __attribute_noinline__ -_dl_allocate_static_tls (struct link_map *map) +int +internal_function +_dl_try_allocate_static_tls (struct link_map *map) { /* If we've already used the variable with dynamic access, or if the alignment requirements are too high, fail. */ @@ -53,8 +53,7 @@ _dl_allocate_static_tls (struct link_map *map) || map->l_tls_align > GL(dl_tls_static_align)) { fail: - _dl_signal_error (0, map->l_name, NULL, N_("\ -cannot allocate memory in static TLS block")); + return -1; } #if TLS_TCB_AT_TP @@ -108,6 +107,20 @@ cannot allocate memory in static TLS block")); } else map->l_need_tls_init = 1; + + return 0; +} + +void +internal_function __attribute_noinline__ +_dl_allocate_static_tls (struct link_map *map) +{ + if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET + || _dl_try_allocate_static_tls (map)) + { + _dl_signal_error (0, map->l_name, NULL, N_("\ +cannot allocate memory in static TLS block")); + } } /* Initialize static TLS area and DTV for current (only) thread. @@ -248,23 +261,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], l->l_lookup_cache.value = _lr; })) \ : l) - /* This macro is used as a callback from elf_machine_rel{a,} when a - static TLS reloc is about to be performed. Since (in dl-load.c) we - permit dynamic loading of objects that might use such relocs, we - have to check whether each use is actually doable. If the object - whose TLS segment the reference resolves to was allocated space in - the static TLS block at startup, then it's ok. Otherwise, we make - an attempt to allocate it in surplus space on the fly. If that - can't be done, we fall back to the error that DF_STATIC_TLS is - intended to produce. */ -#define CHECK_STATIC_TLS(map, sym_map) \ - do { \ - if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET \ - || ((sym_map)->l_tls_offset \ - == FORCED_DYNAMIC_TLS_OFFSET), 0)) \ - _dl_allocate_static_tls (sym_map); \ - } while (0) - #include "dynamic-link.h" ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); -- cgit v1.1