This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH][BZ #16214] Fix TLS access on S390 with -march=z10
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: Siddhesh Poyarekar <siddhesh at redhat dot com>
- Cc: libc-alpha at sourceware dot org, carlos at redhat dot com
- Date: Wed, 27 Nov 2013 22:01:46 +0100
- Subject: Re: [PATCH][BZ #16214] Fix TLS access on S390 with -march=z10
- Authentication-results: sourceware.org; auth=none
- References: <20131125055009 dot GK19834 at spoyarek dot pnq dot redhat dot com>
Hi,
in that version I'm using __tls_get_addr instead of __tls_get_offset.
That way we can avoid the special linkage of __tls_get_offset which
requires the GOT pointer to be set up before. This makes the
__TLS_GET_ADDR macro even a bit simpler. On the downside we now have
to export __tls_get_addr from rtld. Since I didn't find a way to
override the symbol version of __tls_get_addr from GLIBC_2.3 to
GLIBC_PRIVATE I've added a small wrapper where I could add the
GLIBC_PRIVATE symbol version for. The symbol exported from rtld is
___tls_get_addr@@GLIBC_PRIVATE now (note the 3 underscores).
For the TLS_IE macros I've used slightly modified version from
Siddhesh's patch.
Thanks to Siddhesh for tracking this down and the initial patch!
I've verified with head GCC that it fixes the following regressions on
s390x:
< Failed to remake target file `/home/andreas/glibc/glibc-#-build/elf/tst-tls3.out'.
< Failed to remake target file `/home/andreas/glibc/glibc-#-build/elf/tst-tls4.out'.
< Failed to remake target file `/home/andreas/glibc/glibc-#-build/elf/tst-tls5.out'.
< Failed to remake target file `/home/andreas/glibc/glibc-#-build/elf/tst-tls6.out'.
< Failed to remake target file `/home/andreas/glibc/glibc-#-build/elf/tst-tls8.out'.
< Failed to remake target file `/home/andreas/glibc/glibc-#-build/elf/tst-tls16.out'.
< Failed to remake target file `/home/andreas/glibc/glibc-#-build/elf/tst-tls-dlinfo.out'.
Comments?
Bye,
-Andreas-
2013-11-28 Siddhesh Poyarekar <siddhesh@redhat.com>
Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
[BZ #16214]
* sysdeps/s390/dl-tls.h (__TLS_GET_ADDR): Invoke ___tls_get_addr
instead of __tls_get_offset in order to avoid GOT pointer
dependency.
Make rtld export ___tls_get_addr@@GLIBC_PRIVATE while still hiding
__tls_get_addr since we are a __tls_get_offset platform.
* sysdeps/s390/s390-64/tls-macros.h (TLS_IE PIC): Don't rely on
GOT pointer being set up before.
* sysdeps/s390/s390-32/tls-macros.h (TLS_IE PIC): Likewise.
commit 3e376de624840ebe6d4cc22e33e844fc365bbe44
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Wed Nov 27 18:17:09 2013 +0100
[BZ #16214] S/390: Fix TLS GOT pointer setup.
diff --git a/sysdeps/s390/Versions b/sysdeps/s390/Versions
index e18617c..e349458 100644
--- a/sysdeps/s390/Versions
+++ b/sysdeps/s390/Versions
@@ -3,4 +3,8 @@ ld {
# runtime interface to TLS
__tls_get_offset;
}
+ GLIBC_PRIVATE {
+ # Exported by ld used by libc.
+ ___tls_get_addr;
+ }
}
diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h
index 68a5af4..870498d 100644
--- a/sysdeps/s390/dl-tls.h
+++ b/sysdeps/s390/dl-tls.h
@@ -26,11 +26,20 @@ typedef struct
#ifdef SHARED
-/* This is the prototype for the GNU version. */
-extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
-extern unsigned long __tls_get_offset (unsigned long got_offset);
# ifdef IS_IN_rtld
+
+# include <shlib-compat.h>
+
+extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
+
+void *
+__tls_get_addr_internal (tls_index *ti)
+{
+ return __tls_get_addr (ti);
+}
+versioned_symbol (ld, __tls_get_addr_internal, ___tls_get_addr, GLIBC_PRIVATE);
+
/* The special thing about the s390 TLS ABI is that we do not have the
standard __tls_get_addr function but the __tls_get_offset function
which differs in two important aspects:
@@ -63,15 +72,18 @@ __tls_get_offset:\n\
1: .long __tls_get_addr - 0b\n\
");
# endif
-# endif
+# else /* IS_IN_rtld */
+/* This is the prototype for the GNU version. */
+extern void *___tls_get_addr (tls_index *ti);
+extern unsigned long __tls_get_offset (unsigned long got_offset);
+# endif /* !IS_IN_rtld */
# define GET_ADDR_OFFSET \
(ti->ti_offset - (unsigned long) __builtin_thread_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 (); })
+# define __TLS_GET_ADDR(__ti) \
+ ({ (void *) ___tls_get_addr ((char *) (__ti)) \
+ + (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..a592d81 100644
--- a/sysdeps/s390/s390-32/tls-macros.h
+++ b/sysdeps/s390/s390-32/tls-macros.h
@@ -8,12 +8,15 @@
#ifdef PIC
# define TLS_IE(x) \
- ({ unsigned long __offset; \
+ ({ unsigned long __offset, __got; \
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:\tl %1,0(%0)\n\t" \
+ "la %1,0(%1,%0)\n\t" \
+ "l %0,4(%0)\n\t" \
+ "l %0,0(%0,%1):tls_load:" #x "\n" \
+ : "=&a" (__offset), "=&a" (__got) : : "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..3c59436 100644
--- a/sysdeps/s390/s390-64/tls-macros.h
+++ b/sysdeps/s390/s390-64/tls-macros.h
@@ -8,12 +8,13 @@
#ifdef PIC
# define TLS_IE(x) \
- ({ unsigned long __offset; \
- 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" ); \
+ ({ unsigned long __offset, __got; \
+ asm ("bras %0,0f\n\t" \
+ ".quad " #x "@gotntpoff\n" \
+ "0:\tlarl %1,_GLOBAL_OFFSET_TABLE_\n\t" \
+ "lg %0,0(%0)\n\t" \
+ "lg %0,0(%0,%1):tls_load:" #x "\n" \
+ : "=&a" (__offset), "=&a" (__got) : : "cc" ); \
(int *) (__builtin_thread_pointer() + __offset); })
#else
# define TLS_IE(x) \