This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][BZ #16214] Fix TLS access on S390 with -march=z10


Hi,

-march=z10 eliminates GOT pointer loads for static variables whenever
it can, which exposes a bug in the TLS implementation in s390x.  The
TLS implementation assumes that the compiler will load the GOT pointer
(%r12) and implements __tls_get_offset with that assumption.  This
however is true only in cases where the compiler sets up TLS for a
__thread.  For cases where we call TLS_GET_ADDR directly (like in
dl-sym.c and in some test cases), we have to explicitly ensure that
%r12 is set up.

Attached patch does this for s390 and s390x.  It wasn't needed on
s390, but I did it anyway to prevent a possible breakage in future.
Tested and verified that the test cases are fixed and no new
regressions were seen.  OK to commit?

Siddhesh

	[BZ #16214]
	* sysdeps/s390/dl-tls.h (LOAD_R12): New macro.
	(__TLS_GET_ADDR): Use it.
	* sysdeps/s390/s390-32/tls-macros.h [PIC] (TLS_IE): Load GOT
	pointer.
	* sysdeps/s390/s390-64/tls-macros.h [PIC] (TLS_IE): Likewise.

diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h
index 68a5af4..92c32e6 100644
--- a/sysdeps/s390/dl-tls.h
+++ b/sysdeps/s390/dl-tls.h
@@ -65,13 +65,24 @@ __tls_get_offset:\n\
 #  endif
 # endif
 
+# ifdef __s390x__
+#  define LOAD_R12(r12) asm ("lgr %0,%%r12" : "=r" (r12) ::)
+# elif defined __s390__
+#  define LOAD_R12(r12) asm ("lr %0,%%r12" : "=r" (r12) ::)
+# endif
+
 # define GET_ADDR_OFFSET \
   (ti->ti_offset - (unsigned long) __builtin_thread_pointer ())
 
+/* Subtract contents of r12 from __TI.  We don't really care if this is the
+   GOT pointer.  */
 # define __TLS_GET_ADDR(__ti) \
-  ({ extern char _GLOBAL_OFFSET_TABLE_[] attribute_hidden;		  \
-     (void *) __tls_get_offset ((char *) (__ti) - _GLOBAL_OFFSET_TABLE_)  \
-     + (unsigned long) __builtin_thread_pointer (); })
+({									      \
+  unsigned long int r12;						      \
+  LOAD_R12 (r12);							      \
+  ((void *) __tls_get_offset ((unsigned long int) (__ti) - r12)		      \
+   + (unsigned long) __builtin_thread_pointer ());			      \
+})
 
 #endif
 
diff --git a/sysdeps/s390/s390-32/tls-macros.h b/sysdeps/s390/s390-32/tls-macros.h
index 8a0ad58..0a11998 100644
--- a/sysdeps/s390/s390-32/tls-macros.h
+++ b/sysdeps/s390/s390-32/tls-macros.h
@@ -8,12 +8,17 @@
 
 #ifdef PIC
 # define TLS_IE(x) \
-  ({ unsigned long __offset;						      \
+  ({ unsigned long __offset, __save;					      \
      asm ("bras %0,1f\n"						      \
-	  "0:\t.long " #x "@gotntpoff\n"				      \
-	  "1:\tl %0,0(%0)\n\t"						      \
-	  "l %0,0(%0,%%r12):tls_load:" #x				      \
-	  : "=&a" (__offset) : : "cc" );				      \
+	  "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t"			      \
+	  ".long " #x "@gotntpoff\n"					      \
+	  "1:\tlr %1,%%r12\n\t"						      \
+	  "l %%r12,0(%0)\n\t"                                                 \
+	  "la %%r12,0(%%r12,%0)\n\t"					      \
+	  "l %0,4(%0)\n\t"						      \
+	  "l %0,0(%0,%%r12):tls_load:" #x "\n\t"			      \
+	  "lr %%r12, %1\n"						      \
+	  : "=&a" (__offset), "=&a" (__save) : : "cc" );		      \
      (int *) (__builtin_thread_pointer() + __offset); })
 #else
 # define TLS_IE(x) \
diff --git a/sysdeps/s390/s390-64/tls-macros.h b/sysdeps/s390/s390-64/tls-macros.h
index be8aa6c..a65047c 100644
--- a/sysdeps/s390/s390-64/tls-macros.h
+++ b/sysdeps/s390/s390-64/tls-macros.h
@@ -8,12 +8,15 @@
 
 #ifdef PIC
 # define TLS_IE(x) \
-  ({ unsigned long __offset;						      \
+  ({ unsigned long __offset, __save;					      \
      asm ("bras %0,1f\n"						      \
 	  "0:\t.quad " #x "@gotntpoff\n"				      \
-	  "1:\tlg %0,0(%0)\n\t"						      \
-	  "lg %0,0(%0,%%r12):tls_load:" #x				      \
-	  : "=&a" (__offset) : : "cc" );				      \
+	  "1:\tlgr %1,%%r12\n\t"					      \
+	  "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t"			      \
+	  "lg %0,0(%0)\n\t"						      \
+	  "lg %0,0(%0,%%r12):tls_load:" #x "\n\t"			      \
+	  "lgr %%r12,%1"						      \
+	  : "=&a" (__offset), "=&a" (__save) : : "cc" );		      \
      (int *) (__builtin_thread_pointer() + __offset); })
 #else
 # define TLS_IE(x) \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]