summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--elf/Makefile2
-rw-r--r--elf/rtld.c3
-rw-r--r--elf/tst-tls1.c81
-rw-r--r--sysdeps/generic/dl-tls.c18
5 files changed, 100 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index e131c96a07..0d21e736e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,16 @@
 2002-02-09  Ulrich Drepper  <drepper@redhat.com>
 
+	* elf/Makefile (tests): Add tst-tls1.
+	* elf/tst-tls1.c: New file.
+
+	* sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): Don't handle
+	alignment of TCB for now.
+
+	* elf/rtld.c (dl_main): Use p_vaddr as address of TLS
+	initialization image for the application itself.
+
 	* sysdeps/generic/dl-tls.c (_dl_allocate_tls): Correctly terminate
-	loop to initial TLS block.
+	loop to initialize TLS block.
 
 2002-02-08  Richard Henderson  <rth@twiddle.net>
 
diff --git a/elf/Makefile b/elf/Makefile
index 476341902d..4235a594e8 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -117,7 +117,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 	reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \
 	$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
 	neededtest3 neededtest4 unload2 lateglobal initfirst global \
-	restest2 next dblload dblunload reldep5 reldep6
+	restest2 next dblload dblunload reldep5 reldep6 tst-tls1
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
 tests-nodelete-yes = nodelete
diff --git a/elf/rtld.c b/elf/rtld.c
index 2ebde4530a..f87462eda8 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -730,8 +730,7 @@ of this helper program; chances are you did not intend to run this program.\n\
 	GL(dl_loaded)->l_tls_blocksize = ph->p_memsz;
 	GL(dl_loaded)->l_tls_align = ph->p_align;
 	GL(dl_loaded)->l_tls_initimage_size = ph->p_filesz;
-	GL(dl_loaded)->l_tls_initimage = (void *) (GL(dl_loaded)->l_addr
-						   + ph->p_offset);
+	GL(dl_loaded)->l_tls_initimage = (void *) ph->p_vaddr;
 	/* This is the first element of the initialization image list.
 	   We create the list as circular since we have to append at
 	   the end.  */
diff --git a/elf/tst-tls1.c b/elf/tst-tls1.c
new file mode 100644
index 0000000000..4d0913890c
--- /dev/null
+++ b/elf/tst-tls1.c
@@ -0,0 +1,81 @@
+/* glibc test for TLS in ld.so.  */
+#include <stdio.h>
+
+#include <tls.h>
+
+
+/* XXX Until gcc gets told how to define and use thread-local
+   variables we will have to resort to use asms.  */
+//asm (".tls_common foo,4,4");
+asm (".section \".tdata\", \"awT\", @progbits\n\t"
+     ".align 4\n\t"
+     ".globl foo\n"
+     "foo:\t.long 0\n\t"
+     ".globl bar\n"
+     "bar:\t.long 0\n\t"
+     ".previous");
+
+
+int
+main (void)
+{
+#ifdef USE_TLS
+  int result = 0;
+  int a, b;
+
+  /* XXX Each architecture must have its own asm for now.  */
+# ifdef __i386__
+  /* Set the variable using the local exec model.  */
+  puts ("set bar to 1 (LE)");
+  asm ("movl %gs:0,%eax\n\t"
+     "subl $bar@tpoff,%eax\n\t"
+     "movl $1,(%eax)");
+
+#if 0
+  // XXX Doesn't work yet; no runtime relocations.
+  fputs ("get sum of foo and bar (IE)", stdout);
+  asm ("call 1f\n\t"
+       ".subsection 1\n"
+       "1:\tmovl (%%esp), %%ebx\n\t"
+       "ret\n\t"
+       ".previous\n\t"
+       "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t"
+       "movl %%gs:0,%%eax\n\t"
+       "movl %%eax,%%edx\n\t"
+       "addl foo@gottpoff(%%ebx),%%eax\n\t"
+       "addl bar@gottpoff(%%ebx),%%eax\n\t"
+       "movl (%%eax), %0\n\t"
+       "addl (%%edx), %0"
+       : "=a" (a), "=&b" (b));
+  printf (" = %d\n", a);
+  result |= a != 1;
+#endif
+
+  fputs ("get sum of foo and bar (GD)", stdout);
+  asm ("call 1f\n\t"
+       ".subsection 1\n"
+       "1:\tmovl (%%esp), %%ebx\n\t"
+       "ret\n\t"
+       ".previous\n\t"
+       "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t"
+       "leal foo@tlsgd(%%ebx),%%eax\n\t"
+       "call ___tls_get_addr@plt\n\t"
+       "nop\n\t"
+       "movl (%%eax), %%edx\n\t"
+       "leal bar@tlsgd(%%ebx),%%eax\n\t"
+       "call ___tls_get_addr@plt\n\t"
+       "nop\n\t"
+       "addl (%%eax), %%edx\n\t"
+       : "=&a" (a), "=d" (b));
+  printf (" = %d\n", b);
+  result |= b != 1;
+
+# else
+#  error "No support for this architecture so far."
+# endif
+
+  return result;
+#else
+  return 0;
+#endif
+}
diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c
index 5c05baee0c..2c5fa75b62 100644
--- a/sysdeps/generic/dl-tls.c
+++ b/sysdeps/generic/dl-tls.c
@@ -112,21 +112,17 @@ _dl_determine_tlsoffset (struct link_map *firstp)
     }
   while ((runp = runp->l_tls_nextimage) != firstp);
 
+#if 0
   /* The thread descriptor (pointed to by the thread pointer) has its
      own alignment requirement.  Adjust the static TLS size
      and TLS offsets appropriately.  */
+  // XXX How to deal with this.  We cannot simply add zero bytes
+  // XXX after the first (closest to the TCB) TLS block since this
+  // XXX would invalidate the offsets the linker creates for the LE
+  // XXX model.
   if (offset % TLS_TCB_ALIGN != 0)
-    {
-      size_t add = TLS_TCB_ALIGN - offset % TLS_TCB_ALIGN;
-
-      /* XXX If the offset stored is negative we must subtract here.  */
-      offset += add;
-
-      runp = firstp;
-      do
-	runp->l_tls_offset += add;
-      while ((runp = runp->l_tls_nextimage) != firstp);
-    }
+    abort ();
+#endif
 
   GL(dl_tls_static_size) = offset + TLS_TCB_SIZE;
 # elif TLS_DTV_AT_TP