Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 10 Feb 2002 09:15:59 +0000 (09:15 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 10 Feb 2002 09:15:59 +0000 (09:15 +0000)
* elf/tst-tls1.c (main): Add complete set of tests.  Split
architecture specific definitions from the actual test code.

ChangeLog
elf/tst-tls1.c

index a842ca7..2f05470 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2002-02-10  Ulrich Drepper  <drepper@redhat.com>
 
+       * elf/tst-tls1.c (main): Add complete set of tests.  Split
+       architecture specific definitions from the actual test code.
+
        * po/tr.po: Update from translation team.
 
 2002-02-09  Ulrich Drepper  <drepper@redhat.com>
index 4d09138..fc426b0 100644 (file)
@@ -6,14 +6,8 @@
 
 /* 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");
+asm (".tls_common foo,4,4");
+asm (".tls_common bar,4,4");
 
 
 int
@@ -21,59 +15,121 @@ main (void)
 {
 #ifdef USE_TLS
   int result = 0;
-  int a, b;
+  int *ap, *bp;
 
   /* 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)");
+#  define TLS_LE(x) \
+  ({ int *__l;                                                               \
+     asm ("movl %%gs:0,%0\n\t"                                               \
+         "subl $" #x "@tpoff,%0"                                             \
+         : "=r" (__l));                                                      \
+     __l; })
 
-#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
+#define TLS_IE(x) \
+  ({ int *__l, __b;                                                          \
+     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,%0\n\t"                                                \
+         "subl " #x "@gottpoff(%%ebx),%0"                                    \
+         : "=r" (__l), "=&b" (__b));                                         \
+     __l; })
 
-  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;
+#define TLS_LD(x) \
+  ({ int *__l, __b;                                                          \
+     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 " #x "@tlsldm(%%ebx),%%eax\n\t"                               \
+         "call ___tls_get_addr@plt\n\t"                                      \
+         "leal " #x "@dtpoff(%%eax), %%eax"                                  \
+         : "=a" (__l), "=&b" (__b));                                         \
+     __l; })
+
+#define TLS_GD(x) \
+  ({ int *__l, __b;                                                          \
+     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 " #x "@tlsgd(%%ebx),%%eax\n\t"                                \
+         "call ___tls_get_addr@plt\n\t"                                      \
+         "nop"                                                               \
+         : "=a" (__l), "=&b" (__b));                                         \
+     __l; })
 
 # else
 #  error "No support for this architecture so far."
 # endif
 
+  /* Set the variable using the local exec model.  */
+  puts ("set bar to 1 (LE)");
+  ap = TLS_LE (bar);
+  *ap = 1;
+
+
+  /* Get variables using initial exec model.  */
+  fputs ("get sum of foo and bar (IE)", stdout);
+  ap = TLS_IE (foo);
+  bp = TLS_IE (bar);
+  printf (" = %d\n", *ap + *bp);
+  result |= *ap + *bp != 1;
+  if (*ap != 0)
+    {
+      printf ("foo = %d\n", *ap);
+      result = 1;
+    }
+  if (*bp != 1)
+    {
+      printf ("bar = %d\n", *bp);
+      result = 1;
+    }
+
+
+  /* Get variables using local dynamic model.  */
+  fputs ("get sum of foo and bar (LD)", stdout);
+  ap = TLS_LD (foo);
+  bp = TLS_LD (bar);
+  printf (" = %d\n", *ap + *bp);
+  result |= *ap + *bp != 1;
+  if (*ap != 0)
+    {
+      printf ("foo = %d\n", *ap);
+      result = 1;
+    }
+  if (*bp != 1)
+    {
+      printf ("bar = %d\n", *bp);
+      result = 1;
+    }
+
+
+  /* Get variables using generic dynamic model.  */
+  fputs ("get sum of foo and bar (GD)", stdout);
+  ap = TLS_GD (foo);
+  bp = TLS_GD (bar);
+  printf (" = %d\n", *ap + *bp);
+  result |= *ap + *bp != 1;
+  if (*ap != 0)
+    {
+      printf ("foo = %d\n", *ap);
+      result = 1;
+    }
+  if (*bp != 1)
+    {
+      printf ("bar = %d\n", *bp);
+      result = 1;
+    }
+
   return result;
 #else
   return 0;