This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] TLS support for s390*.
- From: Martin Schwidefsky <schwidefsky at de dot ibm dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 24 Jan 2003 15:35:45 +0100
- Subject: [PATCH] TLS support for s390*.
- Organization: IBM Deutschland GmbH
Hi,
nobody seems to have any objections against the TLS ABI for s390*. So
Uli and I decided to go with it. Here is the patch that implements the
binutils part of the TLS support.
blue skies,
Martin.
bfd/ChangeLog:
2003-01-24 Martin Schwidefsky <sky@mschwid3.boeblingen.de.ibm.com>
* bfd-in2.h: Regenerate.
* elf32-s390.c (elf_s390_mkobject, elf_s390_tls_transition,
s390_tls_reloc, dtpoff_base, tpoff, invalid_tls_insn): New functions.
(elf_howto_table): Add TLS relocs.
(elf_s390_reloc_type_lookup): Likewise.
(elf_s390_link_hash_entry): Add tls_type.
(elf_s390_hash_entry, elf_s390_obj_tdata, elf_s390_local_got_tls_type):
New macros.
(elf_s390_link_hash_table): Add tls_ldm_got.
(link_hash_newfunc): Initialize tls_type.
(elf_s390_link_hash_table_create): Initialize refcount of tls_ldm_got.
(elf_s390_copy_indirect_symbol): Copy tls_type information.
(elf_s390_check_relocs): Support TLS relocs.
(elf_s390_gc_sweep_hook): Likewise.
(allocate_dynrelocs): Likewise.
(elf_s390_size_dynamic_sections): Likewise.
(elf_s390_relocate_section): Likewise.
(elf_s390_finish_dynamic_symbol): Likewise.
(bfd_elf32_mkobject): Define for TLS.
* elf64-s390.c: Same changes as for elf32-s390.c.
* libbfd.h: Regenerate.
* reloc.c: Add s390 TLS relocations.
gas/ChangeLog:
2003-01-24 Martin Schwidefsky <sky@mschwid3.boeblingen.de.ibm.com>
* config/tc-s390.c (s390_tls_suffix): New function.
(elf_suffix_type): Add suffix enums for TLS relocations.
(s390_elf_suffix): Add suffix strings for TLS relocations.
(s390_elf_cons): Map new lenght/elf suffix combinations for TLS to
bfd relocations.
(md_gather_operands): Map new instruction operand/elf suffix
combinations for TLS to bfd relocations.
(tc_s390_fix_adjustable): Add new TLS relocations.
(tc_s390_force_relocation): Likewise.
(md_apply_fix3): Likewise.
include/elf/ChangeLog:
2003-01-24 Martin Schwidefsky <sky@mschwid3.boeblingen.de.ibm.com>
* s390.h: Add s390 TLS relocations.
ld/testsuite/ChangeLog:
2003-01-24 Martin Schwidefsky <sky@mschwid3.boeblingen.de.ibm.com>
* ld-s390/s390.exp: New file.
* ld-s390/tlsbin_64.dd: New file.
* ld-s390/tlsbin_64.rd: New file.
* ld-s390/tlsbin_64.s: New file.
* ld-s390/tlsbin_64.sd: New file.
* ld-s390/tlsbin_64.td: New file.
* ld-s390/tlsbin.dd: New file.
* ld-s390/tlsbinpic_64.s: New file.
* ld-s390/tlsbinpic.s: New file.
* ld-s390/tlsbin.rd: New file.
* ld-s390/tlsbin.s: New file.
* ld-s390/tlsbin.sd: New file.
* ld-s390/tlsbin.td: New file.
* ld-s390/tlslib_64.s: New file.
* ld-s390/tlslib.s: New file.
* ld-s390/tlspic1_64.s: New file.
* ld-s390/tlspic1.s: New file.
* ld-s390/tlspic2_64.s: New file.
* ld-s390/tlspic2.s: New file.
* ld-s390/tlspic_64.dd: New file.
* ld-s390/tlspic_64.rd: New file.
* ld-s390/tlspic_64.sd: New file.
* ld-s390/tlspic_64.td: New file.
* ld-s390/tlspic.dd: New file.
* ld-s390/tlspic.rd: New file.
* ld-s390/tlspic.sd: New file.
* ld-s390/tlspic.td: New file.
diff -urN src/bfd/bfd-in2.h src-s390/bfd/bfd-in2.h
--- src/bfd/bfd-in2.h Mon Jan 20 12:38:30 2003
+++ src-s390/bfd/bfd-in2.h Thu Jan 23 23:23:13 2003
@@ -3023,6 +3023,28 @@
/* 64-bit rel. offset from the GOT to a PLT entry. */
BFD_RELOC_390_PLTOFF64,
+/* s390 tls relocations. */
+ BFD_RELOC_390_TLS_LOAD,
+ BFD_RELOC_390_TLS_GDCALL,
+ BFD_RELOC_390_TLS_LDCALL,
+ BFD_RELOC_390_TLS_GD32,
+ BFD_RELOC_390_TLS_GD64,
+ BFD_RELOC_390_TLS_GOTIE12,
+ BFD_RELOC_390_TLS_GOTIE32,
+ BFD_RELOC_390_TLS_GOTIE64,
+ BFD_RELOC_390_TLS_LDM32,
+ BFD_RELOC_390_TLS_LDM64,
+ BFD_RELOC_390_TLS_IE32,
+ BFD_RELOC_390_TLS_IE64,
+ BFD_RELOC_390_TLS_IEENT,
+ BFD_RELOC_390_TLS_LE32,
+ BFD_RELOC_390_TLS_LE64,
+ BFD_RELOC_390_TLS_LDO32,
+ BFD_RELOC_390_TLS_LDO64,
+ BFD_RELOC_390_TLS_DTPMOD,
+ BFD_RELOC_390_TLS_DTPOFF,
+ BFD_RELOC_390_TLS_TPOFF,
+
/* Scenix IP2K - 9-bit register number / data address */
BFD_RELOC_IP2K_FR9,
diff -urN src/bfd/elf32-s390.c src-s390/bfd/elf32-s390.c
--- src/bfd/elf32-s390.c Mon Jan 20 12:38:30 2003
+++ src-s390/bfd/elf32-s390.c Fri Jan 24 09:50:20 2003
@@ -72,10 +72,22 @@
PARAMS ((const Elf_Internal_Rela *));
static bfd_boolean elf_s390_finish_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
+static bfd_boolean elf_s390_mkobject
+ PARAMS ((bfd *));
static bfd_boolean elf_s390_object_p
PARAMS ((bfd *));
static bfd_boolean elf_s390_grok_prstatus
PARAMS ((bfd *, Elf_Internal_Note *));
+static int elf_s390_tls_transition
+ PARAMS ((struct bfd_link_info *, int, int));
+static bfd_reloc_status_type s390_tls_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_vma dtpoff_base
+ PARAMS ((struct bfd_link_info *));
+static bfd_vma tpoff
+ PARAMS ((struct bfd_link_info *, bfd_vma));
+static void invalid_tls_insn
+ PARAMS ((bfd *, asection *, Elf_Internal_Rela *));
#include "elf/s390.h"
@@ -162,6 +174,40 @@
HOWTO(R_390_PLTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
EMPTY_HOWTO (R_390_PLTOFF64), /* Empty entry for R_390_PLTOFF64. */
+ HOWTO(R_390_TLS_LOAD, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LOAD", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_GDCALL", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_LDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LDCALL", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_GD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GD32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GD64), /* Empty entry for R_390_TLS_GD64. */
+ HOWTO(R_390_TLS_GOTIE12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE12", FALSE, 0, 0x00000fff, FALSE),
+ HOWTO(R_390_TLS_GOTIE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GOTIE64), /* Empty entry for R_390_TLS_GOTIE64. */
+ HOWTO(R_390_TLS_LDM32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDM32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDM64), /* Empty entry for R_390_TLS_LDM64. */
+ HOWTO(R_390_TLS_IE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IE32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_IE64), /* Empty entry for R_390_TLS_IE64. */
+ HOWTO(R_390_TLS_IEENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IEENT", FALSE, 0, 0xffffffff, TRUE),
+ HOWTO(R_390_TLS_LE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LE32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LE64), /* Empty entry for R_390_TLS_LE64. */
+ HOWTO(R_390_TLS_LDO32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDO32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDO64), /* Empty entry for R_390_TLS_LDO64. */
+ HOWTO(R_390_TLS_DTPMOD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPMOD", FALSE, 0, 0xffffffff, FALSE),
+ HOWTO(R_390_TLS_DTPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPOFF", FALSE, 0, 0xffffffff, FALSE),
+ HOWTO(R_390_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, 0xffffffff, FALSE),
};
/* GNU extension to record C++ vtable hierarchy. */
@@ -239,6 +285,34 @@
return &elf_howto_table[(int) R_390_PLTOFF16];
case BFD_RELOC_390_PLTOFF32:
return &elf_howto_table[(int) R_390_PLTOFF32];
+ case BFD_RELOC_390_TLS_LOAD:
+ return &elf_howto_table[(int) R_390_TLS_LOAD];
+ case BFD_RELOC_390_TLS_GDCALL:
+ return &elf_howto_table[(int) R_390_TLS_GDCALL];
+ case BFD_RELOC_390_TLS_LDCALL:
+ return &elf_howto_table[(int) R_390_TLS_LDCALL];
+ case BFD_RELOC_390_TLS_GD32:
+ return &elf_howto_table[(int) R_390_TLS_GD32];
+ case BFD_RELOC_390_TLS_GOTIE12:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE12];
+ case BFD_RELOC_390_TLS_GOTIE32:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE32];
+ case BFD_RELOC_390_TLS_LDM32:
+ return &elf_howto_table[(int) R_390_TLS_LDM32];
+ case BFD_RELOC_390_TLS_IE32:
+ return &elf_howto_table[(int) R_390_TLS_IE32];
+ case BFD_RELOC_390_TLS_IEENT:
+ return &elf_howto_table[(int) R_390_TLS_IEENT];
+ case BFD_RELOC_390_TLS_LE32:
+ return &elf_howto_table[(int) R_390_TLS_LE32];
+ case BFD_RELOC_390_TLS_LDO32:
+ return &elf_howto_table[(int) R_390_TLS_LDO32];
+ case BFD_RELOC_390_TLS_DTPMOD:
+ return &elf_howto_table[(int) R_390_TLS_DTPMOD];
+ case BFD_RELOC_390_TLS_DTPOFF:
+ return &elf_howto_table[(int) R_390_TLS_DTPOFF];
+ case BFD_RELOC_390_TLS_TPOFF:
+ return &elf_howto_table[(int) R_390_TLS_TPOFF];
case BFD_RELOC_VTABLE_INHERIT:
return &elf32_s390_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
@@ -274,6 +348,23 @@
}
}
+/* A relocation function which doesn't do anything. */
+static bfd_reloc_status_type
+s390_tls_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ arelent *reloc_entry;
+ asymbol *symbol ATTRIBUTE_UNUSED;
+ PTR data ATTRIBUTE_UNUSED;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message ATTRIBUTE_UNUSED;
+{
+ if (output_bfd)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
static bfd_boolean
elf_s390_is_local_label_name (abfd, name)
bfd *abfd;
@@ -476,8 +567,59 @@
/* Number of GOTPLT references for a function. */
bfd_signed_vma gotplt_refcount;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 3
+#define GOT_TLS_IE_NLT 4
+ unsigned char tls_type;
};
+#define elf_s390_hash_entry(ent) \
+ ((struct elf_s390_link_hash_entry *)(ent))
+
+struct elf_s390_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define elf_s390_tdata(abfd) \
+ ((struct elf_s390_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_s390_local_got_tls_type(abfd) \
+ (elf_s390_tdata (abfd)->local_got_tls_type)
+
+static bfd_boolean
+elf_s390_mkobject (abfd)
+ bfd *abfd;
+{
+ bfd_size_type amt = sizeof (struct elf_s390_obj_tdata);
+ abfd->tdata.any = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.any == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+elf_s390_object_p (abfd)
+ bfd *abfd;
+{
+ /* Allocate our special target data. */
+ struct elf_s390_obj_tdata *new_tdata;
+ bfd_size_type amt = sizeof (struct elf_s390_obj_tdata);
+ new_tdata = bfd_zalloc (abfd, amt);
+ if (new_tdata == NULL)
+ return FALSE;
+ new_tdata->root = *abfd->tdata.elf_obj_data;
+ abfd->tdata.any = new_tdata;
+ /* Set the right machine number for an s390 elf32 file. */
+ return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_31);
+}
+
/* s390 ELF linker hash table. */
struct elf_s390_link_hash_table
@@ -493,6 +635,11 @@
asection *sdynbss;
asection *srelbss;
+ union {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
};
@@ -529,6 +676,7 @@
eh = (struct elf_s390_link_hash_entry *) entry;
eh->dyn_relocs = NULL;
eh->gotplt_refcount = 0;
+ eh->tls_type = GOT_UNKNOWN;
}
return entry;
@@ -560,6 +708,7 @@
ret->srelplt = NULL;
ret->sdynbss = NULL;
ret->srelbss = NULL;
+ ret->tls_ldm_got.refcount = 0;
ret->sym_sec.abfd = NULL;
return &ret->elf.root;
@@ -672,9 +821,43 @@
eind->dyn_relocs = NULL;
}
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+
_bfd_elf_link_hash_copy_indirect (bed, dir, ind);
}
+static int
+elf_s390_tls_transition (info, r_type, is_local)
+ struct bfd_link_info *info;
+ int r_type;
+ int is_local;
+{
+ if (info->shared)
+ return r_type;
+
+ switch (r_type)
+ {
+ case R_390_TLS_GD32:
+ case R_390_TLS_IE32:
+ if (is_local)
+ return R_390_TLS_LE32;
+ return R_390_TLS_IE32;
+ case R_390_TLS_GOTIE32:
+ if (is_local)
+ return R_390_TLS_LE32;
+ return R_390_TLS_GOTIE32;
+ case R_390_TLS_LDM32:
+ return R_390_TLS_LE32;
+ }
+
+ return r_type;
+}
+
/* Look through the relocs for a section during the first phase, and
allocate space in the global offset table or procedure linkage
table. */
@@ -693,6 +876,7 @@
const Elf_Internal_Rela *rel_end;
asection *sreloc;
bfd_signed_vma *local_got_refcounts;
+ int tls_type, old_tls_type;
if (info->relocateable)
return TRUE;
@@ -707,6 +891,7 @@
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
+ unsigned int r_type;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
@@ -727,7 +912,10 @@
/* Create got section and local_got_refcounts array if they
are needed. */
- switch (ELF32_R_TYPE (rel->r_info))
+ r_type = elf_s390_tls_transition (info,
+ ELF32_R_TYPE (rel->r_info),
+ h == NULL);
+ switch (r_type)
{
case R_390_GOT12:
case R_390_GOT16:
@@ -737,18 +925,26 @@
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLTENT:
+ case R_390_TLS_GD32:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE32:
+ case R_390_TLS_IEENT:
+ case R_390_TLS_IE32:
+ case R_390_TLS_LDM32:
if (h == NULL
&& local_got_refcounts == NULL)
{
bfd_size_type size;
size = symtab_hdr->sh_info;
- size *= sizeof (bfd_signed_vma);
+ size *= (sizeof (bfd_signed_vma) + sizeof(char));
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
+ elf_s390_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
}
/* Fall through. */
case R_390_GOTOFF16:
@@ -764,19 +960,8 @@
}
}
- switch (ELF32_R_TYPE (rel->r_info))
+ switch (r_type)
{
- case R_390_GOT12:
- case R_390_GOT16:
- case R_390_GOT32:
- case R_390_GOTENT:
- /* This symbol requires a global offset table entry. */
- if (h != NULL)
- h->got.refcount += 1;
- else
- local_got_refcounts[r_symndx] += 1;
- break;
-
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTPC:
@@ -827,6 +1012,89 @@
local_got_refcounts[r_symndx] += 1;
break;
+ case R_390_TLS_LDM32:
+ htab->tls_ldm_got.refcount += 1;
+ break;
+
+ case R_390_TLS_IE32:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE32:
+ case R_390_TLS_IEENT:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ case R_390_TLS_GD32:
+ /* This symbol requires a global offset table entry. */
+ switch (r_type)
+ {
+ default:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_390_TLS_GD32:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_390_TLS_IE32:
+ case R_390_TLS_GOTIE32:
+ tls_type = GOT_TLS_IE;
+ break;
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_IEENT:
+ tls_type = GOT_TLS_IE_NLT;
+ break;
+ }
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = elf_s390_hash_entry(h)->tls_type;
+ }
+ else
+ {
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type = elf_s390_local_got_tls_type (abfd) [r_symndx];
+ }
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN)
+ {
+ if (old_tls_type == GOT_NORMAL || tls_type == GOT_NORMAL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: `%s' accessed both as normal and thread local symbol"),
+ bfd_archive_filename (abfd), h->root.root.string);
+ return FALSE;
+ }
+ if (old_tls_type > tls_type)
+ tls_type = old_tls_type;
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf_s390_hash_entry (h)->tls_type = tls_type;
+ else
+ elf_s390_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+
+ if (r_type != R_390_TLS_IE32)
+ break;
+ /* Fall through */
+
+ case R_390_TLS_LE32:
+ if (!info->shared)
+ break;
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
case R_390_8:
case R_390_16:
case R_390_32:
@@ -1059,6 +1327,7 @@
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
+ int r_type;
struct elf_link_hash_entry *h;
elf_section_data (sec)->local_dynrel = NULL;
@@ -1077,8 +1346,21 @@
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- switch (ELF32_R_TYPE (rel->r_info))
+ r_type = elf_s390_tls_transition (info,
+ ELF32_R_TYPE (rel->r_info),
+ r_symndx >= symtab_hdr->sh_info);
+ switch (r_type)
{
+ case R_390_TLS_LDM32:
+ if (elf_s390_hash_table (info)->tls_ldm_got.refcount > 0)
+ elf_s390_hash_table (info)->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_390_TLS_GD32:
+ case R_390_TLS_IE32:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE32:
+ case R_390_TLS_IEENT:
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
@@ -1097,38 +1379,14 @@
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
- break;
+ if (r_type != R_390_TLS_IE32)
+ break;
+ /* Fall through */
- case R_390_PLT16DBL:
- case R_390_PLT32DBL:
- case R_390_PLT32:
- case R_390_PLTOFF16:
- case R_390_PLTOFF32:
- if (h != NULL)
- {
- if (h->plt.refcount > 0)
- h->plt.refcount -= 1;
- }
- break;
-
- case R_390_GOTPLT12:
- case R_390_GOTPLT16:
- case R_390_GOTPLT32:
- case R_390_GOTPLTENT:
- if (h != NULL)
- {
- if (h->plt.refcount > 0)
- {
- ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
- h->plt.refcount -= 1;
- }
- }
- else if (local_got_refcounts != NULL)
- {
- if (local_got_refcounts[r_symndx] > 0)
- local_got_refcounts[r_symndx] -= 1;
- }
- break;
+ case R_390_TLS_LE32:
+ if (!info->shared)
+ break;
+ /* Fall through */
case R_390_8:
case R_390_12:
@@ -1165,6 +1423,37 @@
}
break;
+ case R_390_PLT16DBL:
+ case R_390_PLT32DBL:
+ case R_390_PLT32:
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ break;
+
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLTENT:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ {
+ ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
+ h->plt.refcount -= 1;
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
default:
break;
}
@@ -1437,10 +1726,31 @@
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
- if (h->got.refcount > 0)
- {
+ /* If R_390_TLS_{IE32,GOTIE32,GOTIE12,IEENT} symbol is now local to
+ the binary, we can optimize a bit. IE32 and GOTIE32 get converted
+ to R_390_TLS_LE32 requiring no TLS entry. For GOTIE12 and IEENT
+ we can save the dynamic TLS relocation. */
+ if (h->got.refcount > 0
+ && !info->shared
+ && h->dynindx == -1
+ && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE)
+ {
+ if (elf_s390_hash_entry(h)->tls_type == GOT_TLS_IE_NLT)
+ /* For the GOTIE access without a literal pool entry the offset has
+ to be stored somewhere. The immediate value in the instruction
+ is not bit enough so the value is stored in the got. */
+ {
+ h->got.offset = htab->sgot->_raw_size;
+ htab->sgot->_raw_size += GOT_ENTRY_SIZE;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+ }
+ else if (h->got.refcount > 0)
+ {
asection *s;
bfd_boolean dyn;
+ int tls_type = elf_s390_hash_entry(h)->tls_type;
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
@@ -1454,8 +1764,18 @@
s = htab->sgot;
h->got.offset = s->_raw_size;
s->_raw_size += GOT_ENTRY_SIZE;
+ /* R_390_TLS_GD32 needs 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->_raw_size += GOT_ENTRY_SIZE;
dyn = htab->elf.dynamic_sections_created;
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
+ /* R_390_TLS_IE32 needs one dynamic relocation,
+ R_390_TLS_GD32 needs one if local symbol and two if global. */
+ if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+ || tls_type >= GOT_TLS_IE)
+ htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ else if (tls_type == GOT_TLS_GD)
+ htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rela);
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
else
@@ -1601,6 +1921,7 @@
{
bfd_signed_vma *local_got;
bfd_signed_vma *end_local_got;
+ char *local_tls_type;
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
asection *srela;
@@ -1642,14 +1963,17 @@
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
+ local_tls_type = elf_s390_local_got_tls_type (ibfd);
s = htab->sgot;
srela = htab->srelgot;
- for (; local_got < end_local_got; ++local_got)
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
{
if (*local_got > 0)
{
*local_got = s->_raw_size;
s->_raw_size += GOT_ENTRY_SIZE;
+ if (*local_tls_type == GOT_TLS_GD)
+ s->_raw_size += GOT_ENTRY_SIZE;
if (info->shared)
srela->_raw_size += sizeof (Elf32_External_Rela);
}
@@ -1658,6 +1982,17 @@
}
}
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_390_TLS_LDM32
+ relocs. */
+ htab->tls_ldm_got.offset = htab->sgot->_raw_size;
+ htab->sgot->_raw_size += 2 * GOT_ENTRY_SIZE;
+ htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
/* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
@@ -1768,6 +2103,58 @@
return TRUE;
}
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (info)
+ struct bfd_link_info *info;
+{
+ /* If tls_segment is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_segment == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_segment->start;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (info, address)
+ struct bfd_link_info *info;
+ bfd_vma address;
+{
+ struct elf_link_tls_segment *tls_segment
+ = elf_hash_table (info)->tls_segment;
+
+ /* If tls_segment is NULL, we should have signalled an error already. */
+ if (tls_segment == NULL)
+ return 0;
+ return (align_power (tls_segment->size, tls_segment->align)
+ + tls_segment->start - address);
+}
+
+/* Complain if TLS instruction relocation is against an invalid
+ instruction. */
+
+static void
+invalid_tls_insn (input_bfd, input_section, rel)
+ bfd *input_bfd;
+ asection *input_section;
+ Elf_Internal_Rela *rel;
+{
+ reloc_howto_type *howto;
+
+ howto = elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ (*_bfd_error_handler)
+ (_("%s(%s+0x%lx): invalid instruction for TLS relocation %s"),
+ bfd_archive_filename (input_bfd),
+ bfd_get_section_name (input_bfd, input_section),
+ (long) rel->r_offset,
+ howto->name);
+}
+
/* Relocate a 390 ELF section. */
static bfd_boolean
@@ -1811,6 +2198,7 @@
bfd_vma relocation;
bfd_boolean unresolved_reloc;
bfd_reloc_status_type r;
+ int tls_type;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == (int) R_390_GNU_VTINHERIT
@@ -2185,6 +2573,330 @@
}
break;
+ /* Relocations for tls literal pool entries. */
+ case R_390_TLS_IE32:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+ }
+ /* Fall through */
+
+ case R_390_TLS_GD32:
+ case R_390_TLS_GOTIE32:
+ r_type = elf_s390_tls_transition (info, r_type, h == NULL);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (!info->shared && h->dynindx == -1 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_LE32;
+ }
+ if (r_type == R_390_TLS_GD32 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_IE32;
+
+ if (r_type == R_390_TLS_LE32)
+ {
+ /* This relocation gets optimized away by the local exec
+ access optimization. */
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ continue;
+ }
+
+ if (htab->sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ }
+
+ emit_tls_relocs:
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ int dr_type, indx;
+
+ if (htab->srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->sgot->output_section->vma
+ + htab->sgot->output_offset + off);
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ if (r_type == R_390_TLS_GD32)
+ dr_type = R_390_TLS_DTPMOD;
+ else
+ dr_type = R_390_TLS_TPOFF;
+ if (dr_type == R_390_TLS_TPOFF && indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (indx, dr_type);
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++
+ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (r_type == R_390_TLS_GD32)
+ {
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd,
+ relocation - dtpoff_base (info),
+ htab->sgot->contents + off + GOT_ENTRY_SIZE);
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (indx, R_390_TLS_DTPOFF);
+ outrel.r_offset += GOT_ENTRY_SIZE;
+ outrel.r_addend = 0;
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ }
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+ if (r_type == ELF32_R_TYPE (rel->r_info))
+ {
+ relocation = htab->sgot->output_offset + off;
+ if (r_type == R_390_TLS_IE32 || r_type == R_390_TLS_IEENT)
+ relocation += htab->sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, htab->sgot->output_offset + off,
+ contents + rel->r_offset);
+ continue;
+ }
+ break;
+
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_IEENT:
+ if (h == NULL)
+ {
+ if (local_got_offsets == NULL)
+ abort();
+ off = local_got_offsets[r_symndx];
+ if (info->shared)
+ goto emit_tls_relocs;
+ }
+ else
+ {
+ off = h->got.offset;
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE)
+ goto emit_tls_relocs;
+ }
+
+ if (htab->sgot == NULL)
+ abort ();
+
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd, -tpoff (info, relocation),
+ htab->sgot->contents + off);
+ relocation = htab->sgot->output_offset + off;
+ if (r_type == R_390_TLS_IEENT)
+ relocation += htab->sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LDM32:
+ if (! info->shared)
+ /* The literal pool entry this relocation refers to gets ignored
+ by the optimized code of the local exec model. Do nothing
+ and the value will turn out zero. */
+ continue;
+
+ if (htab->sgot == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (htab->srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->sgot->output_section->vma
+ + htab->sgot->output_offset + off);
+
+ bfd_put_32 (output_bfd, 0,
+ htab->sgot->contents + off + GOT_ENTRY_SIZE);
+ outrel.r_info = ELF32_R_INFO (0, R_390_TLS_DTPMOD);
+ outrel.r_addend = 0;
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++
+ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+ relocation = htab->sgot->output_offset + off;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LE32:
+ if (info->shared)
+ {
+ /* Linking a shared library with non-fpic code requires
+ a R_390_TLS_TPOFF relocation. */
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+ int indx;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ if (h != NULL && h->dynindx != -1)
+ indx = h->dynindx;
+ else
+ indx = 0;
+ outrel.r_info = ELF32_R_INFO (indx, R_390_TLS_TPOFF);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ }
+ continue;
+
+ case R_390_TLS_LDO32:
+ if (info->shared || (input_section->flags & SEC_CODE) == 0)
+ relocation -= dtpoff_base (info);
+ else
+ /* When converting LDO to LE, we must negate. */
+ relocation = -tpoff (info, relocation);
+ break;
+
+ /* Relocations for tls instructions. */
+ case R_390_TLS_LOAD:
+ case R_390_TLS_GDCALL:
+ case R_390_TLS_LDCALL:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+
+ if (tls_type == GOT_TLS_GD)
+ continue;
+
+ if (r_type == R_390_TLS_LOAD)
+ {
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ /* IE->LE transition. Four valid cases:
+ l %rx,0(0,%ry) -> lr %rx,%ry + bcr 0,0
+ l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0
+ l %rx,0(%ry,%r12) -> lr %rx,%ry + bcr 0,0
+ l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0 */
+ unsigned int insn, ry;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ ry = 0;
+ if ((insn & 0xff00f000) == 0x58000000)
+ /* l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x000f0000);
+ else if ((insn & 0xff0f0000) == 0x58000000)
+ /* l %rx,0(0,%ry) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x0000f000) << 4;
+ else if ((insn & 0xff00f000) == 0x5800c000)
+ /* l %rx,0(%ry,%r12) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x000f0000);
+ else if ((insn & 0xff0f0000) == 0x580c0000)
+ /* l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x0000f000) << 4;
+ else
+ invalid_tls_insn (input_bfd, input_section, rel);
+ insn = 0x18000700 | (insn & 0x00f00000) | ry;
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ }
+ else if (r_type == R_390_TLS_GDCALL)
+ {
+ unsigned int insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if ((insn & 0xff000fff) != 0x4d000000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ /* GD->LE transition.
+ bas %r14,0(%rx,%r13) -> bc 0,0 */
+ insn = 0x47000000;
+ else
+ /* GD->IE transition.
+ bas %r14,0(%rx,%r13) -> l %r2,0(%r2,%r12) */
+ insn = 0x5822c000;
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ else if (r_type == R_390_TLS_LDCALL)
+ {
+ if (!info->shared)
+ {
+ unsigned int insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if ((insn & 0xff000fff) != 0x4d000000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ /* LD->LE transition.
+ bas %r14,0(%rx,%r13) -> bc 0,0 */
+ insn = 0x47000000;
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ }
+ continue;
+
default:
break;
}
@@ -2399,7 +3111,10 @@
}
}
- if (h->got.offset != (bfd_vma) -1)
+ if (h->got.offset != (bfd_vma) -1
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_GD
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE_NLT)
{
Elf_Internal_Rela rela;
bfd_byte *loc;
@@ -2616,13 +3331,6 @@
}
static bfd_boolean
-elf_s390_object_p (abfd)
- bfd *abfd;
-{
- return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_31);
-}
-
-static bfd_boolean
elf_s390_grok_prstatus (abfd, note)
bfd * abfd;
Elf_Internal_Note * note;
@@ -2689,6 +3397,7 @@
#define elf_backend_reloc_type_class elf_s390_reloc_type_class
#define elf_backend_grok_prstatus elf_s390_grok_prstatus
+#define bfd_elf32_mkobject elf_s390_mkobject
#define elf_backend_object_p elf_s390_object_p
#include "elf32-target.h"
diff -urN src/bfd/elf64-s390.c src-s390/bfd/elf64-s390.c
--- src/bfd/elf64-s390.c Mon Jan 20 12:38:30 2003
+++ src-s390/bfd/elf64-s390.c Fri Jan 24 09:53:39 2003
@@ -72,8 +72,20 @@
PARAMS ((const Elf_Internal_Rela *));
static bfd_boolean elf_s390_finish_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
+static bfd_boolean elf_s390_mkobject
+ PARAMS ((bfd *));
static bfd_boolean elf_s390_object_p
PARAMS ((bfd *));
+static int elf_s390_tls_transition
+ PARAMS ((struct bfd_link_info *, int, int));
+static bfd_reloc_status_type s390_tls_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_vma dtpoff_base
+ PARAMS ((struct bfd_link_info *));
+static bfd_vma tpoff
+ PARAMS ((struct bfd_link_info *, bfd_vma));
+static void invalid_tls_insn
+ PARAMS ((bfd *, asection *, Elf_Internal_Rela *));
#include "elf/s390.h"
@@ -170,6 +182,40 @@
bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLTOFF64", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_LOAD, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LOAD", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_GDCALL", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_LDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LDCALL", FALSE, 0, 0, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GD32), /* Empty entry for R_390_TLS_GD32. */
+ HOWTO(R_390_TLS_GD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GD64", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_GOTIE12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE12", FALSE, 0, 0x00000fff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GOTIE32), /* Empty entry for R_390_TLS_GOTIE32. */
+ HOWTO(R_390_TLS_GOTIE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE64", FALSE, 0, MINUS_ONE, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDM32), /* Empty entry for R_390_TLS_LDM32. */
+ HOWTO(R_390_TLS_LDM64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDM64", FALSE, 0, MINUS_ONE, FALSE),
+ EMPTY_HOWTO (R_390_TLS_IE32), /* Empty entry for R_390_TLS_IE32. */
+ HOWTO(R_390_TLS_IE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IE64", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_IEENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IEENT", FALSE, 0, MINUS_ONE, TRUE),
+ EMPTY_HOWTO (R_390_TLS_LE32), /* Empty entry for R_390_TLS_LE32. */
+ HOWTO(R_390_TLS_LE64, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LE64", FALSE, 0, MINUS_ONE, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDO32), /* Empty entry for R_390_TLS_LDO32. */
+ HOWTO(R_390_TLS_LDO64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDO64", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_DTPMOD, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPMOD", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_DTPOFF, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPOFF", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_TPOFF, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, MINUS_ONE, FALSE),
};
/* GNU extension to record C++ vtable hierarchy. */
@@ -261,6 +307,34 @@
return &elf_howto_table[(int) R_390_PLTOFF32];
case BFD_RELOC_390_PLTOFF64:
return &elf_howto_table[(int) R_390_PLTOFF64];
+ case BFD_RELOC_390_TLS_LOAD:
+ return &elf_howto_table[(int) R_390_TLS_LOAD];
+ case BFD_RELOC_390_TLS_GDCALL:
+ return &elf_howto_table[(int) R_390_TLS_GDCALL];
+ case BFD_RELOC_390_TLS_LDCALL:
+ return &elf_howto_table[(int) R_390_TLS_LDCALL];
+ case BFD_RELOC_390_TLS_GD64:
+ return &elf_howto_table[(int) R_390_TLS_GD64];
+ case BFD_RELOC_390_TLS_GOTIE12:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE12];
+ case BFD_RELOC_390_TLS_GOTIE64:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE64];
+ case BFD_RELOC_390_TLS_LDM64:
+ return &elf_howto_table[(int) R_390_TLS_LDM64];
+ case BFD_RELOC_390_TLS_IE64:
+ return &elf_howto_table[(int) R_390_TLS_IE64];
+ case BFD_RELOC_390_TLS_IEENT:
+ return &elf_howto_table[(int) R_390_TLS_IEENT];
+ case BFD_RELOC_390_TLS_LE64:
+ return &elf_howto_table[(int) R_390_TLS_LE64];
+ case BFD_RELOC_390_TLS_LDO64:
+ return &elf_howto_table[(int) R_390_TLS_LDO64];
+ case BFD_RELOC_390_TLS_DTPMOD:
+ return &elf_howto_table[(int) R_390_TLS_DTPMOD];
+ case BFD_RELOC_390_TLS_DTPOFF:
+ return &elf_howto_table[(int) R_390_TLS_DTPOFF];
+ case BFD_RELOC_390_TLS_TPOFF:
+ return &elf_howto_table[(int) R_390_TLS_TPOFF];
case BFD_RELOC_VTABLE_INHERIT:
return &elf64_s390_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
@@ -296,6 +370,23 @@
}
}
+/* A relocation function which doesn't do anything. */
+static bfd_reloc_status_type
+s390_tls_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ arelent *reloc_entry;
+ asymbol *symbol ATTRIBUTE_UNUSED;
+ PTR data ATTRIBUTE_UNUSED;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message ATTRIBUTE_UNUSED;
+{
+ if (output_bfd)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
static bfd_boolean
elf_s390_is_local_label_name (abfd, name)
bfd *abfd;
@@ -430,8 +521,59 @@
/* Number of GOTPLT references for a function. */
bfd_signed_vma gotplt_refcount;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 3
+#define GOT_TLS_IE_NLT 3
+ unsigned char tls_type;
};
+#define elf_s390_hash_entry(ent) \
+ ((struct elf_s390_link_hash_entry *)(ent))
+
+struct elf_s390_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define elf_s390_tdata(abfd) \
+ ((struct elf_s390_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_s390_local_got_tls_type(abfd) \
+ (elf_s390_tdata (abfd)->local_got_tls_type)
+
+static bfd_boolean
+elf_s390_mkobject (abfd)
+ bfd *abfd;
+{
+ bfd_size_type amt = sizeof (struct elf_s390_obj_tdata);
+ abfd->tdata.any = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.any == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+elf_s390_object_p (abfd)
+ bfd *abfd;
+{
+ /* Allocate our special target data. */
+ struct elf_s390_obj_tdata *new_tdata;
+ bfd_size_type amt = sizeof (struct elf_s390_obj_tdata);
+ new_tdata = bfd_zalloc (abfd, amt);
+ if (new_tdata == NULL)
+ return FALSE;
+ new_tdata->root = *abfd->tdata.elf_obj_data;
+ abfd->tdata.any = new_tdata;
+ /* Set the right machine number for an s390 elf32 file. */
+ return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_64);
+}
+
/* s390 ELF linker hash table. */
struct elf_s390_link_hash_table
@@ -447,6 +589,11 @@
asection *sdynbss;
asection *srelbss;
+ union {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
};
@@ -483,6 +630,7 @@
eh = (struct elf_s390_link_hash_entry *) entry;
eh->dyn_relocs = NULL;
eh->gotplt_refcount = 0;
+ eh->tls_type = GOT_UNKNOWN;
}
return entry;
@@ -514,6 +662,7 @@
ret->srelplt = NULL;
ret->sdynbss = NULL;
ret->srelbss = NULL;
+ ret->tls_ldm_got.refcount = 0;
ret->sym_sec.abfd = NULL;
return &ret->elf.root;
@@ -626,9 +775,43 @@
eind->dyn_relocs = NULL;
}
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+
_bfd_elf_link_hash_copy_indirect (bed, dir, ind);
}
+static int
+elf_s390_tls_transition (info, r_type, is_local)
+ struct bfd_link_info *info;
+ int r_type;
+ int is_local;
+{
+ if (info->shared)
+ return r_type;
+
+ switch (r_type)
+ {
+ case R_390_TLS_GD64:
+ case R_390_TLS_IE64:
+ if (is_local)
+ return R_390_TLS_LE64;
+ return R_390_TLS_IE64;
+ case R_390_TLS_GOTIE64:
+ if (is_local)
+ return R_390_TLS_LE64;
+ return R_390_TLS_GOTIE64;
+ case R_390_TLS_LDM64:
+ return R_390_TLS_LE64;
+ }
+
+ return r_type;
+}
+
/* Look through the relocs for a section during the first phase, and
allocate space in the global offset table or procedure linkage
table. */
@@ -647,6 +830,7 @@
const Elf_Internal_Rela *rel_end;
asection *sreloc;
bfd_signed_vma *local_got_refcounts;
+ int tls_type, old_tls_type;
if (info->relocateable)
return TRUE;
@@ -661,6 +845,7 @@
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
+ unsigned int r_type;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
@@ -681,7 +866,10 @@
/* Create got section and local_got_refcounts array if they
are needed. */
- switch (ELF64_R_TYPE (rel->r_info))
+ r_type = elf_s390_tls_transition (info,
+ ELF64_R_TYPE (rel->r_info),
+ h == NULL);
+ switch (r_type)
{
case R_390_GOT12:
case R_390_GOT16:
@@ -693,18 +881,26 @@
case R_390_GOTPLT32:
case R_390_GOTPLT64:
case R_390_GOTPLTENT:
+ case R_390_TLS_GD64:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE64:
+ case R_390_TLS_IEENT:
+ case R_390_TLS_IE64:
+ case R_390_TLS_LDM64:
if (h == NULL
&& local_got_refcounts == NULL)
{
bfd_size_type size;
size = symtab_hdr->sh_info;
- size *= sizeof (bfd_signed_vma);
+ size *= (sizeof (bfd_signed_vma) + sizeof(char));
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
+ elf_s390_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
}
/* Fall through. */
case R_390_GOTOFF16:
@@ -721,24 +917,8 @@
}
}
- switch (ELF64_R_TYPE (rel->r_info))
+ switch (r_type)
{
- case R_390_GOT12:
- case R_390_GOT16:
- case R_390_GOT32:
- case R_390_GOT64:
- case R_390_GOTENT:
- /* This symbol requires a global offset table entry. */
- if (h != NULL)
- {
- h->got.refcount += 1;
- }
- else
- {
- local_got_refcounts[r_symndx] += 1;
- }
- /* Fall through */
-
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTOFF64:
@@ -790,10 +970,92 @@
h->plt.refcount += 1;
}
else
+ local_got_refcounts[r_symndx] += 1;
+ break;
+
+ case R_390_TLS_LDM64:
+ htab->tls_ldm_got.refcount += 1;
+ break;
+
+ case R_390_TLS_IE64:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE64:
+ case R_390_TLS_IEENT:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT32:
+ case R_390_GOT64:
+ case R_390_GOTENT:
+ case R_390_TLS_GD64:
+ /* This symbol requires a global offset table entry. */
+ switch (r_type)
+ {
+ default:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_390_TLS_GD64:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_390_TLS_IE64:
+ case R_390_TLS_GOTIE64:
+ tls_type = GOT_TLS_IE;
+ break;
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_IEENT:
+ tls_type = GOT_TLS_IE_NLT;
+ break;
+ }
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = elf_s390_hash_entry(h)->tls_type;
+ }
+ else
{
local_got_refcounts[r_symndx] += 1;
+ old_tls_type = elf_s390_local_got_tls_type (abfd) [r_symndx];
}
- break;
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN)
+ {
+ if (old_tls_type == GOT_NORMAL || tls_type == GOT_NORMAL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: `%s' accessed both as normal and thread local symbol"),
+ bfd_archive_filename (abfd), h->root.root.string);
+ return FALSE;
+ }
+ if (old_tls_type > tls_type)
+ tls_type = old_tls_type;
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf_s390_hash_entry (h)->tls_type = tls_type;
+ else
+ elf_s390_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+
+ if (r_type != R_390_TLS_IE64)
+ break;
+ /* Fall through */
+
+ case R_390_TLS_LE64:
+ if (!info->shared)
+ break;
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
case R_390_8:
case R_390_16:
@@ -1031,6 +1293,7 @@
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
+ int r_type;
struct elf_link_hash_entry *h;
elf_section_data (sec)->local_dynrel = NULL;
@@ -1049,8 +1312,21 @@
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- switch (ELF64_R_TYPE (rel->r_info))
+ r_type = elf_s390_tls_transition (info,
+ ELF64_R_TYPE (rel->r_info),
+ r_symndx >= symtab_hdr->sh_info);
+ switch (r_type)
{
+ case R_390_TLS_LDM64:
+ if (elf_s390_hash_table (info)->tls_ldm_got.refcount > 0)
+ elf_s390_hash_table (info)->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_390_TLS_GD64:
+ case R_390_TLS_IE64:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE64:
+ case R_390_TLS_IEENT:
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
@@ -1071,41 +1347,14 @@
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
- break;
+ if (r_type != R_390_TLS_IE64)
+ break;
+ /* Fall through */
- case R_390_PLT16DBL:
- case R_390_PLT32:
- case R_390_PLT32DBL:
- case R_390_PLT64:
- case R_390_PLTOFF16:
- case R_390_PLTOFF32:
- case R_390_PLTOFF64:
- if (h != NULL)
- {
- if (h->plt.refcount > 0)
- h->plt.refcount -= 1;
- }
- break;
-
- case R_390_GOTPLT12:
- case R_390_GOTPLT16:
- case R_390_GOTPLT32:
- case R_390_GOTPLT64:
- case R_390_GOTPLTENT:
- if (h != NULL)
- {
- if (h->plt.refcount > 0)
- {
- ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
- h->plt.refcount -= 1;
- }
- }
- else if (local_got_refcounts != NULL)
- {
- if (local_got_refcounts[r_symndx] > 0)
- local_got_refcounts[r_symndx] -= 1;
- }
- break;
+ case R_390_TLS_LE64:
+ if (!info->shared)
+ break;
+ /* Fall through */
case R_390_8:
case R_390_12:
@@ -1145,6 +1394,40 @@
}
break;
+ case R_390_PLT16DBL:
+ case R_390_PLT32:
+ case R_390_PLT32DBL:
+ case R_390_PLT64:
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ case R_390_PLTOFF64:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ break;
+
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLT64:
+ case R_390_GOTPLTENT:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ {
+ ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
+ h->plt.refcount -= 1;
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
default:
break;
}
@@ -1417,10 +1700,31 @@
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
- if (h->got.refcount > 0)
+ /* If R_390_TLS_{IE64,GOTIE64,GOTIE12,IEENT} symbol is now local to
+ the binary, we can optimize a bit. IE64 and GOTIE64 get converted
+ to R_390_TLS_LE64 requiring no TLS entry. For GOTIE12 and IEENT
+ we can save the dynamic TLS relocation. */
+ if (h->got.refcount > 0
+ && !info->shared
+ && h->dynindx == -1
+ && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE)
+ {
+ if (elf_s390_hash_entry(h)->tls_type == GOT_TLS_IE_NLT)
+ /* For the GOTIE access without a literal pool entry the offset has
+ to be stored somewhere. The immediate value in the instruction
+ is not bit enough so the value is stored in the got. */
+ {
+ h->got.offset = htab->sgot->_raw_size;
+ htab->sgot->_raw_size += GOT_ENTRY_SIZE;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+ }
+ else if (h->got.refcount > 0)
{
asection *s;
bfd_boolean dyn;
+ int tls_type = elf_s390_hash_entry(h)->tls_type;
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
@@ -1434,8 +1738,18 @@
s = htab->sgot;
h->got.offset = s->_raw_size;
s->_raw_size += GOT_ENTRY_SIZE;
+ /* R_390_TLS_GD64 needs 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->_raw_size += GOT_ENTRY_SIZE;
dyn = htab->elf.dynamic_sections_created;
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
+ /* R_390_TLS_IE64 needs one dynamic relocation,
+ R_390_TLS_GD64 needs one if local symbol and two if global. */
+ if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+ || tls_type >= GOT_TLS_IE)
+ htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);
+ else if (tls_type == GOT_TLS_GD)
+ htab->srelgot->_raw_size += 2 * sizeof (Elf64_External_Rela);
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);
}
else
@@ -1581,6 +1895,7 @@
{
bfd_signed_vma *local_got;
bfd_signed_vma *end_local_got;
+ char *local_tls_type;
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
asection *srela;
@@ -1622,14 +1937,17 @@
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
+ local_tls_type = elf_s390_local_got_tls_type (ibfd);
s = htab->sgot;
srela = htab->srelgot;
- for (; local_got < end_local_got; ++local_got)
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
{
if (*local_got > 0)
{
*local_got = s->_raw_size;
s->_raw_size += GOT_ENTRY_SIZE;
+ if (*local_tls_type == GOT_TLS_GD)
+ s->_raw_size += GOT_ENTRY_SIZE;
if (info->shared)
srela->_raw_size += sizeof (Elf64_External_Rela);
}
@@ -1638,6 +1956,17 @@
}
}
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_390_TLS_LDM64
+ relocs. */
+ htab->tls_ldm_got.offset = htab->sgot->_raw_size;
+ htab->sgot->_raw_size += 2 * GOT_ENTRY_SIZE;
+ htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
/* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
@@ -1748,6 +2077,58 @@
return TRUE;
}
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (info)
+ struct bfd_link_info *info;
+{
+ /* If tls_segment is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_segment == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_segment->start;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (info, address)
+ struct bfd_link_info *info;
+ bfd_vma address;
+{
+ struct elf_link_tls_segment *tls_segment
+ = elf_hash_table (info)->tls_segment;
+
+ /* If tls_segment is NULL, we should have signalled an error already. */
+ if (tls_segment == NULL)
+ return 0;
+ return (align_power (tls_segment->size, tls_segment->align)
+ + tls_segment->start - address);
+}
+
+/* Complain if TLS instruction relocation is against an invalid
+ instruction. */
+
+static void
+invalid_tls_insn (input_bfd, input_section, rel)
+ bfd *input_bfd;
+ asection *input_section;
+ Elf_Internal_Rela *rel;
+{
+ reloc_howto_type *howto;
+
+ howto = elf_howto_table + ELF64_R_TYPE (rel->r_info);
+ (*_bfd_error_handler)
+ (_("%s(%s+0x%lx): invalid instruction for TLS relocation %s"),
+ bfd_archive_filename (input_bfd),
+ bfd_get_section_name (input_bfd, input_section),
+ (long) rel->r_offset,
+ howto->name);
+}
+
/* Relocate a 390 ELF section. */
static bfd_boolean
@@ -1791,6 +2172,7 @@
bfd_vma relocation;
bfd_boolean unresolved_reloc;
bfd_reloc_status_type r;
+ int tls_type;
r_type = ELF64_R_TYPE (rel->r_info);
if (r_type == (int) R_390_GNU_VTINHERIT
@@ -2176,6 +2558,346 @@
break;
+ /* Relocations for tls literal pool entries. */
+ case R_390_TLS_IE64:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE);
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloc_out (output_bfd, &outrel, loc);
+ }
+ /* Fall through */
+
+ case R_390_TLS_GD64:
+ case R_390_TLS_GOTIE64:
+ r_type = elf_s390_tls_transition (info, r_type, h == NULL);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (!info->shared && h->dynindx == -1 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_LE64;
+ }
+ if (r_type == R_390_TLS_GD64 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_IE64;
+
+ if (r_type == R_390_TLS_LE64)
+ {
+ /* This relocation gets optimized away by the local exec
+ access optimization. */
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ continue;
+ }
+
+ if (htab->sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ }
+
+ emit_tls_relocs:
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ int dr_type, indx;
+
+ if (htab->srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->sgot->output_section->vma
+ + htab->sgot->output_offset + off);
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ if (r_type == R_390_TLS_GD64)
+ dr_type = R_390_TLS_DTPMOD;
+ else
+ dr_type = R_390_TLS_TPOFF;
+ if (dr_type == R_390_TLS_TPOFF && indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_info = ELF64_R_INFO (indx, dr_type);
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++
+ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (r_type == R_390_TLS_GD64)
+ {
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd,
+ relocation - dtpoff_base (info),
+ htab->sgot->contents + off + GOT_ENTRY_SIZE);
+ }
+ else
+ {
+ outrel.r_info = ELF64_R_INFO (indx, R_390_TLS_DTPOFF);
+ outrel.r_offset += GOT_ENTRY_SIZE;
+ outrel.r_addend = 0;
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ }
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+ if (r_type == ELF64_R_TYPE (rel->r_info))
+ {
+ relocation = htab->sgot->output_offset + off;
+ if (r_type == R_390_TLS_IE64 || r_type == R_390_TLS_IEENT)
+ relocation += htab->sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ bfd_put_64 (output_bfd, htab->sgot->output_offset + off,
+ contents + rel->r_offset);
+ continue;
+ }
+ break;
+
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_IEENT:
+ if (h == NULL)
+ {
+ if (local_got_offsets == NULL)
+ abort();
+ off = local_got_offsets[r_symndx];
+ if (info->shared)
+ goto emit_tls_relocs;
+ }
+ else
+ {
+ off = h->got.offset;
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE)
+ goto emit_tls_relocs;
+ }
+
+ if (htab->sgot == NULL)
+ abort ();
+
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd, -tpoff (info, relocation),
+ htab->sgot->contents + off);
+ relocation = htab->sgot->output_offset + off;
+ if (r_type == R_390_TLS_IEENT)
+ relocation += htab->sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LDM64:
+ if (! info->shared)
+ /* The literal pool entry this relocation refers to gets ignored
+ by the optimized code of the local exec model. Do nothing
+ and the value will turn out zero. */
+ continue;
+
+ if (htab->sgot == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (htab->srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->sgot->output_section->vma
+ + htab->sgot->output_offset + off);
+
+ bfd_put_64 (output_bfd, 0,
+ htab->sgot->contents + off + GOT_ENTRY_SIZE);
+ outrel.r_info = ELF64_R_INFO (0, R_390_TLS_DTPMOD);
+ outrel.r_addend = 0;
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++
+ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+ relocation = htab->sgot->output_offset + off;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LE64:
+ if (info->shared)
+ {
+ /* Linking a shared library with non-fpic code requires
+ a R_390_TLS_TPOFF relocation. */
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+ int indx;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ if (h != NULL && h->dynindx != -1)
+ indx = h->dynindx;
+ else
+ indx = 0;
+ outrel.r_info = ELF64_R_INFO (indx, R_390_TLS_TPOFF);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ }
+ continue;
+
+ case R_390_TLS_LDO64:
+ if (info->shared || (input_section->flags & SEC_CODE) == 0)
+ relocation -= dtpoff_base (info);
+ else
+ /* When converting LDO to LE, we must negate. */
+ relocation = -tpoff (info, relocation);
+ break;
+
+ /* Relocations for tls instructions. */
+ case R_390_TLS_LOAD:
+ case R_390_TLS_GDCALL:
+ case R_390_TLS_LDCALL:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+
+ if (tls_type == GOT_TLS_GD)
+ continue;
+
+ if (r_type == R_390_TLS_LOAD)
+ {
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ /* IE->LE transition. Four valid cases:
+ lg %rx,(0,%ry) -> sllg %rx,%ry,0
+ lg %rx,(%ry,0) -> sllg %rx,%ry,0
+ lg %rx,(%ry,%r12) -> sllg %rx,%ry,0
+ lg %rx,(%r12,%ry) -> sllg %rx,%ry,0 */
+ unsigned int insn0, insn1, ry;
+
+ insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
+ if (insn1 != 0x0004)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ ry = 0;
+ if ((insn0 & 0xff00f000) == 0xe3000000)
+ /* lg %rx,0(%ry,0) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x000f0000);
+ else if ((insn0 & 0xff0f0000) == 0xe3000000)
+ /* lg %rx,0(0,%ry) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x0000f000) << 4;
+ else if ((insn0 & 0xff00f000) == 0xe300c000)
+ /* lg %rx,0(%ry,%r12) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x000f0000);
+ else if ((insn0 & 0xff0f0000) == 0xe30c0000)
+ /* lg %rx,0(%r12,%ry) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x0000f000) << 4;
+ else
+ invalid_tls_insn (input_bfd, input_section, rel);
+ insn0 = 0xeb000000 | (insn0 & 0x00f00000) | ry;
+ insn1 = 0x000d;
+ bfd_put_32 (output_bfd, insn0, contents + rel->r_offset);
+ bfd_put_16 (output_bfd, insn1, contents + rel->r_offset + 4);
+ }
+ }
+ else if (r_type == R_390_TLS_GDCALL)
+ {
+ unsigned int insn0, insn1;
+
+ insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
+ if ((insn0 & 0xffff0000) != 0xc0e50000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ /* GD->LE transition.
+ brasl %r14,__tls_get_addr@plt -> brcl 0,. */
+ insn0 = 0xc0040000;
+ insn1 = 0x0000;
+ }
+ else
+ {
+ /* GD->IE transition.
+ brasl %r14,__tls_get_addr@plt -> lg %r2,0(%r2,%r12) */
+ insn0 = 0xe322c000;
+ insn1 = 0x0004;
+ }
+ bfd_put_32 (output_bfd, insn0, contents + rel->r_offset);
+ bfd_put_16 (output_bfd, insn1, contents + rel->r_offset + 4);
+ }
+ else if (r_type == R_390_TLS_LDCALL)
+ {
+ if (!info->shared)
+ {
+ unsigned int insn0, insn1;
+
+ insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
+ if ((insn0 & 0xffff0000) != 0xc0e50000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ /* LD->LE transition.
+ brasl %r14,__tls_get_addr@plt -> brcl 0,. */
+ insn0 = 0xc0040000;
+ insn1 = 0x0000;
+ bfd_put_32 (output_bfd, insn0, contents + rel->r_offset);
+ bfd_put_16 (output_bfd, insn1, contents + rel->r_offset + 4);
+ }
+ }
+ continue;
+
default:
break;
}
@@ -2335,7 +3057,10 @@
}
}
- if (h->got.offset != (bfd_vma) -1)
+ if (h->got.offset != (bfd_vma) -1
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_GD
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE_NLT)
{
Elf_Internal_Rela rela;
bfd_byte *loc;
@@ -2553,13 +3278,6 @@
return TRUE;
}
-static bfd_boolean
-elf_s390_object_p (abfd)
- bfd *abfd;
-{
- return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_64);
-}
-
/*
* Why was the hash table entry size definition changed from
* ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
@@ -2633,6 +3351,7 @@
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
#define elf_backend_reloc_type_class elf_s390_reloc_type_class
-#define elf_backend_object_p elf_s390_object_p
+#define bfd_elf64_mkobject elf_s390_mkobject
+#define elf_backend_object_p elf_s390_object_p
#include "elf64-target.h"
diff -urN src/bfd/libbfd.h src-s390/bfd/libbfd.h
--- src/bfd/libbfd.h Mon Jan 20 12:38:30 2003
+++ src-s390/bfd/libbfd.h Thu Jan 23 23:23:13 2003
@@ -1217,6 +1217,26 @@
"BFD_RELOC_390_PLTOFF16",
"BFD_RELOC_390_PLTOFF32",
"BFD_RELOC_390_PLTOFF64",
+ "BFD_RELOC_390_TLS_LOAD",
+ "BFD_RELOC_390_TLS_GDCALL",
+ "BFD_RELOC_390_TLS_LDCALL",
+ "BFD_RELOC_390_TLS_GD32",
+ "BFD_RELOC_390_TLS_GD64",
+ "BFD_RELOC_390_TLS_GOTIE12",
+ "BFD_RELOC_390_TLS_GOTIE32",
+ "BFD_RELOC_390_TLS_GOTIE64",
+ "BFD_RELOC_390_TLS_LDM32",
+ "BFD_RELOC_390_TLS_LDM64",
+ "BFD_RELOC_390_TLS_IE32",
+ "BFD_RELOC_390_TLS_IE64",
+ "BFD_RELOC_390_TLS_IEENT",
+ "BFD_RELOC_390_TLS_LE32",
+ "BFD_RELOC_390_TLS_LE64",
+ "BFD_RELOC_390_TLS_LDO32",
+ "BFD_RELOC_390_TLS_LDO64",
+ "BFD_RELOC_390_TLS_DTPMOD",
+ "BFD_RELOC_390_TLS_DTPOFF",
+ "BFD_RELOC_390_TLS_TPOFF",
"BFD_RELOC_IP2K_FR9",
"BFD_RELOC_IP2K_BANK",
"BFD_RELOC_IP2K_ADDR16CJP",
diff -urN src/bfd/reloc.c src-s390/bfd/reloc.c
--- src/bfd/reloc.c Mon Jan 20 12:38:30 2003
+++ src-s390/bfd/reloc.c Thu Jan 23 23:23:13 2003
@@ -3207,6 +3207,49 @@
64-bit rel. offset from the GOT to a PLT entry.
ENUM
+ BFD_RELOC_390_TLS_LOAD
+ENUMX
+ BFD_RELOC_390_TLS_GDCALL
+ENUMX
+ BFD_RELOC_390_TLS_LDCALL
+ENUMX
+ BFD_RELOC_390_TLS_GD32
+ENUMX
+ BFD_RELOC_390_TLS_GD64
+ENUMX
+ BFD_RELOC_390_TLS_GOTIE12
+ENUMX
+ BFD_RELOC_390_TLS_GOTIE32
+ENUMX
+ BFD_RELOC_390_TLS_GOTIE64
+ENUMX
+ BFD_RELOC_390_TLS_LDM32
+ENUMX
+ BFD_RELOC_390_TLS_LDM64
+ENUMX
+ BFD_RELOC_390_TLS_IE32
+ENUMX
+ BFD_RELOC_390_TLS_IE64
+ENUMX
+ BFD_RELOC_390_TLS_IEENT
+ENUMX
+ BFD_RELOC_390_TLS_LE32
+ENUMX
+ BFD_RELOC_390_TLS_LE64
+ENUMX
+ BFD_RELOC_390_TLS_LDO32
+ENUMX
+ BFD_RELOC_390_TLS_LDO64
+ENUMX
+ BFD_RELOC_390_TLS_DTPMOD
+ENUMX
+ BFD_RELOC_390_TLS_DTPOFF
+ENUMX
+ BFD_RELOC_390_TLS_TPOFF
+ENUMDOC
+ s390 tls relocations.
+
+ENUM
BFD_RELOC_IP2K_FR9
ENUMDOC
Scenix IP2K - 9-bit register number / data address
diff -urN src/gas/config/tc-s390.c src-s390/gas/config/tc-s390.c
--- src/gas/config/tc-s390.c Thu Jan 23 17:05:20 2003
+++ src-s390/gas/config/tc-s390.c Thu Jan 23 23:23:13 2003
@@ -600,6 +600,67 @@
}
}
+struct map_tls
+ {
+ char *string;
+ int length;
+ bfd_reloc_code_real_type reloc;
+ };
+
+static bfd_reloc_code_real_type s390_tls_suffix
+ PARAMS ((char **, expressionS *));
+
+/* Parse tls marker and return the desired relocation. */
+static bfd_reloc_code_real_type
+s390_tls_suffix (str_p, exp_p)
+ char **str_p;
+ expressionS *exp_p;
+{
+ static struct map_tls mapping[] =
+ {
+ { "tls_load", 8, BFD_RELOC_390_TLS_LOAD },
+ { "tls_gdcall", 10, BFD_RELOC_390_TLS_GDCALL },
+ { "tls_ldcall", 10, BFD_RELOC_390_TLS_LDCALL },
+ { NULL, 0, BFD_RELOC_UNUSED }
+ };
+ struct map_tls *ptr;
+ char *orig_line;
+ char *str;
+ char *ident;
+ int len;
+
+ str = *str_p;
+ if (*str++ != ':')
+ return BFD_RELOC_UNUSED;
+
+ ident = str;
+ while (ISIDNUM (*str))
+ str++;
+ len = str - ident;
+ if (*str++ != ':')
+ return BFD_RELOC_UNUSED;
+
+ orig_line = input_line_pointer;
+ input_line_pointer = str;
+ expression (exp_p);
+ str = input_line_pointer;
+ if (&input_line_pointer != str_p)
+ input_line_pointer = orig_line;
+
+ if (exp_p->X_op != O_symbol)
+ return BFD_RELOC_UNUSED;
+
+ for (ptr = &mapping[0]; ptr->length > 0; ptr++)
+ if (len == ptr->length
+ && strncasecmp (ident, ptr->string, ptr->length) == 0)
+ {
+ /* Found a matching tls suffix. */
+ *str_p = str;
+ return ptr->reloc;
+ }
+ return BFD_RELOC_UNUSED;
+}
+
/* Structure used to hold suffixes. */
typedef enum
{
@@ -609,7 +670,13 @@
ELF_SUFFIX_GOTENT,
ELF_SUFFIX_GOTOFF,
ELF_SUFFIX_GOTPLT,
- ELF_SUFFIX_PLTOFF
+ ELF_SUFFIX_PLTOFF,
+ ELF_SUFFIX_TLS_GD,
+ ELF_SUFFIX_TLS_GOTIE,
+ ELF_SUFFIX_TLS_IE,
+ ELF_SUFFIX_TLS_LDM,
+ ELF_SUFFIX_TLS_LDO,
+ ELF_SUFFIX_TLS_LE
}
elf_suffix_type;
@@ -641,6 +708,12 @@
{ "gotoff", 6, ELF_SUFFIX_GOTOFF },
{ "gotplt", 6, ELF_SUFFIX_GOTPLT },
{ "pltoff", 6, ELF_SUFFIX_PLTOFF },
+ { "tlsgd", 5, ELF_SUFFIX_TLS_GD },
+ { "gotntpoff", 9, ELF_SUFFIX_TLS_GOTIE },
+ { "indntpoff", 9, ELF_SUFFIX_TLS_IE },
+ { "tlsldm", 6, ELF_SUFFIX_TLS_LDM },
+ { "dtpoff", 6, ELF_SUFFIX_TLS_LDO },
+ { "ntpoff", 6, ELF_SUFFIX_TLS_LE },
{ NULL, 0, ELF_SUFFIX_NONE }
};
@@ -956,38 +1029,72 @@
int size;
char *where;
- if (nbytes == 2 && suffix == ELF_SUFFIX_GOT)
- reloc = BFD_RELOC_390_GOT16;
- else if (nbytes == 4 && suffix == ELF_SUFFIX_GOT)
- reloc = BFD_RELOC_32_GOT_PCREL;
- else if (nbytes == 8 && suffix == ELF_SUFFIX_GOT)
- reloc = BFD_RELOC_390_GOT64;
- else if (nbytes == 2 && suffix == ELF_SUFFIX_GOTOFF)
- reloc = BFD_RELOC_16_GOTOFF;
- else if (nbytes == 4 && suffix == ELF_SUFFIX_GOTOFF)
- reloc = BFD_RELOC_32_GOTOFF;
- else if (nbytes == 8 && suffix == ELF_SUFFIX_GOTOFF)
- reloc = BFD_RELOC_390_GOTOFF64;
- else if (nbytes == 2 && suffix == ELF_SUFFIX_PLTOFF)
- reloc = BFD_RELOC_390_PLTOFF16;
- else if (nbytes == 4 && suffix == ELF_SUFFIX_PLTOFF)
- reloc = BFD_RELOC_390_PLTOFF32;
- else if (nbytes == 8 && suffix == ELF_SUFFIX_PLTOFF)
- reloc = BFD_RELOC_390_PLTOFF64;
- else if (nbytes == 4 && suffix == ELF_SUFFIX_PLT)
- reloc = BFD_RELOC_390_PLT32;
- else if (nbytes == 8 && suffix == ELF_SUFFIX_PLT)
- reloc = BFD_RELOC_390_PLT64;
- else if (nbytes == 4 && suffix == ELF_SUFFIX_GOTPLT)
- reloc = BFD_RELOC_390_GOTPLT32;
- else if (nbytes == 8 && suffix == ELF_SUFFIX_GOTPLT)
- reloc = BFD_RELOC_390_GOTPLT64;
+ if (nbytes == 2)
+ {
+ static bfd_reloc_code_real_type tab2[] =
+ {
+ [ELF_SUFFIX_NONE] BFD_RELOC_UNUSED ,
+ [ELF_SUFFIX_GOT] BFD_RELOC_390_GOT16,
+ [ELF_SUFFIX_PLT] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_GOTENT] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_GOTOFF] BFD_RELOC_16_GOTOFF,
+ [ELF_SUFFIX_GOTPLT] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_PLTOFF] BFD_RELOC_390_PLTOFF16,
+ [ELF_SUFFIX_TLS_GD] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_TLS_GOTIE] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_TLS_IE] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_TLS_LDM] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_TLS_LDO] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_TLS_LE] BFD_RELOC_UNUSED,
+ };
+ reloc = tab2[suffix];
+ }
+ else if (nbytes == 4)
+ {
+ static bfd_reloc_code_real_type tab4[] =
+ {
+ [ELF_SUFFIX_NONE] BFD_RELOC_UNUSED ,
+ [ELF_SUFFIX_GOT] BFD_RELOC_32_GOT_PCREL,
+ [ELF_SUFFIX_PLT] BFD_RELOC_390_PLT32,
+ [ELF_SUFFIX_GOTENT] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_GOTOFF] BFD_RELOC_32_GOTOFF,
+ [ELF_SUFFIX_GOTPLT] BFD_RELOC_390_GOTPLT32,
+ [ELF_SUFFIX_PLTOFF] BFD_RELOC_390_PLTOFF32,
+ [ELF_SUFFIX_TLS_GD] BFD_RELOC_390_TLS_GD32,
+ [ELF_SUFFIX_TLS_GOTIE] BFD_RELOC_390_TLS_GOTIE32,
+ [ELF_SUFFIX_TLS_IE] BFD_RELOC_390_TLS_IE32,
+ [ELF_SUFFIX_TLS_LDM] BFD_RELOC_390_TLS_LDM32,
+ [ELF_SUFFIX_TLS_LDO] BFD_RELOC_390_TLS_LDO32,
+ [ELF_SUFFIX_TLS_LE] BFD_RELOC_390_TLS_LE32,
+ };
+ reloc = tab4[suffix];
+ }
+ else if (nbytes == 8)
+ {
+ static bfd_reloc_code_real_type tab8[] =
+ {
+ [ELF_SUFFIX_NONE] BFD_RELOC_UNUSED ,
+ [ELF_SUFFIX_GOT] BFD_RELOC_390_GOT64,
+ [ELF_SUFFIX_PLT] BFD_RELOC_390_PLT64,
+ [ELF_SUFFIX_GOTENT] BFD_RELOC_UNUSED,
+ [ELF_SUFFIX_GOTOFF] BFD_RELOC_390_GOTOFF64,
+ [ELF_SUFFIX_GOTPLT] BFD_RELOC_390_GOTPLT64,
+ [ELF_SUFFIX_PLTOFF] BFD_RELOC_390_PLTOFF64,
+ [ELF_SUFFIX_TLS_GD] BFD_RELOC_390_TLS_GD64,
+ [ELF_SUFFIX_TLS_GOTIE] BFD_RELOC_390_TLS_GOTIE64,
+ [ELF_SUFFIX_TLS_IE] BFD_RELOC_390_TLS_IE64,
+ [ELF_SUFFIX_TLS_LDM] BFD_RELOC_390_TLS_LDM64,
+ [ELF_SUFFIX_TLS_LDO] BFD_RELOC_390_TLS_LDO64,
+ [ELF_SUFFIX_TLS_LE] BFD_RELOC_390_TLS_LE64,
+ };
+ reloc = tab8[suffix];
+ }
else
reloc = BFD_RELOC_UNUSED;
- if (reloc != BFD_RELOC_UNUSED)
+ if (reloc != BFD_RELOC_UNUSED
+ && (reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc)))
{
- reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
size = bfd_get_reloc_size (reloc_howto);
if (size > nbytes)
as_bad (_("%s relocations do not fit in %d bytes"),
@@ -1035,6 +1142,7 @@
struct s390_fixup fixups[MAX_INSN_FIXUPS];
const struct s390_operand *operand;
const unsigned char *opindex_ptr;
+ expressionS ex;
elf_suffix_type suffix;
bfd_reloc_code_real_type reloc;
int skip_optional;
@@ -1052,7 +1160,6 @@
fc = 0;
for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
{
- expressionS ex;
char *hold;
operand = s390_operands + *opindex_ptr;
@@ -1167,6 +1274,18 @@
&& (operand->bits == 32))
reloc = BFD_RELOC_390_GOTPLTENT;
}
+ else if (suffix == ELF_SUFFIX_TLS_GOTIE)
+ {
+ if ((operand->flags & S390_OPERAND_DISP)
+ && (operand->bits == 12))
+ reloc = BFD_RELOC_390_TLS_GOTIE12;
+ }
+ else if (suffix == ELF_SUFFIX_TLS_IE)
+ {
+ if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 32))
+ reloc = BFD_RELOC_390_TLS_IEENT;
+ }
if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED)
as_bad (_("invalid operand suffix"));
@@ -1262,6 +1381,20 @@
while (ISSPACE (*str))
++str;
+ /* Check for tls instruction marker. */
+ reloc = s390_tls_suffix (&str, &ex);
+ if (reloc != BFD_RELOC_UNUSED)
+ {
+ /* We need to generate a fixup of type 'reloc' for this
+ instruction. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = -1;
+ fixups[fc].reloc = reloc;
+ ++fc;
+ }
+
if (*str != '\0')
{
char *linefeed;
@@ -1286,6 +1419,15 @@
md_apply_fix3. */
for (i = 0; i < fc; i++)
{
+
+ if (fixups[i].opindex < 0)
+ {
+ /* Create tls instruction marker relocation. */
+ fix_new_exp (frag_now, f - frag_now->fr_literal, opcode->oplen,
+ &fixups[i].exp, 0, fixups[i].reloc);
+ continue;
+ }
+
operand = s390_operands + fixups[i].opindex;
if (fixups[i].reloc != BFD_RELOC_UNUSED)
@@ -1699,6 +1841,26 @@
|| fixP->fx_r_type == BFD_RELOC_390_GOTPLT32
|| fixP->fx_r_type == BFD_RELOC_390_GOTPLT64
|| fixP->fx_r_type == BFD_RELOC_390_GOTPLTENT
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LOAD
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GDCALL
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDCALL
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GD32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GD64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE12
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDM32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDM64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_IE32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_IE64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_IEENT
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LE32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LE64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDO32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDO64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_DTPMOD
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_DTPOFF
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_TPOFF
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
return 0;
@@ -1972,6 +2134,32 @@
case BFD_RELOC_VTABLE_ENTRY:
fixP->fx_done = 0;
return;
+
+ case BFD_RELOC_390_TLS_LOAD:
+ case BFD_RELOC_390_TLS_GDCALL:
+ case BFD_RELOC_390_TLS_LDCALL:
+ case BFD_RELOC_390_TLS_GD32:
+ case BFD_RELOC_390_TLS_GD64:
+ case BFD_RELOC_390_TLS_GOTIE12:
+ case BFD_RELOC_390_TLS_GOTIE32:
+ case BFD_RELOC_390_TLS_GOTIE64:
+ case BFD_RELOC_390_TLS_LDM32:
+ case BFD_RELOC_390_TLS_LDM64:
+ case BFD_RELOC_390_TLS_IE32:
+ case BFD_RELOC_390_TLS_IE64:
+ case BFD_RELOC_390_TLS_LE32:
+ case BFD_RELOC_390_TLS_LE64:
+ case BFD_RELOC_390_TLS_LDO32:
+ case BFD_RELOC_390_TLS_LDO64:
+ case BFD_RELOC_390_TLS_DTPMOD:
+ case BFD_RELOC_390_TLS_DTPOFF:
+ case BFD_RELOC_390_TLS_TPOFF:
+ /* Fully resolved at link time. */
+ break;
+ case BFD_RELOC_390_TLS_IEENT:
+ /* Fully resolved at link time. */
+ value += 2;
+ break;
default:
{
diff -urN src/include/elf/s390.h src-s390/include/elf/s390.h
--- src/include/elf/s390.h Mon Jan 20 12:38:30 2003
+++ src-s390/include/elf/s390.h Thu Jan 23 23:23:13 2003
@@ -73,6 +73,43 @@
RELOC_NUMBER (R_390_PLTOFF16, 34) /* 16 bit offset from GOT to PLT. */
RELOC_NUMBER (R_390_PLTOFF32, 35) /* 32 bit offset from GOT to PLT. */
RELOC_NUMBER (R_390_PLTOFF64, 36) /* 16 bit offset from GOT to PLT. */
+ RELOC_NUMBER (R_390_TLS_LOAD, 37) /* Tag for load insn in TLS code. */
+ RELOC_NUMBER (R_390_TLS_GDCALL, 38) /* Tag for function call in general
+ dynamic TLS code. */
+ RELOC_NUMBER (R_390_TLS_LDCALL, 39) /* Tag for function call in local
+ dynamic TLS code. */
+ RELOC_NUMBER (R_390_TLS_GD32, 40) /* Direct 32 bit for general dynamic
+ thread local data. */
+ RELOC_NUMBER (R_390_TLS_GD64, 41) /* Direct 64 bit for general dynamic
+ thread local data. */
+ RELOC_NUMBER (R_390_TLS_GOTIE12, 42)/* 12 bit GOT offset for static TLS
+ block offset. */
+ RELOC_NUMBER (R_390_TLS_GOTIE32, 43)/* 32 bit GOT offset for static TLS
+ block offset. */
+ RELOC_NUMBER (R_390_TLS_GOTIE64, 44)/* 64 bit GOT offset for static TLS
+ block offset. */
+ RELOC_NUMBER (R_390_TLS_LDM32, 45) /* Direct 32 bit for local dynamic
+ thread local data in LD code. */
+ RELOC_NUMBER (R_390_TLS_LDM64, 46) /* Direct 64 bit for local dynamic
+ thread local data in LD code. */
+ RELOC_NUMBER (R_390_TLS_IE32, 47) /* 32 bit address of GOT entry for
+ negated static TLS block offset. */
+ RELOC_NUMBER (R_390_TLS_IE64, 48) /* 64 bit address of GOT entry for
+ negated static TLS block offset. */
+ RELOC_NUMBER (R_390_TLS_IEENT, 49) /* 32 bit rel. offset to GOT entry for
+ negated static TLS block offset. */
+ RELOC_NUMBER (R_390_TLS_LE32, 50) /* 32 bit negated offset relative to
+ static TLS block. */
+ RELOC_NUMBER (R_390_TLS_LE64, 51) /* 64 bit negated offset relative to
+ static TLS block. */
+ RELOC_NUMBER (R_390_TLS_LDO32, 52) /* 32 bit offset relative to TLS
+ block. */
+ RELOC_NUMBER (R_390_TLS_LDO64, 53) /* 64 bit offset relative to TLS
+ block. */
+ RELOC_NUMBER (R_390_TLS_DTPMOD, 54) /* ID of module containing symbol. */
+ RELOC_NUMBER (R_390_TLS_DTPOFF, 55) /* Offset in TLS block. */
+ RELOC_NUMBER (R_390_TLS_TPOFF, 56) /* Negate offset in static TLS
+ block. */
/* These are GNU extensions to enable C++ vtable garbage collection. */
RELOC_NUMBER (R_390_GNU_VTINHERIT, 250)
RELOC_NUMBER (R_390_GNU_VTENTRY, 251)
diff -urN src/ld/testsuite/ld-s390/s390.exp src-s390/ld/testsuite/ld-s390/s390.exp
--- src/ld/testsuite/ld-s390/s390.exp Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/s390.exp Thu Jan 23 23:23:13 2003
@@ -0,0 +1,72 @@
+# Expect script for ld-s390 tests
+# Copyright (C) 2003 Free Software Foundation
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+# Test s390 linking; all types of relocs. This tests the assembler and
+# tools like objdump as well as the linker.
+
+if { !([istarget "s390-*-*"] || [istarget "s390x-*-*"]) } {
+ return
+}
+
+# List contains test-items with 3 items followed by 2 lists:
+# 0:name 1:ld options 2:assembler options
+# 3:filenames of assembler files 4: action and options. 5: name of output file
+
+# Actions:
+# objdump: Apply objdump options on result. Compare with regex (last arg).
+# nm: Apply nm options on result. Compare with regex (last arg).
+# readelf: Apply readelf options on result. Compare with regex (last arg).
+
+set s390tests {
+ {"TLS -fpic -shared transitions" "-shared -melf_s390"
+ "-m31" {tlspic1.s tlspic2.s}
+ {{readelf -Ssrl tlspic.rd} {objdump -dzrj.text tlspic.dd}
+ {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
+ "libtlspic.so"}
+ {"Helper shared library" "-shared -melf_s390"
+ "-m31" {tlslib.s} {} "libtlslib.so"}
+ {"TLS -fpic and -fno-pic exec transitions"
+ "-melf_s390 tmpdir/libtlslib.so" "-m31" {tlsbinpic.s tlsbin.s}
+ {{readelf -Ssrl tlsbin.rd} {objdump -dzrj.text tlsbin.dd}
+ {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
+ "tlsbin"}
+}
+
+set s390xtests {
+ {"TLS -fpic -shared transitions" "-shared -melf64_s390"
+ "-m64 -Aesame" {tlspic1_64.s tlspic2_64.s}
+ {{readelf -WSsrl tlspic_64.rd} {objdump -dzrj.text tlspic_64.dd}
+ {objdump -sj.got tlspic_64.sd} {objdump -sj.tdata tlspic_64.td}}
+ "libtlspic_64.so"}
+ {"Helper shared library" "-shared -melf64_s390"
+ "-m64 -Aesame" {tlslib_64.s} {} "libtlslib_64.so"}
+ {"TLS -fpic and -fno-pic exec transitions"
+ "-melf64_s390 tmpdir/libtlslib_64.so" "-m64 -Aesame"
+ {tlsbinpic_64.s tlsbin_64.s}
+ {{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd}
+ {objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}}
+ "tlsbin_64"}
+}
+
+if [istarget "s390-*-*"] {
+ run_ld_link_tests $s390tests
+}
+
+if [istarget "s390x-*-*"] {
+ run_ld_link_tests $s390xtests
+}
diff -urN src/ld/testsuite/ld-s390/tlsbin.dd src-s390/ld/testsuite/ld-s390/tlsbin.dd
--- src/ld/testsuite/ld-s390/tlsbin.dd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin.dd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,185 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -m31
+#ld: -shared -melf_s390
+#objdump: -dzrj.text
+#target: s390-*-*
+
+# PT_TLS layout is:
+# Offset from Offset from Name
+# TCB base TCB end
+# 0x00 -0xa0 sg1..sg2
+# 0x20 -0x80 sl1..sl2
+# 0x40 -0x60 sh1..sh2
+# 0x60 -0x40 bg1..bg2
+# 0x80 -0x20 bl1..bl2
+
+.*: +file format elf32-s390
+
+Disassembly of section .text:
+
+0+4002e4 <fn2>:
+# function prolog
+ +4002e4: 90 6e f0 18 stm %r6,%r14,24\(%r15\)
+ +4002e8: a7 d5 00 24 bras %r13,400330 <fn2\+0x4c>
+# _GLOBAL_OFFSET_TABLE_
+ +4002ec: 00 00 12 90 .long 0x00001290
+# __tls_get_addr@plt-.LT1
+ +4002f0: ff ff ff d8 .long 0xffffffd8
+# sG1@tlsgd
+ +4002f4: 00 00 00 28 .long 0x00000028
+# sG2@tlsgd
+ +4002f8: 00 00 00 20 .long 0x00000020
+# sg1@tlsgd
+ +4002fc: ff ff ff 60 .long 0xffffff60
+# sl1@tlsgd
+ +400300: ff ff ff 80 .long 0xffffff80
+# sh1@tlsgd
+ +400304: ff ff ff a0 .long 0xffffffa0
+# sl1@tlsldm
+ +400308: 00 00 00 00 .long 0x00000000
+# sl1@dtpoff
+ +40030c: ff ff ff 80 .long 0xffffff80
+# sl2@dtpoff
+ +400310: ff ff ff 84 .long 0xffffff84
+# sh1@tlsldm
+ +400314: 00 00 00 00 .long 0x00000000
+# sh1@dtpoff
+ +400318: ff ff ff a0 .long 0xffffffa0
+# sh2@dtpoff
+ +40031c: ff ff ff a4 .long 0xffffffa4
+# sG2@gotntpoff
+ +400320: 00 00 00 20 .long 0x00000020
+# sg1@gotntpoff
+ +400324: ff ff ff 60 .long 0xffffff60
+# sl1@gotntpoff
+ +400328: ff ff ff 80 .long 0xffffff80
+# sh1@gotntpoff
+ +40032c: ff ff ff a0 .long 0xffffffa0
+# function prolog
+ +400330: 18 ef lr %r14,%r15
+ +400332: 58 c0 d0 00 l %r12,0\(%r13\)
+ +400336: a7 fa ff a0 ahi %r15,-96
+ +40033a: 41 cc d0 00 la %r12,0\(%r12,%r13\)
+ +40033e: 50 e0 e0 00 st %r14,0\(%r14\)
+# Extract TCB and load branch offset
+ +400342: b2 4f 00 90 ear %r9,%a0
+ +400346: 58 70 d0 04 l %r7,4\(%r13\)
+# GD -> IE because variable is not defined in executable
+ +40034a: 58 20 d0 08 l %r2,8\(%r13\)
+ +40034e: 58 22 c0 00 l %r2,0\(%r2,%r12\)
+ +400352: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE because variable is not defined in executable where
+# the variable is referenced through IE too
+ +400356: 58 20 d0 0c l %r2,12\(%r13\)
+ +40035a: 58 22 c0 00 l %r2,0\(%r2,%r12\)
+ +40035e: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> LE with global variable defined in executable
+ +400362: 58 20 d0 10 l %r2,16\(%r13\)
+ +400366: 47 00 00 00 bc 0,0
+ +40036a: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> LE with local variable defined in executable
+ +40036e: 58 20 d0 14 l %r2,20\(%r13\)
+ +400372: 47 00 00 00 bc 0,0
+ +400376: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> LE with hidden variable defined in executable
+ +40037a: 58 20 d0 18 l %r2,24\(%r13\)
+ +40037e: 47 00 00 00 bc 0,0
+ +400382: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# LD -> LE
+ +400386: 58 20 d0 1c l %r2,28\(%r13\)
+ +40038a: 47 00 00 00 bc 0,0
+ +40038e: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +400392: 58 40 d0 20 l %r4,32\(%r13\)
+ +400396: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +40039a: 58 40 d0 24 l %r4,36\(%r13\)
+ +40039e: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# LD -> LE against hidden variables
+ +4003a2: 58 20 d0 28 l %r2,40\(%r13\)
+ +4003a6: 47 00 00 00 bc 0,0
+ +4003aa: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +4003ae: 58 40 d0 2c l %r4,44\(%r13\)
+ +4003b2: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +4003b6: 58 40 d0 30 l %r4,48\(%r13\)
+ +4003ba: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# IE against global var
+ +4003be: 58 30 d0 34 l %r3,52\(%r13\)
+ +4003c2: 58 33 c0 00 l %r3,0\(%r3,%r12\)
+ +4003c6: 58 33 90 00 l %r3,0\(%r3,%r9\)
+# IE -> LE against global var defined in exec
+ +4003ca: 58 30 d0 38 l %r3,56\(%r13\)
+ +4003ce: 18 43 lr %r4,%r3
+ +4003d0: 07 00 bcr 0,%r0
+ +4003d2: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against local var
+ +4003d6: 58 30 d0 3c l %r3,60\(%r13\)
+ +4003da: 18 43 lr %r4,%r3
+ +4003dc: 07 00 bcr 0,%r0
+ +4003de: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against hidden var
+ +4003e2: 58 30 d0 40 l %r3,64\(%r13\)
+ +4003e6: 18 43 lr %r4,%r3
+ +4003e8: 07 00 bcr 0,%r0
+ +4003ea: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against global var with small got access (no optimization)
+ +4003ee: 58 30 c0 14 l %r3,20\(%r12\)
+ +4003f2: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against global var defined in exec with small got access
+# (no optimization)
+ +4003f6: 58 30 c0 18 l %r3,24\(%r12\)
+ +4003fa: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against local var with small got access (no optimization)
+ +4003fe: 58 30 c0 10 l %r3,16\(%r12\)
+ +400402: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against hidden var with small got access (no optimization)
+ +400406: 58 30 c0 1c l %r3,28\(%r12\)
+ +40040a: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# function epilog
+ +40040e: 98 6e f0 78 lm %r6,%r14,120\(%r15\)
+ +400412: 07 fe br %r14
+
+0+400414 <_start>:
+# function prolog
+ +400414: 90 6e f0 18 stm %r6,%r14,24\(%r15\)
+ +400418: a7 d5 00 0c bras %r13,400430 <_start\+0x1c>
+# sG6@indntpoff
+ +40041c: 00 40 15 a0 .long 0x004015a0
+# bg6@indntpoff
+ +400420: ff ff ff d4 .long 0xffffffd4
+# bl6@indntpoff
+ +400424: ff ff ff f4 .long 0xfffffff4
+# sh6@indntpoff
+ +400428: ff ff ff b4 .long 0xffffffb4
+# sg3@indntpoff
+ +40042c: ff ff ff 68 .long 0xffffff68
+# function prolog
+ +400430: 18 ef lr %r14,%r15
+ +400432: a7 fa ff a0 ahi %r15,-96
+ +400436: 50 e0 e0 00 st %r14,0\(%r14\)
+# Extract TCB
+ +40043a: b2 4f 00 90 ear %r9,%a0
+# IE against global var
+ +40043e: 58 30 d0 00 l %r3,0\(%r13\)
+ +400442: 58 33 c0 00 l %r3,0\(%r3,%r12\)
+ +400446: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE -> LE against global var defined in exec
+ +40044a: 58 30 d0 04 l %r3,4\(%r13\)
+ +40044e: 18 43 lr %r4,%r3
+ +400450: 07 00 bcr 0,%r0
+ +400452: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against local var
+ +400456: 58 30 d0 08 l %r3,8\(%r13\)
+ +40045a: 18 43 lr %r4,%r3
+ +40045c: 07 00 bcr 0,%r0
+ +40045e: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against hidden but not local var
+ +400462: 58 30 d0 0c l %r3,12\(%r13\)
+ +400466: 18 43 lr %r4,%r3
+ +400468: 07 00 bcr 0,%r0
+ +40046a: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# LE, global var defined in exec
+ +40046e: 58 40 d0 10 l %r4,16\(%r13\)
+ +400472: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# function epilog
+ +400476: 98 6e f0 78 lm %r6,%r14,120\(%r15\)
+ +40047a: 07 fe br %r14
diff -urN src/ld/testsuite/ld-s390/tlsbin.rd src-s390/ld/testsuite/ld-s390/tlsbin.rd
--- src/ld/testsuite/ld-s390/tlsbin.rd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin.rd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,156 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -m31
+#ld: -shared -melf_s390
+#readelf: -Ssrl
+#target: s390-*-*
+
+There are 19 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ \[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
+ \[ 1\] .interp +.*
+ \[ 2\] .hash +.*
+ \[ 3\] .dynsym +.*
+ \[ 4\] .dynstr +.*
+ \[ 5\] .rela.dyn +.*
+ \[ 6\] .rela.plt +.*
+ \[ 7\] .plt +.*
+ \[ 8\] .text +PROGBITS +0+4002e4 0+2e4 0+198 00 +AX +0 +0 +4
+ \[ 9\] .data +.*
+ \[10\] .tdata +PROGBITS +0+40147c 0+47c 0+60 00 WAT +0 +0 +1
+ \[11\] .tbss +NOBITS +0+4014dc 0+4dc 0+40 00 WAT +0 +0 +1
+ \[12\] .dynamic +DYNAMIC +0+4014dc 0+4dc 0+a0 08 +WA +4 +0 +4
+ \[13\] .got +PROGBITS +0+40157c 0+57c 0+2c 04 +WA +0 +0 +4
+ \[14\] .sbss +.*
+ \[15\] .bss +.*
+ \[16\] .shstrtab +.*
+ \[17\] .symtab +.*
+ \[18\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x400414
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ PHDR +0x0+34 0x0+400034 0x0+400034 0x0+c0 0x0+c0 R E 0x4
+ INTERP +0x0+f4 0x0+4000f4 0x0+4000f4 0x0+11 0x0+11 R +0x1
+.*Requesting program interpreter.*
+ LOAD +0x0+ 0x0+400000 0x0+400000 0x0+47c 0x0+47c R E 0x1000
+ LOAD +0x0+47c 0x0+40147c 0x0+40147c 0x0+12c 0x0+12c RW 0x1000
+ DYNAMIC +0x0+4dc 0x0+4014dc 0x0+4014dc 0x0+a0 0x0+a0 RW 0x4
+ TLS +0x0+47c 0x0+40147c 0x0+40147c 0x0+60 0x0+a0 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 *
+ 01 +.interp *
+ 02 +.interp .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+ 03 +.tdata .tbss .dynamic .got *
+ 04 +.tbss .dynamic *
+ 05 +.tdata .tbss *
+
+Relocation section '.rela.dyn' at offset 0x268 contains 4 entries:
+ Offset +Info +Type +Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0+138 R_390_TLS_TPOFF +0+ +sG3 \+ 0
+[0-9a-f]+ 0+338 R_390_TLS_TPOFF +0+ +sG2 \+ 0
+[0-9a-f]+ 0+638 R_390_TLS_TPOFF +0+ +sG6 \+ 0
+[0-9a-f]+ 0+738 R_390_TLS_TPOFF +0+ +sG1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset +Info +Type +Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0+40b R_390_JMP_SLOT +0+40+2c4 +__tls_get_offset \+ 0
+
+Symbol table '.dynsym' contains 11 entries:
+ +Num: +Value Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND
+ +1: 0+ +0 TLS +GLOBAL DEFAULT UND sG3
+ +2: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +3: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +4: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_offset
+ +5: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +6: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +7: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +8: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +9: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +10: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 71 entries:
+ +Num: +Value Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND
+ +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1
+ +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2
+ +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3
+ +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4
+ +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5
+ +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6
+ +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7
+ +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8
+ +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9
+ +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10
+ +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11
+ +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12
+ +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13
+ +14: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14
+ +15: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +15
+ +16: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +16
+ +17: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +17
+ +18: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +18
+ +19: 0+20 +0 TLS +LOCAL DEFAULT +10 sl1
+ +20: 0+24 +0 TLS +LOCAL DEFAULT +10 sl2
+ +21: 0+28 +0 TLS +LOCAL DEFAULT +10 sl3
+ +22: 0+2c +0 TLS +LOCAL DEFAULT +10 sl4
+ +23: 0+30 +0 TLS +LOCAL DEFAULT +10 sl5
+ +24: 0+34 +0 TLS +LOCAL DEFAULT +10 sl6
+ +25: 0+38 +0 TLS +LOCAL DEFAULT +10 sl7
+ +26: 0+3c +0 TLS +LOCAL DEFAULT +10 sl8
+ +27: 0+80 +0 TLS +LOCAL DEFAULT +11 bl1
+ +28: 0+84 +0 TLS +LOCAL DEFAULT +11 bl2
+ +29: 0+88 +0 TLS +LOCAL DEFAULT +11 bl3
+ +30: 0+8c +0 TLS +LOCAL DEFAULT +11 bl4
+ +31: 0+90 +0 TLS +LOCAL DEFAULT +11 bl5
+ +32: 0+94 +0 TLS +LOCAL DEFAULT +11 bl6
+ +33: 0+98 +0 TLS +LOCAL DEFAULT +11 bl7
+ +34: 0+9c +0 TLS +LOCAL DEFAULT +11 bl8
+ +35: 0+ +0 TLS +GLOBAL DEFAULT UND sG3
+ +36: 0+1c +0 TLS +GLOBAL DEFAULT +10 sg8
+ +37: 0+7c +0 TLS +GLOBAL DEFAULT +11 bg8
+ +38: 0+74 +0 TLS +GLOBAL DEFAULT +11 bg6
+ +39: 0+68 +0 TLS +GLOBAL DEFAULT +11 bg3
+ +40: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +41: 0+8 +0 TLS +GLOBAL DEFAULT +10 sg3
+ +42: 0+48 +0 TLS +GLOBAL HIDDEN +10 sh3
+ +43: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +44: 0+c +0 TLS +GLOBAL DEFAULT +10 sg4
+ +45: 0+10 +0 TLS +GLOBAL DEFAULT +10 sg5
+ +46: 0+70 +0 TLS +GLOBAL DEFAULT +11 bg5
+ +47: 0+58 +0 TLS +GLOBAL HIDDEN +10 sh7
+ +48: 0+5c +0 TLS +GLOBAL HIDDEN +10 sh8
+ +49: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_offset
+ +50: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1
+ +51: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +8 _start
+ +52: 0+4c +0 TLS +GLOBAL HIDDEN +10 sh4
+ +53: 0+78 +0 TLS +GLOBAL DEFAULT +11 bg7
+ +54: 0+50 +0 TLS +GLOBAL HIDDEN +10 sh5
+ +55: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +56: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +57: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +8 fn2
+ +58: 0+4 +0 TLS +GLOBAL DEFAULT +10 sg2
+ +59: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +60: 0+40 +0 TLS +GLOBAL HIDDEN +10 sh1
+ +61: 0+14 +0 TLS +GLOBAL DEFAULT +10 sg6
+ +62: 0+18 +0 TLS +GLOBAL DEFAULT +10 sg7
+ +63: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +64: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +65: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+ +66: 0+44 +0 TLS +GLOBAL HIDDEN +10 sh2
+ +67: 0+54 +0 TLS +GLOBAL HIDDEN +10 sh6
+ +68: 0+64 +0 TLS +GLOBAL DEFAULT +11 bg2
+ +69: 0+60 +0 TLS +GLOBAL DEFAULT +11 bg1
+ +70: 0+6c +0 TLS +GLOBAL DEFAULT +11 bg4
diff -urN src/ld/testsuite/ld-s390/tlsbin.s src-s390/ld/testsuite/ld-s390/tlsbin.s
--- src/ld/testsuite/ld-s390/tlsbin.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,73 @@
+ .section ".tbss", "awT", @nobits
+ .globl bg1, bg2, bg3, bg4, bg5, bg6, bg7, bg8
+bg1: .space 4
+bg2: .space 4
+bg3: .space 4
+bg4: .space 4
+bg5: .space 4
+bg6: .space 4
+bg7: .space 4
+bg8: .space 4
+bl1: .space 4
+bl2: .space 4
+bl3: .space 4
+bl4: .space 4
+bl5: .space 4
+bl6: .space 4
+bl7: .space 4
+bl8: .space 4
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Function prolog */
+ stm %r6,%r14,24(%r15)
+ bras %r13,.LTN1
+ /* Literal pool */
+.LT1:
+.LC0:
+ .long sG6@indntpoff
+.LC1:
+ .long bg6@indntpoff
+.LC2:
+ .long bl6@indntpoff
+.LC3:
+ .long sh6@indntpoff
+.LC4:
+ .long sg3@indntpoff
+.LTN1:
+ /* Function prolog */
+ lr %r14,%r15
+ ahi %r15,-96
+ st %r14,0(%r14)
+
+ /* Extract TCB */
+ ear %r9,%a0
+
+ /* IE against global var */
+ l %r3,.LC0-.LT1(%r13)
+ l %r3,0(%r3,%r12):tls_load:sG6
+ la %r3,0(%r3,%r9)
+
+ /* IE -> LE against global var defined in exec */
+ l %r3,.LC1-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:bg6
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against local var */
+ l %r3,.LC2-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:bl6
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against hidden but not local var */
+ l %r3,.LC3-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:sh6
+ la %r5,0(%r4,%r9)
+
+ /* LE, global var defined in exec */
+ l %r4,.LC4-.LT1(%r13)
+ la %r5,0(%r4,%r9)
+
+ /* Function epilog */
+ lm %r6,%r14,120(%r15)
+ br %r14
diff -urN src/ld/testsuite/ld-s390/tlsbin.sd src-s390/ld/testsuite/ld-s390/tlsbin.sd
--- src/ld/testsuite/ld-s390/tlsbin.sd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin.sd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,13 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -m31
+#ld: -shared -melf_s390
+#objdump: -sj.got
+#target: s390-*-*
+
+.*: file format elf32-s390
+
+Contents of section .got:
+ 40157c [0-9a-f]+ 00000000 00000000 [0-9a-f]+ .@...........@..
+ 40158c ffffff88 00000000 ffffff68 ffffffa8 ...........h....
+ 40159c 00000000 00000000 00000000 ............
diff -urN src/ld/testsuite/ld-s390/tlsbin.td src-s390/ld/testsuite/ld-s390/tlsbin.td
--- src/ld/testsuite/ld-s390/tlsbin.td Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin.td Thu Jan 23 23:23:13 2003
@@ -0,0 +1,16 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -m31
+#ld: -shared -melf_s390
+#objdump: -sj.tdata
+#target: s390-*-*
+
+.*: file format elf32-s390
+
+Contents of section .tdata:
+ 40147c 00000011 00000012 00000013 00000014 .*
+ 40148c 00000015 00000016 00000017 00000018 .*
+ 40149c 00000041 00000042 00000043 00000044 .*
+ 4014ac 00000045 00000046 00000047 00000048 .*
+ 4014bc 00000101 00000102 00000103 00000104 .*
+ 4014cc 00000105 00000106 00000107 00000108 .*
diff -urN src/ld/testsuite/ld-s390/tlsbin_64.dd src-s390/ld/testsuite/ld-s390/tlsbin_64.dd
--- src/ld/testsuite/ld-s390/tlsbin_64.dd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin_64.dd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,213 @@
+#source: tlsbinpic_64.s
+#source: tlsbin_64.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#objdump: -dzrj.text
+#target: s390x-*-*
+
+# PT_TLS layout is:
+# Offset from Offset from Name
+# TCB base TCB end
+# 0x00 -0xa0 sg1..sg2
+# 0x20 -0x80 sl1..sl2
+# 0x40 -0x60 sh1..sh2
+# 0x60 -0x40 bg1..bg2
+# 0x80 -0x20 bl1..bl2
+
+.*: +file format elf64-s390
+
+Disassembly of section .text:
+
+0+80000458 <fn2>:
+# function prolog
+ +80000458: eb 6e f0 30 00 24 stmg %r6,%r14,48\(%r15\)
+ +8000045e: a7 d5 00 3e bras %r13,800004da <fn2\+0x82>
+# sG1@tlsgd
+ +80000462: 00 00 00 00 .long 0x00000000
+ +80000466: 00 00 00 60 .long 0x00000060
+# sG2@tlsgd
+ +8000046a: 00 00 00 00 .long 0x00000000
+ +8000046e: 00 00 00 48 .long 0x00000048
+# sg1@tlsgd
+ +80000472: ff ff ff ff .long 0xffffffff
+ +80000476: ff ff ff 60 .long 0xffffff60
+# sl1@tlsgd
+ +8000047a: ff ff ff ff .long 0xffffffff
+ +8000047e: ff ff ff 80 .long 0xffffff80
+# sh1@tlsgd
+ +80000482: ff ff ff ff .long 0xffffffff
+ +80000486: ff ff ff a0 .long 0xffffffa0
+# sl1@tlsldm
+ +8000048a: 00 00 00 00 .long 0x00000000
+ +8000048e: 00 00 00 00 .long 0x00000000
+# sl1@dtpoff
+ +80000492: ff ff ff ff .long 0xffffffff
+ +80000496: ff ff ff 80 .long 0xffffff80
+# sl2@dtpoff
+ +8000049a: ff ff ff ff .long 0xffffffff
+ +8000049e: ff ff ff 84 .long 0xffffff84
+# sh1@tlsldm
+ +800004a2: 00 00 00 00 .long 0x00000000
+ +800004a6: 00 00 00 00 .long 0x00000000
+# sh1@dtpoff
+ +800004aa: ff ff ff ff .long 0xffffffff
+ +800004ae: ff ff ff a0 .long 0xffffffa0
+# sh2@dtpoff
+ +800004b2: ff ff ff ff .long 0xffffffff
+ +800004b6: ff ff ff a4 .long 0xffffffa4
+# sG2@gotntpoff
+ +800004ba: 00 00 00 00 .long 0x00000000
+ +800004be: 00 00 00 48 .long 0x00000048
+# sg1@gotntpoff
+ +800004c2: ff ff ff ff .long 0xffffffff
+ +800004c6: ff ff ff 60 .long 0xffffff60
+# sl1@gotntpoff
+ +800004ca: ff ff ff ff .long 0xffffffff
+ +800004ce: ff ff ff 80 .long 0xffffff80
+# sh1@gotntpoff
+ +800004d2: ff ff ff ff .long 0xffffffff
+ +800004d6: ff ff ff a0 .long 0xffffffa0
+# function prolog
+ +800004da: b9 04 00 ef lgr %r14,%r15
+ +800004de: a7 fb ff 60 aghi %r15,-160
+ +800004e2: c0 c0 00 00 09 d3 larl %r12,80001888 <_GLOBAL_OFFSET_TABLE_>
+ +800004e8: e3 e0 e0 00 00 24 stg %r14,0\(%r14\)
+# extract TCB
+ +800004ee: b2 4f 00 90 ear %r9,%a0
+ +800004f2: eb 94 00 20 00 0d sllg %r9,%r4,32
+ +800004f8: b2 4f 00 91 ear %r9,%a1
+# GD -> IE because variable is not defined in executable
+ +800004fc: e3 c0 d0 00 00 04 lg %r12,0\(%r13\)
+ +80000502: e3 22 c0 00 00 04 lg %r2,0\(%r2,%r12\)
+ +80000508: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE because variable is not defined in executable where
+# the variable is referenced through IE too
+ +8000050c: e3 20 d0 08 00 04 lg %r2,8\(%r13\)
+ +80000512: e3 22 c0 00 00 04 lg %r2,0\(%r2,%r12\)
+ +80000518: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> LE with global variable defined in executable
+ +8000051c: e3 20 d0 10 00 04 lg %r2,16\(%r13\)
+ +80000522: c0 04 00 00 00 00 brcl 0,80000522 <fn2\+0xca>
+ +80000528: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> LE with local variable defined in executable
+ +8000052c: e3 20 d0 18 00 04 lg %r2,24\(%r13\)
+ +80000532: c0 04 00 00 00 00 brcl 0,80000532 <fn2\+0xda>
+ +80000538: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> LE with hidden variable defined in executable
+ +8000053c: e3 20 d0 20 00 04 lg %r2,32\(%r13\)
+ +80000542: c0 04 00 00 00 00 brcl 0,80000542 <fn2\+0xea>
+ +80000548: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# LD -> LE
+ +8000054c: e3 20 d0 28 00 04 lg %r2,40\(%r13\)
+ +80000552: c0 04 00 00 00 00 brcl 0,80000552 <fn2\+0xfa>
+ +80000558: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +8000055c: e3 40 d0 30 00 04 lg %r4,48\(%r13\)
+ +80000562: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +80000566: e3 40 d0 38 00 04 lg %r4,56\(%r13\)
+ +8000056c: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +80000570: e3 20 d0 40 00 04 lg %r2,64\(%r13\)
+ +80000576: c0 04 00 00 00 00 brcl 0,80000576 <fn2\+0x11e>
+ +8000057c: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +80000580: e3 40 d0 48 00 04 lg %r4,72\(%r13\)
+ +80000586: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +8000058a: e3 40 d0 50 00 04 lg %r4,80\(%r13\)
+ +80000590: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# IE against global var
+ +80000594: e3 30 d0 58 00 04 lg %r3,88\(%r13\)
+ +8000059a: e3 33 c0 00 00 04 lg %r3,0\(%r3,%r12\)
+ +800005a0: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE -> LE against global var defined in exec
+ +800005a4: e3 30 d0 60 00 04 lg %r3,96\(%r13\)
+ +800005aa: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +800005b0: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against local var
+ +800005b4: e3 30 d0 68 00 04 lg %r3,104\(%r13\)
+ +800005ba: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +800005c0: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against hidden var
+ +800005c4: e3 30 d0 70 00 04 lg %r3,112\(%r13\)
+ +800005ca: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +800005d0: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against global var with larl got access
+ +800005d4: c0 30 00 00 09 6e larl %r3,800018b0 <\_GLOBAL\_OFFSET\_TABLE\_\+0x28>
+ +800005da: e3 33 c0 00 00 04 lg %r3,0\(%r3,%r12\)
+ +800005e0: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against global var defined in exec with larl got access
+ +800005e4: c0 30 00 00 09 6e larl %r3,800018c0 <\_GLOBAL\_OFFSET\_TABLE\_\+0x38>
+ +800005ea: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +800005f0: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against local var with larl got access
+ +800005f4: c0 30 00 00 09 5a larl %r3,800018a8 <\_GLOBAL\_OFFSET\_TABLE\_\+0x20>
+ +800005fa: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +80000600: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against hidden var with larl got access
+ +80000604: c0 30 00 00 09 62 larl %r3,800018c8 <\_GLOBAL\_OFFSET\_TABLE\_\+0x40>
+ +8000060a: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +80000610: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against global var with small got access (no optimization)
+ +80000614: e3 30 c0 28 00 04 lg %r3,40\(%r12\)
+ +8000061a: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against global var defined in exec with small got access
+# (no optimization)
+ +8000061e: e3 30 c0 38 00 04 lg %r3,56\(%r12\)
+ +80000624: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against local var with small got access (no optimization)
+ +80000628: e3 30 c0 20 00 04 lg %r3,32\(%r12\)
+ +8000062e: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against hidden var with small got access (no optimization)
+ +80000632: e3 30 c0 40 00 04 lg %r3,64\(%r12\)
+ +80000638: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# function epilog
+ +8000063c: eb 6e f0 d0 00 04 lmg %r6,%r14,208\(%r15\)
+ +80000642: 07 fe br %r14
+
+0+80000644 <_start>:
+# function prolog
+ +80000644: 90 6e f0 18 stm %r6,%r14,24\(%r15\)
+ +80000648: a7 d5 00 16 bras %r13,80000674 <_start\+0x30>
+# sG6@indntpoff
+ +8000064c: 00 00 00 00 .long 0x00000000
+ +80000650: 80 00 18 e0 ssm 2272\(%r1\)
+# bg6@indntpoff
+ +80000654: ff ff ff ff .long 0xffffffff
+ +80000658: ff ff ff d4 .long 0xffffffd4
+# bl6@indntpoff
+ +8000065c: ff ff ff ff .long 0xffffffff
+ +80000660: ff ff ff f4 .long 0xfffffff4
+# sh6@indntpoff
+ +80000664: ff ff ff ff .long 0xffffffff
+ +80000668: ff ff ff b4 .long 0xffffffb4
+# sg3@indntpoff
+ +8000066c: ff ff ff ff .long 0xffffffff
+ +80000670: ff ff ff 68 .long 0xffffff68
+# function prolog
+ +80000674: b9 04 00 ef lgr %r14,%r15
+ +80000678: a7 fb ff 60 aghi %r15,-160
+ +8000067c: e3 e0 e0 00 00 24 stg %r14,0\(%r14\)
+# extract TCB
+ +80000682: b2 4f 00 90 ear %r9,%a0
+ +80000686: eb 94 00 20 00 0d sllg %r9,%r4,32
+ +8000068c: b2 4f 00 91 ear %r9,%a1
+# IE against global var
+ +80000690: e3 30 d0 00 00 04 lg %r3,0\(%r13\)
+ +80000696: e3 33 c0 00 00 04 lg %r3,0\(%r3,%r12\)
+ +8000069c: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE -> LE against global var defined in exec
+ +800006a0: e3 30 d0 08 00 04 lg %r3,8\(%r13\)
+ +800006a6: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +800006ac: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against local var
+ +800006b0: e3 30 d0 10 00 04 lg %r3,16\(%r13\)
+ +800006b6: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +800006bc: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE -> LE against hidden but not local var
+ +800006c0: e3 30 d0 18 00 04 lg %r3,24\(%r13\)
+ +800006c6: eb 43 00 00 00 0d sllg %r4,%r3,0
+ +800006cc: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# LE, global var defined in exec
+ +800006d0: e3 40 d0 20 00 04 lg %r4,32\(%r13\)
+ +800006d6: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# function epilog
+ +800006da: eb 6e f0 d0 00 04 lmg %r6,%r14,208\(%r15\)
+ +800006e0: 07 fe br %r14
+ +800006e2: 07 07 bcr 0,%r7
diff -urN src/ld/testsuite/ld-s390/tlsbin_64.rd src-s390/ld/testsuite/ld-s390/tlsbin_64.rd
--- src/ld/testsuite/ld-s390/tlsbin_64.rd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin_64.rd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,156 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#readelf: -Ssrl
+#target: s390x-*-*
+
+There are 19 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+ \[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
+ \[ 1\] .interp +.*
+ \[ 2\] .hash +.*
+ \[ 3\] .dynsym +.*
+ \[ 4\] .dynstr +.*
+ \[ 5\] .rela.dyn +.*
+ \[ 6\] .rela.plt +.*
+ \[ 7\] .plt +.*
+ \[ 8\] .text +PROGBITS +0+80000458 0+458 0+28c 00 +AX +0 +0 +4
+ \[ 9\] .data +.*
+ \[10\] .tdata +PROGBITS +0+800016e8 0+6e8 0+60 00 WAT +0 +0 +1
+ \[11\] .tbss +NOBITS +0+80001748 0+748 0+40 00 WAT +0 +0 +1
+ \[12\] .dynamic +DYNAMIC +0+80001748 0+748 0+140 10 +WA +4 +0 +8
+ \[13\] .got +PROGBITS +0+80001888 0+888 0+78 08 +WA +0 +0 +8
+ \[14\] .sbss +.*
+ \[15\] .bss +.*
+ \[16\] .shstrtab +.*
+ \[17\] .symtab +.*
+ \[18\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x80000644
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ PHDR +0x0+40 0x0+80000040 0x0+80000040 0x0+150 0x0+150 R E 0x8
+ INTERP +0x0+190 0x0+80000190 0x0+80000190 0x0+11 0x0+11 R +0x1
+.*Requesting program interpreter.*
+ LOAD +0x0+ 0x0+80000000 0x0+80000000 0x0+6e4 0x0+6e4 R E 0x1000
+ LOAD +0x0+6e8 0x0+800016e8 0x0+800016e8 0x0+218 0x0+218 RW 0x1000
+ DYNAMIC +0x0+748 0x0+80001748 0x0+80001748 0x0+140 0x0+140 RW 0x8
+ TLS +0x0+6e8 0x0+800016e8 0x0+800016e8 0x0+60 0x0+a0 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 *
+ 01 +.interp *
+ 02 +.interp .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+ 03 +.tdata .tbss .dynamic .got *
+ 04 +.tbss .dynamic *
+ 05 +.tdata .tbss *
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-z]+ contains 4 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-z]+ +0+10+38 R_390_TLS_TPOFF +0+ sG3 \+ 0
+[0-9a-z]+ +0+30+38 R_390_TLS_TPOFF +0+ sG2 \+ 0
+[0-9a-z]+ +0+60+38 R_390_TLS_TPOFF +0+ sG6 \+ 0
+[0-9a-z]+ +0+70+38 R_390_TLS_TPOFF +0+ sG1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x40+ contains 1 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-z]+ +0+40+b R_390_JMP_SLOT +0+80+438 __tls_get_offset \+ 0
+
+Symbol table '.dynsym' contains 11 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE +LOCAL +DEFAULT +UND
+ +1: 0+ +0 TLS +GLOBAL DEFAULT +UND sG3
+ +2: [0-9a-z]+ +0 OBJECT +GLOBAL DEFAULT +ABS _DYNAMIC
+ +3: 0+ +0 TLS +GLOBAL DEFAULT +UND sG2
+ +4: [0-9a-z]+ +0 FUNC +GLOBAL DEFAULT +UND __tls_get_offset
+ +5: [0-9a-z]+ +0 NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+ +6: 0+ +0 TLS +GLOBAL DEFAULT +UND sG6
+ +7: 0+ +0 TLS +GLOBAL DEFAULT +UND sG1
+ +8: [0-9a-z]+ +0 NOTYPE +GLOBAL DEFAULT +ABS _edata
+ +9: [0-9a-z]+ +0 OBJECT +GLOBAL DEFAULT +ABS _GLOBAL_OFFSET_TABLE_
+ +10: [0-9a-z]+ +0 NOTYPE +GLOBAL DEFAULT +ABS _end
+
+Symbol table '.symtab' contains 71 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE +LOCAL +DEFAULT +UND
+ +1: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +1
+ +2: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +2
+ +3: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +3
+ +4: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +4
+ +5: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +5
+ +6: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +6
+ +7: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +7
+ +8: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +8
+ +9: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +9
+ +10: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +10
+ +11: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +11
+ +12: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +12
+ +13: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +13
+ +14: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +14
+ +15: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +15
+ +16: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +16
+ +17: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +17
+ +18: [0-9a-z]+ +0 SECTION LOCAL +DEFAULT +18
+ +19: 0+20 +0 TLS +LOCAL +DEFAULT +10 sl1
+ +20: 0+24 +0 TLS +LOCAL +DEFAULT +10 sl2
+ +21: 0+28 +0 TLS +LOCAL +DEFAULT +10 sl3
+ +22: 0+2c +0 TLS +LOCAL +DEFAULT +10 sl4
+ +23: 0+30 +0 TLS +LOCAL +DEFAULT +10 sl5
+ +24: 0+34 +0 TLS +LOCAL +DEFAULT +10 sl6
+ +25: 0+38 +0 TLS +LOCAL +DEFAULT +10 sl7
+ +26: 0+3c +0 TLS +LOCAL +DEFAULT +10 sl8
+ +27: 0+80 +0 TLS +LOCAL +DEFAULT +11 bl1
+ +28: 0+84 +0 TLS +LOCAL +DEFAULT +11 bl2
+ +29: 0+88 +0 TLS +LOCAL +DEFAULT +11 bl3
+ +30: 0+8c +0 TLS +LOCAL +DEFAULT +11 bl4
+ +31: 0+90 +0 TLS +LOCAL +DEFAULT +11 bl5
+ +32: 0+94 +0 TLS +LOCAL +DEFAULT +11 bl6
+ +33: 0+98 +0 TLS +LOCAL +DEFAULT +11 bl7
+ +34: 0+9c +0 TLS +LOCAL +DEFAULT +11 bl8
+ +35: 0+ +0 TLS +GLOBAL DEFAULT +UND sG3
+ +36: 0+1c +0 TLS +GLOBAL DEFAULT +10 sg8
+ +37: 0+7c +0 TLS +GLOBAL DEFAULT +11 bg8
+ +38: 0+74 +0 TLS +GLOBAL DEFAULT +11 bg6
+ +39: 0+68 +0 TLS +GLOBAL DEFAULT +11 bg3
+ +40: [0-9a-z]+ +0 OBJECT +GLOBAL DEFAULT +ABS _DYNAMIC
+ +41: 0+8 +0 TLS +GLOBAL DEFAULT +10 sg3
+ +42: 0+48 +0 TLS +GLOBAL HIDDEN +10 sh3
+ +43: 0+ +0 TLS +GLOBAL DEFAULT +UND sG2
+ +44: 0+c +0 TLS +GLOBAL DEFAULT +10 sg4
+ +45: 0+10 +0 TLS +GLOBAL DEFAULT +10 sg5
+ +46: 0+70 +0 TLS +GLOBAL DEFAULT +11 bg5
+ +47: 0+58 +0 TLS +GLOBAL HIDDEN +10 sh7
+ +48: 0+5c +0 TLS +GLOBAL HIDDEN +10 sh8
+ +49: [0-9a-z]+ +0 FUNC +GLOBAL DEFAULT +UND __tls_get_offset
+ +50: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1
+ +51: [0-9a-z]+ +0 FUNC +GLOBAL DEFAULT +8 _start
+ +52: 0+4c +0 TLS +GLOBAL HIDDEN +10 sh4
+ +53: 0+78 +0 TLS +GLOBAL DEFAULT +11 bg7
+ +54: 0+50 +0 TLS +GLOBAL HIDDEN +10 sh5
+ +55: [0-9a-z]+ +0 NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+ +56: 0+ +0 TLS +GLOBAL DEFAULT +UND sG6
+ +57: [0-9a-z]+ +0 FUNC +GLOBAL DEFAULT +8 fn2
+ +58: 0+4 +0 TLS +GLOBAL DEFAULT +10 sg2
+ +59: 0+ +0 TLS +GLOBAL DEFAULT +UND sG1
+ +60: 0+40 +0 TLS +GLOBAL HIDDEN +10 sh1
+ +61: 0+14 +0 TLS +GLOBAL DEFAULT +10 sg6
+ +62: 0+18 +0 TLS +GLOBAL DEFAULT +10 sg7
+ +63: [0-9a-z]+ +0 NOTYPE +GLOBAL DEFAULT +ABS _edata
+ +64: [0-9a-z]+ +0 OBJECT +GLOBAL DEFAULT +ABS _GLOBAL_OFFSET_TABLE_
+ +65: 0+80+190+ +0 NOTYPE +GLOBAL DEFAULT +ABS _end
+ +66: 0+44 +0 TLS +GLOBAL HIDDEN +10 sh2
+ +67: 0+54 +0 TLS +GLOBAL HIDDEN +10 sh6
+ +68: 0+64 +0 TLS +GLOBAL DEFAULT +11 bg2
+ +69: 0+60 +0 TLS +GLOBAL DEFAULT +11 bg1
+ +70: 0+6c +0 TLS +GLOBAL DEFAULT +11 bg4
diff -urN src/ld/testsuite/ld-s390/tlsbin_64.s src-s390/ld/testsuite/ld-s390/tlsbin_64.s
--- src/ld/testsuite/ld-s390/tlsbin_64.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin_64.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,75 @@
+ .section ".tbss", "awT", @nobits
+ .globl bg1, bg2, bg3, bg4, bg5, bg6, bg7, bg8
+bg1: .space 4
+bg2: .space 4
+bg3: .space 4
+bg4: .space 4
+bg5: .space 4
+bg6: .space 4
+bg7: .space 4
+bg8: .space 4
+bl1: .space 4
+bl2: .space 4
+bl3: .space 4
+bl4: .space 4
+bl5: .space 4
+bl6: .space 4
+bl7: .space 4
+bl8: .space 4
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Function prolog */
+ stm %r6,%r14,24(%r15)
+ bras %r13,.LTN1
+ /* Literal pool */
+.LT1:
+.LC0:
+ .quad sG6@indntpoff
+.LC1:
+ .quad bg6@indntpoff
+.LC2:
+ .quad bl6@indntpoff
+.LC3:
+ .quad sh6@indntpoff
+.LC4:
+ .quad sg3@indntpoff
+.LTN1:
+ /* Function prolog */
+ lgr %r14,%r15
+ aghi %r15,-160
+ stg %r14,0(%r14)
+
+ /* Extract TCB */
+ ear %r9,%a0
+ sllg %r9,%r4,32
+ ear %r9,%a1
+
+ /* IE against global var */
+ lg %r3,.LC0-.LT1(%r13)
+ lg %r3,0(%r3,%r12):tls_load:sG6
+ la %r3,0(%r3,%r9)
+
+ /* IE -> LE against global var defined in exec */
+ lg %r3,.LC1-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:bg6
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against local var */
+ lg %r3,.LC2-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:bl6
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against hidden but not local var */
+ lg %r3,.LC3-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:sh6
+ la %r5,0(%r4,%r9)
+
+ /* LE, global var defined in exec */
+ lg %r4,.LC4-.LT1(%r13)
+ la %r5,0(%r4,%r9)
+
+ /* Function epilog */
+ lmg %r6,%r14,208(%r15)
+ br %r14
diff -urN src/ld/testsuite/ld-s390/tlsbin_64.sd src-s390/ld/testsuite/ld-s390/tlsbin_64.sd
--- src/ld/testsuite/ld-s390/tlsbin_64.sd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin_64.sd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,18 @@
+#source: tlsbinpic_64.s
+#source: tlsbin_64.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#objdump: -sj.got
+#target: s390x-*-*
+
+.*: file format elf64-s390
+
+Contents of section .got:
+ 80001888 [0-9a-f]+ [0-9a-f]+ 00000000 00000000 .*
+ 80001898 00000000 00000000 [0-9a-f]+ [0-9a-f]+ .*
+ 800018a8 ffffffff ffffff88 00000000 00000000 .*
+ 800018b8 00000000 00000000 ffffffff ffffff68 .*
+ 800018c8 ffffffff ffffffa8 00000000 00000000 .*
+ 800018d8 00000000 00000000 00000000 00000000 .*
+ 800018e8 00000000 00000000 00000000 00000000 .*
+ 800018f8 00000000 00000000 .*
diff -urN src/ld/testsuite/ld-s390/tlsbin_64.td src-s390/ld/testsuite/ld-s390/tlsbin_64.td
--- src/ld/testsuite/ld-s390/tlsbin_64.td Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbin_64.td Thu Jan 23 23:23:13 2003
@@ -0,0 +1,16 @@
+#source: tlsbinpic_64.s
+#source: tlsbin_64.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#objdump: -sj.tdata
+#target: s390x-*-*
+
+.*: file format elf64-s390
+
+Contents of section .tdata:
+ 800016e8 00000011 00000012 00000013 00000014 .*
+ 800016f8 00000015 00000016 00000017 00000018 .*
+ 80001708 00000041 00000042 00000043 00000044 .*
+ 80001718 00000045 00000046 00000047 00000048 .*
+ 80001728 00000101 00000102 00000103 00000104 .*
+ 80001738 00000105 00000106 00000107 00000108 .*
diff -urN src/ld/testsuite/ld-s390/tlsbinpic.s src-s390/ld/testsuite/ld-s390/tlsbinpic.s
--- src/ld/testsuite/ld-s390/tlsbinpic.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbinpic.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,168 @@
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+ .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2
+sg1: .long 17
+sg2: .long 18
+sg3: .long 19
+sg4: .long 20
+sg5: .long 21
+sg6: .long 22
+sg7: .long 23
+sg8: .long 24
+sl1: .long 65
+sl2: .long 66
+sl3: .long 67
+sl4: .long 68
+sl5: .long 69
+sl6: .long 70
+sl7: .long 71
+sl8: .long 72
+sh1: .long 257
+sh2: .long 258
+sh3: .long 259
+sh4: .long 260
+sh5: .long 261
+sh6: .long 262
+sh7: .long 263
+sh8: .long 264
+ .text
+ .globl fn2
+ .type fn2,@function
+fn2:
+ /* Function prolog */
+ stm %r6,%r14,24(%r15)
+ bras %r13,.LTN1
+ /* Literal pool */
+.LT1:
+.LC0:
+ .long _GLOBAL_OFFSET_TABLE_-.LT1
+.LC1:
+ .long __tls_get_offset@plt-.LT1
+.LC2:
+ .long sG1@tlsgd
+.LC3:
+ .long sG2@tlsgd
+.LC4:
+ .long sg1@tlsgd
+.LC5:
+ .long sl1@tlsgd
+.LC6:
+ .long sh1@tlsgd
+.LC7:
+ .long sl1@tlsldm
+.LC8:
+ .long sl1@dtpoff
+.LC9:
+ .long sl2@dtpoff
+.LC10:
+ .long sh1@tlsldm
+.LC11:
+ .long sh1@dtpoff
+.LC12:
+ .long sh2@dtpoff
+.LC13:
+ .long sG2@gotntpoff
+.LC14:
+ .long sg1@gotntpoff
+.LC15:
+ .long sl1@gotntpoff
+.LC16:
+ .long sh1@gotntpoff
+.LTN1:
+ /* Function prolog */
+ lr %r14,%r15
+ l %r12,.LC0-.LT1(%r13)
+ ahi %r15,-96
+ la %r12,0(%r12,%r13)
+ st %r14,0(%r14)
+
+ /* Extract TCB and load branch offset */
+ ear %r9,%a0
+ l %r7,.LC1-.LT1(%r13)
+
+ /* GD -> IE because variable is not defined in executable */
+ l %r2,.LC2-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sG1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE because variable is not defined in executable where
+ the variable is referenced through IE too */
+ l %r2,.LC3-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sG2
+ la %r2,0(%r2,%r9)
+
+ /* GD -> LE with global variable defined in executable */
+ l %r2,.LC4-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sg1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> LE with local variable defined in executable */
+ l %r2,.LC5-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sl1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> LE with hidden variable defined in executable */
+ l %r2,.LC6-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sh1
+ la %r2,0(%r2,%r9)
+
+ /* LD -> LE */
+ l %r2,.LC7-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_ldcall:sl1
+ la %r3,0(%r2,%r9)
+ l %r4,.LC8-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ l %r4,.LC9-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* LD -> LE against hidden variables */
+ l %r2,.LC10-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_ldcall:sh1
+ la %r3,0(%r2,%r9)
+ l %r4,.LC11-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ l %r4,.LC12-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* IE against global var */
+ l %r3,.LC13-.LT1(%r13)
+ l %r3,0(%r3,%r12):tls_load:sG2
+ l %r3,0(%r3,%r9)
+
+ /* IE -> LE against global var defined in exec */
+ l %r3,.LC14-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:sg1
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against local var */
+ l %r3,.LC15-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:sl1
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against hidden var */
+ l %r3,.LC16-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:sh1
+ la %r5,0(%r4,%r9)
+
+ /* IE against global var with small got access (no optimization) */
+ l %r3,sG3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against global var defined in exec with small got access
+ (no optimization) */
+ l %r3,sg3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against local var with small got access (no optimization) */
+ l %r3,sl3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against hidden var with small got access (no optimization) */
+ l %r3,sh3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* Function epilog */
+ lm %r6,%r14,120(%r15)
+ br %r14
diff -urN src/ld/testsuite/ld-s390/tlsbinpic_64.s src-s390/ld/testsuite/ld-s390/tlsbinpic_64.s
--- src/ld/testsuite/ld-s390/tlsbinpic_64.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlsbinpic_64.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,184 @@
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+ .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2
+sg1: .long 17
+sg2: .long 18
+sg3: .long 19
+sg4: .long 20
+sg5: .long 21
+sg6: .long 22
+sg7: .long 23
+sg8: .long 24
+sl1: .long 65
+sl2: .long 66
+sl3: .long 67
+sl4: .long 68
+sl5: .long 69
+sl6: .long 70
+sl7: .long 71
+sl8: .long 72
+sh1: .long 257
+sh2: .long 258
+sh3: .long 259
+sh4: .long 260
+sh5: .long 261
+sh6: .long 262
+sh7: .long 263
+sh8: .long 264
+ .text
+ .globl fn2
+ .type fn2,@function
+fn2:
+ /* Function prolog */
+ stmg %r6,%r14,48(%r15)
+ bras %r13,.LTN1
+ /* Literal pool */
+.LT1:
+.LC2:
+ .quad sG1@tlsgd
+.LC3:
+ .quad sG2@tlsgd
+.LC4:
+ .quad sg1@tlsgd
+.LC5:
+ .quad sl1@tlsgd
+.LC6:
+ .quad sh1@tlsgd
+.LC7:
+ .quad sl1@tlsldm
+.LC8:
+ .quad sl1@dtpoff
+.LC9:
+ .quad sl2@dtpoff
+.LC10:
+ .quad sh1@tlsldm
+.LC11:
+ .quad sh1@dtpoff
+.LC12:
+ .quad sh2@dtpoff
+.LC13:
+ .quad sG2@gotntpoff
+.LC14:
+ .quad sg1@gotntpoff
+.LC15:
+ .quad sl1@gotntpoff
+.LC16:
+ .quad sh1@gotntpoff
+.LTN1:
+ /* Function prolog */
+ lgr %r14,%r15
+ aghi %r15,-160
+ larl %r12,_GLOBAL_OFFSET_TABLE_
+ stg %r14,0(%r14)
+
+ /* Extract TCB */
+ ear %r9,%a0
+ sllg %r9,%r4,32
+ ear %r9,%a1
+
+ /* GD -> IE because variable is not defined in executable */
+ lg %r12,.LC2-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sG1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE because variable is not defined in executable where
+ the variable is referenced through IE too */
+ lg %r2,.LC3-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sG2
+ la %r2,0(%r2,%r9)
+
+ /* GD -> LE with global variable defined in executable */
+ lg %r2,.LC4-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sg1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> LE with local variable defined in executable */
+ lg %r2,.LC5-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sl1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> LE with hidden variable defined in executable */
+ lg %r2,.LC6-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sh1
+ la %r2,0(%r2,%r9)
+
+ /* LD -> LE */
+ lg %r2,.LC7-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:sl1
+ la %r3,0(%r2,%r9)
+ lg %r4,.LC8-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ lg %r4,.LC9-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* LD -> LE against hidden variables */
+ lg %r2,.LC10-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:sh1
+ la %r3,0(%r2,%r9)
+ lg %r4,.LC11-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ lg %r4,.LC12-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* IE against global var */
+ lg %r3,.LC13-.LT1(%r13)
+ lg %r3,0(%r3,%r12):tls_load:sG2
+ la %r3,0(%r3,%r9)
+
+ /* IE -> LE against global var defined in exec */
+ lg %r3,.LC14-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:sg1
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against local var */
+ lg %r3,.LC15-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:sl2
+ la %r5,0(%r4,%r9)
+
+ /* IE -> LE against hidden var */
+ lg %r3,.LC16-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:sh1
+ la %r5,0(%r4,%r9)
+
+ /* IE against global var with larl got access */
+ larl %r3,sG3@indntpoff
+ lg %r3,0(%r3,%r12):tls_load:sG3
+ la %r3,0(%r3,%r9)
+
+ /* IE against global var defined in exec with larl got access */
+ larl %r3,sg3@indntpoff
+ lg %r4,0(%r3,%r12):tls_load:sg3
+ la %r5,0(%r4,%r9)
+
+ /* IE against local var with larl got access */
+ larl %r3,sl3@indntpoff
+ lg %r4,0(%r3,%r12):tls_load:sl3
+ la %r5,0(%r4,%r9)
+
+ /* IE against hidden var with larl got access */
+ larl %r3,sh3@indntpoff
+ lg %r4,0(%r3,%r12):tls_load:sh3
+ la %r5,0(%r4,%r9)
+
+ /* IE against global var with small got access (no optimization) */
+ lg %r3,sG3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against global var defined in exec with small got access
+ (no optimization) */
+ lg %r3,sg3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against local var with small got access (no optimization) */
+ lg %r3,sl3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against hidden var with small got access (no optimization) */
+ lg %r3,sh3@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* Function epilog */
+ lmg %r6,%r14,208(%r15)
+ br %r14
diff -urN src/ld/testsuite/ld-s390/tlslib.s src-s390/ld/testsuite/ld-s390/tlslib.s
--- src/ld/testsuite/ld-s390/tlslib.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlslib.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,17 @@
+ .section ".tdata", "awT", @progbits
+ .globl sG1, sG2, sG3, sG4, sG5, sG6, sG7, sG8,
+sG1: .long 513
+sG2: .long 514
+sG3: .long 515
+sG4: .long 516
+sG5: .long 517
+sG6: .long 518
+sG7: .long 519
+sG8: .long 520
+
+ .text
+ /* Dummy. */
+ .globl __tls_get_offset
+ .type __tls_get_offset,@function
+__tls_get_offset:
+ br %r14
diff -urN src/ld/testsuite/ld-s390/tlslib_64.s src-s390/ld/testsuite/ld-s390/tlslib_64.s
--- src/ld/testsuite/ld-s390/tlslib_64.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlslib_64.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,17 @@
+ .section ".tdata", "awT", @progbits
+ .globl sG1, sG2, sG3, sG4, sG5, sG6, sG7, sG8,
+sG1: .long 513
+sG2: .long 514
+sG3: .long 515
+sG4: .long 516
+sG5: .long 517
+sG6: .long 518
+sG7: .long 519
+sG8: .long 520
+
+ .text
+ /* Dummy. */
+ .globl __tls_get_offset
+ .type __tls_get_offset,@function
+__tls_get_offset:
+ br %r14
diff -urN src/ld/testsuite/ld-s390/tlspic.dd src-s390/ld/testsuite/ld-s390/tlspic.dd
--- src/ld/testsuite/ld-s390/tlspic.dd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic.dd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,161 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m31
+#ld: -shared -melf_s390
+#objdump: -dzrj.text
+#target: s390-*-*
+
+.*: +file format elf32-s390
+
+Disassembly of section .text:
+
+0+4bc <fn1>:
+# function prolog
+ +4bc: 90 6e f0 18 stm %r6,%r14,24\(%r15\)
+ +4c0: a7 d5 00 30 bras %r13,520 <fn1\+0x64>
+# _GLOBAL_OFFSET_TABLE_-.LT1
+ +4c4: 00 00 12 78 .long 0x00001278
+# __tls_get_addr@plt-.LT1
+ +4c8: ff ff ff d8 .long 0xffffffd8
+# sg1@tlsgd
+ +4cc: 00 00 00 38 .long 0x00000038
+# sg2@tlsgd
+ +4d0: 00 00 00 48 .long 0x00000048
+# sl1@tlsgd
+ +4d4: 00 00 00 10 .long 0x00000010
+# sl2@tlsgd
+ +4d8: 00 00 00 18 .long 0x00000018
+# sh1@tlsgd
+ +4dc: 00 00 00 4c .long 0x0000004c
+# sh2@tlsgd
+ +4e0: 00 00 00 54 .long 0x00000054
+# sH1@tlsgd
+ +4e4: 00 00 00 28 .long 0x00000028
+# sH2@tlsgd
+ +4e8: 00 00 00 30 .long 0x00000030
+# sl1@tlsldm
+ +4ec: 00 00 00 20 .long 0x00000020
+# sl1@dtpoff
+ +4f0: 00 00 00 20 .long 0x00000020
+# sl2@dtpoff
+ +4f4: 00 00 00 24 .long 0x00000024
+# sh1@tlsldm
+ +4f8: 00 00 00 20 .long 0x00000020
+# sh1@dtpoff
+ +4fc: 00 00 00 40 .long 0x00000040
+# sh2@dtpoff
+ +500: 00 00 00 44 .long 0x00000044
+# sH1@tlsldm
+ +504: 00 00 00 20 .long 0x00000020
+# sH1@dtpoff
+ +508: 00 00 00 60 .long 0x00000060
+# sH2@dtpoff
+ +50c: 00 00 00 64 .long 0x00000064
+# sg2@gotntpoff
+ +510: 00 00 00 48 .long 0x00000048
+# sl2@gotntpoff
+ +514: 00 00 00 18 .long 0x00000018
+# sh2@gotntpoff
+ +518: 00 00 00 54 .long 0x00000054
+# sH2@gotntpoff
+ +51c: 00 00 00 30 .long 0x00000030
+# function prolog
+ +520: 18 ef lr %r14,%r15
+ +522: 58 c0 d0 00 l %r12,0\(%r13\)
+ +526: a7 fa ff a0 ahi %r15,-96
+ +52a: 41 cc d0 00 la %r12,0\(%r12,%r13\)
+ +52e: 50 e0 e0 00 st %r14,0\(%r14\)
+# Extract TCB and load branch offset
+ +532: b2 4f 00 90 ear %r9,%a0
+ +536: 58 70 d0 04 l %r7,4\(%r13\)
+# GD
+ +53a: 58 20 d0 08 l %r2,8\(%r13\)
+ +53e: 4d e7 d0 00 bas %r14,0\(%r7,%r13\)
+ +542: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE because variable is referenced through IE too
+ +546: 58 20 d0 0c l %r2,12\(%r13\)
+ +54a: 58 22 c0 00 l %r2,0\(%r2,%r12\)
+ +54e: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD against local variable
+ +552: 58 20 d0 10 l %r2,16\(%r13\)
+ +556: 4d e7 d0 00 bas %r14,0\(%r7,%r13\)
+ +55a: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE against local variable referenced through IE too
+ +55e: 58 20 d0 14 l %r2,20\(%r13\)
+ +562: 58 22 c0 00 l %r2,0\(%r2,%r12\)
+ +566: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD against hidden and local variable
+ +56a: 58 20 d0 18 l %r2,24\(%r13\)
+ +56e: 4d e7 d0 00 bas %r14,0\(%r7,%r13\)
+ +572: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE against hidden and local variable referenced through
+# IE too
+ +576: 58 20 d0 1c l %r2,28\(%r13\)
+ +57a: 58 22 c0 00 l %r2,0\(%r2,%r12\)
+ +57e: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD against hidden but not local variable
+ +582: 58 20 d0 20 l %r2,32\(%r13\)
+ +586: 4d e7 d0 00 bas %r14,0\(%r7,%r13\)
+ +58a: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE against hidden but not local variable referenced through
+# IE too
+ +58e: 58 20 d0 24 l %r2,36\(%r13\)
+ +592: 58 22 c0 00 l %r2,0\(%r2,%r12\)
+ +596: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# LD
+ +59a: 58 20 d0 28 l %r2,40\(%r13\)
+ +59e: 4d e7 d0 00 bas %r14,0\(%r7,%r13\)
+ +5a2: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +5a6: 58 40 d0 2c l %r4,44\(%r13\)
+ +5aa: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +5ae: 58 40 d0 30 l %r4,48\(%r13\)
+ +5b2: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# LD against hidden and local variables
+ +5b6: 58 20 d0 34 l %r2,52\(%r13\)
+ +5ba: 4d e7 d0 00 bas %r14,0\(%r7,%r13\)
+ +5be: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +5c2: 58 40 d0 38 l %r4,56\(%r13\)
+ +5c6: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +5ca: 58 40 d0 34 l %r4,52\(%r13\)
+ +5ce: 41 55 30 00 la %r5,0\(%r5,%r3\)
+# LD against hidden but not local variables
+ +5d2: 58 20 d0 40 l %r2,64\(%r13\)
+ +5d6: 4d e7 d0 00 bas %r14,0\(%r7,%r13\)
+ +5da: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +5de: 58 30 d0 44 l %r3,68\(%r13\)
+ +5e2: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +5e6: 58 40 d0 48 l %r4,72\(%r13\)
+ +5ea: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# IE against global var
+ +5ee: 58 30 d0 4c l %r3,76\(%r13\)
+ +5f2: 58 33 c0 00 l %r3,0\(%r3,%r12\)
+ +5f6: 41 33 30 00 la %r3,0\(%r3,%r3\)
+# IE against local var
+ +5fa: 58 30 d0 50 l %r3,80\(%r13\)
+ +5fe: 58 43 c0 00 l %r4,0\(%r3,%r12\)
+ +602: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# IE against hidden and local var
+ +606: 58 30 d0 54 l %r3,84\(%r13\)
+ +60a: 58 43 c0 00 l %r4,0\(%r3,%r12\)
+ +60e: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# IE against hidden but not local var
+ +612: 58 30 d0 58 l %r3,88\(%r13\)
+ +616: 58 43 c0 00 l %r4,0\(%r3,%r12\)
+ +61a: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# IE against global var with small got access (no optimization)
+ +61e: 58 30 c0 34 l %r3,52\(%r12\)
+ +622: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against local var with small got access (no optimization)
+ +626: 58 30 c0 1c l %r3,28\(%r12\)
+ +62a: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against hidden and local var with small got access
+# (no optimization)
+ +62e: 58 30 c0 40 l %r3,64\(%r12\)
+ +632: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against hidden but not local var with small got access
+# (no optimization)
+ +636: 58 30 c0 44 l %r3,68\(%r12\)
+ +63a: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# function prolog
+ +63e: 98 6e f0 78 lm %r6,%r14,120\(%r15\)
+ +642: 07 fe br %r14
diff -urN src/ld/testsuite/ld-s390/tlspic.rd src-s390/ld/testsuite/ld-s390/tlspic.rd
--- src/ld/testsuite/ld-s390/tlspic.rd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic.rd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,165 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m31
+#ld: -shared -melf_s390
+#readelf: -Ssrl
+#target: s390-*-*
+
+There are 18 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ \[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 0
+ \[ 1\] .hash +.*
+ \[ 2\] .dynsym +.*
+ \[ 3\] .dynstr +.*
+ \[ 4\] .rela.dyn +.*
+ \[ 5\] .rela.plt +.*
+ \[ 6\] .plt +.*
+ \[ 7\] .text +PROGBITS +0+4bc 0+4bc 0+188 00 AX 0 +0 4
+ \[ 8\] .data +.*
+ \[ 9\] .tdata +PROGBITS +0+1644 0+644 0+60 00 WAT 0 +0 1
+ \[10\] .tbss +NOBITS +0+16a4 0+6a4 0+20 00 WAT 0 +0 1
+ \[11\] .dynamic +DYNAMIC +0+16a4 0+6a4 0+98 08 WA 3 +0 4
+ \[12\] .got +PROGBITS +0+173c 0+73c 0+58 04 WA 0 +0 4
+ \[13\] .sbss +.*
+ \[14\] .bss +.*
+ \[15\] .shstrtab +.*
+ \[16\] .symtab +.*
+ \[17\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x4bc
+There are 4 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz MemSiz Flg Align
+ LOAD +0x0+ 0x0+ 0x0+ 0x[0-9a-f]+ 0x[0-9a-f]+ R E 0x1000
+ LOAD +0x0+644 0x0+1644 0x0+1644 0x00150 0x00150 RW 0x1000
+ DYNAMIC +0x0+6a4 0x0+16a4 0x0+16a4 0x0+98 0x0+98 RW 0x4
+ TLS +0x0+644 0x0+1644 0x0+1644 0x0+60 0x0+80 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ +00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text
+ +01 +.tdata .tbss .dynamic .got
+ +02 +.tbss .dynamic
+ +03 +.tdata .tbss
+
+Relocation section '.rela.dyn' at offset 0x3c8 contains 14 entries:
+ Offset +Info +Type +Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-f]+ 0+38 R_390_TLS_TPOFF +0+24
+[0-9a-f]+ 0+38 R_390_TLS_TPOFF +0+30
+[0-9a-f]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-f]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-f]+ 0+38 R_390_TLS_TPOFF +0+64
+[0-9a-f]+ 0+38 R_390_TLS_TPOFF +0+50
+[0-9a-f]+ 0+38 R_390_TLS_TPOFF +0+70
+[0-9a-f]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-f]+ 0+38 R_390_TLS_TPOFF +0+44
+[0-9a-f]+ 0+1338 R_390_TLS_TPOFF +0+10 +sg5 \+ 0
+[0-9a-f]+ 0+1536 R_390_TLS_DTPMOD 0+ +sg1 \+ 0
+[0-9a-f]+ 0+1537 R_390_TLS_DTPOFF 0+ +sg1 \+ 0
+[0-9a-f]+ 0+1838 R_390_TLS_TPOFF +0+4 +sg2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset +Info +Type +Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0+140b R_390_JMP_SLOT +0+ +__tls_get_offset \+ 0
+
+Symbol table '.dynsym' contains 30 entries:
+ +Num: +Value Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND
+ +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1
+ +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2
+ +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3
+ +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4
+ +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5
+ +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6
+ +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7
+ +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8
+ +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9
+ +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10
+ +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11
+ +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12
+ +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13
+ +14: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14
+ +15: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +16: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +17: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +18: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +19: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +20: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_offset
+ +21: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +22: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +23: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +24: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +25: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +26: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +27: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +28: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +29: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 57 entries:
+ +Num: +Value Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND
+ +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1
+ +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2
+ +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3
+ +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4
+ +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5
+ +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6
+ +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7
+ +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8
+ +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9
+ +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10
+ +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11
+ +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12
+ +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13
+ +14: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14
+ +15: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +15
+ +16: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +16
+ +17: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +17
+ +18: 0+20 +0 TLS +LOCAL DEFAULT +9 sl1
+ +19: 0+24 +0 TLS +LOCAL DEFAULT +9 sl2
+ +20: 0+28 +0 TLS +LOCAL DEFAULT +9 sl3
+ +21: 0+2c +0 TLS +LOCAL DEFAULT +9 sl4
+ +22: 0+30 +0 TLS +LOCAL DEFAULT +9 sl5
+ +23: 0+34 +0 TLS +LOCAL DEFAULT +9 sl6
+ +24: 0+38 +0 TLS +LOCAL DEFAULT +9 sl7
+ +25: 0+3c +0 TLS +LOCAL DEFAULT +9 sl8
+ +26: 0+60 +0 TLS +LOCAL HIDDEN +10 sH1
+ +27: 0+48 +0 TLS +LOCAL HIDDEN +9 sh3
+ +28: 0+64 +0 TLS +LOCAL HIDDEN +10 sH2
+ +29: 0+78 +0 TLS +LOCAL HIDDEN +10 sH7
+ +30: 0+58 +0 TLS +LOCAL HIDDEN +9 sh7
+ +31: 0+5c +0 TLS +LOCAL HIDDEN +9 sh8
+ +32: 0+6c +0 TLS +LOCAL HIDDEN +10 sH4
+ +33: 0+4c +0 TLS +LOCAL HIDDEN +9 sh4
+ +34: 0+68 +0 TLS +LOCAL HIDDEN +10 sH3
+ +35: 0+50 +0 TLS +LOCAL HIDDEN +9 sh5
+ +36: 0+70 +0 TLS +LOCAL HIDDEN +10 sH5
+ +37: 0+74 +0 TLS +LOCAL HIDDEN +10 sH6
+ +38: 0+7c +0 TLS +LOCAL HIDDEN +10 sH8
+ +39: 0+40 +0 TLS +LOCAL HIDDEN +9 sh1
+ +40: 0+44 +0 TLS +LOCAL HIDDEN +9 sh2
+ +41: 0+54 +0 TLS +LOCAL HIDDEN +9 sh6
+ +42: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +43: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +44: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +45: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +46: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +47: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_offset
+ +48: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +49: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +50: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +51: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +52: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +53: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +54: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +55: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +56: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
diff -urN src/ld/testsuite/ld-s390/tlspic.sd src-s390/ld/testsuite/ld-s390/tlspic.sd
--- src/ld/testsuite/ld-s390/tlspic.sd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic.sd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,16 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m31
+#ld: -shared -melf_s390
+#objdump: -sj.got
+#target: s390-*-*
+
+.*: +file format elf32-s390
+
+Contents of section .got:
+ 173c [0-9a-f]+ 00000000 00000000 [0-9a-f]+ .*
+ 174c 00000000 00000020 00000000 00000000 .*
+ 175c 00000000 00000000 00000000 00000060 .*
+ 176c 00000000 00000000 00000000 00000000 .*
+ 177c 00000000 00000000 00000000 00000000 .*
+ 178c 00000040 00000000 +.*
diff -urN src/ld/testsuite/ld-s390/tlspic.td src-s390/ld/testsuite/ld-s390/tlspic.td
--- src/ld/testsuite/ld-s390/tlspic.td Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic.td Thu Jan 23 23:23:13 2003
@@ -0,0 +1,16 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m31
+#ld: -shared -melf_s390
+#objdump: -sj.tdata
+#target: s390-*-*
+
+.*: +file format elf32-s390
+
+Contents of section .tdata:
+ 1644 00000011 00000012 00000013 00000014 .*
+ 1654 00000015 00000016 00000017 00000018 .*
+ 1664 00000041 00000042 00000043 00000044 .*
+ 1674 00000045 00000046 00000047 00000048 .*
+ 1684 00000101 00000102 00000103 00000104 .*
+ 1694 00000105 00000106 00000107 00000108 .*
diff -urN src/ld/testsuite/ld-s390/tlspic1.s src-s390/ld/testsuite/ld-s390/tlspic1.s
--- src/ld/testsuite/ld-s390/tlspic1.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic1.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,206 @@
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+ .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1: .long 17
+sg2: .long 18
+sg3: .long 19
+sg4: .long 20
+sg5: .long 21
+sg6: .long 22
+sg7: .long 23
+sg8: .long 24
+sl1: .long 65
+sl2: .long 66
+sl3: .long 67
+sl4: .long 68
+sl5: .long 69
+sl6: .long 70
+sl7: .long 71
+sl8: .long 72
+sh1: .long 257
+sh2: .long 258
+sh3: .long 259
+sh4: .long 260
+sh5: .long 261
+sh6: .long 262
+sh7: .long 263
+sh8: .long 264
+ .text
+ .globl fn1
+ .type fn1,@function
+fn1:
+ /* Funtion prolog */
+ stm %r6,%r14,24(%r15)
+ bras %r13,.LTN1
+ /* Literal pool */
+.LT1:
+.LC0:
+ .long _GLOBAL_OFFSET_TABLE_-.LT1
+.LC1:
+ .long __tls_get_offset@plt-.LT1
+.LC2:
+ .long sg1@tlsgd
+.LC3:
+ .long sg2@tlsgd
+.LC4:
+ .long sl1@tlsgd
+.LC5:
+ .long sl2@tlsgd
+.LC6:
+ .long sh1@tlsgd
+.LC7:
+ .long sh2@tlsgd
+.LC8:
+ .long sH1@tlsgd
+.LC9:
+ .long sH2@tlsgd
+.LC10:
+ .long sl1@tlsldm
+.LC11:
+ .long sl1@dtpoff
+.LC12:
+ .long sl2@dtpoff
+.LC13:
+ .long sh1@tlsldm
+.LC14:
+ .long sh1@dtpoff
+.LC15:
+ .long sh2@dtpoff
+.LC16:
+ .long sH1@tlsldm
+.LC17:
+ .long sH1@dtpoff
+.LC18:
+ .long sH2@dtpoff
+.LC19:
+ .long sg2@gotntpoff
+.LC20:
+ .long sl2@gotntpoff
+.LC21:
+ .long sh2@gotntpoff
+.LC22:
+ .long sH2@gotntpoff
+.LTN1:
+ /* Funtion prolog */
+ lr %r14,%r15
+ l %r12,.LC0-.LT1(%r13)
+ ahi %r15,-96
+ la %r12,0(%r12,%r13)
+ st %r14,0(%r14)
+
+ /* Extract TCB and load branch offset */
+ ear %r9,%a0
+ l %r7,.LC1-.LT1(%r13)
+
+ /* GD */
+ l %r2,.LC2-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sg1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE because variable is referenced through IE too */
+ l %r2,.LC3-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sg2
+ la %r2,0(%r2,%r9)
+
+ /* GD against local variable */
+ l %r2,.LC4-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sl1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE against local variable referenced through IE too */
+ l %r2,.LC5-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sl2
+ la %r2,0(%r2,%r9)
+
+ /* GD against hidden and local variable */
+ l %r2,.LC6-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sh1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE against hidden and local variable referenced through
+ IE too */
+ l %r2,.LC7-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sh2
+ la %r2,0(%r2,%r9)
+
+ /* GD against hidden but not local variable */
+ l %r2,.LC8-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sH1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE against hidden but not local variable referenced through
+ IE too */
+ l %r2,.LC9-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_gdcall:sH2
+ la %r2,0(%r2,%r9)
+
+ /* LD */
+ l %r2,.LC10-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_ldcall:sl1
+ la %r3,0(%r2,%r9)
+ l %r4,.LC11-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ l %r4,.LC12-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* LD against hidden and local variables */
+ l %r2,.LC13-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_ldcall:sh1
+ la %r3,0(%r2,%r9)
+ l %r4,.LC14-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ l %r4,.LC13-.LT1(%r13)
+ la %r5,0(%r5,%r3)
+
+ /* LD against hidden but not local variables */
+ l %r2,.LC16-.LT1(%r13)
+ bas %r14,0(%r7,%r13):tls_ldcall:sH1
+ la %r3,0(%r2,%r9)
+ l %r3,.LC17-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ l %r4,.LC18-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* IE against global var */
+ l %r3,.LC19-.LT1(%r13)
+ l %r3,0(%r3,%r12):tls_load:sg2
+ la %r3,0(%r3,%r3)
+
+ /* IE against local var */
+ l %r3,.LC20-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:sl2
+ la %r5,0(%r4,%r3)
+
+ /* IE against hidden and local var */
+ l %r3,.LC21-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:sh2
+ la %r5,0(%r4,%r3)
+
+ /* IE against hidden but not local var */
+ l %r3,.LC22-.LT1(%r13)
+ l %r4,0(%r3,%r12):tls_load:sH2
+ la %r5,0(%r4,%r3)
+
+ /* IE against global var with small got access (no optimization) */
+ l %r3,sg5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against local var with small got access (no optimization) */
+ l %r3,sl5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against hidden and local var with small got access
+ (no optimization) */
+ l %r3,sh5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against hidden but not local var with small got access
+ (no optimization) */
+ l %r3,sH5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* Function epilog */
+ lm %r6,%r14,120(%r15)
+ br %r14
+
diff -urN src/ld/testsuite/ld-s390/tlspic1_64.s src-s390/ld/testsuite/ld-s390/tlspic1_64.s
--- src/ld/testsuite/ld-s390/tlspic1_64.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic1_64.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,222 @@
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+ .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1: .long 17
+sg2: .long 18
+sg3: .long 19
+sg4: .long 20
+sg5: .long 21
+sg6: .long 22
+sg7: .long 23
+sg8: .long 24
+sl1: .long 65
+sl2: .long 66
+sl3: .long 67
+sl4: .long 68
+sl5: .long 69
+sl6: .long 70
+sl7: .long 71
+sl8: .long 72
+sh1: .long 257
+sh2: .long 258
+sh3: .long 259
+sh4: .long 260
+sh5: .long 261
+sh6: .long 262
+sh7: .long 263
+sh8: .long 264
+ .text
+ .globl fn1
+ .type fn1,@function
+fn1:
+ /* Funtion prolog */
+ stmg %r6,%r14,48(%r15)
+ bras %r13,.LTN1
+ /* Literal pool */
+.LT1:
+.LC2:
+ .quad sg1@tlsgd
+.LC3:
+ .quad sg2@tlsgd
+.LC4:
+ .quad sl1@tlsgd
+.LC5:
+ .quad sl2@tlsgd
+.LC6:
+ .quad sh1@tlsgd
+.LC7:
+ .quad sh2@tlsgd
+.LC8:
+ .quad sH1@tlsgd
+.LC9:
+ .quad sH2@tlsgd
+.LC10:
+ .quad sl1@tlsldm
+.LC11:
+ .quad sl1@dtpoff
+.LC12:
+ .quad sl2@dtpoff
+.LC13:
+ .quad sh1@tlsldm
+.LC14:
+ .quad sh1@dtpoff
+.LC15:
+ .quad sh2@dtpoff
+.LC16:
+ .quad sH1@tlsldm
+.LC17:
+ .quad sH1@dtpoff
+.LC18:
+ .quad sH2@dtpoff
+.LC19:
+ .quad sg2@gotntpoff
+.LC20:
+ .quad sl2@gotntpoff
+.LC21:
+ .quad sh2@gotntpoff
+.LC22:
+ .quad sH2@gotntpoff
+.LTN1:
+ /* Funtion prolog */
+ lgr %r14,%r15
+ larl %r12,_GLOBAL_OFFSET_TABLE_
+ aghi %r15,-160
+ stg %r14,0(%r14)
+
+ /* Extract TCB */
+ ear %r9,%a0
+ sllg %r9,%r4,32
+ ear %r9,%a1
+
+ /* GD */
+ lg %r2,.LC2-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sg1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE because variable is referenced through IE too */
+ lg %r2,.LC3-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sg2
+ la %r2,0(%r2,%r9)
+
+ /* GD against local variable */
+ lg %r2,.LC4-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sl1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE against local variable referenced through IE too */
+ lg %r2,.LC5-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sl2
+ la %r2,0(%r2,%r9)
+
+ /* GD against hidden and local variable */
+ lg %r2,.LC6-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sh1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE against hidden and local variable referenced through
+ IE too */
+ lg %r2,.LC7-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sh2
+ la %r2,0(%r2,%r9)
+
+ /* GD against hidden but not local variable */
+ lg %r2,.LC8-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sH1
+ la %r2,0(%r2,%r9)
+
+ /* GD -> IE against hidden but not local variable referenced through
+ IE too */
+ lg %r2,.LC9-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:sH2
+ la %r2,0(%r2,%r9)
+
+ /* LD */
+ lg %r2,.LC10-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:sl1
+ la %r3,0(%r2,%r9)
+ lg %r4,.LC11-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ lg %r4,.LC12-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* LD against hidden and local variables */
+ lg %r2,.LC13-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:sh1
+ la %r3,0(%r2,%r9)
+ lg %r4,.LC14-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ lg %r4,.LC15-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* LD against hidden but not local variables */
+ lg %r2,.LC16-.LT1(%r13)
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:sH1
+ la %r3,0(%r2,%r9)
+ lg %r4,.LC17-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+ lg %r4,.LC18-.LT1(%r13)
+ la %r5,0(%r4,%r3)
+
+ /* IE against global var */
+ lg %r3,.LC19-.LT1(%r13)
+ lg %r3,0(%r3,%r12):tls_load:sg2
+ la %r3,0(%r3,%r9)
+
+ /* IE against local var */
+ lg %r3,.LC20-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:sl2
+ la %r5,0(%r4,%r9)
+
+ /* IE against hidden and local var */
+ lg %r3,.LC21-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:sh2
+ la %r5,0(%r4,%r9)
+
+ /* IE against hidden but not local var */
+ lg %r3,.LC22-.LT1(%r13)
+ lg %r4,0(%r3,%r12):tls_load:sH2
+ la %r5,0(%r4,%r9)
+
+ /* IE against global var with larl got access */
+ larl %r3,sg5@indntpoff
+ lg %r3,0(%r3,%r12):tls_load:sg2
+ la %r3,0(%r3,%r9)
+
+ /* IE against local var with larl got access */
+ larl %r3,sl5@indntpoff
+ lg %r4,0(%r3,%r12):tls_load:sl2
+ la %r5,0(%r4,%r9)
+
+ /* IE against hidden and local var with larl got access */
+ larl %r3,sh5@indntpoff
+ lg %r4,0(%r3,%r12):tls_load:sh2
+ la %r5,0(%r4,%r9)
+
+ /* IE against hidden but not local var with larl got access */
+ larl %r3,sH5@indntpoff
+ lg %r4,0(%r3,%r12):tls_load:sH2
+ la %r5,0(%r4,%r9)
+
+ /* IE against global var with small got access (no optimization) */
+ lg %r3,sg5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against local var with small got access (no optimization) */
+ lg %r3,sl5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against hidden and local var with small got access
+ (no optimization) */
+ lg %r3,sh5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* IE against hidden but not local var with small got access
+ (no optimization) */
+ lg %r3,sH5@gotntpoff(%r12)
+ la %r3,0(%r3,%r9)
+
+ /* Function epilog */
+ lmg %r6,%r14,208(%r15)
+ br %r14
+
diff -urN src/ld/testsuite/ld-s390/tlspic2.s src-s390/ld/testsuite/ld-s390/tlspic2.s
--- src/ld/testsuite/ld-s390/tlspic2.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic2.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,11 @@
+ .section ".tbss", "awT", @nobits
+ .globl sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+ .hidden sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+sH1: .space 4
+sH2: .space 4
+sH3: .space 4
+sH4: .space 4
+sH5: .space 4
+sH6: .space 4
+sH7: .space 4
+sH8: .space 4
diff -urN src/ld/testsuite/ld-s390/tlspic2_64.s src-s390/ld/testsuite/ld-s390/tlspic2_64.s
--- src/ld/testsuite/ld-s390/tlspic2_64.s Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic2_64.s Thu Jan 23 23:23:13 2003
@@ -0,0 +1,11 @@
+ .section ".tbss", "awT", @nobits
+ .globl sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+ .hidden sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+sH1: .space 4
+sH2: .space 4
+sH3: .space 4
+sH4: .space 4
+sH5: .space 4
+sH6: .space 4
+sH7: .space 4
+sH8: .space 4
diff -urN src/ld/testsuite/ld-s390/tlspic_64.dd src-s390/ld/testsuite/ld-s390/tlspic_64.dd
--- src/ld/testsuite/ld-s390/tlspic_64.dd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic_64.dd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,194 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#objdump: -dzrj.text
+#target: s390x-*-*
+
+.*: +file format elf64-s390
+
+Disassembly of section .text:
+
+0+790 <fn1>:
+# function prolog
+ +790: eb 6e f0 30 00 24 stmg %r6,%r14,48\(%r15\)
+ +796: a7 d5 00 56 bras %r13,842 <fn1\+0xb2>
+# sg1@tlsgd
+ +79a: 00 00 00 00 .long 0x00000000
+ +79e: 00 00 00 70 .long 0x00000070
+# sg2@tlsgd
+ +7a2: 00 00 00 00 .long 0x00000000
+ +7a6: 00 00 00 90 .long 0x00000090
+# sl1@tlsgd
+ +7aa: 00 00 00 00 .long 0x00000000
+ +7ae: 00 00 00 20 .long 0x00000020
+# sl2@tlsgd
+ +7b2: 00 00 00 00 .long 0x00000000
+ +7b6: 00 00 00 30 .long 0x00000030
+# sh1@tlsgd
+ +7ba: 00 00 00 00 .long 0x00000000
+ +7be: 00 00 00 98 .long 0x00000098
+# sh2@tlsgd
+ +7c2: 00 00 00 00 .long 0x00000000
+ +7c6: 00 00 00 a8 .long 0x000000a8
+# sH1@tlsgd
+ +7ca: 00 00 00 00 .long 0x00000000
+ +7ce: 00 00 00 50 .long 0x00000050
+# sH2@tlsgd
+ +7d2: 00 00 00 00 .long 0x00000000
+ +7d6: 00 00 00 60 .long 0x00000060
+# sl1@tlsldm
+ +7da: 00 00 00 00 .long 0x00000000
+ +7de: 00 00 00 40 .long 0x00000040
+# sl1@dtpoff
+ +7e2: 00 00 00 00 .long 0x00000000
+ +7e6: 00 00 00 20 .long 0x00000020
+# sl2@dtpoff
+ +7ea: 00 00 00 00 .long 0x00000000
+ +7ee: 00 00 00 24 .long 0x00000024
+# sh1@tlsldm
+ +7f2: 00 00 00 00 .long 0x00000000
+ +7f6: 00 00 00 40 .long 0x00000040
+# sh1@dtpoff
+ +7fa: 00 00 00 00 .long 0x00000000
+ +7fe: 00 00 00 40 .long 0x00000040
+# sh2@dtpoff
+ +802: 00 00 00 00 .long 0x00000000
+ +806: 00 00 00 44 .long 0x00000044
+# sH1@tlsldm
+ +80a: 00 00 00 00 .long 0x00000000
+ +80e: 00 00 00 40 .long 0x00000040
+# sH1@dtpoff
+ +812: 00 00 00 00 .long 0x00000000
+ +816: 00 00 00 60 .long 0x00000060
+# sH2@dtpoff
+ +81a: 00 00 00 00 .long 0x00000000
+ +81e: 00 00 00 64 .long 0x00000064
+# sg2@gotntpoff
+ +822: 00 00 00 00 .long 0x00000000
+ +826: 00 00 00 90 .long 0x00000090
+# sl2@gotntpoff
+ +82a: 00 00 00 00 .long 0x00000000
+ +82e: 00 00 00 30 .long 0x00000030
+# sh2@gotntpoff
+ +832: 00 00 00 00 .long 0x00000000
+ +836: 00 00 00 a8 .long 0x000000a8
+# sH2@gotntpoff
+ +83a: 00 00 00 00 .long 0x00000000
+ +83e: 00 00 00 60 .long 0x00000060
+# function prolog
+ +842: b9 04 00 ef lgr %r14,%r15
+ +846: c0 c0 00 00 09 a5 larl %r12,1b90 <_GLOBAL_OFFSET_TABLE_>
+ +84c: a7 fb ff 60 aghi %r15,-160
+ +850: e3 e0 e0 00 00 24 stg %r14,0\(%r14\)
+# extract TCB
+ +856: b2 4f 00 90 ear %r9,%a0
+ +85a: eb 94 00 20 00 0d sllg %r9,%r4,32
+ +860: b2 4f 00 91 ear %r9,%a1
+# GD
+ +864: e3 20 d0 00 00 04 lg %r2,0\(%r13\)
+ +86a: c0 e5 ff ff ff 83 brasl %r14,770 <sH8\+0x6f4>
+ +870: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE because variable is referenced through IE too
+ +874: e3 20 d0 08 00 04 lg %r2,8\(%r13\)
+ +87a: e3 22 c0 00 00 04 lg %r2,0\(%r2,%r12\)
+ +880: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD against local variable
+ +884: e3 20 d0 10 00 04 lg %r2,16\(%r13\)
+ +88a: c0 e5 ff ff ff 73 brasl %r14,770 <sH8\+0x6f4>
+ +890: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE against local variable referenced through IE too
+ +894: e3 20 d0 18 00 04 lg %r2,24\(%r13\)
+ +89a: e3 22 c0 00 00 04 lg %r2,0\(%r2,%r12\)
+ +8a0: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD against hidden and local variable
+ +8a4: e3 20 d0 20 00 04 lg %r2,32\(%r13\)
+ +8aa: c0 e5 ff ff ff 63 brasl %r14,770 <sH8\+0x6f4>
+ +8b0: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE against hidden and local variable referenced through
+# IE too
+ +8b4: e3 20 d0 28 00 04 lg %r2,40\(%r13\)
+ +8ba: e3 22 c0 00 00 04 lg %r2,0\(%r2,%r12\)
+ +8c0: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD against hidden but not local variable
+ +8c4: e3 20 d0 30 00 04 lg %r2,48\(%r13\)
+ +8ca: c0 e5 ff ff ff 53 brasl %r14,770 <sH8\+0x6f4>
+ +8d0: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# GD -> IE against hidden but not local variable referenced through
+# IE too
+ +8d4: e3 20 d0 38 00 04 lg %r2,56\(%r13\)
+ +8da: e3 22 c0 00 00 04 lg %r2,0\(%r2,%r12\)
+ +8e0: 41 22 90 00 la %r2,0\(%r2,%r9\)
+# LD
+ +8e4: e3 20 d0 40 00 04 lg %r2,64\(%r13\)
+ +8ea: c0 e5 ff ff ff 43 brasl %r14,770 <sH8\+0x6f4>
+ +8f0: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +8f4: e3 40 d0 48 00 04 lg %r4,72\(%r13\)
+ +8fa: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +8fe: e3 40 d0 50 00 04 lg %r4,80\(%r13\)
+ +904: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# LD against hidden and local variables
+ +908: e3 20 d0 58 00 04 lg %r2,88\(%r13\)
+ +90e: c0 e5 ff ff ff 31 brasl %r14,770 <sH8\+0x6f4>
+ +914: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +918: e3 40 d0 60 00 04 lg %r4,96\(%r13\)
+ +91e: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +922: e3 40 d0 68 00 04 lg %r4,104\(%r13\)
+ +928: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# LD against hidden but not local variables
+ +92c: e3 20 d0 70 00 04 lg %r2,112\(%r13\)
+ +932: c0 e5 ff ff ff 1f brasl %r14,770 <sH8\+0x6f4>
+ +938: 41 32 90 00 la %r3,0\(%r2,%r9\)
+ +93c: e3 40 d0 78 00 04 lg %r4,120\(%r13\)
+ +942: 41 54 30 00 la %r5,0\(%r4,%r3\)
+ +946: e3 40 d0 80 00 04 lg %r4,128\(%r13\)
+ +94c: 41 54 30 00 la %r5,0\(%r4,%r3\)
+# IE against global var
+ +950: e3 30 d0 88 00 04 lg %r3,136\(%r13\)
+ +956: e3 33 c0 00 00 04 lg %r3,0\(%r3,%r12\)
+ +95c: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against local var
+ +960: e3 30 d0 90 00 04 lg %r3,144\(%r13\)
+ +966: e3 43 c0 00 00 04 lg %r4,0\(%r3,%r12\)
+ +96c: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against hidden and local var
+ +970: e3 30 d0 98 00 04 lg %r3,152\(%r13\)
+ +976: e3 43 c0 00 00 04 lg %r4,0\(%r3,%r12\)
+ +97c: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against hidden but not local var
+ +980: e3 30 d0 a0 00 04 lg %r3,160\(%r13\)
+ +986: e3 43 c0 00 00 04 lg %r4,0\(%r3,%r12\)
+ +98c: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against global var with larl got access
+ +990: c0 30 00 00 09 34 larl %r3,1bf8 <\_GLOBAL\_OFFSET\_TABLE\_\+0x68>
+ +996: e3 33 c0 00 00 04 lg %r3,0\(%r3,%r12\)
+ +99c: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against local var with larl got access
+ +9a0: c0 30 00 00 09 14 larl %r3,1bc8 <\_GLOBAL\_OFFSET\_TABLE\_\+0x38>
+ +9a6: e3 43 c0 00 00 04 lg %r4,0\(%r3,%r12\)
+ +9ac: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against hidden and local var with larl got access
+ +9b0: c0 30 00 00 09 30 larl %r3,1c10 <\_GLOBAL\_OFFSET\_TABLE\_\+0x80>
+ +9b6: e3 43 c0 00 00 04 lg %r4,0\(%r3,%r12\)
+ +9bc: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against hidden but not local var with larl got access
+ +9c0: c0 30 00 00 09 2c larl %r3,1c18 <\_GLOBAL\_OFFSET\_TABLE\_\+0x88>
+ +9c6: e3 43 c0 00 00 04 lg %r4,0\(%r3,%r12\)
+ +9cc: 41 54 90 00 la %r5,0\(%r4,%r9\)
+# IE against global var with small got access (no optimization)
+ +9d0: e3 30 c0 68 00 04 lg %r3,104\(%r12\)
+ +9d6: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against local var with small got access (no optimization)
+ +9da: e3 30 c0 38 00 04 lg %r3,56\(%r12\)
+ +9e0: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against hidden and local var with small got access
+# (no optimization)
+ +9e4: e3 30 c0 80 00 04 lg %r3,128\(%r12\)
+ +9ea: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# IE against hidden but not local var with small got access
+# (no optimization)
+ +9ee: e3 30 c0 88 00 04 lg %r3,136\(%r12\)
+ +9f4: 41 33 90 00 la %r3,0\(%r3,%r9\)
+# function epilog
+ +9f8: eb 6e f0 d0 00 04 lmg %r6,%r14,208\(%r15\)
+ +9fe: 07 fe br %r14
diff -urN src/ld/testsuite/ld-s390/tlspic_64.rd src-s390/ld/testsuite/ld-s390/tlspic_64.rd
--- src/ld/testsuite/ld-s390/tlspic_64.rd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic_64.rd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,165 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#readelf: -WSsrl
+#target: s390x-*-*
+
+There are 18 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+ \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ \[ 1\] .hash +.*
+ \[ 2\] .dynsym +.*
+ \[ 3\] .dynstr +.*
+ \[ 4\] .rela.dyn +.*
+ \[ 5\] .rela.plt +.*
+ \[ 6\] .plt +.*
+ \[ 7\] .text +PROGBITS +0+790 0+790 0+270 00 +AX +0 +0 +4
+ \[ 8\] .data +.*
+ \[ 9\] .tdata +PROGBITS +0+1a00 0+a00 0+60 00 WAT +0 +0 +1
+ \[10\] .tbss +NOBITS +0+1a60 0+a60 0+20 00 WAT +0 +0 +1
+ \[11\] .dynamic +DYNAMIC +0+1a60 0+a60 0+130 10 +WA +3 +0 +8
+ \[12\] .got +PROGBITS +0+1b90 0+b90 0+b0 08 +WA +0 +0 +8
+ \[13\] .sbss +.*
+ \[14\] .bss +.*
+ \[15\] .shstrtab +.*
+ \[16\] .symtab +.*
+ \[17\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x790
+There are 4 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ LOAD +0x0+ 0x0+ 0x0+ 0x[0-9a-f]+ 0x[0-9a-f]+ R E 0x1000
+ LOAD +0x0+a00 0x0+1a00 0x0+1a00 0x0+240 0x0+240 RW +0x1000
+ DYNAMIC +0x0+a60 0x0+1a60 0x0+1a60 0x0+130 0x0+130 RW +0x8
+ TLS +0x0+a00 0x0+1a00 0x0+1a00 0x0+60 0x0+80 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+ 01 +.tdata .tbss .dynamic .got *
+ 02 +.tbss .dynamic *
+ 03 +.tdata .tbss *
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 14 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+[0-9a-z]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-z]+ 0+38 R_390_TLS_TPOFF +0+24
+[0-9a-z]+ 0+38 R_390_TLS_TPOFF +0+30
+[0-9a-z]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-z]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-z]+ 0+38 R_390_TLS_TPOFF +0+64
+[0-9a-z]+ 0+38 R_390_TLS_TPOFF +0+50
+[0-9a-z]+ 0+38 R_390_TLS_TPOFF +0+70
+[0-9a-z]+ 0+36 R_390_TLS_DTPMOD +0+
+[0-9a-z]+ 0+38 R_390_TLS_TPOFF +0+44
+[0-9a-z]+ 0+130+38 R_390_TLS_TPOFF +0+10 sg5 \+ 0
+[0-9a-z]+ 0+150+36 R_390_TLS_DTPMOD +0+ sg1 \+ 0
+[0-9a-z]+ 0+150+37 R_390_TLS_DTPOFF +0+ sg1 \+ 0
+[0-9a-z]+ 0+180+38 R_390_TLS_TPOFF +0+4 sg2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x738 contains 1 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+0+1ba8 0+140+b R_390_JMP_SLOT +0+ __tls_get_offset \+ 0
+
+Symbol table '.dynsym' contains 30 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND
+ +1: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +1
+ +2: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +2
+ +3: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +3
+ +4: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +4
+ +5: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +5
+ +6: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +6
+ +7: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +7
+ +8: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +8
+ +9: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +9
+ +10: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +10
+ +11: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +11
+ +12: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +12
+ +13: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +13
+ +14: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +14
+ +15: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +16: [0-9a-z]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +17: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +18: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +19: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +20: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_offset
+ +21: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +22: [0-9a-z]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +23: [0-9a-z]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +24: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +25: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +26: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +27: [0-9a-z]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +28: [0-9a-z]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +29: 0+1c40 +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 57 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND
+ +1: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +1
+ +2: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +2
+ +3: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +3
+ +4: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +4
+ +5: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +5
+ +6: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +6
+ +7: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +7
+ +8: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +8
+ +9: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +9
+ +10: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +10
+ +11: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +11
+ +12: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +12
+ +13: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +13
+ +14: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +14
+ +15: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +15
+ +16: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +16
+ +17: [0-9a-z]+ +0 SECTION LOCAL DEFAULT +17
+ +18: 0+20 +0 TLS +LOCAL DEFAULT +9 sl1
+ +19: 0+24 +0 TLS +LOCAL DEFAULT +9 sl2
+ +20: 0+28 +0 TLS +LOCAL DEFAULT +9 sl3
+ +21: 0+2c +0 TLS +LOCAL DEFAULT +9 sl4
+ +22: 0+30 +0 TLS +LOCAL DEFAULT +9 sl5
+ +23: 0+34 +0 TLS +LOCAL DEFAULT +9 sl6
+ +24: 0+38 +0 TLS +LOCAL DEFAULT +9 sl7
+ +25: 0+3c +0 TLS +LOCAL DEFAULT +9 sl8
+ +26: 0+60 +0 TLS +LOCAL HIDDEN +10 sH1
+ +27: 0+48 +0 TLS +LOCAL HIDDEN +9 sh3
+ +28: 0+64 +0 TLS +LOCAL HIDDEN +10 sH2
+ +29: 0+78 +0 TLS +LOCAL HIDDEN +10 sH7
+ +30: 0+58 +0 TLS +LOCAL HIDDEN +9 sh7
+ +31: 0+5c +0 TLS +LOCAL HIDDEN +9 sh8
+ +32: 0+6c +0 TLS +LOCAL HIDDEN +10 sH4
+ +33: 0+4c +0 TLS +LOCAL HIDDEN +9 sh4
+ +34: 0+68 +0 TLS +LOCAL HIDDEN +10 sH3
+ +35: 0+50 +0 TLS +LOCAL HIDDEN +9 sh5
+ +36: 0+70 +0 TLS +LOCAL HIDDEN +10 sH5
+ +37: 0+74 +0 TLS +LOCAL HIDDEN +10 sH6
+ +38: 0+7c +0 TLS +LOCAL HIDDEN +10 sH8
+ +39: 0+40 +0 TLS +LOCAL HIDDEN +9 sh1
+ +40: 0+44 +0 TLS +LOCAL HIDDEN +9 sh2
+ +41: 0+54 +0 TLS +LOCAL HIDDEN +9 sh6
+ +42: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +43: [0-9a-z]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +44: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +45: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +46: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +47: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_offset
+ +48: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +49: [0-9a-z]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +50: [0-9a-z]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +51: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +52: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +53: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +54: [0-9a-z]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +55: [0-9a-z]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +56: [0-9a-z]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
diff -urN src/ld/testsuite/ld-s390/tlspic_64.sd src-s390/ld/testsuite/ld-s390/tlspic_64.sd
--- src/ld/testsuite/ld-s390/tlspic_64.sd Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic_64.sd Thu Jan 23 23:23:13 2003
@@ -0,0 +1,21 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#objdump: -sj.got
+#target: s390x-*-*
+
+.*: +file format elf64-s390
+
+Contents of section .got:
+ 1b90 [0-9a-f]+ [0-9a-f]+ 00000000 00000000 .*
+ 1ba0 00000000 00000000 [0-9a-f]+ [0-9a-f]+ .*
+ 1bb0 00000000 00000000 00000000 00000020 .*
+ 1bc0 00000000 00000000 00000000 00000000 .*
+ 1bd0 00000000 00000000 00000000 00000000 .*
+ 1be0 00000000 00000000 00000000 00000060 .*
+ 1bf0 00000000 00000000 00000000 00000000 .*
+ 1c00 00000000 00000000 00000000 00000000 .*
+ 1c10 00000000 00000000 00000000 00000000 .*
+ 1c20 00000000 00000000 00000000 00000000 .*
+ 1c30 00000000 00000040 00000000 00000000 .*
diff -urN src/ld/testsuite/ld-s390/tlspic_64.td src-s390/ld/testsuite/ld-s390/tlspic_64.td
--- src/ld/testsuite/ld-s390/tlspic_64.td Thu Jan 1 01:00:00 1970
+++ src-s390/ld/testsuite/ld-s390/tlspic_64.td Thu Jan 23 23:23:13 2003
@@ -0,0 +1,16 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -m64 -Aesame
+#ld: -shared -melf64_s390
+#objdump: -sj.tdata
+#target: s390x-*-*
+
+.*: +file format elf64-s390
+
+Contents of section .tdata:
+ 1a00 00000011 00000012 00000013 00000014 .*
+ 1a10 00000015 00000016 00000017 00000018 .*
+ 1a20 00000041 00000042 00000043 00000044 .*
+ 1a30 00000045 00000046 00000047 00000048 .*
+ 1a40 00000101 00000102 00000103 00000104 .*
+ 1a50 00000105 00000106 00000107 00000108 .*