summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/ldso.c42
-rw-r--r--test/tls/Makefile6
-rw-r--r--test/tls/tst-tls16.c21
-rw-r--r--test/tls/tst-tlsmod16.c25
4 files changed, 72 insertions, 22 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 8a57e784a..c05db8241 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -842,6 +842,27 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
_dl_protect_relro (tpnt);
}
+ if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
+ ++_dl_tls_generation;
+
+ _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
+
+ /* Now that we have completed relocation, the initializer data
+ for the TLS blocks has its final values and we can copy them
+ into the main thread's TLS area, which we allocated above. */
+ _dl_allocate_tls_init (tcbp);
+
+ /* And finally install it for the main thread. If ld.so itself uses
+ TLS we know the thread pointer was initialized earlier. */
+ if (! tls_init_tp_called)
+ {
+ const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
+ if (__builtin_expect (lossage != NULL, 0))
+ {
+ _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
+ _dl_exit(30);
+ }
+ }
/* OK, at this point things are pretty much ready to run. Now we need
* to touch up a few items that are required, and then we can let the
* user application have at it. Note that the dynamic linker itself
@@ -921,27 +942,6 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
_dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
_dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
- if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
- ++_dl_tls_generation;
-
- _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
-
- /* Now that we have completed relocation, the initializer data
- for the TLS blocks has its final values and we can copy them
- into the main thread's TLS area, which we allocated above. */
- _dl_allocate_tls_init (tcbp);
-
- /* And finally install it for the main thread. If ld.so itself uses
- TLS we know the thread pointer was initialized earlier. */
- if (! tls_init_tp_called)
- {
- const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
- if (__builtin_expect (lossage != NULL, 0))
- {
- _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
- _dl_exit(30);
- }
- }
#endif
/* Notify the debugger that all objects are now mapped in. */
diff --git a/test/tls/Makefile b/test/tls/Makefile
index 00fcb0064..223ad7a87 100644
--- a/test/tls/Makefile
+++ b/test/tls/Makefile
@@ -3,7 +3,7 @@
TESTS := tst-tls1 tst-tls2 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 \
tst-tls8 tst-tls9 tst-tls10 tst-tls11 tst-tls12 tst-tls13 \
- tst-tls14 tst-tls15 tst-tls1-static tst-tls2-static \
+ tst-tls14 tst-tls15 tst-tls16 tst-tls1-static tst-tls2-static \
tst-tls9-static
TESTS_DISABLED := tst-tls1-static tst-tls2-static tst-tls9-static
@@ -42,6 +42,7 @@ CFLAGS_tst-tlsmod14a.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod14b.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod15a.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod15b.so := -fPIC -DSHARED -shared
+CFLAGS_tst-tlsmod16.so := -fPIC -DSHARED -shared
LDFLAGS_tst-tlsmod1.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tlsmod2.so := -shared -static-libgcc -L$(top_builddir)lib
@@ -66,6 +67,7 @@ LDFLAGS_tst-tlsmod14a.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tlsmod14b.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tlsmod15a.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tlsmod15b.so := -shared -static-libgcc -L$(top_builddir)lib
+LDFLAGS_tst-tlsmod16.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tls3 := tst-tlsmod1.so
LDFLAGS_tst-tls4 := -ldl
@@ -80,6 +82,7 @@ LDFLAGS_tst-tls12 := -Wl,-rpath-link=. tst-tlsmod12.so
LDFLAGS_tst-tls13 := -ldl -Wl,-rpath-link=.
LDFLAGS_tst-tls14 := -ldl -Wl,-rpath-link=. tst-tlsmod14a.so
LDFLAGS_tst-tls15 := -ldl -Wl,-rpath-link=.
+LDFLAGS_tst-tls16 := tst-tlsmod16.so
tst-tls3: tst-tlsmod1.so
tst-tls4: tst-tlsmod2.so
@@ -94,6 +97,7 @@ tst-tls12: tst-tlsmod11.so tst-tlsmod12.so
tst-tls13: tst-tlsmod13.so tst-tlsmod13a.so
tst-tls14: tst-tlsmod14a.so tst-tlsmod14b.so
tst-tls15: tst-tlsmod15a.so tst-tlsmod15b.so
+tst-tls16: tst-tlsmod16.so
RET_tst-tls13 := 1
ifeq ($(TARGET_ARCH),mips)
diff --git a/test/tls/tst-tls16.c b/test/tls/tst-tls16.c
new file mode 100644
index 000000000..53aece181
--- /dev/null
+++ b/test/tls/tst-tls16.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <tls.h>
+
+#define TLS_VAR_INIT_VALUE 99
+
+#ifdef USE_TLS
+extern __thread int tls_var;
+#endif
+
+int main(void)
+{
+ int ret = EXIT_SUCCESS;
+#ifdef USE_TLS
+ if (tls_var != TLS_VAR_INIT_VALUE) {
+ printf("tls_var = %d - Expected value = %d\n", tls_var, TLS_VAR_INIT_VALUE);
+ ret = EXIT_FAILURE;
+ }
+#endif
+ return ret;
+}
diff --git a/test/tls/tst-tlsmod16.c b/test/tls/tst-tlsmod16.c
new file mode 100644
index 000000000..bd04b5081
--- /dev/null
+++ b/test/tls/tst-tlsmod16.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <tls.h>
+
+#define TLS_VAR_INIT_VALUE 99
+
+#ifdef USE_TLS
+__thread int tls_var __attribute__((tls_model("global-dynamic")));
+static __thread int local_tls_var __attribute__((tls_model("local-dynamic")));
+#endif
+
+void __attribute__((constructor)) libtls_ctor(void);
+void libtls_ctor(void)
+{
+ printf("libtls: constructor!\n");
+#ifdef USE_TLS
+ local_tls_var = TLS_VAR_INIT_VALUE;
+ tls_var = local_tls_var;
+#endif
+}
+
+void __attribute__((destructor)) libtls_dtor(void);
+void libtls_dtor(void)
+{
+ printf("libtls: destructor!\n");
+}