Quellcode durchsuchen

test/tls: fix ebx clobber in i386 TLS_IE/TLS_GD macros

The non-PIC variants of TLS_IE and TLS_GD load %ebx with the GOT
address through a PC thunk but do not tell the compiler (only
"=r" (__l) is declared; non-PIC TLS_LD already does this right with
its "=&b" (__b) dummy output).  At -O2 gcc is free to keep a live
value in %ebx across the asm - and does: it places the result of the
previous TLS_* macro there, which the next macro's thunk then
clobbers.  tst-tls1/tst-tls2 then add up GOT[0] (the address of
_DYNAMIC, e.g. 0x080462AC) instead of the TLS variable:

  get sum of foo and bar (IE) = 134528812

This is invisible at -O0 (values live on the stack), which is why the
suite's default build never hit it; the openadk package build uses -O2
and fails exactly like this on i686 with gcc 13 and gcc 15.

The PIC variants silently assumed %ebx already holds the GOT address,
which modern gcc (no reserved PIC register since gcc 5) does not
guarantee either.  Unify all GOT-using macros to the thunk form with a
"=&b" dummy output and drop the __PIC__ split.

Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>
ramin vor 1 Monat
Ursprung
Commit
d97a31f0aa
1 geänderte Dateien mit 10 neuen und 36 gelöschten Zeilen
  1. 10 36
      test/tls/tls-macros-i386.h

+ 10 - 36
test/tls/tls-macros-i386.h

@@ -5,16 +5,11 @@
 	  : "=r" (__l));						      \
      __l; })
 
-#ifdef __PIC__
-# define TLS_IE(x) \
-  ({ int *__l;								      \
-     __asm__ ("movl %%gs:0,%0\n\t"						      \
-	  "subl " #x "@gottpoff(%%ebx),%0"				      \
-	  : "=r" (__l));						      \
-     __l; })
-#else
-# define TLS_IE(x) \
-  ({ int *__l;                                                               \
+/* The GOT-using sequences load %ebx themselves and must reserve it via
+   a dummy "b" output, or gcc may keep a live value there across the asm.  */
+
+#define TLS_IE(x) \
+  ({ int *__l, __b;							      \
      __asm__ ("call 1f\n\t"							      \
 	  ".subsection 1\n"						      \
 	  "1:\tmovl (%%esp), %%ebx\n\t"					      \
@@ -23,20 +18,10 @@
 	  "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t"			      \
 	  "movl %%gs:0,%0\n\t"						      \
 	  "subl " #x "@gottpoff(%%ebx),%0"				      \
-	  : "=r" (__l));					              \
+	  : "=r" (__l), "=&b" (__b));					      \
      __l; })
-#endif
 
-#ifdef __PIC__
-# define TLS_LD(x) \
-  ({ int *__l, __c, __d;						      \
-     __asm__ ("leal " #x "@tlsldm(%%ebx),%%eax\n\t"				      \
-	  "call ___tls_get_addr@plt\n\t"				      \
-	  "leal " #x "@dtpoff(%%eax), %%eax"				      \
-	  : "=a" (__l), "=&c" (__c), "=&d" (__d));			      \
-     __l; })
-#else
-# define TLS_LD(x) \
+#define TLS_LD(x) \
   ({ int *__l, __b, __c, __d;						      \
      __asm__ ("call 1f\n\t"							      \
 	  ".subsection 1\n"						      \
@@ -49,19 +34,9 @@
 	  "leal " #x "@dtpoff(%%eax), %%eax"				      \
 	  : "=a" (__l), "=&b" (__b), "=&c" (__c), "=&d" (__d));		      \
      __l; })
-#endif
 
-#ifdef __PIC__
-# define TLS_GD(x) \
-  ({ int *__l, __c, __d;						      \
-     __asm__ ("leal " #x "@tlsgd(%%ebx),%%eax\n\t"				      \
-	  "call ___tls_get_addr@plt\n\t"				      \
-	  "nop"								      \
-	  : "=a" (__l), "=&c" (__c), "=&d" (__d));			      \
-     __l; })
-#else
-# define TLS_GD(x) \
-  ({ int *__l, __c, __d;						      \
+#define TLS_GD(x) \
+  ({ int *__l, __b, __c, __d;						      \
      __asm__ ("call 1f\n\t"							      \
 	  ".subsection 1\n"						      \
 	  "1:\tmovl (%%esp), %%ebx\n\t"					      \
@@ -71,6 +46,5 @@
 	  "leal " #x "@tlsgd(%%ebx),%%eax\n\t"				      \
 	  "call ___tls_get_addr@plt\n\t"				      \
 	  "nop"								      \
-	  : "=a" (__l), "=&c" (__c), "=&d" (__d));		              \
+	  : "=a" (__l), "=&b" (__b), "=&c" (__c), "=&d" (__d));		      \
      __l; })
-#endif