summaryrefslogtreecommitdiff
path: root/sysdeps/s390
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/s390')
-rw-r--r--sysdeps/s390/Versions4
-rw-r--r--sysdeps/s390/dl-tls.h35
-rw-r--r--sysdeps/s390/ffs.c1
-rw-r--r--sysdeps/s390/fpu/fegetround.c1
-rw-r--r--sysdeps/s390/s390-32/configure2
-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.h11
-rw-r--r--sysdeps/s390/s390-32/tls-macros.h13
-rw-r--r--sysdeps/s390/s390-64/configure2
-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.h14
-rw-r--r--sysdeps/s390/s390-64/tls-macros.h13
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) \