This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH/RFA] SH TLS support (Revised)
- From: kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: binutils at sources dot redhat dot com
- Date: Sat, 05 Oct 2002 14:58:14 +0900
- Subject: [PATCH/RFA] SH TLS support (Revised)
Hi,
Ulrich Drepper pointed out to me that some SH TLS relocations can be
removed. By this, only 8 TLS relocations are required and ld/gas
changes can be simplified a little bit. Here is a revised patch for
SH TLS support. Regtested on sh-unknown-linux-gnu and sh64-unknown-elf.
Sorry for sending a relatively large patch twice.
Regards,
kaz
--
2002-10-05 Kaz Kojima <kkojima@rr.iij4u.or.jp>
[bfd/ChangeLog]
* elf32-sh-lin.c (USE_SH_TLS32): Define.
* elf32-sh.c (sh_elf_tls_transition, sh_elf_mkobject,
sh_elf_object_p, dtpoff_base): New functions.
(sh_elf_howto_table): Add TLS relocs.
(sh_reloc_map): Likewise.
(sh_elf_info_to_howto): Support TLS relocs.
(elf_sh_link_hash_entry): Add tls_type and tls_tpoff32.
(sh_elf_hash_entry, sh_elf_tdata, sh_elf_local_got_tls_type):
New macros.
(sh_elf_obj_tdata): New.
(elf_sh_link_hash_table): Add tls_ldm_got.
(sh_elf_link_hash_table_create): Clear refcount of tls_ldm_got.
(allocate_dynrelocs): Support TLS relocs.
(sh_elf_size_dynamic_sections): Likewise.
(sh_elf_relocate_section): Likewise.
(sh_elf_gc_sweep_hook): Likewise.
(sh_elf_check_relocs): Likewise.
(sh_elf_finish_dynamic_symbol): Likewise.
(bfd_elf32_mkobject, elf_backend_object_p): Define for TLS case.
* reloc.c: Add SH TSL relocs.
[gas/ChangeLog]
* config/tc-sh.c (md_apply_fix3): Add TLS relocs.
(sh_parse_name): Support @TLSGD, @TLSLDM, @GOTTPOFF, @TPOFF and
@DTPOFF.
[include/ChangeLog]
* elf/sh.h: Add SH TLS relocs.
[gas/testsuite/ChangeLog]
* gas/sh/tlsd.s, gas/sh/tlsd.d: New.
* gas/sh/tlsnopic.s, gas/sh/tlsnopic.d: New.
* gas/sh/tlspic.s, gas/sh/tlspic.d: New.
* gas/sh/basic.exp: Add new tests.
[ld/testsuite/ChangeLog]
* ld-sh/sh-tls.exp: New.
* ld-sh/tlsbin.s, ld-sh/tlsbinpic.s, ld-sh/tlslib.s: New.
* ld-sh/tlsbin.dd: New.
* ld-sh/tlsbin.rd: New.
* ld-sh/tlsbin.sd: New.
* ld-sh/tlsbin.td: New.
* ld-sh/tlspic1.s, ld-sh/tlspic2.s: New.
* ld-sh/tlspic.dd: New.
* ld-sh/tlspic.rd: New.
* ld-sh/tlspic.sd: New.
* ld-sh/tlspic.td: New.
diff -urN ORIG/src/bfd/elf32-sh-lin.c LOCAL/src/bfd/elf32-sh-lin.c
--- ORIG/src/bfd/elf32-sh-lin.c Tue Sep 18 18:57:24 2001
+++ LOCAL/src/bfd/elf32-sh-lin.c Sat Oct 5 13:54:49 2002
@@ -105,6 +105,6 @@
#define elf_backend_grok_prstatus elf32_shlin_grok_prstatus
#define elf_backend_grok_psinfo elf32_shlin_grok_psinfo
-
+#define USE_SH_TLS32
#include "elf32-sh.c"
diff -urN ORIG/src/bfd/elf32-sh.c LOCAL/src/bfd/elf32-sh.c
--- ORIG/src/bfd/elf32-sh.c Thu Oct 3 06:53:40 2002
+++ LOCAL/src/bfd/elf32-sh.c Sat Oct 5 13:57:19 2002
@@ -59,6 +59,14 @@
static void sh_elf_copy_indirect_symbol
PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *));
+#ifdef USE_SH_TLS32
+static int sh_elf_tls_transition
+ PARAMS ((struct bfd_link_info *, int, int));
+static boolean sh_elf_mkobject
+ PARAMS((bfd *));
+static boolean sh_elf_object_p
+ PARAMS((bfd *));
+#endif
static boolean sh_elf_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
@@ -82,6 +90,10 @@
PARAMS((bfd *, struct bfd_link_info *));
static boolean sh_elf_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
+#ifdef USE_SH_TLS32
+static bfd_vma dtpoff_base
+ PARAMS ((struct bfd_link_info *));
+#endif
static asection * sh_elf_gc_mark_hook
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *, Elf_Internal_Sym *));
@@ -713,6 +725,120 @@
EMPTY_HOWTO (141),
EMPTY_HOWTO (142),
EMPTY_HOWTO (143),
+
+#ifdef USE_SH_TLS32
+ HOWTO (R_SH_TLS_GD_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_GD_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_LD_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_LD_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_LDO_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_LDO_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_IE_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_IE_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_LE_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_LE_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_DTPMOD32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_DTPMOD32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_DTPOFF32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_DTPOFF32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_TPOFF32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_SH_TLS_TPOFF32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+#else
EMPTY_HOWTO (144),
EMPTY_HOWTO (145),
EMPTY_HOWTO (146),
@@ -721,6 +847,8 @@
EMPTY_HOWTO (149),
EMPTY_HOWTO (150),
EMPTY_HOWTO (151),
+#endif
+
EMPTY_HOWTO (152),
EMPTY_HOWTO (153),
EMPTY_HOWTO (154),
@@ -1776,6 +1904,16 @@
{ BFD_RELOC_VTABLE_ENTRY, R_SH_GNU_VTENTRY },
{ BFD_RELOC_SH_LOOP_START, R_SH_LOOP_START },
{ BFD_RELOC_SH_LOOP_END, R_SH_LOOP_END },
+#ifdef USE_SH_TLS32
+ { BFD_RELOC_SH_TLS_GD_32, R_SH_TLS_GD_32 },
+ { BFD_RELOC_SH_TLS_LD_32, R_SH_TLS_LD_32 },
+ { BFD_RELOC_SH_TLS_LDO_32, R_SH_TLS_LDO_32 },
+ { BFD_RELOC_SH_TLS_IE_32, R_SH_TLS_IE_32 },
+ { BFD_RELOC_SH_TLS_LE_32, R_SH_TLS_LE_32 },
+ { BFD_RELOC_SH_TLS_DTPMOD32, R_SH_TLS_DTPMOD32 },
+ { BFD_RELOC_SH_TLS_DTPOFF32, R_SH_TLS_DTPOFF32 },
+ { BFD_RELOC_SH_TLS_TPOFF32, R_SH_TLS_TPOFF32 },
+#endif
{ BFD_RELOC_32_GOT_PCREL, R_SH_GOT32 },
{ BFD_RELOC_32_PLT_PCREL, R_SH_PLT32 },
{ BFD_RELOC_SH_COPY, R_SH_COPY },
@@ -1873,7 +2011,10 @@
BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_2 || r > R_SH_LAST_INVALID_RELOC_2);
BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_LAST_INVALID_RELOC_3);
+#ifdef USE_SH_TLS32
BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
+#endif
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_5 || r > R_SH_LAST_INVALID_RELOC_5);
cache_ptr->howto = &sh_elf_howto_table[r];
}
@@ -3390,8 +3531,46 @@
struct elf_sh_dyn_relocs *dyn_relocs;
bfd_signed_vma gotplt_refcount;
+
+#ifdef USE_SH_TLS32
+ enum {
+ GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE
+ } tls_type;
+
+ /* If true, R_SH_TLS_TPOFF32 relocation is generated. */
+ boolean tls_tpoff32;
+#endif
};
+#ifdef USE_SH_TLS32
+#define sh_elf_hash_entry(ent) ((struct elf_sh_link_hash_entry *)(ent))
+
+struct sh_elf_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define sh_elf_tdata(abfd) \
+ ((struct sh_elf_obj_tdata *) (abfd)->tdata.any)
+
+#define sh_elf_local_got_tls_type(abfd) \
+ (sh_elf_tdata (abfd)->local_got_tls_type)
+
+static boolean
+sh_elf_mkobject (abfd)
+ bfd *abfd;
+{
+ bfd_size_type amt = sizeof (struct sh_elf_obj_tdata);
+ abfd->tdata.any = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.any == NULL)
+ return false;
+ return true;
+}
+#endif
+
/* sh ELF linker hash table. */
struct elf_sh_link_hash_table
@@ -3409,6 +3588,15 @@
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
+
+#ifdef USE_SH_TLS32
+ /* A counter or offset to track a TLS got entry. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+#endif
};
/* Traverse an sh ELF linker hash table. */
@@ -3458,6 +3646,10 @@
#ifdef INCLUDE_SHMEDIA
ret->datalabel_got_offset = (bfd_vma) -1;
#endif
+#ifdef USE_SH_TLS32
+ ret->tls_type = GOT_UNKNOWN;
+ ret->tls_tpoff32 = false;
+#endif
}
return (struct bfd_hash_entry *) ret;
@@ -3491,6 +3683,9 @@
ret->sdynbss = NULL;
ret->srelbss = NULL;
ret->sym_sec.abfd = NULL;
+#ifdef USE_SH_TLS32
+ ret->tls_ldm_got.refcount = 0;
+#endif
return &ret->root.root;
}
@@ -3943,6 +4138,9 @@
{
asection *s;
boolean dyn;
+#ifdef USE_SH_TLS32
+ int tls_type = sh_elf_hash_entry(h)->tls_type;
+#endif
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
@@ -3969,9 +4167,26 @@
h->got.offset = s->_raw_size;
#endif
s->_raw_size += 4;
+#ifdef USE_SH_TLS32
+ /* R_SH_TLS_GD needs 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->_raw_size += 4;
+#endif
dyn = htab->root.dynamic_sections_created;
+#ifdef USE_SH_TLS32
+ /* R_SH_TLS_IE_32 needs one dynamic relocation,
+ R_SH_TLS_GD 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
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+#endif
}
else
h->got.offset = (bfd_vma) -1;
@@ -4006,6 +4221,11 @@
}
else
{
+#ifdef USE_SH_TLS32
+ if (sh_elf_hash_entry(h)->tls_tpoff32)
+ goto keep;
+#endif
+
/* For the non-shared case, discard space for relocs against
symbols which turn out to need copy relocs or are not
dynamic. */
@@ -4113,6 +4333,9 @@
{
bfd_signed_vma *local_got;
bfd_signed_vma *end_local_got;
+#ifdef USE_SH_TLS32
+ char *local_tls_type;
+#endif
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
asection *srel;
@@ -4158,6 +4381,9 @@
locsymcount *= 2;
#endif
end_local_got = local_got + locsymcount;
+#ifdef USE_SH_TLS32
+ local_tls_type = sh_elf_local_got_tls_type (ibfd);
+#endif
s = htab->sgot;
srel = htab->srelgot;
for (; local_got < end_local_got; ++local_got)
@@ -4166,14 +4392,34 @@
{
*local_got = s->_raw_size;
s->_raw_size += 4;
+#ifdef USE_SH_TLS32
+ if (*local_tls_type == GOT_TLS_GD)
+ s->_raw_size += 4;
+#endif
if (info->shared)
srel->_raw_size += sizeof (Elf32_External_Rela);
}
else
*local_got = (bfd_vma) -1;
+#ifdef USE_SH_TLS32
+ ++local_tls_type;
+#endif
}
}
+#ifdef USE_SH_TLS32
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_SH_TLS_LD_32
+ relocs. */
+ htab->tls_ldm_got.offset = htab->sgot->_raw_size;
+ htab->sgot->_raw_size += 8;
+ htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+#endif
+
/* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */
elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info);
@@ -4309,6 +4555,7 @@
asection *sgotplt;
asection *splt;
asection *sreloc;
+ asection *srelgot;
htab = sh_elf_hash_table (info);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -4320,6 +4567,7 @@
sgotplt = htab->sgotplt;
splt = htab->splt;
sreloc = NULL;
+ srelgot = NULL;
rel = relocs;
relend = relocs + input_section->reloc_count;
@@ -4335,6 +4583,10 @@
bfd_vma addend = (bfd_vma) 0;
bfd_reloc_status_type r;
int seen_stt_datalabel = 0;
+ bfd_vma off;
+#ifdef USE_SH_TLS32
+ int tls_type;
+#endif
r_symndx = ELF32_R_SYM (rel->r_info);
@@ -4354,8 +4606,12 @@
&& r_type <= (int) R_SH_LAST_INVALID_RELOC)
|| ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_3
&& r_type <= (int) R_SH_LAST_INVALID_RELOC_3)
+#ifdef USE_SH_TLS32
|| ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
&& r_type <= (int) R_SH_LAST_INVALID_RELOC_4)
+#endif
+ || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_5
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC_5)
|| (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
&& r_type <= (int) R_SH_LAST_INVALID_RELOC_2))
{
@@ -4526,7 +4782,13 @@
with them here. */
|| ((input_section->flags & SEC_DEBUGGING) != 0
&& (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_DYNAMIC) != 0))))
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))
+#ifdef USE_SH_TLS32
+ || (sec->output_section == NULL
+ && (sh_elf_hash_entry(h)->tls_type == GOT_TLS_IE
+ || sh_elf_hash_entry(h)->tls_type == GOT_TLS_GD))
+#endif
+ )
relocation = 0;
else if (sec->output_section == NULL)
{
@@ -4534,7 +4796,7 @@
(_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
bfd_archive_filename (input_bfd), h->root.root.string,
bfd_get_section_name (input_bfd, input_section));
- relocation = 0;
+ return false;
}
else
relocation = ((h->root.u.def.value
@@ -4779,7 +5041,6 @@
if (h != NULL)
{
- bfd_vma off;
boolean dyn;
off = h->got.offset;
@@ -4837,8 +5098,6 @@
}
else
{
- bfd_vma off;
-
#ifdef INCLUDE_SHMEDIA
if (rel->r_addend)
{
@@ -4872,11 +5131,14 @@
if (info->shared)
{
- asection *srelgot;
Elf_Internal_Rela outrel;
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
- BFD_ASSERT (srelgot != NULL);
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_get_section_by_name (dynobj,
+ ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+ }
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
@@ -5010,6 +5272,452 @@
rel->r_offset, sec, start, end);
break;
}
+
+#ifdef USE_SH_TLS32
+ case R_SH_TLS_GD_32:
+ case R_SH_TLS_IE_32:
+ r_type = sh_elf_tls_transition (info, r_type, h == NULL);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = sh_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = sh_elf_hash_entry(h)->tls_type;
+ if (! info->shared
+ && (h->dynindx == -1
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ && (tls_type == GOT_TLS_IE
+ || sh_elf_hash_entry(h)->tls_tpoff32))
+ r_type = R_SH_TLS_LE_32;
+ }
+
+ if (r_type == R_SH_TLS_GD_32 && tls_type == GOT_TLS_IE)
+ r_type = R_SH_TLS_IE_32;
+
+ if (r_type == R_SH_TLS_LE_32)
+ {
+ bfd_vma offset;
+ unsigned short insn;
+ int indx;
+ Elf_Internal_Rela outrel;
+
+ if (ELF32_R_TYPE (rel->r_info) == R_SH_TLS_GD_32)
+ {
+ /* GD->LE transition:
+ mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+ jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+ 1: .long x$TLSGD; 2: .long __tls_get_addr@PLT; 3:
+ We change it into:
+ mov.l 1f,r4; stc gbr,r0; add r4,r0; nop;
+ nop; nop; ...
+ 1: .long x@TPOFF; 2: .long __tls_get_addr@PLT; 3:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of GD instructions is 16 or 18. */
+ offset -= 16;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xff00) == 0xc700)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd400);
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xff00) == 0xc700);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xff00) == 0xd100);
+ insn = bfd_get_16 (input_bfd, contents + offset + 6);
+ BFD_ASSERT (insn == 0x310c);
+ insn = bfd_get_16 (input_bfd, contents + offset + 8);
+ BFD_ASSERT (insn == 0x410b);
+ insn = bfd_get_16 (input_bfd, contents + offset + 10);
+ BFD_ASSERT (insn == 0x34cc);
+
+ bfd_put_16 (output_bfd, 0x0012, contents + offset + 2);
+ bfd_put_16 (output_bfd, 0x304c, contents + offset + 4);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+ }
+ else
+ {
+ int index;
+
+ /* IE->LE transition:
+ mov.l 1f,r0; stc gbr,rN; mov.l @(r0,r12),rM;
+ bra 2f; add ...; .align 2; 1: x@GOTTPOFF; 2:
+ We change it into:
+ mov.l .Ln,rM; stc gbr,rN; nop; ...;
+ 1: x@TPOFF; 2:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of IE instructions is 10 or 12. */
+ offset -= 10;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xf0ff) == 0x0012)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd000);
+ index = insn & 0x00ff;
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xf0ff) == 0x0012);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xf0ff) == 0x00ce);
+ insn = 0xd000 | (insn & 0x0f00) | index;
+ bfd_put_16 (output_bfd, insn, contents + offset + 0);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
+ }
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ continue;
+ }
+
+ sgot = htab->sgot;
+ if (sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ }
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ Elf32_External_Rela *loc;
+ int dr_type, indx;
+
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+ }
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + off);
+
+ indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+ dr_type = (r_type == R_SH_TLS_GD_32 ? R_SH_TLS_DTPMOD32 :
+ R_SH_TLS_TPOFF32);
+ if (dr_type == R_SH_TLS_TPOFF32 && indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (indx, dr_type);
+ loc = (Elf32_External_Rela *) srelgot->contents;
+ loc += srelgot->reloc_count++;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (r_type == R_SH_TLS_GD_32)
+ {
+ if (indx == 0)
+ {
+ bfd_put_32 (output_bfd,
+ relocation - dtpoff_base (info),
+ sgot->contents + off + 4);
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_SH_TLS_DTPOFF32);
+ outrel.r_offset += 4;
+ outrel.r_addend = 0;
+ srelgot->reloc_count++;
+ loc++;
+ 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 == (int) ELF32_R_TYPE (rel->r_info))
+ relocation = sgot->output_offset + off;
+ else
+ {
+ bfd_vma offset;
+ unsigned short insn;
+
+ /* GD->IE transition:
+ mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+ jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+ 1: .long x$TLSGD; 2: .long __tls_get_addr@PLT; 3:
+ We change it into:
+ mov.l 1f,r0; stc gbr,r4; mov.l @(r0,r12),r0; add r4,r0;
+ nop; nop; bra 3f; nop; .align 2;
+ 1: .long x@TPOFF; 2:...; 3:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of GD instructions is 16 or 18. */
+ offset -= 16;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xff00) == 0xc700)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd400);
+
+ /* Replace mov.l 1f,R4 with mov.l 1f,r0. */
+ bfd_put_16 (output_bfd, insn & 0xf0ff, contents + offset);
+
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xff00) == 0xc700);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xff00) == 0xd100);
+ insn = bfd_get_16 (input_bfd, contents + offset + 6);
+ BFD_ASSERT (insn == 0x310c);
+ insn = bfd_get_16 (input_bfd, contents + offset + 8);
+ BFD_ASSERT (insn == 0x410b);
+ insn = bfd_get_16 (input_bfd, contents + offset + 10);
+ BFD_ASSERT (insn == 0x34cc);
+
+ bfd_put_16 (output_bfd, 0x0412, contents + offset + 2);
+ bfd_put_16 (output_bfd, 0x00ce, contents + offset + 4);
+ bfd_put_16 (output_bfd, 0x304c, contents + offset + 6);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+
+ bfd_put_32 (output_bfd, sgot->output_offset + off,
+ contents + rel->r_offset);
+
+ continue;
+ }
+
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_TLS_LD_32:
+ if (! info->shared)
+ {
+ bfd_vma offset;
+ unsigned short insn;
+
+ /* LD->LE transition:
+ mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+ jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+ 1: .long x$TLSLD; 2: .long __tls_get_addr@PLT; 3:
+ We change it into:
+ stc gbr,r0; nop; nop; nop;
+ nop; nop; bra 3f; ...; 3:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of LD instructions is 16 or 18. */
+ offset -= 16;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xff00) == 0xc700)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd400);
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xff00) == 0xc700);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xff00) == 0xd100);
+ insn = bfd_get_16 (input_bfd, contents + offset + 6);
+ BFD_ASSERT (insn == 0x310c);
+ insn = bfd_get_16 (input_bfd, contents + offset + 8);
+ BFD_ASSERT (insn == 0x410b);
+ insn = bfd_get_16 (input_bfd, contents + offset + 10);
+ BFD_ASSERT (insn == 0x34cc);
+
+ bfd_put_16 (output_bfd, 0x0012, contents + offset + 0);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 2);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+
+ continue;
+ }
+
+ sgot = htab->sgot;
+ if (sgot == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ Elf32_External_Rela *loc;
+
+ srelgot = htab->srelgot;
+ if (srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + off);
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (0, R_SH_TLS_DTPMOD32);
+ loc = (Elf32_External_Rela *) srelgot->contents;
+ loc += srelgot->reloc_count++;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+
+ relocation = sgot->output_offset + off;
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_TLS_LDO_32:
+ if (! info->shared)
+ {
+ int indx;
+ Elf_Internal_Rela outrel;
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ continue;
+ }
+ else
+ relocation -= dtpoff_base (info);
+
+ addend = rel->r_addend;
+ goto final_link_relocate;
+
+ case R_SH_TLS_LE_32:
+ {
+ int indx;
+ Elf_Internal_Rela outrel;
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ continue;
+ }
+#endif
}
relocation_done:
@@ -5157,6 +5865,22 @@
return NULL;
}
+#ifdef USE_SH_TLS32
+/* 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;
+}
+#endif
+
static asection *
sh_elf_gc_mark_hook (sec, info, rel, h, sym)
asection *sec;
@@ -5224,8 +5948,21 @@
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
+#ifdef USE_SH_TLS32
+ switch (sh_elf_tls_transition (info, ELF32_R_TYPE (rel->r_info),
+ ELF32_R_SYM (rel->r_info)
+ >= symtab_hdr->sh_info))
+#else
switch (ELF32_R_TYPE (rel->r_info))
+#endif
{
+#ifdef USE_SH_TLS32
+ case R_SH_TLS_LD_32:
+ if (sh_elf_hash_table (info)->tls_ldm_got.refcount > 0)
+ sh_elf_hash_table (info)->tls_ldm_got.refcount -= 1;
+ break;
+#endif
+
case R_SH_GOT32:
case R_SH_GOTOFF:
case R_SH_GOTPC:
@@ -5245,6 +5982,10 @@
case R_SH_GOTPC_MEDHI16:
case R_SH_GOTPC_HI16:
#endif
+#ifdef USE_SH_TLS32
+ case R_SH_TLS_GD_32:
+ case R_SH_TLS_IE_32:
+#endif
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
@@ -5388,9 +6129,42 @@
edir->gotplt_refcount = eind->gotplt_refcount;
eind->gotplt_refcount = 0;
+#ifdef USE_SH_TLS32
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+#endif
_bfd_elf_link_hash_copy_indirect (bed, dir, ind);
}
+#ifdef USE_SH_TLS32
+static int
+sh_elf_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_SH_TLS_GD_32:
+ case R_SH_TLS_IE_32:
+ if (is_local)
+ return R_SH_TLS_LE_32;
+ return R_SH_TLS_IE_32;
+ case R_SH_TLS_LD_32:
+ return R_SH_TLS_LE_32;
+ }
+
+ return r_type;
+}
+#endif
+
/* Look through the relocs for a section during the first phase.
Since we don't do .gots or .plts, we just need to consider the
virtual table relocs for gc. */
@@ -5412,6 +6186,10 @@
asection *sgot;
asection *srelgot;
asection *sreloc;
+ unsigned int r_type;
+#ifdef USE_SH_TLS32
+ int tls_type, old_tls_type;
+#endif
sgot = NULL;
srelgot = NULL;
@@ -5437,15 +6215,29 @@
unsigned long r_symndx;
r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+#ifdef USE_SH_TLS32
+ r_type = sh_elf_tls_transition (info, r_type, h == NULL);
+ if (! info->shared
+ && r_type == R_SH_TLS_IE_32
+ && h != NULL
+ && h->root.type != bfd_link_hash_undefined
+ && h->root.type != bfd_link_hash_undefweak
+ && (h->dynindx == -1
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ r_type = R_SH_TLS_LE_32;
+#endif
+
/* Some relocs require a global offset table. */
if (htab->sgot == NULL)
{
- switch (ELF32_R_TYPE (rel->r_info))
+ switch (r_type)
{
case R_SH_GOTPLT32:
case R_SH_GOT32:
@@ -5473,6 +6265,11 @@
case R_SH_GOTPC_MEDHI16:
case R_SH_GOTPC_HI16:
#endif
+#ifdef USE_SH_TLS32
+ case R_SH_TLS_GD_32:
+ case R_SH_TLS_LD_32:
+ case R_SH_TLS_IE_32:
+#endif
if (dynobj == NULL)
htab->root.dynobj = dynobj = abfd;
if (! create_got_section (dynobj, info))
@@ -5484,7 +6281,7 @@
}
}
- switch (ELF32_R_TYPE (rel->r_info))
+ switch (r_type)
{
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
@@ -5501,6 +6298,13 @@
break;
force_got:
+#ifdef USE_SH_TLS32
+ case R_SH_TLS_IE_32:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* FALLTHROUGH */
+ case R_SH_TLS_GD_32:
+#endif
case R_SH_GOT32:
#ifdef INCLUDE_SHMEDIA
case R_SH_GOT_LOW16:
@@ -5510,8 +6314,28 @@
case R_SH_GOT10BY4:
case R_SH_GOT10BY8:
#endif
+#ifdef USE_SH_TLS32
+ switch (r_type)
+ {
+ default:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_SH_TLS_GD_32:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_SH_TLS_IE_32:
+ tls_type = GOT_TLS_IE;
+ break;
+ }
+#endif
+
if (h != NULL)
- h->got.refcount += 1;
+ {
+ h->got.refcount += 1;
+#ifdef USE_SH_TLS32
+ old_tls_type = sh_elf_hash_entry(h)->tls_type;
+#endif
+ }
else
{
bfd_signed_vma *local_got_refcounts;
@@ -5530,15 +6354,61 @@
codelabel local GOT offsets. */
size *= 2;
#endif
+#ifdef USE_SH_TLS32
+ size += symtab_hdr->sh_info * sizeof (char);
+#endif
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;
+#ifdef USE_SH_TLS32
+#ifdef INCLUDE_SHMEDIA
+ sh_elf_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
+#else
+ sh_elf_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+#endif
+#endif
}
local_got_refcounts[r_symndx] += 1;
+#ifdef USE_SH_TLS32
+ old_tls_type = sh_elf_local_got_tls_type (abfd) [r_symndx];
+#endif
}
+
+#ifdef USE_SH_TLS32
+ /* 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
+ && (old_tls_type != GOT_TLS_GD || tls_type != GOT_TLS_IE))
+ {
+ if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+ tls_type = GOT_TLS_IE;
+ else
+ {
+ (*_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)
+ {
+ if (h != NULL)
+ sh_elf_hash_entry(h)->tls_type = tls_type;
+ else
+ sh_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+
+ break;
+
+ case R_SH_TLS_LD_32:
+ sh_elf_hash_table(info)->tls_ldm_got.refcount += 1;
break;
+#endif
case R_SH_GOTPLT32:
#ifdef INCLUDE_SHMEDIA
@@ -5620,7 +6490,7 @@
symbol. */
if ((info->shared
&& (sec->flags & SEC_ALLOC) != 0
- && (ELF32_R_TYPE (rel->r_info) != R_SH_REL32
+ && (r_type != R_SH_REL32
|| (h != NULL
&& (! info->symbolic
|| h->root.type == bfd_link_hash_defweak
@@ -5710,11 +6580,112 @@
}
p->count += 1;
- if (ELF32_R_TYPE (rel->r_info) == R_SH_REL32)
+ if (r_type == R_SH_REL32)
p->pc_count += 1;
}
break;
+
+#ifdef USE_SH_TLS32
+ case R_SH_TLS_LE_32:
+ if (info->shared)
+ {
+ (*_bfd_error_handler) (_("%s: TLS local exec code cannot be linked into shared objects"),
+ bfd_archive_filename (abfd));
+ return false;
+ }
+
+ if (ELF32_R_TYPE (rel->r_info) == R_SH_TLS_LD_32)
+ break;
+
+ /* FALLTHROUGH */
+ case R_SH_TLS_LDO_32:
+ /* We make a R_SH_TLS_TPOFF32 relocation. Count it as a
+ copy relocation. */
+ if (! info->shared)
+ {
+ struct elf_sh_dyn_relocs *p;
+ struct elf_sh_dyn_relocs **head;
+
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (abfd,
+ elf_elfheader (abfd)->e_shstrndx,
+ elf_section_data (sec)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ flagword flags;
+
+ sreloc = bfd_make_section (dynobj, name);
+ flags = (SEC_HAS_CONTENTS | SEC_READONLY
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if ((sec->flags & SEC_ALLOC) != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+ if (sreloc == NULL
+ || ! bfd_set_section_flags (dynobj, sreloc, flags)
+ || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+ return false;
+ }
+ elf_section_data (sec)->sreloc = sreloc;
+ if (sec->flags & SEC_READONLY)
+ info->flags |= DF_TEXTREL;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf_sh_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ asection *s;
+
+ /* Track dynamic relocs needed for local syms too. */
+ s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
+ sec, r_symndx);
+ if (s == NULL)
+ return false;
+
+ head = ((struct elf_sh_dyn_relocs **)
+ &elf_section_data (s)->local_dynrel);
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof (*p);
+ p = ((struct elf_sh_dyn_relocs *) bfd_alloc (dynobj, amt));
+ if (p == NULL)
+ return false;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (h)
+ sh_elf_hash_entry(h)->tls_tpoff32 = true;
+ }
+ break;
+#endif
+
+ default:
+ break;
}
}
@@ -5835,6 +6806,27 @@
}
#endif /* not sh_elf_merge_private_data */
+#ifdef USE_SH_TLS32
+static boolean
+sh_elf_object_p (abfd)
+ bfd *abfd;
+{
+ struct sh_elf_obj_tdata *new_tdata;
+ bfd_size_type amt = sizeof (struct sh_elf_obj_tdata);
+
+ if (sh_elf_set_mach_from_flags (abfd) == false)
+ return false;
+
+ /* Allocate our special target data. */
+ 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;
+ return true;
+}
+#endif
+
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
@@ -5991,7 +6983,12 @@
}
}
- if (h->got.offset != (bfd_vma) -1)
+ if (h->got.offset != (bfd_vma) -1
+#ifdef USE_SH_TLS32
+ && sh_elf_hash_entry(h)->tls_type != GOT_TLS_GD
+ && sh_elf_hash_entry(h)->tls_type != GOT_TLS_IE
+#endif
+ )
{
asection *sgot;
asection *srel;
@@ -6280,7 +7277,12 @@
#define elf_backend_relocate_section sh_elf_relocate_section
#define bfd_elf32_bfd_get_relocated_section_contents \
sh_elf_get_relocated_section_contents
+#ifdef USE_SH_TLS32
+#define bfd_elf32_mkobject sh_elf_mkobject
+#define elf_backend_object_p sh_elf_object_p
+#else
#define elf_backend_object_p sh_elf_set_mach_from_flags
+#endif
#define bfd_elf32_bfd_set_private_bfd_flags \
sh_elf_set_private_flags
#define bfd_elf32_bfd_copy_private_bfd_data \
diff -urN ORIG/src/bfd/reloc.c LOCAL/src/bfd/reloc.c
--- ORIG/src/bfd/reloc.c Sat Sep 28 04:29:16 2002
+++ LOCAL/src/bfd/reloc.c Sat Oct 5 13:54:49 2002
@@ -2575,6 +2575,22 @@
BFD_RELOC_SH_IMM_HI16_PCREL
ENUMX
BFD_RELOC_SH_PT_16
+ENUMX
+ BFD_RELOC_SH_TLS_GD_32
+ENUMX
+ BFD_RELOC_SH_TLS_LD_32
+ENUMX
+ BFD_RELOC_SH_TLS_LDO_32
+ENUMX
+ BFD_RELOC_SH_TLS_IE_32
+ENUMX
+ BFD_RELOC_SH_TLS_LE_32
+ENUMX
+ BFD_RELOC_SH_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_SH_TLS_DTPOFF32
+ENUMX
+ BFD_RELOC_SH_TLS_TPOFF32
ENUMDOC
Hitachi SH relocs. Not all of these appear in object files.
diff -urN ORIG/src/gas/config/tc-sh.c LOCAL/src/gas/config/tc-sh.c
--- ORIG/src/gas/config/tc-sh.c Thu Oct 3 13:58:28 2002
+++ LOCAL/src/gas/config/tc-sh.c Sat Oct 5 13:54:49 2002
@@ -3546,11 +3546,16 @@
case BFD_RELOC_32_GOT_PCREL:
case BFD_RELOC_SH_GOTPLT32:
+ case BFD_RELOC_SH_TLS_GD_32:
+ case BFD_RELOC_SH_TLS_LD_32:
+ case BFD_RELOC_SH_TLS_IE_32:
* valP = 0; /* Fully resolved at runtime. No addend. */
md_number_to_chars (buf, 0, 4);
break;
case BFD_RELOC_32_GOTOFF:
+ case BFD_RELOC_SH_TLS_LDO_32:
+ case BFD_RELOC_SH_TLS_LE_32:
md_number_to_chars (buf, val, 4);
break;
#endif
@@ -4015,6 +4020,16 @@
reloc_type = BFD_RELOC_32_GOT_PCREL;
else if ((next_end = sh_end_of_match (next + 1, "PLT")))
reloc_type = BFD_RELOC_32_PLT_PCREL;
+ else if ((next_end = sh_end_of_match (next + 1, "TLSGD")))
+ reloc_type = BFD_RELOC_SH_TLS_GD_32;
+ else if ((next_end = sh_end_of_match (next + 1, "TLSLDM")))
+ reloc_type = BFD_RELOC_SH_TLS_LD_32;
+ else if ((next_end = sh_end_of_match (next + 1, "GOTTPOFF")))
+ reloc_type = BFD_RELOC_SH_TLS_IE_32;
+ else if ((next_end = sh_end_of_match (next + 1, "TPOFF")))
+ reloc_type = BFD_RELOC_SH_TLS_LE_32;
+ else if ((next_end = sh_end_of_match (next + 1, "DTPOFF")))
+ reloc_type = BFD_RELOC_SH_TLS_LDO_32;
else
goto no_suffix;
diff -urN ORIG/src/gas/testsuite/gas/sh/basic.exp LOCAL/src/gas/testsuite/gas/sh/basic.exp
--- ORIG/src/gas/testsuite/gas/sh/basic.exp Sat Sep 28 09:41:27 2002
+++ LOCAL/src/gas/testsuite/gas/sh/basic.exp Sat Oct 5 13:54:49 2002
@@ -136,4 +136,13 @@
if {[istarget sh*-*elf] || [istarget sh*-linux*]} then {
run_dump_test "pic"
}
+
+ if {[istarget "sh*-linux*"] && ![istarget sh64*-linux*]} then {
+ # Test TLS.
+ run_dump_test "tlsd"
+
+ run_dump_test "tlspic"
+
+ run_dump_test "tlsnopic"
+ }
}
diff -urN ORIG/src/gas/testsuite/gas/sh/tlsd.d LOCAL/src/gas/testsuite/gas/sh/tlsd.d
--- ORIG/src/gas/testsuite/gas/sh/tlsd.d Thu Jan 1 09:00:00 1970
+++ LOCAL/src/gas/testsuite/gas/sh/tlsd.d Sat Oct 5 13:55:14 2002
@@ -0,0 +1,54 @@
+#objdump: -dr
+#name: sh dynamic tls
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <fn>:
+ 0: 2f c6 [ ]*mov\.l r12,@-r15
+ 2: 2f e6 [ ]*mov\.l r14,@-r15
+ 4: 4f 22 [ ]*sts\.l pr,@-r15
+ 6: c7 14 [ ]*mova 58 <fn\+0x58>,r0
+ 8: dc 13 [ ]*mov\.l 58 <fn\+0x58>,r12[ ]+! 0x0
+ a: 3c 0c [ ]*add r0,r12
+ c: 6e f3 [ ]*mov r15,r14
+ e: d4 04 [ ]*mov\.l 20 <fn\+0x20>,r4[ ]+! 0x0
+ 10: c7 04 [ ]*mova 24 <fn\+0x24>,r0
+ 12: d1 04 [ ]*mov\.l 24 <fn\+0x24>,r1[ ]+! 0x0
+ 14: 31 0c [ ]*add r0,r1
+ 16: 41 0b [ ]*jsr @r1
+ 18: 34 cc [ ]*add r12,r4
+ 1a: a0 05 [ ]*bra 28 <fn\+0x28>
+ 1c: 00 09 [ ]*nop
+ 1e: 00 09 [ ]*nop
+ \.\.\.
+[ ]+20: R_SH_TLS_GD_32 foo
+[ ]+24: R_SH_PLT32 __tls_get_addr
+ 28: d4 03 [ ]*mov\.l 38 <fn\+0x38>,r4[ ]+! 0x0
+ 2a: c7 04 [ ]*mova 3c <fn\+0x3c>,r0
+ 2c: d1 03 [ ]*mov\.l 3c <fn\+0x3c>,r1[ ]+! 0x0
+ 2e: 31 0c [ ]*add r0,r1
+ 30: 41 0b [ ]*jsr @r1
+ 32: 34 cc [ ]*add r12,r4
+ 34: a0 04 [ ]*bra 40 <fn\+0x40>
+ 36: 00 09 [ ]*nop
+ \.\.\.
+[ ]+38: R_SH_TLS_LD_32 bar
+[ ]+3c: R_SH_PLT32 __tls_get_addr
+ 40: e2 01 [ ]*mov #1,r2
+ 42: d1 06 [ ]*mov\.l 5c <fn\+0x5c>,r1[ ]+! 0x0
+ 44: 30 1c [ ]*add r1,r0
+ 46: 20 22 [ ]*mov\.l r2,@r0
+ 48: d1 05 [ ]*mov\.l 60 <fn\+0x60>,r1[ ]+! 0x0
+ 4a: 30 1c [ ]*add r1,r0
+ 4c: 6f e3 [ ]*mov r14,r15
+ 4e: 4f 26 [ ]*lds\.l @r15\+,pr
+ 50: 6e f6 [ ]*mov\.l @r15\+,r14
+ 52: 00 0b [ ]*rts
+ 54: 6c f6 [ ]*mov\.l @r15\+,r12
+ 56: 00 09 [ ]*nop
+ \.\.\.
+[ ]+58: R_SH_GOTPC _GLOBAL_OFFSET_TABLE_
+[ ]+5c: R_SH_TLS_LDO_32 bar
+[ ]+60: R_SH_TLS_LDO_32 baz
diff -urN ORIG/src/gas/testsuite/gas/sh/tlsd.s LOCAL/src/gas/testsuite/gas/sh/tlsd.s
--- ORIG/src/gas/testsuite/gas/sh/tlsd.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/gas/testsuite/gas/sh/tlsd.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,71 @@
+ .section .tbss,"awT",@nobits
+ .align 2
+ .global foo, bar
+ .hidden bar
+foo: .long 25
+bar: .long 27
+baz: .long 29
+ .text
+ .align 1
+ .global fn
+ .type fn, @function
+fn:
+ mov.l r12,@-r15
+ mov.l r14,@-r15
+ sts.l pr,@-r15
+ mova .L3,r0
+ mov.l .L3,r12
+ add r0,r12
+ mov r15,r14
+
+ ! Dynamic TLS model, foo not known to be in the current object
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long foo@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+
+ ! Dynamic TLS model, bar and baz known to be in the current object
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long bar@TLSLDM
+2: .long __tls_get_addr@PLT
+3:
+ ! Just show that there can be arbitrary instructions here
+ mov #1,r2
+
+ mov.l .L4,r1
+ add r1,r0
+ ! r0 now contains &bar
+
+ ! Again, arbitrary instructions
+ mov.l r2,@r0
+
+ mov.l .L5,r1
+ add r1,r0
+ ! r0 now contains &baz
+
+ mov r14,r15
+ lds.l @r15+,pr
+ mov.l @r15+,r14
+ rts
+ mov.l @r15+,r12
+
+ .align 2
+.L3: .long _GLOBAL_OFFSET_TABLE_
+.L4: .long bar@DTPOFF
+.L5: .long baz@DTPOFF
diff -urN ORIG/src/gas/testsuite/gas/sh/tlsnopic.d LOCAL/src/gas/testsuite/gas/sh/tlsnopic.d
--- ORIG/src/gas/testsuite/gas/sh/tlsnopic.d Thu Jan 1 09:00:00 1970
+++ LOCAL/src/gas/testsuite/gas/sh/tlsnopic.d Sat Oct 5 13:55:14 2002
@@ -0,0 +1,19 @@
+#objdump: -dr
+#name: sh non-pic tls
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <fn>:
+ 0: 2f e6 [ ]*mov\.l r14,@-r15
+ 2: 6e f3 [ ]*mov r15,r14
+ 4: 01 12 [ ]*stc gbr,r1
+ 6: d0 02 [ ]*mov\.l 10 <fn\+0x10>,r0[ ]+! 0x0
+ 8: 30 1c [ ]*add r1,r0
+ a: 6f e3 [ ]*mov r14,r15
+ c: 00 0b [ ]*rts
+ e: 6e f6 [ ]*mov\.l @r15\+,r14
+ 10: 00 00 [ ]*\.word 0x0+0
+[ ]+10: R_SH_TLS_LE_32 foo
+ \.\.\.
diff -urN ORIG/src/gas/testsuite/gas/sh/tlsnopic.s LOCAL/src/gas/testsuite/gas/sh/tlsnopic.s
--- ORIG/src/gas/testsuite/gas/sh/tlsnopic.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/gas/testsuite/gas/sh/tlsnopic.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,23 @@
+ .section .tbss,"awT",@nobits
+ .align 2
+ .long foo
+ .text
+ .align 1
+ .global fn
+ .type fn, @function
+fn:
+ ! Main binary, no PIC
+ mov.l r14,@-r15
+ mov r15,r14
+
+ stc gbr,r1
+ mov.l .L2,r0
+ add r1,r0
+ ! r0 now contains &foo
+
+ mov r14,r15
+ rts
+ mov.l @r15+,r14
+.L3:
+ .align 2
+.L2: .long foo@TPOFF
diff -urN ORIG/src/gas/testsuite/gas/sh/tlspic.d LOCAL/src/gas/testsuite/gas/sh/tlspic.d
--- ORIG/src/gas/testsuite/gas/sh/tlspic.d Thu Jan 1 09:00:00 1970
+++ LOCAL/src/gas/testsuite/gas/sh/tlspic.d Sat Oct 5 13:55:14 2002
@@ -0,0 +1,32 @@
+#objdump: -dr
+#name: sh pic tls
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <fn>:
+ 0: 2f c6 [ ]*mov\.l r12,@-r15
+ 2: 2f e6 [ ]*mov\.l r14,@-r15
+ 4: 6e f3 [ ]*mov r15,r14
+ 6: c7 08 [ ]*mova 28 <fn\+0x28>,r0
+ 8: dc 07 [ ]*mov\.l 28 <fn\+0x28>,r12[ ]+! 0x0
+ a: 3c 0c [ ]*add r0,r12
+ c: d0 02 [ ]*mov\.l 18 <fn\+0x18>,r0[ ]+! 0x0
+ e: 01 12 [ ]*stc gbr,r1
+ 10: 00 ce [ ]*mov\.l @\(r0,r12\),r0
+ 12: a0 03 [ ]*bra 1c <fn\+0x1c>
+ 14: 31 0c [ ]*add r0,r1
+ 16: 00 09 [ ]*nop
+ 18: 00 00 [ ]*\.word 0x0000
+[ ]+18: R_SH_TLS_IE_32 foo
+ 1a: 00 00 [ ]*\.word 0x0000
+ 1c: 60 13 [ ]*mov r1,r0
+ 1e: 6f e3 [ ]*mov r14,r15
+ 20: 6e f6 [ ]*mov\.l @r15\+,r14
+ 22: 00 0b [ ]*rts
+ 24: 6c f6 [ ]*mov\.l @r15\+,r12
+ 26: 00 09 [ ]*nop
+ 28: 00 00 [ ]*\.word 0x0+0
+[ ]+28: R_SH_GOTPC _GLOBAL_OFFSET_TABLE_
+ \.\.\.
diff -urN ORIG/src/gas/testsuite/gas/sh/tlspic.s LOCAL/src/gas/testsuite/gas/sh/tlspic.s
--- ORIG/src/gas/testsuite/gas/sh/tlspic.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/gas/testsuite/gas/sh/tlspic.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,30 @@
+ .text
+ .align 1
+ .global fn
+ .type fn, @function
+fn:
+ ! Main binary, PIC
+ mov.l r12,@-r15
+ mov.l r14,@-r15
+ mov r15,r14
+ mova .L3,r0
+ mov.l .L3,r12
+ add r0,r12
+
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long foo@GOTTPOFF
+2: ! now r1 contains &foo
+
+ mov r1,r0
+ mov r14,r15
+ mov.l @r15+,r14
+ rts
+ mov.l @r15+,r12
+
+ .align 2
+.L3: .long _GLOBAL_OFFSET_TABLE_
diff -urN ORIG/src/include/elf/sh.h LOCAL/src/include/elf/sh.h
--- ORIG/src/include/elf/sh.h Wed Jun 5 10:50:42 2002
+++ LOCAL/src/include/elf/sh.h Sat Oct 5 13:55:14 2002
@@ -167,7 +167,17 @@
RELOC_NUMBER (R_SH_DIR10SL, 50)
RELOC_NUMBER (R_SH_DIR10SQ, 51)
FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_3, 52)
- FAKE_RELOC (R_SH_LAST_INVALID_RELOC_3, 159)
+ FAKE_RELOC (R_SH_LAST_INVALID_RELOC_3, 143)
+ RELOC_NUMBER (R_SH_TLS_GD_32, 144)
+ RELOC_NUMBER (R_SH_TLS_LD_32, 145)
+ RELOC_NUMBER (R_SH_TLS_LDO_32, 146)
+ RELOC_NUMBER (R_SH_TLS_IE_32, 147)
+ RELOC_NUMBER (R_SH_TLS_LE_32, 148)
+ RELOC_NUMBER (R_SH_TLS_DTPMOD32, 149)
+ RELOC_NUMBER (R_SH_TLS_DTPOFF32, 150)
+ RELOC_NUMBER (R_SH_TLS_TPOFF32, 151)
+ FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_4, 152)
+ FAKE_RELOC (R_SH_LAST_INVALID_RELOC_4, 159)
RELOC_NUMBER (R_SH_GOT32, 160)
RELOC_NUMBER (R_SH_PLT32, 161)
RELOC_NUMBER (R_SH_COPY, 162)
@@ -205,8 +215,8 @@
RELOC_NUMBER (R_SH_GLOB_DAT64, 194)
RELOC_NUMBER (R_SH_JMP_SLOT64, 195)
RELOC_NUMBER (R_SH_RELATIVE64, 196)
- FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_4, 197)
- FAKE_RELOC (R_SH_LAST_INVALID_RELOC_4, 241)
+ FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_5, 197)
+ FAKE_RELOC (R_SH_LAST_INVALID_RELOC_5, 241)
RELOC_NUMBER (R_SH_SHMEDIA_CODE, 242)
RELOC_NUMBER (R_SH_PT_16, 243)
RELOC_NUMBER (R_SH_IMMS16, 244)
diff -urN ORIG/src/ld/testsuite/ld-sh/sh-tls.exp LOCAL/src/ld/testsuite/ld-sh/sh-tls.exp
--- ORIG/src/ld/testsuite/ld-sh/sh-tls.exp Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/sh-tls.exp Sat Oct 5 13:55:14 2002
@@ -0,0 +1,41 @@
+# Expect script for ld-sh TLS tests
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# 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 SH TLS handling.
+
+if {! [istarget sh*-*-linux*] || [istarget sh64*-*-linux*]} {
+ # Currently only for 32-bit linux target.
+ return
+}
+
+set tlstests {
+ {"TLS -fpic -shared transitions" "-shared -mshlelf_linux"
+ "" {tlspic1.s tlspic2.s}
+ {{readelf -Ssrl tlspic.rd} {objdump -drj.text tlspic.dd}
+ {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
+ "libtlspic.so"}
+ {"Helper shared library" "-shared -mshlelf_linux"
+ "" {tlslib.s} {} "libtlslib.so"}
+ {"TLS -fpic and -fno-pic exec transitions"
+ "-mshlelf_linux tmpdir/libtlslib.so" "" {tlsbinpic.s tlsbin.s}
+ {{readelf -Ssrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
+ {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
+ "tlsbin"}
+}
+
+run_ld_link_tests $tlstests
diff -urN ORIG/src/ld/testsuite/ld-sh/tlsbin.dd LOCAL/src/ld/testsuite/ld-sh/tlsbin.dd
--- ORIG/src/ld/testsuite/ld-sh/tlsbin.dd Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin.dd Sat Oct 5 13:55:14 2002
@@ -0,0 +1,295 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#ld: -mshlelf_linux tmpdir/libtlslib.so
+#objdump: -drj.text
+#target: sh*-linux*
+
+.*: +file format elf32-sh-linux
+
+Disassembly of section \.text:
+
+0+401000 <fn2>:
+ 401000: c6 2f mov\.l r12,@-r15
+ 401002: e6 2f mov\.l r14,@-r15
+ 401004: 22 4f sts\.l pr,@-r15
+ 401006: 5f c7 mova 401184 <fn2\+0x184>,r0
+ 401008: 5e dc mov\.l 401184 <fn2\+0x184>,r12 ! 0x[0-9a-f]+
+ 40100a: 0c 3c add r0,r12
+ 40100c: f3 6e mov r15,r14
+ 40100e: 09 00 nop
+ 401010: 09 00 nop
+ 401012: 09 00 nop
+ 401014: 09 00 nop
+ 401016: 04 d0 mov\.l 401028 <fn2\+0x28>,r0 ! 0x1c
+ 401018: 12 04 stc gbr,r4
+ 40101a: ce 00 mov\.l @\(r0,r12\),r0
+ 40101c: 4c 30 add r4,r0
+ 40101e: 09 00 nop
+ 401020: 09 00 nop
+ 401022: 05 a0 bra 401030 <fn2\+0x30>
+ 401024: 09 00 nop
+ 401026: 09 00 nop
+ 401028: 1c 00 .*[ ]*.*
+ 40102a: 00 00 .*[ ]*.*
+ 40102c: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 40102e: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 401030: 09 00 nop
+ 401032: 09 00 nop
+ 401034: 09 00 nop
+ 401036: 09 00 nop
+ 401038: 03 d0 mov\.l 401048 <fn2\+0x48>,r0 ! 0x14
+ 40103a: 12 04 stc gbr,r4
+ 40103c: ce 00 mov\.l @\(r0,r12\),r0
+ 40103e: 4c 30 add r4,r0
+ 401040: 09 00 nop
+ 401042: 09 00 nop
+ 401044: 04 a0 bra 401050 <fn2\+0x50>
+ 401046: 09 00 nop
+ 401048: 14 00 .*[ ]*.*
+ 40104a: 00 00 .*[ ]*.*
+ 40104c: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 40104e: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 401050: 09 00 nop
+ 401052: 09 00 nop
+ 401054: 09 00 nop
+ 401056: 09 00 nop
+ 401058: 03 d4 mov\.l 401068 <fn2\+0x68>,r4 ! 0x0
+ 40105a: 12 00 stc gbr,r0
+ 40105c: 4c 30 add r4,r0
+ 40105e: 09 00 nop
+ 401060: 09 00 nop
+ 401062: 09 00 nop
+ 401064: 04 a0 bra 401070 <fn2\+0x70>
+ 401066: 09 00 nop
+ 401068: 00 00 .*[ ]*.*
+ 40106a: 00 00 .*[ ]*.*
+ 40106c: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 40106e: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 401070: 09 00 nop
+ 401072: 09 00 nop
+ 401074: 09 00 nop
+ 401076: 09 00 nop
+ 401078: 03 d4 mov\.l 401088 <fn2\+0x88>,r4 ! 0x0
+ 40107a: 12 00 stc gbr,r0
+ 40107c: 4c 30 add r4,r0
+ 40107e: 09 00 nop
+ 401080: 09 00 nop
+ 401082: 09 00 nop
+ 401084: 04 a0 bra 401090 <fn2\+0x90>
+ 401086: 09 00 nop
+ 401088: 00 00 .*[ ]*.*
+ 40108a: 00 00 .*[ ]*.*
+ 40108c: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 40108e: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 401090: 09 00 nop
+ 401092: 09 00 nop
+ 401094: 09 00 nop
+ 401096: 09 00 nop
+ 401098: 03 d4 mov\.l 4010a8 <fn2\+0xa8>,r4 ! 0x0
+ 40109a: 12 00 stc gbr,r0
+ 40109c: 4c 30 add r4,r0
+ 40109e: 09 00 nop
+ 4010a0: 09 00 nop
+ 4010a2: 09 00 nop
+ 4010a4: 04 a0 bra 4010b0 <fn2\+0xb0>
+ 4010a6: 09 00 nop
+ 4010a8: 00 00 .*[ ]*.*
+ 4010aa: 00 00 .*[ ]*.*
+ 4010ac: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 4010ae: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 4010b0: 09 00 nop
+ 4010b2: 09 00 nop
+ 4010b4: 09 00 nop
+ 4010b6: 09 00 nop
+ 4010b8: 12 00 stc gbr,r0
+ 4010ba: 09 00 nop
+ 4010bc: 09 00 nop
+ 4010be: 09 00 nop
+ 4010c0: 09 00 nop
+ 4010c2: 09 00 nop
+ 4010c4: 04 a0 bra 4010d0 <fn2\+0xd0>
+ 4010c6: 09 00 nop
+ 4010c8: 00 00 .*[ ]*.*
+ 4010ca: 00 00 .*[ ]*.*
+ 4010cc: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 4010ce: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 4010d0: 09 00 nop
+ 4010d2: 09 00 nop
+ 4010d4: 2c d1 mov\.l 401188 <fn2\+0x188>,r1 ! 0x0
+ 4010d6: 0c 31 add r0,r1
+ 4010d8: 09 00 nop
+ 4010da: 09 00 nop
+ 4010dc: 2b d2 mov\.l 40118c <fn2\+0x18c>,r2 ! 0x0
+ 4010de: 0c 32 add r0,r2
+ 4010e0: 09 00 nop
+ 4010e2: 09 00 nop
+ 4010e4: 09 00 nop
+ 4010e6: 09 00 nop
+ 4010e8: 12 00 stc gbr,r0
+ 4010ea: 09 00 nop
+ 4010ec: 09 00 nop
+ 4010ee: 09 00 nop
+ 4010f0: 09 00 nop
+ 4010f2: 09 00 nop
+ 4010f4: 04 a0 bra 401100 <fn2\+0x100>
+ 4010f6: 09 00 nop
+ 4010f8: 00 00 .*[ ]*.*
+ 4010fa: 00 00 .*[ ]*.*
+ 4010fc: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 4010fe: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ 401100: 09 00 nop
+ 401102: 09 00 nop
+ 401104: 22 d1 mov\.l 401190 <fn2\+0x190>,r1 ! 0x0
+ 401106: 0c 31 add r0,r1
+ 401108: 09 00 nop
+ 40110a: 09 00 nop
+ 40110c: 21 d2 mov\.l 401194 <fn2\+0x194>,r2 ! 0x0
+ 40110e: 0c 32 add r0,r2
+ 401110: 09 00 nop
+ 401112: 09 00 nop
+ 401114: 09 00 nop
+ 401116: 09 00 nop
+ 401118: 02 d0 mov\.l 401124 <fn2\+0x124>,r0 ! 0x14
+ 40111a: 12 01 stc gbr,r1
+ 40111c: ce 00 mov\.l @\(r0,r12\),r0
+ 40111e: 03 a0 bra 401128 <fn2\+0x128>
+ 401120: 0c 31 add r0,r1
+ 401122: 09 00 nop
+ 401124: 14 00 .*[ ]*.*
+ 401126: 00 00 .*[ ]*.*
+ 401128: 09 00 nop
+ 40112a: 09 00 nop
+ 40112c: 09 00 nop
+ 40112e: 09 00 nop
+ 401130: 02 d0 mov\.l 40113c <fn2\+0x13c>,r0 ! 0x18
+ 401132: 12 01 stc gbr,r1
+ 401134: ce 00 mov\.l @\(r0,r12\),r0
+ 401136: 03 a0 bra 401140 <fn2\+0x140>
+ 401138: 1c 30 add r1,r0
+ 40113a: 09 00 nop
+ 40113c: 18 00 .*[ ]*.*
+ 40113e: 00 00 .*[ ]*.*
+ 401140: 09 00 nop
+ 401142: 09 00 nop
+ 401144: 09 00 nop
+ 401146: 09 00 nop
+ 401148: 02 d0 mov\.l 401154 <fn2\+0x154>,r0 ! 0x0
+ 40114a: 12 01 stc gbr,r1
+ 40114c: 09 00 nop
+ 40114e: 03 a0 bra 401158 <fn2\+0x158>
+ 401150: 0c 31 add r0,r1
+ 401152: 09 00 nop
+ 401154: 00 00 .*[ ]*.*
+ 401156: 00 00 .*[ ]*.*
+ 401158: 09 00 nop
+ 40115a: 09 00 nop
+ 40115c: 09 00 nop
+ 40115e: 09 00 nop
+ 401160: 02 d0 mov\.l 40116c <fn2\+0x16c>,r0 ! 0x0
+ 401162: 12 01 stc gbr,r1
+ 401164: 09 00 nop
+ 401166: 03 a0 bra 401170 <fn2\+0x170>
+ 401168: 0c 31 add r0,r1
+ 40116a: 09 00 nop
+ 40116c: 00 00 .*[ ]*.*
+ 40116e: 00 00 .*[ ]*.*
+ 401170: 09 00 nop
+ 401172: 09 00 nop
+ 401174: 09 00 nop
+ 401176: 09 00 nop
+ 401178: e3 6f mov r14,r15
+ 40117a: 26 4f lds\.l @r15\+,pr
+ 40117c: f6 6e mov\.l @r15\+,r14
+ 40117e: 0b 00 rts
+ 401180: f6 6c mov\.l @r15\+,r12
+ 401182: 09 00 nop
+ 401184: 3c 1f .*[ ]*.*
+ 401186: 01 00 .*[ ]*.*
+ \.\.\.
+
+00402000 <_start>:
+ 402000: c6 2f mov\.l r12,@-r15
+ 402002: e6 2f mov\.l r14,@-r15
+ 402004: f3 6e mov r15,r14
+ 402006: 27 c7 mova 4020a4 <_start\+0xa4>,r0
+ 402008: 26 dc mov\.l 4020a4 <_start\+0xa4>,r12 ! 0x[0-9a-f]+
+ 40200a: 0c 3c add r0,r12
+ 40200c: 09 00 nop
+ 40200e: 09 00 nop
+ 402010: 09 00 nop
+ 402012: 09 00 nop
+ 402014: 02 d0 mov\.l 402020 <_start\+0x20>,r0 ! 0x10
+ 402016: 12 01 stc gbr,r1
+ 402018: ce 00 mov\.l @\(r0,r12\),r0
+ 40201a: 03 a0 bra 402024 <_start\+0x24>
+ 40201c: 0c 31 add r0,r1
+ 40201e: 09 00 nop
+ 402020: 10 00 .*[ ]*.*
+ 402022: 00 00 .*[ ]*.*
+ 402024: 09 00 nop
+ 402026: 09 00 nop
+ 402028: 09 00 nop
+ 40202a: 09 00 nop
+ 40202c: 02 d0 mov\.l 402038 <_start\+0x38>,r0 ! 0x0
+ 40202e: 12 01 stc gbr,r1
+ 402030: 09 00 nop
+ 402032: 03 a0 bra 40203c <_start\+0x3c>
+ 402034: 0c 31 add r0,r1
+ 402036: 09 00 nop
+ 402038: 00 00 .*[ ]*.*
+ 40203a: 00 00 .*[ ]*.*
+ 40203c: 09 00 nop
+ 40203e: 09 00 nop
+ 402040: 09 00 nop
+ 402042: 09 00 nop
+ 402044: 02 d0 mov\.l 402050 <_start\+0x50>,r0 ! 0x0
+ 402046: 12 01 stc gbr,r1
+ 402048: 09 00 nop
+ 40204a: 03 a0 bra 402054 <_start\+0x54>
+ 40204c: 0c 31 add r0,r1
+ 40204e: 09 00 nop
+ 402050: 00 00 .*[ ]*.*
+ 402052: 00 00 .*[ ]*.*
+ 402054: 09 00 nop
+ 402056: 09 00 nop
+ 402058: 09 00 nop
+ 40205a: 09 00 nop
+ 40205c: 02 d0 mov\.l 402068 <_start\+0x68>,r0 ! 0x0
+ 40205e: 12 01 stc gbr,r1
+ 402060: 09 00 nop
+ 402062: 03 a0 bra 40206c <_start\+0x6c>
+ 402064: 0c 31 add r0,r1
+ 402066: 09 00 nop
+ 402068: 00 00 .*[ ]*.*
+ 40206a: 00 00 .*[ ]*.*
+ 40206c: 09 00 nop
+ 40206e: 09 00 nop
+ 402070: 09 00 nop
+ 402072: 09 00 nop
+ 402074: 12 01 stc gbr,r1
+ 402076: 0c d0 mov\.l 4020a8 <_start\+0xa8>,r0 ! 0x0
+ 402078: 1c 30 add r1,r0
+ 40207a: 09 00 nop
+ 40207c: 09 00 nop
+ 40207e: 09 00 nop
+ 402080: 09 00 nop
+ 402082: 12 01 stc gbr,r1
+ 402084: 09 d0 mov\.l 4020ac <_start\+0xac>,r0 ! 0x0
+ 402086: 1c 30 add r1,r0
+ 402088: 09 00 nop
+ 40208a: 09 00 nop
+ 40208c: 09 00 nop
+ 40208e: 09 00 nop
+ 402090: 12 01 stc gbr,r1
+ 402092: 07 d0 mov\.l 4020b0 <_start\+0xb0>,r0 ! 0x0
+ 402094: 1c 30 add r1,r0
+ 402096: 09 00 nop
+ 402098: 09 00 nop
+ 40209a: 09 00 nop
+ 40209c: 09 00 nop
+ 40209e: e3 6f mov r14,r15
+ 4020a0: 0b 00 rts
+ 4020a2: f6 6e mov\.l @r15\+,r14
+ 4020a4: 1c 10 .*[ ]*.*
+ 4020a6: 01 00 .*[ ]*.*
+ \.\.\.
diff -urN ORIG/src/ld/testsuite/ld-sh/tlsbin.rd LOCAL/src/ld/testsuite/ld-sh/tlsbin.rd
--- ORIG/src/ld/testsuite/ld-sh/tlsbin.rd Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin.rd Sat Oct 5 13:55:14 2002
@@ -0,0 +1,142 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#ld: -mshlelf_linux tmpdir/libtlslib.so
+#readelf: -Ssrl
+#target: sh*-linux*
+
+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+ 0+ +0 +0 +0
+ \[ 1\] \.interp +.*
+ \[ 2\] \.hash +.*
+ \[ 3\] \.dynsym +.*
+ \[ 4\] \.dynstr +.*
+ \[ 5\] \.rela\.dyn +.*
+ \[ 6\] \.rela\.plt +.*
+ \[ 7\] \.plt +.*
+ \[ 8\] \.text +PROGBITS +0+401000 .*
+ \[ 9\] \.data +.*
+ \[10\] \.tdata +PROGBITS +0+413000 [0-9a-f]+ 0+018 00 WAT 0 0 1
+ \[11\] \.tbss +NOBITS +0+413018 [0-9a-f]+ 0+010 00 WAT 0 0 1
+ \[12\] \.dynamic +DYNAMIC +0+413018 .*
+ \[13\] \.got +PROGBITS +0+4130c0 .*
+ \[14\] \.sbss +.*
+ \[15\] \.bss +.*
+ \[16\] \.shstrtab +.*
+ \[17\] \.symtab +.*
+ \[18\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x402000
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ PHDR.*
+ INTERP.*
+.*Requesting program interpreter.*
+ LOAD.*
+ LOAD.*
+ DYNAMIC.*
+ TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+18 0x0+28 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-f]+ contains 19 entries:
+ Offset +Info +Type +Sym\.Value +Sym\. Name \+ Addend
+0+401068 00000097 R_SH_TLS_TPOFF32 +0+00
+0+401088 00000097 R_SH_TLS_TPOFF32 +0+08
+0+4010a8 00000097 R_SH_TLS_TPOFF32 +0+10
+0+401154 00000097 R_SH_TLS_TPOFF32 +0+00
+0+40116c 00000097 R_SH_TLS_TPOFF32 +0+10
+0+401188 00000097 R_SH_TLS_TPOFF32 +0+08
+0+40118c 00000097 R_SH_TLS_TPOFF32 +0+0c
+0+401190 00000097 R_SH_TLS_TPOFF32 +0+10
+0+401194 00000097 R_SH_TLS_TPOFF32 +0+14
+0+402038 00000097 R_SH_TLS_TPOFF32 +0+18
+0+402050 00000097 R_SH_TLS_TPOFF32 +0+24
+0+402068 00000097 R_SH_TLS_TPOFF32 +0+14
+0+4020a8 00000097 R_SH_TLS_TPOFF32 +0+00
+0+4020ac 00000097 R_SH_TLS_TPOFF32 +0+20
+0+4020b0 00000097 R_SH_TLS_TPOFF32 +0+10
+0+4130d0 00000197 R_SH_TLS_TPOFF32 +0+ +sG3 \+ 0
+0+4130d4 00000397 R_SH_TLS_TPOFF32 +0+ +sG2 \+ 0
+0+4130d8 00000497 R_SH_TLS_TPOFF32 +0+ +sG4 \+ 0
+0+4130dc 00000797 R_SH_TLS_TPOFF32 +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+4130cc 000005a4 R_SH_JMP_SLOT +[0-9a-f]+ +__tls_get_addr \+ 0
+
+Symbol table '\.dynsym' contains 12 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+ +0 TLS +GLOBAL DEFAULT UND sG4
+ +5: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_addr
+ +6: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +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
+ +11: [0-9a-f]+ +0 NOTYPE +GLOBAL DEFAULT +9 __data_start
+
+Symbol table '\.symtab' contains 42 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: 00000008 +0 TLS +LOCAL DEFAULT +10 sl1
+ +20: 0000000c +0 TLS +LOCAL DEFAULT +10 sl2
+ +21: 00000020 +0 TLS +LOCAL DEFAULT +11 bl1
+ +22: 00000024 +0 TLS +LOCAL DEFAULT +11 bl2
+ +23: 0+ +0 TLS +GLOBAL DEFAULT UND sG3
+ +24: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +25: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +26: 0+ +0 TLS +GLOBAL DEFAULT UND sG4
+ +27: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_addr
+ +28: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1
+ +29: 0+402000 +0 FUNC +GLOBAL DEFAULT +8 _start
+ +30: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +31: 0+401000 +0 FUNC +GLOBAL DEFAULT +8 fn2
+ +32: 00000004 +0 TLS +GLOBAL DEFAULT +10 sg2
+ +33: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +34: 00000010 +0 TLS +GLOBAL HIDDEN +10 sh1
+ +35: 004130e0 +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +36: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +37: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+ +38: 00000014 +0 TLS +GLOBAL HIDDEN +10 sh2
+ +39: 0000001c +0 TLS +GLOBAL DEFAULT +11 bg2
+ +40: 00000018 +0 TLS +GLOBAL DEFAULT +11 bg1
+ +41: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT +9 __data_start
diff -urN ORIG/src/ld/testsuite/ld-sh/tlsbin.s LOCAL/src/ld/testsuite/ld-sh/tlsbin.s
--- ORIG/src/ld/testsuite/ld-sh/tlsbin.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,90 @@
+ .section ".tbss", "awT", @nobits
+ .globl bg1, bg2
+bg1: .space 4
+bg2: .space 4
+bl1: .space 4
+bl2: .space 4
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ mov.l r12,@-r15
+ mov.l r14,@-r15
+ mov r15,r14
+ ! Set up .GOT pointer for non-pic @gottpoff sequences
+ mova .L3,r0
+ mov.l .L3,r12
+ add r0,r12
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE against global var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sG3@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE -> LE against global var defined in exec
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long bg1@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE -> LE against local var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long bl2@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE -> LE against hidden but not local var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sh2@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! LE @TPOFF, global var defined in exec
+ stc gbr,r1
+ mov.l .L4,r0
+ add r1,r0
+ nop;nop;nop;nop
+
+ ! LE @TPOFF, local var
+ stc gbr,r1
+ mov.l .L5,r0
+ add r1,r0
+ nop;nop;nop;nop
+
+ ! LE @TPOFF, hidden var defined in exec
+ stc gbr,r1
+ mov.l .L6,r0
+ add r1,r0
+ nop;nop;nop;nop
+
+ mov r14,r15
+ rts
+ mov.l @r15+,r14
+
+ .align 2
+.L3: .long _GLOBAL_OFFSET_TABLE_
+.L4: .long sg1@TPOFF
+.L5: .long bl1@TPOFF
+.L6: .long sh1@TPOFF
diff -urN ORIG/src/ld/testsuite/ld-sh/tlsbin.sd LOCAL/src/ld/testsuite/ld-sh/tlsbin.sd
--- ORIG/src/ld/testsuite/ld-sh/tlsbin.sd Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin.sd Sat Oct 5 13:55:14 2002
@@ -0,0 +1,11 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#ld: -mshlelf_linux tmpdir/libtlslib.so
+#objdump: -sj.got
+#target: sh*-linux*
+
+.*: +file format elf32-sh-linux
+
+Contents of section \.got:
+ 4130c0 [0-9a-f]+ 00000000 00000000 [0-9a-f]+ .*
+ 4130d0 00000000 00000000 00000000 00000000 .*
diff -urN ORIG/src/ld/testsuite/ld-sh/tlsbin.td LOCAL/src/ld/testsuite/ld-sh/tlsbin.td
--- ORIG/src/ld/testsuite/ld-sh/tlsbin.td Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin.td Sat Oct 5 13:55:14 2002
@@ -0,0 +1,11 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#ld: -mshlelf_linux tmpdir/libtlslib.so
+#objdump: -sj.tdata
+#target: sh*-linux*
+
+.*: +file format elf32-sh-linux
+
+Contents of section .tdata:
+ 413000 11000000 12000000 41000000 42000000 .*
+ 413010 01010000 02010000 +.*
diff -urN ORIG/src/ld/testsuite/ld-sh/tlsbinpic.s LOCAL/src/ld/testsuite/ld-sh/tlsbinpic.s
--- ORIG/src/ld/testsuite/ld-sh/tlsbinpic.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbinpic.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,206 @@
+ ! Force .got aligned to 4K, so it very likely gets at 0x413000
+ .data
+ .balign 4096
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2
+ .globl sh1, sh2
+ .hidden sh1, sh2
+sg1: .long 17
+sg2: .long 18
+sl1: .long 65
+sl2: .long 66
+sh1: .long 257
+sh2: .long 258
+ ! Force .text aligned to 4K, so it very likely gets at 0x401000.
+ .text
+ .balign 4096
+ .globl fn2
+ .type fn2,@function
+fn2:
+ mov.l r12,@-r15
+ mov.l r14,@-r15
+ sts.l pr,@-r15
+ mova .L3,r0
+ mov.l .L3,r12
+ add r0,r12
+ mov r15,r14
+ nop;nop;nop;nop
+
+ ! GD -> IE because variable is not defined in executable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sG1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> IE because variable is not defined in executable where
+ ! the variable is referenced through @gottpoff too
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sG2@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> LE with global variable defined in executable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sg1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> LE with local variable defined in executable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sl1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> LE with hidden variable defined in executable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sh1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! LD -> LE with local variable defined in executable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sl1@TLSLDM
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop
+ mov.l .L4,r1
+ add r0,r1
+ nop;nop
+ mov.l .L5,r2
+ add r0,r2
+ nop;nop;nop;nop
+
+ ! LD -> LE against hidden variables
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sh1@TLSLDM
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop
+ mov.l .L6,r1
+ add r0,r1
+ nop;nop
+ mov.l .L7,r2
+ add r0,r2
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE against global var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sG2@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE against global var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r1,r0
+ .align 2
+1: .long sG4@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE -> LE against global var defined in exec
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sg1@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE -> LE against hidden var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sh1@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ mov r14,r15
+ lds.l @r15+,pr
+ mov.l @r15+,r14
+ rts
+ mov.l @r15+,r12
+
+ .align 2
+.L3: .long _GLOBAL_OFFSET_TABLE_
+.L4: .long sl1@DTPOFF
+.L5: .long sl2@DTPOFF
+.L6: .long sh1@DTPOFF
+.L7: .long sh2@DTPOFF
+ ! Fill page with 0.
+ .space .L8-.
+ .balign 4096
+.L8:
diff -urN ORIG/src/ld/testsuite/ld-sh/tlslib.s LOCAL/src/ld/testsuite/ld-sh/tlslib.s
--- ORIG/src/ld/testsuite/ld-sh/tlslib.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlslib.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,20 @@
+ .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
+ .align 1
+ ! Dummy.
+ .globl __tls_get_addr
+ .type __tls_get_addr,@function
+__tls_get_addr:
+ rts
+ nop
+
diff -urN ORIG/src/ld/testsuite/ld-sh/tlspic.dd LOCAL/src/ld/testsuite/ld-sh/tlspic.dd
--- ORIG/src/ld/testsuite/ld-sh/tlspic.dd Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic.dd Sat Oct 5 13:55:14 2002
@@ -0,0 +1,291 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#ld: -shared -mshlelf_linux
+#objdump: -drj.text
+#target: sh*-linux*
+
+.*: +file format elf32-sh-linux
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <fn1>:
+ [0-9a-f]+: c6 2f mov\.l r12,@-r15
+ [0-9a-f]+: e6 2f mov\.l r14,@-r15
+ [0-9a-f]+: 22 4f sts\.l pr,@-r15
+ [0-9a-f]+: 83 c7 mova 624 <fn1\+0x214>,r0
+ [0-9a-f]+: 82 dc mov\.l 624 <fn1\+0x214>,r12 ! 0x[0-9a-f]+
+ [0-9a-f]+: 0c 3c add r0,r12
+ [0-9a-f]+: f3 6e mov r15,r14
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 04 d4 mov\.l 438 <fn1\+0x28>,r4 ! 0x30
+ [0-9a-f]+: 04 c7 mova 43c <fn1\+0x2c>,r0
+ [0-9a-f]+: 04 d1 mov\.l 43c <fn1\+0x2c>,r1 ! 0x[0-9a-f]+
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 0b 41 jsr @r1
+ [0-9a-f]+: cc 34 add r12,r4
+ [0-9a-f]+: 05 a0 bra 440 <fn1\+0x30>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 30 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d0 mov\.l 458 <fn1\+0x48>,r0 ! 0x38
+ [0-9a-f]+: 12 04 stc gbr,r4
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 4c 30 add r4,r0
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 04 a0 bra 460 <fn1\+0x50>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 38 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d4 mov\.l 478 <fn1\+0x68>,r4 ! 0x10
+ [0-9a-f]+: 04 c7 mova 47c <fn1\+0x6c>,r0
+ [0-9a-f]+: 03 d1 mov\.l 47c <fn1\+0x6c>,r1 ! 0x[0-9a-f]+
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 0b 41 jsr @r1
+ [0-9a-f]+: cc 34 add r12,r4
+ [0-9a-f]+: 04 a0 bra 480 <fn1\+0x70>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 10 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d0 mov\.l 498 <fn1\+0x88>,r0 ! 0x18
+ [0-9a-f]+: 12 04 stc gbr,r4
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 4c 30 add r4,r0
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 04 a0 bra 4a0 <fn1\+0x90>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 18 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d4 mov\.l 4b8 <fn1\+0xa8>,r4 ! 0x3c
+ [0-9a-f]+: 04 c7 mova 4bc <fn1\+0xac>,r0
+ [0-9a-f]+: 03 d1 mov\.l 4bc <fn1\+0xac>,r1 ! 0x[0-9a-f]+
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 0b 41 jsr @r1
+ [0-9a-f]+: cc 34 add r12,r4
+ [0-9a-f]+: 04 a0 bra 4c0 <fn1\+0xb0>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 3c 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d0 mov\.l 4d8 <fn1\+0xc8>,r0 ! 0x44
+ [0-9a-f]+: 12 04 stc gbr,r4
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 4c 30 add r4,r0
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 04 a0 bra 4e0 <fn1\+0xd0>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 44 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d4 mov\.l 4f8 <fn1\+0xe8>,r4 ! 0x24
+ [0-9a-f]+: 04 c7 mova 4fc <fn1\+0xec>,r0
+ [0-9a-f]+: 03 d1 mov\.l 4fc <fn1\+0xec>,r1 ! 0x[0-9a-f]+
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 0b 41 jsr @r1
+ [0-9a-f]+: cc 34 add r12,r4
+ [0-9a-f]+: 04 a0 bra 500 <fn1\+0xf0>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 24 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d0 mov\.l 518 <fn1\+0x108>,r0 ! 0x2c
+ [0-9a-f]+: 12 04 stc gbr,r4
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 4c 30 add r4,r0
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 04 a0 bra 520 <fn1\+0x110>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 2c 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d4 mov\.l 538 <fn1\+0x128>,r4 ! 0x1c
+ [0-9a-f]+: 04 c7 mova 53c <fn1\+0x12c>,r0
+ [0-9a-f]+: 03 d1 mov\.l 53c <fn1\+0x12c>,r1 ! 0x[0-9a-f]+
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 0b 41 jsr @r1
+ [0-9a-f]+: cc 34 add r12,r4
+ [0-9a-f]+: 04 a0 bra 540 <fn1\+0x130>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 1c 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 38 d1 mov\.l 628 <fn1\+0x218>,r1 ! 0x8
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 37 d2 mov\.l 62c <fn1\+0x21c>,r2 ! 0xc
+ [0-9a-f]+: 0c 32 add r0,r2
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d4 .*[ ]*.*
+ [0-9a-f]+: 04 c7 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 0b 41 jsr @r1
+ [0-9a-f]+: cc 34 add r12,r4
+ [0-9a-f]+: 04 a0 bra 570 <fn1\+0x160>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 1c 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 2e d1 mov\.l 630 <fn1\+0x220>,r1 ! 0x10
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 2d d2 mov\.l 634 <fn1\+0x224>,r2 ! 0x14
+ [0-9a-f]+: 0c 32 add r0,r2
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 03 d4 mov\.l 598 <fn1\+0x188>,r4 ! 0x1c
+ [0-9a-f]+: 04 c7 mova 59c <fn1\+0x18c>,r0
+ [0-9a-f]+: 03 d1 mov\.l 59c <fn1\+0x18c>,r1 ! 0x[0-9a-f]+
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 0b 41 jsr @r1
+ [0-9a-f]+: cc 34 add r12,r4
+ [0-9a-f]+: 04 a0 bra 5a0 <fn1\+0x190>
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 1c 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 24 d1 mov\.l 638 <fn1\+0x228>,r1 ! 0x18
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 23 d2 mov\.l 63c <fn1\+0x22c>,r2 ! 0x1c
+ [0-9a-f]+: 0c 32 add r0,r2
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 02 d0 mov\.l 5c4 <fn1\+0x1b4>,r0 ! 0x38
+ [0-9a-f]+: 12 01 stc gbr,r1
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 03 a0 bra 5c8 <fn1\+0x1b8>
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 38 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 02 d0 mov\.l 5dc <fn1\+0x1cc>,r0 ! 0x18
+ [0-9a-f]+: 12 01 stc gbr,r1
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 03 a0 bra 5e0 <fn1\+0x1d0>
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 18 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 02 d0 mov\.l 5f4 <fn1\+0x1e4>,r0 ! 0x44
+ [0-9a-f]+: 12 01 stc gbr,r1
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 03 a0 bra 5f8 <fn1\+0x1e8>
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 44 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 02 d0 mov\.l 60c <fn1\+0x1fc>,r0 ! 0x2c
+ [0-9a-f]+: 12 01 stc gbr,r1
+ [0-9a-f]+: ce 00 mov\.l @\(r0,r12\),r0
+ [0-9a-f]+: 03 a0 bra 610 <fn1\+0x200>
+ [0-9a-f]+: 0c 31 add r0,r1
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 2c 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: e3 6f mov r14,r15
+ [0-9a-f]+: 26 4f lds\.l @r15\+,pr
+ [0-9a-f]+: f6 6e mov\.l @r15\+,r14
+ [0-9a-f]+: 0b 00 rts
+ [0-9a-f]+: f6 6c mov\.l @r15\+,r12
+ [0-9a-f]+: 09 00 nop
+ [0-9a-f]+: cc 00 .*[ ]*.*
+ [0-9a-f]+: 01 00 .*[ ]*.*
+ [0-9a-f]+: 08 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 0c 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 10 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 14 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 18 00 .*[ ]*.*
+ [0-9a-f]+: 00 00 .*[ ]*.*
+ [0-9a-f]+: 1c 00 .*[ ]*.*
+ \.\.\.
diff -urN ORIG/src/ld/testsuite/ld-sh/tlspic.rd LOCAL/src/ld/testsuite/ld-sh/tlspic.rd
--- ORIG/src/ld/testsuite/ld-sh/tlspic.rd Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic.rd Sat Oct 5 13:55:14 2002
@@ -0,0 +1,132 @@
+#source: tlspic1.s
+#source: tlsbin2.s
+#ld: -shared -mshlelf_linux
+#readelf: -Ssrl
+#target: sh*-linux*
+
+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+ 0+ +0 +0 +0
+ \[ 1\] \.hash +.*
+ \[ 2\] \.dynsym +.*
+ \[ 3\] \.dynstr +.*
+ \[ 4\] \.rela\.dyn +.*
+ \[ 5\] \.rela\.plt +.*
+ \[ 6\] \.plt +.*
+ \[ 7\] \.text +PROGBITS +0+410 .*
+ \[ 8\] \.data +.*
+ \[ 9\] \.tdata +PROGBITS +0+10640 [0-9a-f]+ 0+018 00 WAT 0 0 1
+ \[10\] \.tbss +NOBITS +0+10658 [0-9a-f]+ 0+008 00 WAT 0 0 1
+ \[11\] \.dynamic +DYNAMIC +0+10658 .*
+ \[12\] \.got +PROGBITS +0+106f0 .*
+ \[13\] \.sbss +.*
+ \[14\] \.bss +.*
+ \[15\] \.shstrtab +.*
+ \[16\] \.symtab +.*
+ \[17\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x410
+There are 4 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ LOAD.*
+ LOAD.*
+ DYNAMIC.*
+ TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+18 0x0+20 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 10 entries:
+ Offset +Info +Type +Sym\.Value +Sym\. Name \+ Addend
+0+10700 00000095 R_SH_TLS_DTPMOD32 +0+00
+0+10708 00000097 R_SH_TLS_TPOFF32 +0+0c
+0+1070c 00000095 R_SH_TLS_DTPMOD32 +0+00
+0+10714 00000095 R_SH_TLS_DTPMOD32 +0+00
+0+1071c 00000097 R_SH_TLS_TPOFF32 +0+1c
+0+1072c 00000095 R_SH_TLS_DTPMOD32 +0+00
+0+10734 00000097 R_SH_TLS_TPOFF32 +0+14
+0+10720 00001195 R_SH_TLS_DTPMOD32 +0+ +sg1 \+ 0
+0+10724 00001196 R_SH_TLS_DTPOFF32 +0+ +sg1 \+ 0
+0+10728 00001497 R_SH_TLS_TPOFF32 +0+04 +sg2 \+ 0
+
+Relocation section '\.rela\.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset +Info +Type +Sym\.Value +Sym\. Name \+ Addend
+0+106fc 000010a4 R_SH_JMP_SLOT +[0-9a-f]+ +__tls_get_addr \+ 0
+
+Symbol table '\.dynsym' contains 25 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 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +16: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
+ +17: 0+00 +0 TLS +GLOBAL DEFAULT +9 sg1
+ +18: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +19: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +20: 0+04 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +21: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +22: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +23: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+ +24: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT +8 __data_start
+
+Symbol table '\.symtab' contains 34 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+08 +0 TLS +LOCAL DEFAULT +9 sl1
+ +19: 0+0c +0 TLS +LOCAL DEFAULT +9 sl2
+ +20: 0+18 +0 TLS +LOCAL HIDDEN +10 sH1
+ +21: 0+1c +0 TLS +LOCAL HIDDEN +10 sH2
+ +22: 0+10 +0 TLS +LOCAL HIDDEN +9 sh1
+ +23: 0+14 +0 TLS +LOCAL HIDDEN +9 sh2
+ +24: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +25: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
+ +26: 0+00 +0 TLS +GLOBAL DEFAULT +9 sg1
+ +27: [0-9a-f]+ +0 FUNC GLOBAL DEFAULT +7 fn1
+ +28: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +29: 0+04 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +30: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +31: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +32: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+ +33: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT +8 __data_start
diff -urN ORIG/src/ld/testsuite/ld-sh/tlspic.sd LOCAL/src/ld/testsuite/ld-sh/tlspic.sd
--- ORIG/src/ld/testsuite/ld-sh/tlspic.sd Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic.sd Sat Oct 5 13:55:14 2002
@@ -0,0 +1,14 @@
+#source: tlspic1.s
+#source: tlsbin2.s
+#ld: -shared -mshlelf_linux
+#objdump: -sj.got
+#target: sh*-linux*
+
+.*: +file format elf32-sh-linux
+
+Contents of section \.got:
+ 106f0 [0-9a-f]+ 00000000 00000000 [0-9a-f]+ .*
+ 10700 00000000 08000000 00000000 00000000 .*
+ 10710 00000000 00000000 18000000 00000000 .*
+ 10720 00000000 00000000 00000000 00000000 .*
+ 10730 10000000 00000000 +.*
diff -urN ORIG/src/ld/testsuite/ld-sh/tlspic.td LOCAL/src/ld/testsuite/ld-sh/tlspic.td
--- ORIG/src/ld/testsuite/ld-sh/tlspic.td Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic.td Sat Oct 5 13:55:14 2002
@@ -0,0 +1,11 @@
+#source: tlspic1.s
+#source: tlsbin2.s
+#ld: -shared -mshlelf_linux
+#objdump: -sj.tdata
+#target: sh*-linux*
+
+.*: +file format elf32-sh-linux
+
+Contents of section \.tdata:
+ 10640 11000000 12000000 41000000 42000000 .*
+ 10650 01010000 02010000 +.*
diff -urN ORIG/src/ld/testsuite/ld-sh/tlspic1.s LOCAL/src/ld/testsuite/ld-sh/tlspic1.s
--- ORIG/src/ld/testsuite/ld-sh/tlspic1.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic1.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,267 @@
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2
+ .globl sh1, sh2
+ .hidden sh1, sh2
+sg1: .long 17
+sg2: .long 18
+sl1: .long 65
+sl2: .long 66
+sh1: .long 257
+sh2: .long 258
+ .text
+ .align 1
+ .globl fn1
+ .type fn1,@function
+fn1:
+ mov.l r12,@-r15
+ mov.l r14,@-r15
+ sts.l pr,@-r15
+ mova .L3,r0
+ mov.l .L3,r12
+ add r0,r12
+ mov r15,r14
+ nop;nop;nop;nop
+
+ ! GD
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sg1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> IE because variable is referenced through @GOTTPOFF too
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sg2@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD against local variable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sl1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> IE against local variable referenced through @GOTTPOFF too
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sl2@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD against hidden and local variable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sh1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> IE against hidden and local variable referenced through
+ ! @GOTTPOFF too
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sh2@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD against hidden but not local variable
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sH1@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! GD -> IE against hidden but not local variable referenced through
+ ! @GOTTPOFF too
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sH2@TLSGD
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop;nop;nop
+
+ ! LD
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sl1@TLSLDM
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop
+ mov.l .L4,r1
+ add r0,r1
+ nop;nop
+ mov.l .L5,r2
+ add r0,r2
+ nop;nop;nop;nop
+
+ ! LD against hidden and local variables
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sl1@TLSLDM
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop
+ mov.l .L6,r1
+ add r0,r1
+ nop;nop
+ mov.l .L7,r2
+ add r0,r2
+ nop;nop;nop;nop
+
+ ! LD against hidden but not local variables
+ mov.l 1f,r4
+ mova 2f,r0
+ mov.l 2f,r1
+ add r0,r1
+ jsr @r1
+ add r12,r4
+ bra 3f
+ nop
+ .align 2
+1: .long sH1@TLSLDM
+2: .long __tls_get_addr@PLT
+3:
+ nop;nop
+ mov.l .L8,r1
+ add r0,r1
+ nop;nop
+ mov.l .L9,r2
+ add r0,r2
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE against global var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sg2@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE against local var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sl2@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE against hidden and local var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sh2@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ ! @GOTTPOFF IE against hidden but not local var
+ mov.l 1f,r0
+ stc gbr,r1
+ mov.l @(r0,r12),r0
+ bra 2f
+ add r0,r1
+ .align 2
+1: .long sH2@GOTTPOFF
+2:
+ nop;nop;nop;nop
+
+ mov r14,r15
+ lds.l @r15+,pr
+ mov.l @r15+,r14
+ rts
+ mov.l @r15+,r12
+
+ .align 2
+.L3: .long _GLOBAL_OFFSET_TABLE_
+.L4: .long sl1@DTPOFF
+.L5: .long sl1@DTPOFF + 4
+.L6: .long sh1@DTPOFF
+.L7: .long sh2@DTPOFF
+.L8: .long sH1@DTPOFF
+.L9: .long sH2@DTPOFF
diff -urN ORIG/src/ld/testsuite/ld-sh/tlspic2.s LOCAL/src/ld/testsuite/ld-sh/tlspic2.s
--- ORIG/src/ld/testsuite/ld-sh/tlspic2.s Thu Jan 1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic2.s Sat Oct 5 13:55:14 2002
@@ -0,0 +1,5 @@
+ .section ".tbss", "awT", @nobits
+ .globl sH1, sH2
+ .hidden sH1, sH2
+sH1: .space 4
+sH2: .space 4