diff options
Diffstat (limited to 'sysdeps/s390')
-rw-r--r-- | sysdeps/s390/Versions | 4 | ||||
-rw-r--r-- | sysdeps/s390/dl-tls.h | 35 | ||||
-rw-r--r-- | sysdeps/s390/ffs.c | 1 | ||||
-rw-r--r-- | sysdeps/s390/fpu/fegetround.c | 1 | ||||
-rw-r--r-- | sysdeps/s390/s390-32/configure | 2 | ||||
-rw-r--r-- | sysdeps/s390/s390-32/configure.ac (renamed from sysdeps/s390/s390-32/configure.in) | 0 | ||||
-rw-r--r-- | sysdeps/s390/s390-32/stackguard-macros.h | 11 | ||||
-rw-r--r-- | sysdeps/s390/s390-32/tls-macros.h | 13 | ||||
-rw-r--r-- | sysdeps/s390/s390-64/configure | 2 | ||||
-rw-r--r-- | sysdeps/s390/s390-64/configure.ac (renamed from sysdeps/s390/s390-64/configure.in) | 0 | ||||
-rw-r--r-- | sysdeps/s390/s390-64/stackguard-macros.h | 14 | ||||
-rw-r--r-- | sysdeps/s390/s390-64/tls-macros.h | 13 |
12 files changed, 76 insertions, 20 deletions
diff --git a/sysdeps/s390/Versions b/sysdeps/s390/Versions index e18617c399..baf9842eeb 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_internal; + } } diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h index 68a5af4152..52192a26d8 100644 --- a/sysdeps/s390/dl-tls.h +++ b/sysdeps/s390/dl-tls.h @@ -26,11 +26,26 @@ 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; +/* Make a temporary alias of __tls_get_addr to remove the hidden + attribute. Then export __tls_get_addr as __tls_get_addr_internal + for use from libc. We do not want to export __tls_get_addr, but we + do need to use it from libc when looking up the address of a TLS + variable. We don't use __tls_get_offset because it requires r12 to + be setup and that might not always be true. Either way it's more + optimal to use __tls_get_addr directly (that's what + __tls_get_offset does anyways). */ +strong_alias (__tls_get_addr, __tls_get_addr_internal_tmp); +versioned_symbol (ld, __tls_get_addr_internal_tmp, + __tls_get_addr_internal, 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 +78,21 @@ __tls_get_offset:\n\ 1: .long __tls_get_addr - 0b\n\ "); # endif -# endif +# else /* IS_IN_rtld */ +extern void *__tls_get_addr_internal (tls_index *ti); +# 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 (); }) +/* Use the privately exported __tls_get_addr_internal instead of + __tls_get_offset in order to avoid the __tls_get_offset special + linkage requiring the GOT pointer to be set up in r12. The + compiler will take care of setting up r12 only if itself issued the + __tls_get_offset call. */ +# define __TLS_GET_ADDR(__ti) \ + ({ (void *) __tls_get_addr_internal ((char *) (__ti)) \ + + (unsigned long) __builtin_thread_pointer (); }) #endif diff --git a/sysdeps/s390/ffs.c b/sysdeps/s390/ffs.c index 807441da64..2dbb7430e2 100644 --- a/sysdeps/s390/ffs.c +++ b/sysdeps/s390/ffs.c @@ -63,6 +63,7 @@ __ffs (x) } weak_alias (__ffs, ffs) +libc_hidden_def (__ffs) libc_hidden_builtin_def (ffs) #if ULONG_MAX == UINT_MAX #undef ffsl diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c index 4843a56d26..94482f6318 100644 --- a/sysdeps/s390/fpu/fegetround.c +++ b/sysdeps/s390/fpu/fegetround.c @@ -29,3 +29,4 @@ fegetround (void) return cw & FPC_RM_MASK; } +libm_hidden_def (fegetround) diff --git a/sysdeps/s390/s390-32/configure b/sysdeps/s390/s390-32/configure index 669bb9be5c..024565f85a 100644 --- a/sysdeps/s390/s390-32/configure +++ b/sysdeps/s390/s390-32/configure @@ -1,4 +1,4 @@ -# This file is generated from configure.in by Autoconf. DO NOT EDIT! +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/s390. $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h diff --git a/sysdeps/s390/s390-32/configure.in b/sysdeps/s390/s390-32/configure.ac index b5af4e12fc..b5af4e12fc 100644 --- a/sysdeps/s390/s390-32/configure.in +++ b/sysdeps/s390/s390-32/configure.ac diff --git a/sysdeps/s390/s390-32/stackguard-macros.h b/sysdeps/s390/s390-32/stackguard-macros.h index b74c5799b3..449e8d488f 100644 --- a/sysdeps/s390/s390-32/stackguard-macros.h +++ b/sysdeps/s390/s390-32/stackguard-macros.h @@ -2,3 +2,14 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; }) + +/* On s390/s390x there is no unique pointer guard, instead we use the + same value as the stack guard. */ +#define POINTER_CHK_GUARD \ + ({ \ + uintptr_t x; \ + asm ("ear %0,%%a0; l %0,%1(%0)" \ + : "=a" (x) \ + : "i" (offsetof (tcbhead_t, stack_guard))); \ + x; \ + }) diff --git a/sysdeps/s390/s390-32/tls-macros.h b/sysdeps/s390/s390-32/tls-macros.h index 8a0ad5863c..a592d81585 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/configure b/sysdeps/s390/s390-64/configure index 669bb9be5c..024565f85a 100644 --- a/sysdeps/s390/s390-64/configure +++ b/sysdeps/s390/s390-64/configure @@ -1,4 +1,4 @@ -# This file is generated from configure.in by Autoconf. DO NOT EDIT! +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/s390. $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h diff --git a/sysdeps/s390/s390-64/configure.in b/sysdeps/s390/s390-64/configure.ac index b5af4e12fc..b5af4e12fc 100644 --- a/sysdeps/s390/s390-64/configure.in +++ b/sysdeps/s390/s390-64/configure.ac diff --git a/sysdeps/s390/s390-64/stackguard-macros.h b/sysdeps/s390/s390-64/stackguard-macros.h index 0cebb5f022..c8270fbe79 100644 --- a/sysdeps/s390/s390-64/stackguard-macros.h +++ b/sysdeps/s390/s390-64/stackguard-macros.h @@ -2,3 +2,17 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; }) + +/* On s390/s390x there is no unique pointer guard, instead we use the + same value as the stack guard. */ +#define POINTER_CHK_GUARD \ + ({ \ + uintptr_t x; \ + asm ("ear %0,%%a0;" \ + "sllg %0,%0,32;" \ + "ear %0,%%a1;" \ + "lg %0,%1(%0)" \ + : "=a" (x) \ + : "i" (offsetof (tcbhead_t, stack_guard))); \ + x; \ + }) diff --git a/sysdeps/s390/s390-64/tls-macros.h b/sysdeps/s390/s390-64/tls-macros.h index be8aa6cde0..3c59436341 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) \ |