diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-05-05 06:20:31 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-05-05 06:20:31 +0200 |
commit | 7cbf1c8416b04c65dc3d253061d8a674ee3c616e (patch) | |
tree | e931adb0174f9f4ce64f4dfa97c6fcd489f0fc12 /elf/dl-tls.c | |
parent | 2c71177309cc59788c2288c6033c9dbbd23f02c3 (diff) | |
download | glibc-7cbf1c8416b04c65dc3d253061d8a674ee3c616e.zip glibc-7cbf1c8416b04c65dc3d253061d8a674ee3c616e.tar.gz glibc-7cbf1c8416b04c65dc3d253061d8a674ee3c616e.tar.bz2 |
elf, nptl: Initialize static TLS directly in ld.so
The stack list is available in ld.so since commit
1daccf403b1bd86370eb94edca794dc106d02039 ("nptl: Move stack list
variables into _rtld_global"), so it's possible to walk the stack
list directly in ld.so and perform the initialization there.
This eliminates an unprotected function pointer from _rtld_global
and reduces the libpthread initialization code.
Diffstat (limited to 'elf/dl-tls.c')
-rw-r--r-- | elf/dl-tls.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/elf/dl-tls.c b/elf/dl-tls.c index f8b32b3..6baff0c 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -29,6 +29,10 @@ #include <dl-tls.h> #include <ldsodefs.h> +#if THREAD_GSCOPE_IN_TCB +# include <list.h> +#endif + #define TUNABLE_NAMESPACE rtld #include <dl-tunables.h> @@ -1005,3 +1009,38 @@ cannot create TLS data structures")); listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; } } + +#if THREAD_GSCOPE_IN_TCB +static inline void __attribute__((always_inline)) +init_one_static_tls (struct pthread *curp, struct link_map *map) +{ +# if TLS_TCB_AT_TP + void *dest = (char *) curp - map->l_tls_offset; +# elif TLS_DTV_AT_TP + void *dest = (char *) curp + map->l_tls_offset + TLS_PRE_TCB_SIZE; +# else +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" +# endif + + /* Initialize the memory. */ + memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size), + '\0', map->l_tls_blocksize - map->l_tls_initimage_size); +} + +void +_dl_init_static_tls (struct link_map *map) +{ + lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE); + + /* Iterate over the list with system-allocated threads first. */ + list_t *runp; + list_for_each (runp, &GL (dl_stack_used)) + init_one_static_tls (list_entry (runp, struct pthread, list), map); + + /* Now the list with threads using user-allocated stacks. */ + list_for_each (runp, &GL (dl_stack_user)) + init_one_static_tls (list_entry (runp, struct pthread, list), map); + + lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE); +} +#endif /* THREAD_GSCOPE_IN_TCB */ |