aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-tls.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2021-05-05 06:20:31 +0200
committerFlorian Weimer <fweimer@redhat.com>2021-05-05 06:20:31 +0200
commit7cbf1c8416b04c65dc3d253061d8a674ee3c616e (patch)
treee931adb0174f9f4ce64f4dfa97c6fcd489f0fc12 /elf/dl-tls.c
parent2c71177309cc59788c2288c6033c9dbbd23f02c3 (diff)
downloadglibc-7cbf1c8416b04c65dc3d253061d8a674ee3c616e.tar
glibc-7cbf1c8416b04c65dc3d253061d8a674ee3c616e.tar.gz
glibc-7cbf1c8416b04c65dc3d253061d8a674ee3c616e.tar.bz2
glibc-7cbf1c8416b04c65dc3d253061d8a674ee3c616e.zip
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.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index f8b32b3ecb..6baff0c1ea 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 */