about summary refs log tree commit diff
path: root/elf/dl-reloc.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-01-17 20:20:00 +0000
committerUlrich Drepper <drepper@redhat.com>2008-01-17 20:20:00 +0000
commit4c533566c2bb94162bcc1f66c5cf9db609e20803 (patch)
treeeb3d31e6a55056dc285e43b4700dccded4b88771 /elf/dl-reloc.c
parenta0f6c236e068b4fa2d1116cdf7d31b2c2722ab6c (diff)
downloadglibc-4c533566c2bb94162bcc1f66c5cf9db609e20803.tar.gz
glibc-4c533566c2bb94162bcc1f66c5cf9db609e20803.tar.xz
glibc-4c533566c2bb94162bcc1f66c5cf9db609e20803.zip
* include/link.h (FORCED_DYNAMIC_TLS_OFFSET): Define.
	* elf/dl-close.c (_dl_close): Check for it.
	* elf/dl-reloc.c (CHECK_STATIC_TLS): Likewise.
	(_dl_allocate_static_tls): Likewise.
	* elf/dl-tls.c (_dl_allocate_tls_init): Likewise.
	(__tls_get_addr): Protect from race conditions in setting l_tls_offset
	to it.
	* elf/tst-tls16.c: New file.
	* elf/tst-tlsmod16a.c: New file.
	* elf/tst-tlsmod16b.c: New file.
	* elf/Makefile: Add rules to build and run tst-tls16.
Diffstat (limited to 'elf/dl-reloc.c')
-rw-r--r--elf/dl-reloc.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index c315b5d972..e9784c2094 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -47,8 +47,10 @@ void
 internal_function __attribute_noinline__
 _dl_allocate_static_tls (struct link_map *map)
 {
-  /* If the alignment requirements are too high fail.  */
-  if (map->l_tls_align > GL(dl_tls_static_align))
+  /* If we've already used the variable with dynamic access, or if the
+     alignment requirements are too high, fail.  */
+  if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
+      || map->l_tls_align > GL(dl_tls_static_align))
     {
     fail:
       _dl_signal_error (0, map->l_name, NULL, N_("\
@@ -255,10 +257,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
        an attempt to allocate it in surplus space on the fly.  If that
        can't be done, we fall back to the error that DF_STATIC_TLS is
        intended to produce.  */
-#define CHECK_STATIC_TLS(map, sym_map)					      \
-    do {								      \
-      if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0))     \
-	_dl_allocate_static_tls (sym_map);				      \
+#define CHECK_STATIC_TLS(map, sym_map)					\
+    do {								\
+      if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET	\
+			    || ((sym_map)->l_tls_offset			\
+				== FORCED_DYNAMIC_TLS_OFFSET), 0))	\
+	_dl_allocate_static_tls (sym_map);				\
     } while (0)
 
 #include "dynamic-link.h"