This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]