summaryrefslogtreecommitdiff
path: root/sysdeps/s390
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-01-28 10:42:28 +0000
committerUlrich Drepper <drepper@redhat.com>2003-01-28 10:42:28 +0000
commite6ebd2e4db59da6c1726ecfa3516f1f1b3048442 (patch)
treedfa3797737a8e4dc76ed38e52cf7baa27e936003 /sysdeps/s390
parent772e3426a7b6f5200cb1029d41308b8b666cdbab (diff)
Update.
2003-01-27 Martin Schwidefsky <schwidefsky@de.ibm.com> * elf/elf.h: Add new s390 relocs. * elf/tls-macros.h: Add s390 versions. * sysdeps/s390/Versions [GLIBC_2.3] (ld): Export __tls_get_offset. * sysdeps/s390/dl-tls.h: New file. * sysdeps/s390/libc-tls.c: New file. * sysdeps/s390/s390-32/dl-machine.h (elf_machine_type_class): Add TLS relocs for class PLT. (elf_machine_rela): Handle TLS relocs. * sysdeps/s390/s390-64/dl-machine.h: Likewise. * sysdeps/s390/s390-32/elf/configure.in: Add TLS check. * sysdeps/s390/s390-64/elf/configure.in: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/clone.S: Add support for CLONE_CHILD_*TID flags. * sysdeps/unix/sysv/linux/s390/s390-64/clone.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/mmap.S: Use branch with 32 bit offset. * sysdeps/unix/sysv/linux/s390/s390-64/socket.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/syscall.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S (__syscall_error): Support USE___THREAD. Define RTLD_PRIVATE_ERRNO variant. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S (__syscall_error): Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: (SYSCALL_ERROR_LABEL): Move define next to SYSCALL_ERROR_HANDLER. (SYSCALL_ERROR_HANDLER): Add USE___THREAD and RTLD_PRIVATE_ERRNO variants. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: (SYSCALL_ERROR_LABEL): Move define next to SYSCALL_ERROR_HANDLER. Use direct branch to syscall_error for !PIC and PIC && !_LIBC_REENTRANT. (SYSCALL_ERROR_HANDLER): Add USE___THREAD and RTLD_PRIVATE_ERRNO variants.
Diffstat (limited to 'sysdeps/s390')
-rw-r--r--sysdeps/s390/Versions6
-rw-r--r--sysdeps/s390/dl-tls.h73
-rw-r--r--sysdeps/s390/libc-tls.c37
-rw-r--r--sysdeps/s390/s390-32/dl-machine.h92
-rw-r--r--sysdeps/s390/s390-32/elf/configure52
-rw-r--r--sysdeps/s390/s390-32/elf/configure.in37
-rw-r--r--sysdeps/s390/s390-64/dl-machine.h92
-rw-r--r--sysdeps/s390/s390-64/elf/configure52
-rw-r--r--sysdeps/s390/s390-64/elf/configure.in37
9 files changed, 460 insertions, 18 deletions
diff --git a/sysdeps/s390/Versions b/sysdeps/s390/Versions
new file mode 100644
index 0000000000..7136af2760
--- /dev/null
+++ b/sysdeps/s390/Versions
@@ -0,0 +1,6 @@
+ld {
+ GLIBC_2.3 {
+ # runtime interface to TLS
+ __tls_get_offset;
+ }
+} \ No newline at end of file
diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h
new file mode 100644
index 0000000000..fbd85c1753
--- /dev/null
+++ b/sysdeps/s390/dl-tls.h
@@ -0,0 +1,73 @@
+/* Thread-local storage handling in the ELF dynamic linker. s390 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+#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);
+
+/* 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:
+ 1) __tls_get_offset gets a got offset instead of a pointer to the
+ tls_index structure
+ 2) __tls_get_offset returns the offset of the requested variable to
+ the thread descriptor instead of a pointer to the variable.
+ */
+#if defined __s390x__
+asm("\n\
+ .text\n\
+ .globl __tls_get_offset\n\
+ .type __tls_get_offset, @function\n\
+ .align 4\n\
+__tls_get_offset:\n\
+ la %r2,0(%r2,%r12)\n\
+ jg __tls_get_addr\n\
+");
+#elif defined __s390__
+asm("\n\
+ .text\n\
+ .globl __tls_get_offset\n\
+ .type __tls_get_offset, @function\n\
+ .align 4\n\
+__tls_get_offset:\n\
+ basr %r3,0\n\
+0: la %r2,0(%r2,%r12)\n\
+ l %r4,1f-0b(%r3)\n\
+ b 0(%r4,%r3)\n\
+1: .long __tls_get_addr - 0b\n\
+");
+#endif
+
+#define GET_ADDR_OFFSET \
+ (ti->ti_offset - (unsigned long) __builtin_thread_pointer ())
+
+#define __TLS_GET_ADDR(__ti) \
+ (__tls_get_addr(__ti) + (unsigned long) __builtin_thread_pointer ())
+
+#endif
diff --git a/sysdeps/s390/libc-tls.c b/sysdeps/s390/libc-tls.c
new file mode 100644
index 0000000000..bc433f8f6f
--- /dev/null
+++ b/sysdeps/s390/libc-tls.c
@@ -0,0 +1,37 @@
+/* Thread-local storage handling in the ELF dynamic linker. IA-64 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/libc-tls.c>
+
+#if USE_TLS
+
+/* On s390, the literal pool entry that refers to __tls_get_offset
+ is not removed, even if all branches that use the literal pool
+ entry gets removed by TLS optimizations. To get binaries
+ statically linked __tls_get_offset is defined here but
+ aborts if it is used. */
+
+void *
+__tls_get_offset (size_t m, size_t offset)
+{
+ abort ();
+}
+
+#endif
+
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 557c04e4ea..6905814c41 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. S390 Version.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Carl Pederson & Martin Schwidefsky.
This file is part of the GNU C Library.
@@ -312,13 +312,22 @@ _dl_start_user:\n\
#define RTLD_START_SPECIAL_INIT /* nothing */
#endif
-/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
- PLT entries should not be allowed to define the value.
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
of the main executable's symbols, as for a COPY reloc. */
-#define elf_machine_type_class(type) \
+#ifdef USE_TLS
+# define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \
+ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
@@ -372,25 +381,90 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
{
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
if (__builtin_expect (r_type == R_390_RELATIVE, 0))
- *reloc_addr = map->l_addr + reloc->r_addend;
-#ifndef RTLD_BOOTSTRAP
- else if (__builtin_expect (r_type == R_390_NONE, 0))
- return;
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (GL(dl_rtld_map));
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
#endif
+ if (__builtin_expect (r_type == R_390_NONE, 0))
+ return;
else
{
const Elf32_Sym *const refsym = sym;
+#if defined USE_TLS && !defined RTLD_BOOTSTRAP
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+#else
Elf32_Addr value = RESOLVE (&sym, version, r_type);
+
+# ifndef RTLD_BOOTSTRAP
if (sym)
+# endif
value += sym->st_value;
+#endif /* use TLS and !RTLD_BOOTSTRAP */
switch (r_type)
{
case R_390_GLOB_DAT:
case R_390_JMP_SLOT:
- *reloc_addr = value;
+ *reloc_addr = value + reloc->r_addend;
+ break;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+ case R_390_TLS_DTPMOD:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_390_TLS_DTPOFF:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value + reloc->r_addend;
+# endif
break;
+ case R_390_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset;
+# else
+ /* We know the offset of the object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = (sym->st_value + reloc->r_addend
+ - sym_map->l_tls_offset);
+ }
+#endif
+ break;
+#endif /* use TLS */
+
#ifndef RTLD_BOOTSTRAP
case R_390_COPY:
if (sym == NULL)
diff --git a/sysdeps/s390/s390-32/elf/configure b/sysdeps/s390/s390-32/elf/configure
new file mode 100644
index 0000000000..64eff1f05f
--- /dev/null
+++ b/sysdeps/s390/s390-32/elf/configure
@@ -0,0 +1,52 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for s390 TLS support" >&5
+echo $ECHO_N "checking for s390 TLS support... $ECHO_C" >&6
+if test "${libc_cv_390_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@NTPOFF
+ .long foo@GOTNTPOFF
+ .long foo@INDNTPOFF
+ l %r1,foo@GOTNTPOFF(%r12)
+ l %r1,0(%r1):tls_load:foo
+ bas %r14,0(%r1,%r13):tls_gdcall:foo
+ bas %r14,0(%r1,%r13):tls_ldcall:foo
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_390_tls" >&5
+echo "${ECHO_T}$libc_cv_390_tls" >&6
+if test $libc_cv_390_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/sysdeps/s390/s390-32/elf/configure.in b/sysdeps/s390/s390-32/elf/configure.in
new file mode 100644
index 0000000000..fcf9329995
--- /dev/null
+++ b/sysdeps/s390/s390-32/elf/configure.in
@@ -0,0 +1,37 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for s390 TLS support, libc_cv_390_tls, [dnl
+cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@NTPOFF
+ .long foo@GOTNTPOFF
+ .long foo@INDNTPOFF
+ l %r1,foo@GOTNTPOFF(%r12)
+ l %r1,0(%r1):tls_load:foo
+ bas %r14,0(%r1,%r13):tls_gdcall:foo
+ bas %r14,0(%r1,%r13):tls_ldcall:foo
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.S 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_390_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index a4033eeed1..e7ae3f77f8 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -1,6 +1,6 @@
/* Machine-dependent ELF dynamic relocation inline functions.
64 bit S/390 Version.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -284,13 +284,22 @@ _dl_start_user:\n\
#define RTLD_START_SPECIAL_INIT /* nothing */
#endif
-/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
- PLT entries should not be allowed to define the value.
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
of the main executable's symbols, as for a COPY reloc. */
-#define elf_machine_type_class(type) \
+#ifdef USE_TLS
+# define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \
+ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
@@ -340,18 +349,41 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
{
const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
if (__builtin_expect (r_type == R_390_RELATIVE, 0))
- *reloc_addr = map->l_addr + reloc->r_addend;
-#ifndef RTLD_BOOTSTRAP
- else if (__builtin_expect (r_type == R_390_NONE, 0))
- return;
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (GL(dl_rtld_map));
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
#endif
+ if (__builtin_expect (r_type == R_390_NONE, 0))
+ return;
else
{
const Elf64_Sym *const refsym = sym;
+#if defined USE_TLS && !defined RTLD_BOOTSTRAP
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+#else
Elf64_Addr value = RESOLVE (&sym, version, r_type);
+
+# ifndef RTLD_BOOTSTRAP
if (sym)
+# endif
value += sym->st_value;
+#endif /* use TLS and !RTLD_BOOTSTRAP */
switch (r_type)
{
@@ -359,6 +391,48 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
case R_390_JMP_SLOT:
*reloc_addr = value + reloc->r_addend;
break;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+ case R_390_TLS_DTPMOD:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_390_TLS_DTPOFF:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value + reloc->r_addend;
+# endif
+ break;
+ case R_390_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset;
+# else
+ /* We know the offset of the object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = (sym->st_value + reloc->r_addend
+ - sym_map->l_tls_offset);
+ }
+#endif
+ break;
+#endif /* use TLS */
+
#ifndef RTLD_BOOTSTRAP
case R_390_COPY:
if (sym == NULL)
@@ -439,7 +513,7 @@ elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc)
{
Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
- const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+ const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
/* Check for unexpected PLT reloc type. */
if (__builtin_expect (r_type == R_390_JMP_SLOT, 1))
{
diff --git a/sysdeps/s390/s390-64/elf/configure b/sysdeps/s390/s390-64/elf/configure
new file mode 100644
index 0000000000..42fc6e6a5f
--- /dev/null
+++ b/sysdeps/s390/s390-64/elf/configure
@@ -0,0 +1,52 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for s390 TLS support" >&5
+echo $ECHO_N "checking for s390 TLS support... $ECHO_C" >&6
+if test "${libc_cv_390_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .quad foo@TLSGD
+ .quad foo@TLSLDM
+ .quad foo@DTPOFF
+ .quad foo@NTPOFF
+ .quad foo@GOTNTPOFF
+ .quad foo@INDNTPOFF
+ lg %r1,foo@GOTNTPOFF(%r12)
+ lg %r1,0(%r1):tls_load:foo
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:foo
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:foo
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_390_tls" >&5
+echo "${ECHO_T}$libc_cv_390_tls" >&6
+if test $libc_cv_390_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/sysdeps/s390/s390-64/elf/configure.in b/sysdeps/s390/s390-64/elf/configure.in
new file mode 100644
index 0000000000..ac953fcff3
--- /dev/null
+++ b/sysdeps/s390/s390-64/elf/configure.in
@@ -0,0 +1,37 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for s390 TLS support, libc_cv_390_tls, [dnl
+cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .quad foo@TLSGD
+ .quad foo@TLSLDM
+ .quad foo@DTPOFF
+ .quad foo@NTPOFF
+ .quad foo@GOTNTPOFF
+ .quad foo@INDNTPOFF
+ lg %r1,foo@GOTNTPOFF(%r12)
+ lg %r1,0(%r1):tls_load:foo
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:foo
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:foo
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.S 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_390_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)