summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/dl-tls.c5
-rw-r--r--test/tls/Makefile.in11
-rw-r--r--test/tls/tst-tls18.c38
-rw-r--r--test/tls/tst-tlsmod18a.c21
4 files changed, 73 insertions, 2 deletions
diff --git a/ldso/ldso/dl-tls.c b/ldso/ldso/dl-tls.c
index 52b7aa534..d2808f968 100644
--- a/ldso/ldso/dl-tls.c
+++ b/ldso/ldso/dl-tls.c
@@ -842,7 +842,10 @@ __tls_get_addr (GET_ADDR_ARGS)
void *p;
if (__builtin_expect (dtv[0].counter != _dl_tls_generation, 0))
- the_map = _dl_update_slotinfo (GET_ADDR_MODULE);
+ {
+ the_map = _dl_update_slotinfo (GET_ADDR_MODULE);
+ dtv = THREAD_DTV ();
+ }
p = dtv[GET_ADDR_MODULE].pointer.val;
diff --git a/test/tls/Makefile.in b/test/tls/Makefile.in
index 082ab1cd0..69a8eaf27 100644
--- a/test/tls/Makefile.in
+++ b/test/tls/Makefile.in
@@ -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-tls16 tst-tls17 tst-tls-at-ctor \
+ tst-tls14 tst-tls15 tst-tls16 tst-tls17 tst-tls18 tst-tls-at-ctor \
tst-tls1-static tst-tls2-static tst-tls9-static
TESTS_DISABLED := tst-tls1-static tst-tls2-static tst-tls9-static
@@ -27,6 +27,7 @@ EXTRA_CFLAGS := -DNOT_IN_libc=1 \
-include $(top_builddir)include/libc-symbols.h
tlsmod17a-suffixes := 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+tlsmod18a-suffixes := 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
CFLAGS_tst-tlsmod1.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod2.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod3.so := -fPIC -DSHARED -shared
@@ -49,6 +50,7 @@ CFLAGS_tst-tlsmod16a.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod16b.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod17a.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod17b.so := -fPIC -DSHARED -shared
+CFLAGS_tst-tlsmod18a.so := -fPIC -DSHARED -shared
CFLAGS_tst-tlsmod-at-ctor.so := -fPIC -DSHARED -shared
LDFLAGS_tst-tlsmod1.so := -shared -static-libgcc -L$(top_builddir)lib
@@ -80,6 +82,7 @@ LDFLAGS_tst-tlsmod16b.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tlsmod17a.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tlsmod17b.so := -shared -static-libgcc -L$(top_builddir)lib \
$(patsubst %,tst-tlsmod17a%.so,$(tlsmod17a-suffixes))
+LDFLAGS_tst-tlsmod18a.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tlsmod-at-ctor.so := -shared -static-libgcc -L$(top_builddir)lib
LDFLAGS_tst-tls3 := tst-tlsmod1.so tst-tlsmod4.so
@@ -97,6 +100,7 @@ LDFLAGS_tst-tls14 := -ldl -Wl,-rpath-link=. tst-tlsmod14a.so
LDFLAGS_tst-tls15 := -ldl -Wl,-rpath-link=.
LDFLAGS_tst-tls16 := -ldl -Wl,-rpath-link=.
LDFLAGS_tst-tls17 := -ldl -Wl,-rpath-link=.
+LDFLAGS_tst-tls18 := -ldl -Wl,-rpath-link=.
LDFLAGS_tst-tls-at-ctor := tst-tlsmod-at-ctor.so
tst-tls3: tst-tlsmod1.so tst-tlsmod4.so
@@ -119,6 +123,11 @@ tst-tlsmod17a%.so: tst-tlsmod17a.c
$(Q)$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_tst-tlsmod17a.so) $< -o $@ \
-DN=$* -Wl,-soname,$@ $(LDFLAGS) $(EXTRA_LIBS) \
$(LDFLAGS_tst-tlsmod17a.so)
+tst-tls18: $(patsubst %,tst-tlsmod18a%.so,$(tlsmod18a-suffixes))
+tst-tlsmod18a%.so: tst-tlsmod18a.c
+ $(Q)$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_tst-tlsmod18a.so) $< -o $@ \
+ -DN=$* -Wl,-soname,$@ $(LDFLAGS) $(EXTRA_LIBS) \
+ $(LDFLAGS_tst-tlsmod18a.so)
tst-tls-at-ctor: tst-tlsmod-at-ctor.so
RET_tst-tls13 := 1
diff --git a/test/tls/tst-tls18.c b/test/tls/tst-tls18.c
new file mode 100644
index 000000000..00dcdff4e
--- /dev/null
+++ b/test/tls/tst-tls18.c
@@ -0,0 +1,38 @@
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+ char modname[sizeof "tst-tlsmod18aXX.so"];
+ void *h[20];
+ for (int i = 0; i < 20; i++)
+ {
+ snprintf (modname, sizeof modname, "tst-tlsmod18a%d.so", i);
+ h[i] = dlopen (modname, RTLD_LAZY);
+ if (h[i] == NULL)
+ {
+ printf ("unexpectedly failed to open %s", modname);
+ exit (1);
+ }
+ }
+
+ for (int i = 0; i < 20; i++)
+ {
+ int (*fp) (void) = (int (*) (void)) dlsym (h[i], "test");
+ if (fp == NULL)
+ {
+ printf ("cannot find test in tst-tlsmod18a%d.so", i);
+ exit (1);
+ }
+
+ if (fp ())
+ exit (1);
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/test/tls/tst-tlsmod18a.c b/test/tls/tst-tlsmod18a.c
new file mode 100644
index 000000000..9aba607ed
--- /dev/null
+++ b/test/tls/tst-tlsmod18a.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+#ifndef N
+# define N 0
+#endif
+
+static __thread int var = 4;
+
+int
+test (void)
+{
+ int *p = &var;
+ /* GCC assumes &var is never NULL, add optimization barrier. */
+ __asm __volatile ("" : "+r" (p));
+ if (p == NULL || *p != 4)
+ {
+ printf ("fail %d %p\n", N, p);
+ return 1;
+ }
+ return 0;
+}