diff options
-rw-r--r-- | ldso/ldso/ldso.c | 42 | ||||
-rw-r--r-- | test/tls/Makefile | 6 | ||||
-rw-r--r-- | test/tls/tst-tls16.c | 21 | ||||
-rw-r--r-- | test/tls/tst-tlsmod16.c | 25 |
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"); +} |