aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-10-31 20:50:16 +0000
committerUlrich Drepper <drepper@redhat.com>2008-10-31 20:50:16 +0000
commit41e25904a520d49ba14d7e9a0a7ea84731572ebd (patch)
tree953dbd8a651ae74dde22e8b277592a2f9057b5d5 /elf
parente148a6443cfeb032ac872d4134e4d41446932879 (diff)
downloadglibc-41e25904a520d49ba14d7e9a0a7ea84731572ebd.zip
glibc-41e25904a520d49ba14d7e9a0a7ea84731572ebd.tar.gz
glibc-41e25904a520d49ba14d7e9a0a7ea84731572ebd.tar.bz2
* elf/dl-tls.c (__tls_get_addr): After calling _dl_update_slotinfocvs/fedora-glibc-20081031T2102
refetch dtv, as it might have changed. * elf/Makefile: Add rules to build and run tst-tls18. * elf/tst-tls18.c: New test. * elf/tst-tlsmod18a.c: New file.
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile10
-rw-r--r--elf/dl-tls.c5
-rw-r--r--elf/tst-tls18.c37
-rw-r--r--elf/tst-tlsmod18a.c21
4 files changed, 71 insertions, 2 deletions
diff --git a/elf/Makefile b/elf/Makefile
index df3170c..8079fe9 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -166,7 +166,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \
- tst-tls16 tst-tls17 tst-tls-dlinfo \
+ tst-tls16 tst-tls17 tst-tls18 tst-tls-dlinfo \
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
tst-dlmodcount tst-dlopenrpath tst-deep1 \
tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
@@ -182,6 +182,7 @@ tests: $(objpfx)tst-pie1.out
endif
tests: $(objpfx)tst-leaks1-mem
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
modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
testobj1_1 failobj constload2 constload3 unloadmod \
dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \
@@ -203,6 +204,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \
$(patsubst %,tst-tlsmod17a%,$(tlsmod17a-suffixes)) \
tst-tlsmod17b \
+ $(patsubst %,tst-tlsmod18a%,$(tlsmod18a-suffixes)) \
circlemod1 circlemod1a circlemod2 circlemod2a \
circlemod3 circlemod3a \
reldep8mod1 reldep8mod2 reldep8mod3 \
@@ -724,6 +726,12 @@ $(patsubst %,$(objpfx)tst-tlsmod17a%.os,$(tlsmod17a-suffixes)): $(objpfx)tst-tls
$(patsubst %,$(objpfx)tst-tlsmod17a%.so,$(tlsmod17a-suffixes)): $(objpfx)tst-tlsmod17a%.so: $(objpfx)ld.so
$(objpfx)tst-tlsmod17b.so: $(patsubst %,$(objpfx)tst-tlsmod17a%.so,$(tlsmod17a-suffixes))
+$(objpfx)tst-tls18: $(libdl)
+$(objpfx)tst-tls18.out: $(patsubst %,$(objpfx)tst-tlsmod18a%.so,$(tlsmod18a-suffixes))
+$(patsubst %,$(objpfx)tst-tlsmod18a%.os,$(tlsmod18a-suffixes)): $(objpfx)tst-tlsmod18a%.os : tst-tlsmod18a.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ -DN=$* -DNOT_IN_libc=1 $<
+$(patsubst %,$(objpfx)tst-tlsmod18a%.so,$(tlsmod18a-suffixes)): $(objpfx)tst-tlsmod18a%.so: $(objpfx)ld.so
+
CFLAGS-tst-align.c = $(stack-align-test-flags)
CFLAGS-tst-align2.c = $(stack-align-test-flags)
CFLAGS-tst-alignmod.c = $(stack-align-test-flags)
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index e234a0a..824adc1 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -756,7 +756,10 @@ __tls_get_addr (GET_ADDR_ARGS)
void *p;
if (__builtin_expect (dtv[0].counter != GL(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/elf/tst-tls18.c b/elf/tst-tls18.c
new file mode 100644
index 0000000..96b8e6b
--- /dev/null
+++ b/elf/tst-tls18.c
@@ -0,0 +1,37 @@
+#include <dlfcn.h>
+#include <stdio.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/elf/tst-tlsmod18a.c b/elf/tst-tlsmod18a.c
new file mode 100644
index 0000000..1d728da
--- /dev/null
+++ b/elf/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;
+}