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 (Take 3)


Hi,

I've revised SH 32-bit TLS patch. There is no new regression for
sh-unknown-linux-gnu, sh4-unknown-netbsdelf and sh64-unknown-elf.
Thanks again for many suggestions.

Regards,
	kaz
--
	2002-10-10  Kaz Kojima  <kkojima@rr.iij4u.or.jp>

[bfd/ChangeLog]
	* elf32-sh.c (sh_elf_optimized_tls_reloc, 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): Support TLS relocs. Don't try to find
	.rela.got section when found already. Return false after printing
	error about unresolvable relocation.
	(sh_elf_gc_sweep_hook): Support TLS relocs.
	(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 (sh_force_relocation): Make sure TLS relocs get
	emitted.
	(md_apply_fix3): Add TLS relocs.
	(sh_parse_name): Support @TLSGD, @TLSLDM, @GOTTPOFF, @TPOFF and
	@DTPOFF.

[include/ChangeLog]
	* include/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]
	* rd-sh.exp: If the test matches *-dso.d, copy the output
	of linker to the file tmpdir/*-dso.so.
	* ld-sh/tlsbin.s, ld-sh/tlsbinpic.s, ld-sh/tlslib.s: New.
	* ld-sh/tlsbin-0-dso.d: New.
	* ld-sh/tlsbin-1.d: New.
	* ld-sh/tlsbin-2.d: New.
	* ld-sh/tlsbin-3.d: New.
	* ld-sh/tlsbin-4.d: New.
	* ld-sh/tlspic1.s, ld-sh/tlspic2.s: New.
	* ld-sh/tlspic-1.d: New.
	* ld-sh/tlspic-2.d: New.
	* ld-sh/tlspic-3.d: New.
	* ld-sh/tlspic-4.d: New.


diff -u3prN 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	Wed Oct  9 09:44:00 2002
@@ -59,6 +59,12 @@ static bfd_byte *sh_elf_get_relocated_se
 static void sh_elf_copy_indirect_symbol
   PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
 	   struct elf_link_hash_entry *));
+static int sh_elf_optimized_tls_reloc
+  PARAMS ((struct bfd_link_info *, int, int));
+static boolean sh_elf_mkobject
+  PARAMS((bfd *));
+static boolean sh_elf_object_p
+  PARAMS((bfd *));
 static boolean sh_elf_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
 	   const Elf_Internal_Rela *));
@@ -82,6 +88,8 @@ static boolean create_got_section
   PARAMS((bfd *, struct bfd_link_info *));
 static boolean sh_elf_create_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
+static bfd_vma dtpoff_base
+  PARAMS ((struct bfd_link_info *));
 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,14 +721,119 @@ static reloc_howto_type sh_elf_howto_tab
   EMPTY_HOWTO (141),
   EMPTY_HOWTO (142),
   EMPTY_HOWTO (143),
-  EMPTY_HOWTO (144),
-  EMPTY_HOWTO (145),
-  EMPTY_HOWTO (146),
-  EMPTY_HOWTO (147),
-  EMPTY_HOWTO (148),
-  EMPTY_HOWTO (149),
-  EMPTY_HOWTO (150),
-  EMPTY_HOWTO (151),
+
+  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 */
+
   EMPTY_HOWTO (152),
   EMPTY_HOWTO (153),
   EMPTY_HOWTO (154),
@@ -1776,6 +1889,14 @@ static const struct elf_reloc_map sh_rel
   { 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 },
+  { 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 },
   { BFD_RELOC_32_GOT_PCREL, R_SH_GOT32 },
   { BFD_RELOC_32_PLT_PCREL, R_SH_PLT32 },
   { BFD_RELOC_SH_COPY, R_SH_COPY },
@@ -1874,6 +1995,7 @@ sh_elf_info_to_howto (abfd, cache_ptr, d
   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);
   BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
+  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 +3512,45 @@ struct elf_sh_link_hash_entry
   struct elf_sh_dyn_relocs *dyn_relocs;
 
   bfd_signed_vma gotplt_refcount;
+
+  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;
+};
+
+#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)
+
+/* Override the generic function because we need to store sh_elf_obj_tdata
+   as the specific tdata.  */
+
+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;
+}
+                 
 /* sh ELF linker hash table.  */
 
 struct elf_sh_link_hash_table
@@ -3409,6 +3568,13 @@ struct elf_sh_link_hash_table
 
   /* Small local sym to section mapping cache.  */
   struct sym_sec_cache sym_sec;
+
+  /* A counter or offset to track a TLS got entry.  */
+  union
+    {
+      bfd_signed_vma refcount;
+      bfd_vma offset;
+    } tls_ldm_got;
 };
 
 /* Traverse an sh ELF linker hash table.  */
@@ -3458,6 +3624,8 @@ sh_elf_link_hash_newfunc (entry, table, 
 #ifdef INCLUDE_SHMEDIA
       ret->datalabel_got_offset = (bfd_vma) -1;
 #endif
+      ret->tls_type = GOT_UNKNOWN;
+      ret->tls_tpoff32 = false;
     }
 
   return (struct bfd_hash_entry *) ret;
@@ -3491,6 +3659,7 @@ sh_elf_link_hash_table_create (abfd)
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
   ret->sym_sec.abfd = NULL;
+  ret->tls_ldm_got.refcount = 0;
 
   return &ret->root.root;
 }
@@ -3943,6 +4112,7 @@ allocate_dynrelocs (h, inf)
     {
       asection *s;
       boolean dyn;
+      int tls_type = sh_elf_hash_entry (h)->tls_type;
 
       /* Make sure this symbol is output as a dynamic symbol.
 	 Undefined weak syms won't yet be marked as dynamic.  */
@@ -3969,8 +4139,18 @@ allocate_dynrelocs (h, inf)
       h->got.offset = s->_raw_size;
 #endif
       s->_raw_size += 4;
+      /* R_SH_TLS_GD needs 2 consecutive GOT slots.  */
+      if (tls_type == GOT_TLS_GD)
+	s->_raw_size += 4;
       dyn = htab->root.dynamic_sections_created;
-      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
+      /* 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
@@ -4006,6 +4186,9 @@ allocate_dynrelocs (h, inf)
     }
   else
     {
+      if (sh_elf_hash_entry (h)->tls_tpoff32)
+	goto keep;
+
       /* For the non-shared case, discard space for relocs against
 	 symbols which turn out to need copy relocs or are not
 	 dynamic.  */
@@ -4113,6 +4296,7 @@ sh_elf_size_dynamic_sections (output_bfd
     {
       bfd_signed_vma *local_got;
       bfd_signed_vma *end_local_got;
+      char *local_tls_type;
       bfd_size_type locsymcount;
       Elf_Internal_Shdr *symtab_hdr;
       asection *srel;
@@ -4158,6 +4342,7 @@ sh_elf_size_dynamic_sections (output_bfd
       locsymcount *= 2;
 #endif
       end_local_got = local_got + locsymcount;
+      local_tls_type = sh_elf_local_got_tls_type (ibfd);
       s = htab->sgot;
       srel = htab->srelgot;
       for (; local_got < end_local_got; ++local_got)
@@ -4166,14 +4351,28 @@ sh_elf_size_dynamic_sections (output_bfd
 	    {
 	      *local_got = s->_raw_size;
 	      s->_raw_size += 4;
+	      if (*local_tls_type == GOT_TLS_GD)
+		s->_raw_size += 4;
 	      if (info->shared)
 		srel->_raw_size += sizeof (Elf32_External_Rela);
 	    }
 	  else
 	    *local_got = (bfd_vma) -1;
+	  ++local_tls_type;
 	}
     }
 
+  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;
+
   /* 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 +4508,7 @@ sh_elf_relocate_section (output_bfd, inf
   asection *sgotplt;
   asection *splt;
   asection *sreloc;
+  asection *srelgot;
 
   htab = sh_elf_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -4320,6 +4520,7 @@ sh_elf_relocate_section (output_bfd, inf
   sgotplt = htab->sgotplt;
   splt = htab->splt;
   sreloc = NULL;
+  srelgot = NULL;
 
   rel = relocs;
   relend = relocs + input_section->reloc_count;
@@ -4335,6 +4536,8 @@ sh_elf_relocate_section (output_bfd, inf
       bfd_vma addend = (bfd_vma) 0;
       bfd_reloc_status_type r;
       int seen_stt_datalabel = 0;
+      bfd_vma off;
+      int tls_type;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
@@ -4356,6 +4559,8 @@ sh_elf_relocate_section (output_bfd, inf
 	      && r_type <= (int) R_SH_LAST_INVALID_RELOC_3)
 	  || (   r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
 	      && r_type <= (int) R_SH_LAST_INVALID_RELOC_4)
+	  || (   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,15 +4731,18 @@ sh_elf_relocate_section (output_bfd, inf
 			     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)))
+		  || (sec->output_section == NULL
+		      && (sh_elf_hash_entry (h)->tls_type == GOT_TLS_IE
+			  || sh_elf_hash_entry (h)->tls_type == GOT_TLS_GD)))
 		relocation = 0;
 	      else if (sec->output_section == NULL)
 		{
 		  (*_bfd_error_handler)
-		    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
+		    (_("%s: 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 +4987,6 @@ sh_elf_relocate_section (output_bfd, inf
 
 	  if (h != NULL)
 	    {
-	      bfd_vma off;
 	      boolean dyn;
 
 	      off = h->got.offset;
@@ -4837,8 +5044,6 @@ sh_elf_relocate_section (output_bfd, inf
 	    }
 	  else
 	    {
-	      bfd_vma off;
-
 #ifdef INCLUDE_SHMEDIA
 	      if (rel->r_addend)
 		{
@@ -4872,11 +5077,14 @@ sh_elf_relocate_section (output_bfd, inf
 
 		  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 +5218,450 @@ sh_elf_relocate_section (output_bfd, inf
 				   rel->r_offset, sec, start, end);
 	    break;
 	  }
+
+	case R_SH_TLS_GD_32:
+	case R_SH_TLS_IE_32:
+	  r_type = sh_elf_optimized_tls_reloc (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;
+	  }
 	}
 
     relocation_done:
@@ -5157,6 +5809,20 @@ sh_elf_get_relocated_section_contents (o
   return NULL;
 }
 
+/* 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;
+}
+
 static asection *
 sh_elf_gc_mark_hook (sec, info, rel, h, sym)
      asection *sec;
@@ -5224,8 +5890,15 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
-    switch (ELF32_R_TYPE (rel->r_info))
+    switch (sh_elf_optimized_tls_reloc (info, ELF32_R_TYPE (rel->r_info),
+				   ELF32_R_SYM (rel->r_info)
+				   >= symtab_hdr->sh_info))
       {
+      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;
+
       case R_SH_GOT32:
       case R_SH_GOTOFF:
       case R_SH_GOTPC:
@@ -5245,6 +5918,8 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
       case R_SH_GOTPC_MEDHI16:
       case R_SH_GOTPC_HI16:
 #endif
+      case R_SH_TLS_GD_32:
+      case R_SH_TLS_IE_32:
 	r_symndx = ELF32_R_SYM (rel->r_info);
 	if (r_symndx >= symtab_hdr->sh_info)
 	  {
@@ -5388,9 +6063,39 @@ sh_elf_copy_indirect_symbol (bed, dir, i
   edir->gotplt_refcount = eind->gotplt_refcount;
   eind->gotplt_refcount = 0;
 
+  if (ind->root.type == bfd_link_hash_indirect
+      && dir->got.refcount <= 0)
+    {
+      edir->tls_type = eind->tls_type;
+      eind->tls_type = GOT_UNKNOWN;
+    }
+
   _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
 
+static int
+sh_elf_optimized_tls_reloc (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;
+}
+
 /* 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 +6117,8 @@ sh_elf_check_relocs (abfd, info, sec, re
   asection *sgot;
   asection *srelgot;
   asection *sreloc;
+  unsigned int r_type;
+  int tls_type, old_tls_type;
 
   sgot = NULL;
   srelgot = NULL;
@@ -5437,15 +6144,27 @@ sh_elf_check_relocs (abfd, info, sec, re
       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];
 
+      r_type = sh_elf_optimized_tls_reloc (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;
+
       /* 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 +6192,9 @@ sh_elf_check_relocs (abfd, info, sec, re
 	    case R_SH_GOTPC_MEDHI16:
 	    case R_SH_GOTPC_HI16:
 #endif
+	    case R_SH_TLS_GD_32:
+	    case R_SH_TLS_LD_32:
+	    case R_SH_TLS_IE_32:
 	      if (dynobj == NULL)
 		htab->root.dynobj = dynobj = abfd;
 	      if (! create_got_section (dynobj, info))
@@ -5484,7 +6206,7 @@ sh_elf_check_relocs (abfd, info, sec, re
 	    }
 	}
 
-      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 +6223,12 @@ sh_elf_check_relocs (abfd, info, sec, re
 	  break;
 
 	force_got:
+	case R_SH_TLS_IE_32:
+	  if (info->shared)
+	    info->flags |= DF_STATIC_TLS;
+
+	  /* FALLTHROUGH */
+	case R_SH_TLS_GD_32:
 	case R_SH_GOT32:
 #ifdef INCLUDE_SHMEDIA
 	case R_SH_GOT_LOW16:
@@ -5510,8 +6238,24 @@ sh_elf_check_relocs (abfd, info, sec, re
 	case R_SH_GOT10BY4:
 	case R_SH_GOT10BY8:
 #endif
+	  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;
+	    }
+
 	  if (h != NULL)
-	    h->got.refcount += 1;
+	    {
+	      h->got.refcount += 1;
+	      old_tls_type = sh_elf_hash_entry (h)->tls_type;
+	    }
 	  else
 	    {
 	      bfd_signed_vma *local_got_refcounts;
@@ -5530,14 +6274,54 @@ sh_elf_check_relocs (abfd, info, sec, re
 		     codelabel local GOT offsets.  */
 		  size *= 2;
 #endif
+		  size += symtab_hdr->sh_info;
 		  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 	INCLUDE_SHMEDIA
+		  /* Take care of both the datalabel and codelabel local
+		     GOT offsets.  */
+		  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
 		}
 	      local_got_refcounts[r_symndx] += 1;
+	      old_tls_type = sh_elf_local_got_tls_type (abfd) [r_symndx];
+	    }
+
+	  /* If a TLS symbol is accessed using IE at least once,
+	     there is no point to use dynamic model for it.  */
+	  if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+	      && (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;
 
 	case R_SH_GOTPLT32:
@@ -5620,7 +6404,7 @@ sh_elf_check_relocs (abfd, info, sec, re
 	     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 +6494,110 @@ sh_elf_check_relocs (abfd, info, sec, re
 		}
 
 	      p->count += 1;
-	      if (ELF32_R_TYPE (rel->r_info) == R_SH_REL32)
+	      if (r_type == R_SH_REL32)
 		p->pc_count += 1;
 	    }
 
 	  break;
+
+	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;
+
+	default:
+	  break;
 	}
     }
 
@@ -5835,6 +6718,29 @@ sh_elf_merge_private_data (ibfd, obfd)
 }
 #endif /* not sh_elf_merge_private_data */
 
+/* Override the generic function because we need to store sh_elf_obj_tdata
+   as the specific tdata. We set also the machine architecture from flags
+   here.  */
+
+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;
+}
+
 /* Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
 
@@ -5991,7 +6897,9 @@ sh_elf_finish_dynamic_symbol (output_bfd
 	}
     }
 
-  if (h->got.offset != (bfd_vma) -1)
+  if (h->got.offset != (bfd_vma) -1
+      && sh_elf_hash_entry (h)->tls_type != GOT_TLS_GD
+      && sh_elf_hash_entry (h)->tls_type != GOT_TLS_IE)
     {
       asection *sgot;
       asection *srel;
@@ -6280,7 +7188,8 @@ sh_elf_reloc_type_class (rela)
 #define elf_backend_relocate_section	sh_elf_relocate_section
 #define bfd_elf32_bfd_get_relocated_section_contents \
 					sh_elf_get_relocated_section_contents
-#define elf_backend_object_p		sh_elf_set_mach_from_flags
+#define bfd_elf32_mkobject		sh_elf_mkobject
+#define elf_backend_object_p		sh_elf_object_p
 #define bfd_elf32_bfd_set_private_bfd_flags \
 					sh_elf_set_private_flags
 #define bfd_elf32_bfd_copy_private_bfd_data \
diff -u3prN 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	Wed Oct  9 08:00:17 2002
@@ -2575,6 +2575,22 @@ ENUMX
   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 -u3prN 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	Thu Oct 10 06:17:43 2002
@@ -3241,10 +3241,16 @@ sh_force_relocation (fix)
   if (sh_local_pcrel (fix))
     return 0;
 
+  /* Make sure some relocations get emitted.  */
   if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
       || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
       || fix->fx_r_type == BFD_RELOC_SH_LOOP_START
       || fix->fx_r_type == BFD_RELOC_SH_LOOP_END
+      || fix->fx_r_type == BFD_RELOC_SH_TLS_GD_32
+      || fix->fx_r_type == BFD_RELOC_SH_TLS_LD_32
+      || fix->fx_r_type == BFD_RELOC_SH_TLS_IE_32
+      || fix->fx_r_type == BFD_RELOC_SH_TLS_LDO_32
+      || fix->fx_r_type == BFD_RELOC_SH_TLS_LE_32
       || S_FORCE_RELOC (fix->fx_addsy))
     return 1;
 
@@ -3546,11 +3552,16 @@ md_apply_fix3 (fixP, valP, seg)
 
     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 +4026,16 @@ sh_parse_name (name, exprP, nextcharP)
     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 -u3prN 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	Wed Oct  9 21:47:41 2002
@@ -135,5 +135,12 @@ if [istarget sh*-*-*] then {
 
     if {[istarget sh*-*elf] || [istarget sh*-linux*]} then {
 	run_dump_test "pic"
+
+	# Test TLS.
+	run_dump_test "tlsd"
+
+	run_dump_test "tlspic"
+
+	run_dump_test "tlsnopic"
     }
 }
diff -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 2002
@@ -167,7 +167,17 @@ START_RELOC_NUMBERS (elf_sh_reloc_type)
   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 @@ START_RELOC_NUMBERS (elf_sh_reloc_type)
   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 -u3prN ORIG/src/ld/testsuite/ld-sh/rd-sh.exp LOCAL/src/ld/testsuite/ld-sh/rd-sh.exp
--- ORIG/src/ld/testsuite/ld-sh/rd-sh.exp	Mon Oct 15 00:18:11 2001
+++ LOCAL/src/ld/testsuite/ld-sh/rd-sh.exp	Wed Oct  9 13:14:18 2002
@@ -33,4 +33,11 @@ foreach shtest $rd_test_list {
     # We need to strip the ".d", but can leave the dirname.
     verbose [file rootname $shtest]
     run_dump_test [file rootname $shtest]
+    if [string match $srcdir/$subdir/*-dso.d $shtest] {
+	set cmd "cp tmpdir/dump tmpdir/[file rootname [file tail $shtest]].so"
+	send_log "$cmd\n"
+	set cmdret [catch "exec $cmd" comp_output]
+	send_log "$comp_output\n"
+	# FIXME: What if it fails?  Need we do something?
+    }
 }
diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlsbin-0-dso.d LOCAL/src/ld/testsuite/ld-sh/tlsbin-0-dso.d
--- ORIG/src/ld/testsuite/ld-sh/tlsbin-0-dso.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin-0-dso.d	Wed Oct  9 22:44:23 2002
@@ -0,0 +1,9 @@
+#source: tlslib.s
+#as: -little
+#ld: -shared -EL
+#objdump: -drj.text
+#target: sh*-*-linux* sh*-*-netbsd*
+
+.*: +file format elf32-sh.*
+
+#pass
diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlsbin-1.d LOCAL/src/ld/testsuite/ld-sh/tlsbin-1.d
--- ORIG/src/ld/testsuite/ld-sh/tlsbin-1.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin-1.d	Wed Oct  9 22:43:40 2002
@@ -0,0 +1,296 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -little
+#ld: -EL tmpdir/tlsbin-0-dso.so
+#objdump: -drj.text
+#target: sh*-*-linux* sh*-*-netbsd*
+
+.*: +file format elf32-sh.*
+
+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 -u3prN ORIG/src/ld/testsuite/ld-sh/tlsbin-2.d LOCAL/src/ld/testsuite/ld-sh/tlsbin-2.d
--- ORIG/src/ld/testsuite/ld-sh/tlsbin-2.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin-2.d	Thu Oct 10 08:32:40 2002
@@ -0,0 +1,145 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -little
+#ld: -EL tmpdir/tlsbin-0-dso.so
+#readelf: -Ssrl
+#target: sh*-*-linux* sh*-*-netbsd*
+
+There are [0-9]+ 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 .*
+#...
+  \[[0-9a-f]+\] \.got +PROGBITS +0+4130c0 .*
+  \[[0-9a-f]+\] \.sbss +.*
+  \[[0-9a-f]+\] \.bss +.*
+#...
+  \[[0-9a-f]+\] \.shstrtab +.*
+  \[[0-9a-f]+\] \.symtab +.*
+  \[[0-9a-f]+\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x402000
+There are [0-9]+ 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  0000[0-9a-f]+97 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 [0-9]+ 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
+#...
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+#...
+
+Symbol table '\.symtab' contains [0-9]+ 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 *
+#...
+ +[0-9]+: 00000008 +0 TLS +LOCAL  DEFAULT +10 sl1
+ +[0-9]+: 0000000c +0 TLS +LOCAL  DEFAULT +10 sl2
+ +[0-9]+: 00000020 +0 TLS +LOCAL  DEFAULT +11 bl1
+ +[0-9]+: 00000024 +0 TLS +LOCAL  DEFAULT +11 bl2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT  UND __tls_get_addr
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1
+ +[0-9]+: 0+402000 +0 FUNC +GLOBAL DEFAULT +8 _start
+#...
+ +[0-9]+: 0+401000 +0 FUNC +GLOBAL DEFAULT +8 fn2
+#...
+ +[0-9]+: 00000004 +0 TLS +GLOBAL DEFAULT +10 sg2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: 00000010 +0 TLS +GLOBAL HIDDEN +10 sh1
+ +[0-9]+: 004130e0 +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +[0-9]+: 00000014 +0 TLS +GLOBAL HIDDEN +10 sh2
+ +[0-9]+: 0000001c +0 TLS +GLOBAL DEFAULT +11 bg2
+ +[0-9]+: 00000018 +0 TLS +GLOBAL DEFAULT +11 bg1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT +9 __data_start
+#pass
diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlsbin-3.d LOCAL/src/ld/testsuite/ld-sh/tlsbin-3.d
--- ORIG/src/ld/testsuite/ld-sh/tlsbin-3.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin-3.d	Wed Oct  9 22:58:10 2002
@@ -0,0 +1,12 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -little
+#ld: -EL tmpdir/tlsbin-0-dso.so
+#objdump: -sj.got
+#target: sh*-*-linux* sh*-*-netbsd*
+
+.*: +file format elf32-sh.*
+
+Contents of section \.got:
+ 4130c0 [0-9a-f]+ 00000000 00000000 [0-9a-f]+  .*
+ 4130d0 00000000 00000000 00000000 00000000  .*
diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlsbin-4.d LOCAL/src/ld/testsuite/ld-sh/tlsbin-4.d
--- ORIG/src/ld/testsuite/ld-sh/tlsbin-4.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlsbin-4.d	Wed Oct  9 22:58:19 2002
@@ -0,0 +1,12 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: -little
+#ld: -EL tmpdir/tlsbin-0-dso.so
+#objdump: -sj.tdata
+#target: sh*-*-linux* sh*-*-netbsd*
+
+.*: +file format elf32-sh.*
+
+Contents of section .tdata:
+ 413000 11000000 12000000 41000000 42000000  .*
+ 413010 01010000 02010000 +.*
diff -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN ORIG/src/ld/testsuite/ld-sh/tlspic-1.d LOCAL/src/ld/testsuite/ld-sh/tlspic-1.d
--- ORIG/src/ld/testsuite/ld-sh/tlspic-1.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic-1.d	Wed Oct  9 23:07:44 2002
@@ -0,0 +1,292 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -little
+#ld: -shared -EL
+#objdump: -drj.text
+#target: sh*-*-linux* sh*-*-netbsd*
+
+.*: +file format elf32-sh.*
+
+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	[0-9a-f]+ <fn1\+0x214>,r0
+ [0-9a-f]+:	82 dc       	mov\.l	[0-9a-f]+ <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	[0-9a-f]+ <fn1\+0x28>,r4	! 0x30
+ [0-9a-f]+:	04 c7       	mova	[0-9a-f]+ <fn1\+0x2c>,r0
+ [0-9a-f]+:	04 d1       	mov\.l	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <fn1\+0x68>,r4	! 0x10
+ [0-9a-f]+:	04 c7       	mova	[0-9a-f]+ <fn1\+0x6c>,r0
+ [0-9a-f]+:	03 d1       	mov\.l	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <fn1\+0xa8>,r4	! 0x3c
+ [0-9a-f]+:	04 c7       	mova	[0-9a-f]+ <fn1\+0xac>,r0
+ [0-9a-f]+:	03 d1       	mov\.l	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <fn1\+0xe8>,r4	! 0x24
+ [0-9a-f]+:	04 c7       	mova	[0-9a-f]+ <fn1\+0xec>,r0
+ [0-9a-f]+:	03 d1       	mov\.l	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <fn1\+0x128>,r4	! 0x1c
+ [0-9a-f]+:	04 c7       	mova	[0-9a-f]+ <fn1\+0x12c>,r0
+ [0-9a-f]+:	03 d1       	mov\.l	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <fn1\+0x188>,r4	! 0x1c
+ [0-9a-f]+:	04 c7       	mova	[0-9a-f]+ <fn1\+0x18c>,r0
+ [0-9a-f]+:	03 d1       	mov\.l	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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	[0-9a-f]+ <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 -u3prN ORIG/src/ld/testsuite/ld-sh/tlspic-2.d LOCAL/src/ld/testsuite/ld-sh/tlspic-2.d
--- ORIG/src/ld/testsuite/ld-sh/tlspic-2.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic-2.d	Thu Oct 10 08:31:51 2002
@@ -0,0 +1,132 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -little
+#ld: -shared -EL
+#readelf: -Ssrl
+#target: sh*-*-linux* sh*-*-netbsd*
+
+There are [0-9]+ 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+[0-9a-f]+ .*
+  \[ 8\] \.data +.*
+  \[ 9\] \.tdata +PROGBITS +0+[0-9a-f]+ [0-9a-f]+ 0+018 00 WAT  0   0  1
+  \[10\] \.tbss +NOBITS +0+[0-9a-f]+ [0-9a-f]+ 0+008 00 WAT  0   0  1
+  \[11\] \.dynamic +DYNAMIC +0+[0-9a-f]+ .*
+#...
+  \[[0-9a-f]+\] \.got +PROGBITS +0+[0-9a-f]+ .*
+  \[[0-9a-f]+\] \.sbss +.*
+  \[[0-9a-f]+\] \.bss +.*
+#...
+  \[[0-9a-f]+\] \.shstrtab +.*
+  \[[0-9a-f]+\] \.symtab +.*
+  \[[0-9a-f]+\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x[0-9a-f]+
+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+[0-9a-f]+  00000095 R_SH_TLS_DTPMOD32 +0+00
+0+[0-9a-f]+  00000097 R_SH_TLS_TPOFF32 +0+0c
+0+[0-9a-f]+  00000095 R_SH_TLS_DTPMOD32 +0+00
+0+[0-9a-f]+  00000095 R_SH_TLS_DTPMOD32 +0+00
+0+[0-9a-f]+  00000097 R_SH_TLS_TPOFF32 +0+1c
+0+[0-9a-f]+  00000095 R_SH_TLS_DTPMOD32 +0+00
+0+[0-9a-f]+  00000097 R_SH_TLS_TPOFF32 +0+14
+0+[0-9a-f]+  0000[0-9a-f]+95 R_SH_TLS_DTPMOD32 +0+ +sg1 \+ 0
+0+[0-9a-f]+  0000[0-9a-f]+96 R_SH_TLS_DTPOFF32 +0+ +sg1 \+ 0
+0+[0-9a-f]+  0000[0-9a-f]+97 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+[0-9a-f]+  0000[0-9a-f]+a4 R_SH_JMP_SLOT +[0-9a-f]+ +__tls_get_addr \+ 0
+
+Symbol table '\.dynsym' contains [0-9]+ 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 *
+#...
+ +[0-9a-f]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  UND __tls_get_addr
+ +[0-9a-f]+: 0+00 +0 TLS +GLOBAL DEFAULT +9 sg1
+#...
+ +[0-9a-f]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+#...
+ +[0-9a-f]+: 0+04 +0 TLS +GLOBAL DEFAULT +9 sg2
+#...
+
+Symbol table '\.symtab' contains [0-9]+ 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 *
+#...
+ +[0-9]+: 0+08 +0 TLS +LOCAL  DEFAULT +9 sl1
+ +[0-9]+: 0+0c +0 TLS +LOCAL  DEFAULT +9 sl2
+ +[0-9]+: 0+18 +0 TLS +LOCAL  HIDDEN +10 sH1
+ +[0-9]+: 0+1c +0 TLS +LOCAL  HIDDEN +10 sH2
+ +[0-9]+: 0+10 +0 TLS +LOCAL  HIDDEN +9 sh1
+ +[0-9]+: 0+14 +0 TLS +LOCAL  HIDDEN +9 sh2
+#...
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  UND __tls_get_addr
+ +[0-9]+: 0+00 +0 TLS +GLOBAL DEFAULT +9 sg1
+#...
+ +[0-9]+: [0-9a-f]+ +0 FUNC    GLOBAL DEFAULT +7 fn1
+#...
+ +[0-9]+: 0+04 +0 TLS +GLOBAL DEFAULT +9 sg2
+#pass
diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlspic-3.d LOCAL/src/ld/testsuite/ld-sh/tlspic-3.d
--- ORIG/src/ld/testsuite/ld-sh/tlspic-3.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic-3.d	Wed Oct  9 23:02:23 2002
@@ -0,0 +1,15 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -little
+#ld: -shared -EL
+#objdump: -sj.got
+#target: sh*-*-linux* sh*-*-netbsd*
+
+.*: +file format elf32-sh.*
+
+Contents of section \.got:
+ [0-9a-f]+ [0-9a-f]+ 00000000 00000000 [0-9a-f]+  .*
+ [0-9a-f]+ 00000000 08000000 00000000 00000000  .*
+ [0-9a-f]+ 00000000 00000000 18000000 00000000  .*
+ [0-9a-f]+ 00000000 00000000 00000000 00000000  .*
+ [0-9a-f]+ 10000000 00000000 +.*
diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlspic-4.d LOCAL/src/ld/testsuite/ld-sh/tlspic-4.d
--- ORIG/src/ld/testsuite/ld-sh/tlspic-4.d	Thu Jan  1 09:00:00 1970
+++ LOCAL/src/ld/testsuite/ld-sh/tlspic-4.d	Wed Oct  9 23:00:47 2002
@@ -0,0 +1,12 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: -little
+#ld: -shared -EL
+#objdump: -sj.tdata
+#target: sh*-*-linux* sh*-*-netbsd*
+
+.*: +file format elf32-sh.*
+
+Contents of section \.tdata:
+ [0-9a-f]+ 11000000 12000000 41000000 42000000  .*
+ [0-9a-f]+ 01010000 02010000 +.*
diff -u3prN 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	Wed Oct  9 08:00:17 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 -u3prN 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	Wed Oct  9 08:00:17 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]