libc/ 2014-10-18 Jan Kratochvil * NEWS: Add _dl_tls_get_addr_link_map note. * elf/Makefile (tests): Add tst-tls20. ($(objpfx)tst-tls20): New. * elf/Versions (GLIBC_2.21): New. * elf/dl-tls.c: Conditionally define GET_ADDR_FORWARD. (_dl_tls_get_addr_link_map): New function. * elf/tst-tls20.c: New file. * sysdeps/ia64/dl-tls.h (GET_ADDR_FORWARD): New. diff --git a/NEWS b/NEWS index f3e222d..3e3d33d 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,9 @@ Version 2.21 * The following bugs are resolved with this release: 6652, 12926, 14171, 15884, 17266, 17363, 17370, 17371, 17411, 17460. + +* ELF thread-local storage support (TLS) has now new function + _dl_tls_get_addr_link_map in ld.so. Version 2.20 diff --git a/elf/Makefile b/elf/Makefile index 94074f3..b634b8d 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -146,7 +146,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ tst-stackguard1 tst-addr1 tst-thrlock \ tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ - tst-ptrguard1 + tst-ptrguard1 tst-tls20 # reldep9 ifeq ($(build-hardcoded-path-in-tests),yes) tests += tst-dlopen-aout @@ -513,6 +513,7 @@ $(objpfx)tst-initordera3.so: $(objpfx)tst-initorderb2.so $(objpfx)tst-initorderb $(objpfx)tst-initordera4.so: $(objpfx)tst-initordera3.so $(objpfx)tst-initorder: $(objpfx)tst-initordera4.so $(objpfx)tst-initordera1.so $(objpfx)tst-initorderb2.so $(objpfx)tst-null-argv: $(objpfx)tst-null-argv-lib.so +$(objpfx)tst-tls20: $(objpfx)ld.so tst-null-argv-ENV = LD_DEBUG=all LD_DEBUG_OUTPUT=$(objpfx)tst-null-argv.debug.out LDFLAGS-nodel2mod3.so = $(no-as-needed) diff --git a/elf/Versions b/elf/Versions index 23deda9..af9f824 100644 --- a/elf/Versions +++ b/elf/Versions @@ -50,6 +50,9 @@ ld { # stack canary __stack_chk_guard; } + GLIBC_2.21 { + _dl_tls_get_addr_link_map; + } GLIBC_PRIVATE { # Those are in the dynamic linker, but used by libc.so. __libc_enable_secure; diff --git a/elf/dl-tls.c b/elf/dl-tls.c index 5204fda..4ac4550 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -547,6 +547,11 @@ rtld_hidden_def (_dl_deallocate_tls) # ifndef GET_ADDR_OFFSET # define GET_ADDR_OFFSET ti->ti_offset # endif +# ifndef GET_ADDR_FORWARD +# define GET_ADDR_FORWARD(modid, offset) \ + tls_index ti = { modid, offset }; \ + return __tls_get_addr (&ti); +# endif static void * @@ -807,6 +812,15 @@ __tls_get_addr (GET_ADDR_ARGS) return (char *) p + GET_ADDR_OFFSET; } + +/* Provide __tls_get_addr interface using link_map * + when GET_ADDR_MODULE value is not known. */ +void * +_dl_tls_get_addr_link_map (const struct link_map *ti_module_link_map, + unsigned long int ti_offset) +{ + GET_ADDR_FORWARD (ti_module_link_map->l_tls_modid, ti_offset) +} #endif diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c new file mode 100644 index 0000000..24dcb0d --- /dev/null +++ b/elf/tst-tls20.c @@ -0,0 +1,24 @@ +#include +#include +#include + +extern + void *_dl_tls_get_addr_link_map (const struct link_map *ti_module_link_map, + unsigned long int ti_offset); + +#define TLSVAR_OFFSET 0 +__thread int tlsvar; + +int +main (void) +{ + /* Main executable is the first entry. + Cast it for internal libc headers compatibility. */ + struct link_map *map = (void *) _r_debug.r_map; + int *tlsvarp = _dl_tls_get_addr_link_map (map, TLSVAR_OFFSET); + + if (tlsvarp != &tlsvar) + abort (); + + return 0; +} diff --git a/sysdeps/ia64/dl-tls.h b/sysdeps/ia64/dl-tls.h index 9e63c8e..22022c8 100644 --- a/sysdeps/ia64/dl-tls.h +++ b/sysdeps/ia64/dl-tls.h @@ -19,10 +19,12 @@ /* On IA-64 the __tls_get_addr function take the module ID and the offset as parameters. */ -#define GET_ADDR_ARGS size_t tls_ia64_m, size_t tls_ia64_offset -#define GET_ADDR_PARAM tls_ia64_m, tls_ia64_offset -#define GET_ADDR_MODULE tls_ia64_m -#define GET_ADDR_OFFSET tls_ia64_offset +#define GET_ADDR_ARGS size_t tls_ia64_m, \ + size_t tls_ia64_offset +#define GET_ADDR_PARAM tls_ia64_m, tls_ia64_offset +#define GET_ADDR_MODULE tls_ia64_m +#define GET_ADDR_OFFSET tls_ia64_offset +#define GET_ADDR_FORWARD(modid, offset) return __tls_get_addr (modid, offset); /* We have no tls_index type. */ #define DONT_USE_TLS_INDEX 1