This is the mail archive of the binutils@sourceware.org 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]

Re: RFC: TLS improvements for IA32 and AMD64/EM64T


On Sep 17, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Sep 16, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:
>> On Sep 16, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:
>>> Over the past few months, I've been working on porting to IA32 and
>>> AMD64/EM64T the interesting bits of the TLS design I came up with for
>>> FR-V, achieving some impressive speedups along with slight code size
>>> reductions in the most common cases.
>> Here's the patch.  Built and tested on x86_64-linux-gnu and
>> i686-pc-linux-gnu.  Ok to install?

> Updated patch, using different relocation numbers, and different
> dynamic table numbers as well.  Same tests run and passed.  Ok to
> install?

Updated again.  Only significant change is that we no longer emit the
new dynamic table entries on x86-64 if we're linking with -z now,
since then we know we won't be resolving the relocations lazily, and
so the entries are not used at all.

Index: bfd/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	Introduce TLS descriptors for i386 and x86_64.
	* reloc.c (BFD_RELOC_386_TLS_GOTDESC, BFD_RELOC_386_TLS_DESC,
	BFD_RELOC_386_TLS_DESC_CALL, BFD_RELOC_X86_64_GOTPC32_TLSDESC,
	BFD_RELOC_X86_64_TLSDESC, BFD_RELOC_X86_64_TLSDESC_CALL): New.
	* libbfd.h, bfd-in2.h: Rebuilt.
	* elf32-i386.c (elf_howto_table): New relocations.
	(R_386_tls): Adjust.
	(elf_i386_reloc_type_lookup): Map new relocations.
	(GOT_TLS_GDESC, GOT_TLS_GD_BOTH_P): New macros.
	(GOT_TLS_GD_P, GOT_TLS_GDESC_P, GOT_TLS_GD_ANY_P): New macros.
	(struct elf_i386_link_hash_entry): Add tlsdesc_got field.
	(struct elf_i386_obj_tdata): Add local_tlsdesc_gotent field.
	(elf_i386_local_tlsdesc_gotent): New macro.
	(struct elf_i386_link_hash_table): Add sgotplt_jump_table_size.
	(elf_i386_compute_jump_table_size): New macro.
	(link_hash_newfunc): Initialize tlsdesc_got.
	(elf_i386_link_hash_table_create): Set sgotplt_jump_table_size.
	(elf_i386_tls_transition): Handle R_386_TLS_GOTDESC and
	R_386_TLS_DESC_CALL.
	(elf_i386_check_relocs): Likewise.  Allocate space for
	local_tlsdesc_gotent.
	(elf_i386_gc_sweep_hook): Handle R_386_TLS_GOTDESC and
	R_386_TLS_DESC_CALL.
	(allocate_dynrelocs): Count function PLT relocations.  Reserve
	space for TLS descriptors and relocations.
	(elf_i386_size_dynamic_sections): Reserve space for TLS
	descriptors and relocations.  Set up sgotplt_jump_table_size.
	Don't zero reloc_count in srelplt.
	(elf_i386_always_size_sections): New.  Set up _TLS_MODULE_BASE_.
	(elf_i386_relocate_section): Handle R_386_TLS_GOTDESC and
	R_386_TLS_DESC_CALL.
	(elf_i386_finish_dynamic_symbol): Use GOT_TLS_GD_ANY_P.
	(elf_backend_always_size_sections): Define.
	* elf64-x86-64.c (x86_64_elf_howto): Add R_X86_64_GOTPC32_TLSDESC,
	R_X86_64_TLSDESC, R_X86_64_TLSDESC_CALL.
	(R_X86_64_standard): Adjust.
	(x86_64_reloc_map): Map new relocs.
	(elf64_x86_64_rtype_to_howto): New, split out of...
	(elf64_x86_64_info_to_howto): ... this function, and...
	(elf64_x86_64_reloc_type_lookup): ... use it to map elf_reloc_val.
	(GOT_TLS_GDESC, GOT_TLS_GD_BOTH_P): New macros.
	(GOT_TLS_GD_P, GOT_TLS_GDESC_P, GOT_TLS_GD_ANY_P): New macros.
	(struct elf64_x86_64_link_hash_entry): Add tlsdesc_got field.
	(struct elf64_x86_64_obj_tdata): Add local_tlsdesc_gotent field.
	(elf64_x86_64_local_tlsdesc_gotent): New macro.
	(struct elf64_x86_64_link_hash_table): Add tlsdesc_plt,
	tlsdesc_got and sgotplt_jump_table_size fields.
	(elf64_x86_64_compute_jump_table_size): New macro.
	(link_hash_newfunc): Initialize tlsdesc_got.
	(elf64_x86_64_link_hash_table_create): Initialize new fields.
	(elf64_x86_64_tls_transition): Handle R_X86_64_GOTPC32_TLSDESC and
	R_X86_64_TLSDESC_CALL.
	(elf64_x86_64_check_relocs): Likewise.  Allocate space for
	local_tlsdesc_gotent.
	(elf64_x86_64_gc_sweep_hook): Handle R_X86_64_GOTPC32_TLSDESC and
	R_X86_64_TLSDESC_CALL.
	(allocate_dynrelocs): Count function PLT relocations.  Reserve
	space for TLS descriptors and relocations.
	(elf64_x86_64_size_dynamic_sections): Reserve space for TLS
	descriptors and relocations.  Set up sgotplt_jump_table_size,
	tlsdesc_plt and tlsdesc_got.  Make room for them.  Don't zero
	reloc_count in srelplt.  Add dynamic entries for DT_TLSDESC_PLT
	and DT_TLSDESC_GOT.
	(elf64_x86_64_always_size_sections): New.  Set up
	_TLS_MODULE_BASE_.
	(elf64_x86_64_relocate_section): Handle R_386_TLS_GOTDESC and
	R_386_TLS_DESC_CALL.
	(elf64_x86_64_finish_dynamic_symbol): Use GOT_TLS_GD_ANY_P.
	(elf64_x86_64_finish_dynamic_sections): Set DT_TLSDESC_PLT and
	DT_TLSDESC_GOT.  Set up TLS descriptor lazy resolver PLT entry.
	(elf_backend_always_size_sections): Define.

Index: binutils/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	Introduce TLS descriptors for i386 and x86_64.
	* readelf.c (get_dynamic_type): Handle DT_TLSDESC_GOT and
	DT_TLSDESC_PLT.

Index: gas/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	Introduce TLS descriptors for i386 and x86_64.
	* config/tc-i386.c (tc_i386_fix_adjustable): Handle
	BFD_RELOC_386_TLS_GOTDESC, BFD_RELOC_386_TLS_DESC_CALL,
	BFD_RELOC_X86_64_GOTPC32_TLSDESC, BFD_RELOC_X86_64_TLSDESC_CALL.
	(optimize_disp): Emit fix up for BFD_RELOC_386_TLS_DESC_CALL and
	BFD_RELOC_X86_64_TLSDESC_CALL immediately, and clear the
	displacement bits.
	(build_modrm_byte): Set up zero modrm for TLS desc calls.
	(lex_got): Handle @tlsdesc and @tlscall.
	(md_apply_fix, tc_gen_reloc): Handle the new relocations.

Index: include/elf/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	Introduce TLS descriptors for i386 and x86_64.
	* common.h (DT_TLSDESC_GOT, DT_TLSDESC_PLT): New.
	* i386.h (R_386_TLS_GOTDESC, R_386_TLS_DESC_CALL, R_386_TLS_DESC):
	New.
	* x86-64.h (R_X86_64_GOTPC32_TLSDESC, R_X86_64_TLSDESC_CALL,
	R_X86_64_TLSDESC): New.

Index: ld/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	Introduce TLS descriptors for i386 and x86_64.
	* ld-i386/i386.exp: Run on x86_64-*-linux* and amd64-*-linux*.
	Add new tests.
	* ld-i386/pcrel16.d: Add -melf_i386.
	* ld-i386/pcrel8.d: Likewise.
	* ld-i386/tlsbindesc.dd: New.
	* ld-i386/tlsbindesc.rd: New.
	* ld-i386/tlsbindesc.s: New.
	* ld-i386/tlsbindesc.sd: New.
	* ld-i386/tlsbindesc.td: New.
	* ld-i386/tlsdesc.dd: New.
	* ld-i386/tlsdesc.rd: New.
	* ld-i386/tlsdesc.s: New.
	* ld-i386/tlsdesc.sd: New.
	* ld-i386/tlsdesc.td: New.
	* ld-i386/tlsgdesc.dd: New.
	* ld-i386/tlsgdesc.rd: New.
	* ld-i386/tlsgdesc.s: New.
	* ld-x86-64/x86-64.exp: Run new tests.
	* ld-x86-64/tlsbindesc.dd: New.
	* ld-x86-64/tlsbindesc.rd: New.
	* ld-x86-64/tlsbindesc.s: New.
	* ld-x86-64/tlsbindesc.sd: New.
	* ld-x86-64/tlsbindesc.td: New.
	* ld-x86-64/tlsdesc.dd: New.
	* ld-x86-64/tlsdesc.pd: New.
	* ld-x86-64/tlsdesc.rd: New.
	* ld-x86-64/tlsdesc.s: New.
	* ld-x86-64/tlsdesc.sd: New.
	* ld-x86-64/tlsdesc.td: New.
	* ld-x86-64/tlsgdesc.dd: New.
	* ld-x86-64/tlsgdesc.rd: New.
	* ld-x86-64/tlsgdesc.s: New.

Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/uberbaum/./bfd/bfd-in2.h,v
retrieving revision 1.366
diff -u -p -r1.366 bfd-in2.h
--- bfd/bfd-in2.h 8 Sep 2005 12:49:18 -0000 1.366
+++ bfd/bfd-in2.h 21 Sep 2005 06:12:08 -0000
@@ -2647,6 +2647,9 @@ in the instruction.  */
   BFD_RELOC_386_TLS_DTPMOD32,
   BFD_RELOC_386_TLS_DTPOFF32,
   BFD_RELOC_386_TLS_TPOFF32,
+  BFD_RELOC_386_TLS_GOTDESC,
+  BFD_RELOC_386_TLS_DESC_CALL,
+  BFD_RELOC_386_TLS_DESC,
 
 /* x86-64/elf relocations  */
   BFD_RELOC_X86_64_GOT32,
@@ -2667,6 +2670,9 @@ in the instruction.  */
   BFD_RELOC_X86_64_TPOFF32,
   BFD_RELOC_X86_64_GOTOFF64,
   BFD_RELOC_X86_64_GOTPC32,
+  BFD_RELOC_X86_64_GOTPC32_TLSDESC,
+  BFD_RELOC_X86_64_TLSDESC_CALL,
+  BFD_RELOC_X86_64_TLSDESC,
 
 /* ns32k relocations  */
   BFD_RELOC_NS32K_IMM_8,
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/uberbaum/./bfd/elf32-i386.c,v
retrieving revision 1.149
diff -u -p -r1.149 elf32-i386.c
--- bfd/elf32-i386.c 31 Aug 2005 23:45:45 -0000 1.149
+++ bfd/elf32-i386.c 21 Sep 2005 06:12:10 -0000
@@ -126,9 +126,19 @@ static reloc_howto_type elf_howto_table[
   HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
 	bfd_elf_generic_reloc, "R_386_TLS_TPOFF32",
 	TRUE, 0xffffffff, 0xffffffff, FALSE),
+  EMPTY_HOWTO (38),
+  HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+	bfd_elf_generic_reloc, "R_386_TLS_GOTDESC",
+	TRUE, 0xffffffff, 0xffffffff, FALSE),
+  HOWTO(R_386_TLS_DESC_CALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+	bfd_elf_generic_reloc, "R_386_TLS_DESC_CALL",
+	FALSE, 0, 0, FALSE),
+  HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+	bfd_elf_generic_reloc, "R_386_TLS_DESC",
+	TRUE, 0xffffffff, 0xffffffff, FALSE),
 
   /* Another gap.  */
-#define R_386_tls (R_386_TLS_TPOFF32 + 1 - R_386_tls_offset)
+#define R_386_tls (R_386_TLS_DESC + 1 - R_386_tls_offset)
 #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_tls)
 
 /* GNU extension to record C++ vtable hierarchy.  */
@@ -292,6 +302,18 @@ elf_i386_reloc_type_lookup (bfd *abfd AT
       TRACE ("BFD_RELOC_386_TLS_TPOFF32");
       return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset];
 
+    case BFD_RELOC_386_TLS_GOTDESC:
+      TRACE ("BFD_RELOC_386_TLS_GOTDESC");
+      return &elf_howto_table[R_386_TLS_GOTDESC - R_386_tls_offset];
+
+    case BFD_RELOC_386_TLS_DESC_CALL:
+      TRACE ("BFD_RELOC_386_TLS_DESC_CALL");
+      return &elf_howto_table[R_386_TLS_DESC_CALL - R_386_tls_offset];
+
+    case BFD_RELOC_386_TLS_DESC:
+      TRACE ("BFD_RELOC_386_TLS_DESC");
+      return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset];
+
     case BFD_RELOC_VTABLE_INHERIT:
       TRACE ("BFD_RELOC_VTABLE_INHERIT");
       return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
@@ -559,7 +581,20 @@ struct elf_i386_link_hash_entry
 #define GOT_TLS_IE_POS	5
 #define GOT_TLS_IE_NEG	6
 #define GOT_TLS_IE_BOTH 7
+#define GOT_TLS_GDESC	8
+#define GOT_TLS_GD_BOTH_P(type)						\
+  ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
+#define GOT_TLS_GD_P(type)						\
+  ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GDESC_P(type)						\
+  ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GD_ANY_P(type)						\
+  (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
   unsigned char tls_type;
+
+  /* Offset of the GOTPLT entry reserved for the TLS descriptor,
+     starting at the end of the jump table.  */
+  bfd_vma tlsdesc_got;
 };
 
 #define elf_i386_hash_entry(ent) ((struct elf_i386_link_hash_entry *)(ent))
@@ -570,6 +605,9 @@ struct elf_i386_obj_tdata
 
   /* tls_type for each local got entry.  */
   char *local_got_tls_type;
+
+  /* GOTPLT entries for TLS descriptors.  */
+  bfd_vma *local_tlsdesc_gotent;
 };
 
 #define elf_i386_tdata(abfd) \
@@ -578,6 +616,9 @@ struct elf_i386_obj_tdata
 #define elf_i386_local_got_tls_type(abfd) \
   (elf_i386_tdata (abfd)->local_got_tls_type)
 
+#define elf_i386_local_tlsdesc_gotent(abfd) \
+  (elf_i386_tdata (abfd)->local_tlsdesc_gotent)
+
 static bfd_boolean
 elf_i386_mkobject (bfd *abfd)
 {
@@ -620,6 +661,10 @@ struct elf_i386_link_hash_table
     bfd_vma offset;
   } tls_ldm_got;
 
+  /* The amount of space used by the reserved portion of the sgotplt
+     section, plus whatever space is used by the jump slots.  */
+  bfd_vma sgotplt_jump_table_size;
+
   /* Small local sym to section mapping cache.  */
   struct sym_sec_cache sym_sec;
 };
@@ -629,6 +674,9 @@ struct elf_i386_link_hash_table
 #define elf_i386_hash_table(p) \
   ((struct elf_i386_link_hash_table *) ((p)->hash))
 
+#define elf_i386_compute_jump_table_size(htab) \
+  ((htab)->srelplt->reloc_count * 4)
+
 /* Create an entry in an i386 ELF linker hash table.  */
 
 static struct bfd_hash_entry *
@@ -655,6 +703,7 @@ link_hash_newfunc (struct bfd_hash_entry
       eh = (struct elf_i386_link_hash_entry *) entry;
       eh->dyn_relocs = NULL;
       eh->tls_type = GOT_UNKNOWN;
+      eh->tlsdesc_got = (bfd_vma) -1;
     }
 
   return entry;
@@ -686,6 +735,7 @@ elf_i386_link_hash_table_create (bfd *ab
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
   ret->tls_ldm_got.refcount = 0;
+  ret->sgotplt_jump_table_size = 0;
   ret->sym_sec.abfd = NULL;
   ret->is_vxworks = 0;
   ret->srelplt2 = NULL;
@@ -848,6 +898,8 @@ elf_i386_tls_transition (struct bfd_link
   switch (r_type)
     {
     case R_386_TLS_GD:
+    case R_386_TLS_GOTDESC:
+    case R_386_TLS_DESC_CALL:
     case R_386_TLS_IE_32:
       if (is_local)
 	return R_386_TLS_LE_32;
@@ -952,6 +1004,8 @@ elf_i386_check_relocs (bfd *abfd,
 
 	case R_386_GOT32:
 	case R_386_TLS_GD:
+	case R_386_TLS_GOTDESC:
+	case R_386_TLS_DESC_CALL:
 	  /* This symbol requires a global offset table entry.  */
 	  {
 	    int tls_type, old_tls_type;
@@ -961,6 +1015,9 @@ elf_i386_check_relocs (bfd *abfd,
 	      default:
 	      case R_386_GOT32: tls_type = GOT_NORMAL; break;
 	      case R_386_TLS_GD: tls_type = GOT_TLS_GD; break;
+	      case R_386_TLS_GOTDESC:
+	      case R_386_TLS_DESC_CALL:
+		tls_type = GOT_TLS_GDESC; break;
 	      case R_386_TLS_IE_32:
 		if (ELF32_R_TYPE (rel->r_info) == r_type)
 		  tls_type = GOT_TLS_IE_NEG;
@@ -990,13 +1047,16 @@ elf_i386_check_relocs (bfd *abfd,
 		    bfd_size_type size;
 
 		    size = symtab_hdr->sh_info;
-		    size *= (sizeof (bfd_signed_vma) + sizeof(char));
+		    size *= (sizeof (bfd_signed_vma)
+			     + sizeof (bfd_vma) + sizeof(char));
 		    local_got_refcounts = bfd_zalloc (abfd, size);
 		    if (local_got_refcounts == NULL)
 		      return FALSE;
 		    elf_local_got_refcounts (abfd) = local_got_refcounts;
+		    elf_i386_local_tlsdesc_gotent (abfd)
+		      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
 		    elf_i386_local_got_tls_type (abfd)
-		      = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+		      = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
 		  }
 		local_got_refcounts[r_symndx] += 1;
 		old_tls_type = elf_i386_local_got_tls_type (abfd) [r_symndx];
@@ -1007,11 +1067,14 @@ elf_i386_check_relocs (bfd *abfd,
 	    /* If a TLS symbol is accessed using IE at least once,
 	       there is no point to use dynamic model for it.  */
 	    else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
-		     && (old_tls_type != GOT_TLS_GD
+		     && (! GOT_TLS_GD_ANY_P (old_tls_type)
 			 || (tls_type & GOT_TLS_IE) == 0))
 	      {
-		if ((old_tls_type & GOT_TLS_IE) && tls_type == GOT_TLS_GD)
+		if ((old_tls_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (tls_type))
 		  tls_type = old_tls_type;
+		else if (GOT_TLS_GD_ANY_P (old_tls_type)
+			 && GOT_TLS_GD_ANY_P (tls_type))
+		  tls_type |= old_tls_type;
 		else
 		  {
 		    (*_bfd_error_handler)
@@ -1319,6 +1382,8 @@ elf_i386_gc_sweep_hook (bfd *abfd,
 	  break;
 
 	case R_386_TLS_GD:
+	case R_386_TLS_GOTDESC:
+	case R_386_TLS_DESC_CALL:
 	case R_386_TLS_IE_32:
 	case R_386_TLS_IE:
 	case R_386_TLS_GOTIE:
@@ -1582,6 +1647,7 @@ allocate_dynrelocs (struct elf_link_hash
 
 	  /* We also need to make an entry in the .rel.plt section.  */
 	  htab->srelplt->size += sizeof (Elf32_External_Rel);
+	  htab->srelplt->reloc_count++;
 
 	  if (htab->is_vxworks && !info->shared)
 	    {
@@ -1615,6 +1681,9 @@ allocate_dynrelocs (struct elf_link_hash
       h->needs_plt = 0;
     }
 
+  eh = (struct elf_i386_link_hash_entry *) h;
+  eh->tlsdesc_got = (bfd_vma) -1;
+
   /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary,
      make it a R_386_TLS_LE_32 requiring no TLS entry.  */
   if (h->got.refcount > 0
@@ -1638,11 +1707,22 @@ allocate_dynrelocs (struct elf_link_hash
 	}
 
       s = htab->sgot;
-      h->got.offset = s->size;
-      s->size += 4;
-      /* R_386_TLS_GD needs 2 consecutive GOT slots.  */
-      if (tls_type == GOT_TLS_GD || tls_type == GOT_TLS_IE_BOTH)
-	s->size += 4;
+      if (GOT_TLS_GDESC_P (tls_type))
+	{
+	  eh->tlsdesc_got = htab->sgotplt->size
+	    - elf_i386_compute_jump_table_size (htab);
+	  htab->sgotplt->size += 8;
+	  h->got.offset = (bfd_vma) -2;
+	}
+      if (! GOT_TLS_GDESC_P (tls_type)
+	  || GOT_TLS_GD_P (tls_type))
+	{
+	  h->got.offset = s->size;
+	  s->size += 4;
+	  /* R_386_TLS_GD needs 2 consecutive GOT slots.  */
+	  if (GOT_TLS_GD_P (tls_type) || tls_type == GOT_TLS_IE_BOTH)
+	    s->size += 4;
+	}
       dyn = htab->elf.dynamic_sections_created;
       /* R_386_TLS_IE_32 needs one dynamic relocation,
 	 R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation,
@@ -1651,21 +1731,23 @@ allocate_dynrelocs (struct elf_link_hash
 	 global.  */
       if (tls_type == GOT_TLS_IE_BOTH)
 	htab->srelgot->size += 2 * sizeof (Elf32_External_Rel);
-      else if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+      else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
 	       || (tls_type & GOT_TLS_IE))
 	htab->srelgot->size += sizeof (Elf32_External_Rel);
-      else if (tls_type == GOT_TLS_GD)
+      else if (GOT_TLS_GD_P (tls_type))
 	htab->srelgot->size += 2 * sizeof (Elf32_External_Rel);
-      else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-		|| h->root.type != bfd_link_hash_undefweak)
+      else if (! GOT_TLS_GDESC_P (tls_type)
+	       && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+		   || h->root.type != bfd_link_hash_undefweak)
 	       && (info->shared
 		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
 	htab->srelgot->size += sizeof (Elf32_External_Rel);
+      if (GOT_TLS_GDESC_P (tls_type))
+	htab->srelplt->size += sizeof (Elf32_External_Rel);
     }
   else
     h->got.offset = (bfd_vma) -1;
 
-  eh = (struct elf_i386_link_hash_entry *) h;
   if (eh->dyn_relocs == NULL)
     return TRUE;
 
@@ -1813,6 +1895,7 @@ elf_i386_size_dynamic_sections (bfd *out
       bfd_signed_vma *local_got;
       bfd_signed_vma *end_local_got;
       char *local_tls_type;
+      bfd_vma *local_tlsdesc_gotent;
       bfd_size_type locsymcount;
       Elf_Internal_Shdr *symtab_hdr;
       asection *srel;
@@ -1855,25 +1938,42 @@ elf_i386_size_dynamic_sections (bfd *out
       locsymcount = symtab_hdr->sh_info;
       end_local_got = local_got + locsymcount;
       local_tls_type = elf_i386_local_got_tls_type (ibfd);
+      local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd);
       s = htab->sgot;
       srel = htab->srelgot;
-      for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+      for (; local_got < end_local_got;
+	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
 	{
+	  *local_tlsdesc_gotent = (bfd_vma) -1;
 	  if (*local_got > 0)
 	    {
-	      *local_got = s->size;
-	      s->size += 4;
-	      if (*local_tls_type == GOT_TLS_GD
-		  || *local_tls_type == GOT_TLS_IE_BOTH)
-		s->size += 4;
+	      if (GOT_TLS_GDESC_P (*local_tls_type))
+		{
+		  *local_tlsdesc_gotent = htab->sgotplt->size
+		    - elf_i386_compute_jump_table_size (htab);
+		  htab->sgotplt->size += 8;
+		  *local_got = (bfd_vma) -2;
+		}
+	      if (! GOT_TLS_GDESC_P (*local_tls_type)
+		  || GOT_TLS_GD_P (*local_tls_type))
+		{
+		  *local_got = s->size;
+		  s->size += 4;
+		  if (GOT_TLS_GD_P (*local_tls_type)
+		      || *local_tls_type == GOT_TLS_IE_BOTH)
+		    s->size += 4;
+		}
 	      if (info->shared
-		  || *local_tls_type == GOT_TLS_GD
+		  || GOT_TLS_GD_ANY_P (*local_tls_type)
 		  || (*local_tls_type & GOT_TLS_IE))
 		{
 		  if (*local_tls_type == GOT_TLS_IE_BOTH)
 		    srel->size += 2 * sizeof (Elf32_External_Rel);
-		  else
+		  else if (GOT_TLS_GD_P (*local_tls_type)
+			   || ! GOT_TLS_GDESC_P (*local_tls_type))
 		    srel->size += sizeof (Elf32_External_Rel);
+		  if (GOT_TLS_GDESC_P (*local_tls_type))
+		    htab->srelplt->size += sizeof (Elf32_External_Rel);
 		}
 	    }
 	  else
@@ -1917,6 +2017,14 @@ elf_i386_size_dynamic_sections (bfd *out
      sym dynamic relocs.  */
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
 
+  /* For every jump slot reserved in the sgotplt, reloc_count is
+     incremented.  However, when we reserve space for TLS descriptors,
+     it's not incremented, so in order to compute the space reserved
+     for them, it suffices to multiply the reloc count by the jump
+     slot size.  */
+  if (htab->srelplt)
+    htab->sgotplt_jump_table_size = htab->srelplt->reloc_count * 4;
+
   /* We now have determined the sizes of the various dynamic sections.
      Allocate memory for them.  */
   relocs = FALSE;
@@ -1948,7 +2056,8 @@ elf_i386_size_dynamic_sections (bfd *out
 
 	  /* We use the reloc_count field as a counter if we need
 	     to copy relocs into the output file.  */
-	  s->reloc_count = 0;
+	  if (s != htab->srelplt)
+	    s->reloc_count = 0;
 	}
       else
 	{
@@ -2035,6 +2144,41 @@ elf_i386_size_dynamic_sections (bfd *out
   return TRUE;
 }
 
+static bfd_boolean
+elf_i386_always_size_sections (bfd *output_bfd,
+			       struct bfd_link_info *info)
+{
+  asection *tls_sec = elf_hash_table (info)->tls_sec;
+
+  if (tls_sec)
+    {
+      struct elf_link_hash_entry *tlsbase;
+
+      tlsbase = elf_link_hash_lookup (elf_hash_table (info),
+				      "_TLS_MODULE_BASE_",
+				      FALSE, FALSE, FALSE);
+
+      if (tlsbase && tlsbase->type == STT_TLS)
+	{
+	  struct bfd_link_hash_entry *bh = NULL;
+	  const struct elf_backend_data *bed
+	    = get_elf_backend_data (output_bfd);
+
+	  if (!(_bfd_generic_link_add_one_symbol
+		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+		 tls_sec, 0, NULL, FALSE,
+		 bed->collect, &bh)))
+	    return FALSE;
+	  tlsbase = (struct elf_link_hash_entry *)bh;
+	  tlsbase->def_regular = 1;
+	  tlsbase->other = STV_HIDDEN;
+	  (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+	}
+    }
+
+  return TRUE;
+}
+
 /* Set the correct type for an x86 ELF section.  We do this by the
    section name, which is a hack, but ought to work.  */
 
@@ -2112,6 +2256,7 @@ elf_i386_relocate_section (bfd *output_b
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
   bfd_vma *local_got_offsets;
+  bfd_vma *local_tlsdesc_gotents;
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
@@ -2119,6 +2264,7 @@ elf_i386_relocate_section (bfd *output_b
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   local_got_offsets = elf_local_got_offsets (input_bfd);
+  local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd);
 
   rel = relocs;
   relend = relocs + input_section->reloc_count;
@@ -2130,7 +2276,7 @@ elf_i386_relocate_section (bfd *output_b
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
       asection *sec;
-      bfd_vma off;
+      bfd_vma off, offplt;
       bfd_vma relocation;
       bfd_boolean unresolved_reloc;
       bfd_reloc_status_type r;
@@ -2552,6 +2698,8 @@ elf_i386_relocate_section (bfd *output_b
 	  /* Fall through */
 
 	case R_386_TLS_GD:
+	case R_386_TLS_GOTDESC:
+	case R_386_TLS_DESC_CALL:
 	case R_386_TLS_IE_32:
 	case R_386_TLS_GOTIE:
 	  r_type = elf_i386_tls_transition (info, r_type, h == NULL);
@@ -2566,7 +2714,9 @@ elf_i386_relocate_section (bfd *output_b
 	    }
 	  if (tls_type == GOT_TLS_IE)
 	    tls_type = GOT_TLS_IE_NEG;
-	  if (r_type == R_386_TLS_GD)
+	  if (r_type == R_386_TLS_GD
+	      || r_type == R_386_TLS_GOTDESC
+	      || r_type == R_386_TLS_DESC_CALL)
 	    {
 	      if (tls_type == GOT_TLS_IE_POS)
 		r_type = R_386_TLS_GOTIE;
@@ -2640,6 +2790,67 @@ elf_i386_relocate_section (bfd *output_b
 		  rel++;
 		  continue;
 		}
+	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
+		{
+		  /* GDesc -> LE transition.
+		     It's originally something like:
+		     leal x@tlsdesc(%ebx), %eax
+
+		     aoliva FIXME.  Decide whether to change it to:
+		     gs: .byte 0x65 ; movl $x@ntpoff, %eax
+		     or
+		     leal x@ntpoff, %eax
+		     
+		     Registers other than %eax may be set up here.  */
+		  
+		  unsigned int val, type;
+		  bfd_vma roff;
+
+		  /* First, make sure it's a leal adding ebx to a
+		     32-bit offset into any register, although it's
+		     probably almost always going to be eax.  */
+		  roff = rel->r_offset;
+		  BFD_ASSERT (roff >= 2);
+		  type = bfd_get_8 (input_bfd, contents + roff - 2);
+		  BFD_ASSERT (type == 0x8d);
+		  val = bfd_get_8 (input_bfd, contents + roff - 1);
+		  BFD_ASSERT ((val & 0xc7) == 0x83);
+		  BFD_ASSERT (roff + 4 <= input_section->size);
+
+		  /* Now modify the instruction as appropriate.  */
+		  bfd_put_8 (output_bfd, 0x65, contents + roff - 2);
+		  /* aoliva FIXME: remove the above and xor the byte
+		     below with 0x86.  */
+		  bfd_put_8 (output_bfd, 0xb8 | ((val >> 3) & 7),
+			     contents + roff - 1);
+		  bfd_put_32 (output_bfd, -tpoff (info, relocation),
+			      contents + roff);
+		  continue;
+		}
+	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
+		{
+		  /* GDesc -> LE transition.
+		     It's originally:
+		     call *(%eax)
+		     Turn it into:
+		     movl %eax, %eax  */
+		  
+		  unsigned int val, type;
+		  bfd_vma roff;
+
+		  /* First, make sure it's a call *(%eax).  */
+		  roff = rel->r_offset;
+		  BFD_ASSERT (roff + 2 <= input_section->size);
+		  type = bfd_get_8 (input_bfd, contents + roff);
+		  BFD_ASSERT (type == 0xff);
+		  val = bfd_get_8 (input_bfd, contents + roff + 1);
+		  BFD_ASSERT (val == 0x10);
+
+		  /* Now modify the instruction as appropriate.  */
+		  bfd_put_8 (output_bfd, 0x89, contents + roff);
+		  bfd_put_8 (output_bfd, 0xc0, contents + roff + 1);
+		  continue;
+		}
 	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE)
 		{
 		  unsigned int val, type;
@@ -2754,13 +2965,17 @@ elf_i386_relocate_section (bfd *output_b
 	    abort ();
 
 	  if (h != NULL)
-	    off = h->got.offset;
+	    {
+	      off = h->got.offset;
+	      offplt = elf_i386_hash_entry (h)->tlsdesc_got;
+	    }
 	  else
 	    {
 	      if (local_got_offsets == NULL)
 		abort ();
 
 	      off = local_got_offsets[r_symndx];
+	      offplt = local_tlsdesc_gotents[r_symndx];
 	    }
 
 	  if ((off & 1) != 0)
@@ -2770,35 +2985,77 @@ elf_i386_relocate_section (bfd *output_b
 	      Elf_Internal_Rela outrel;
 	      bfd_byte *loc;
 	      int dr_type, indx;
+	      asection *sreloc;
 
 	      if (htab->srelgot == NULL)
 		abort ();
 
+	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
+
+	      if (GOT_TLS_GDESC_P (tls_type))
+		{
+		  outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);
+		  BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8
+			      <= htab->sgotplt->size);
+		  outrel.r_offset = (htab->sgotplt->output_section->vma
+				     + htab->sgotplt->output_offset
+				     + offplt
+				     + htab->sgotplt_jump_table_size);
+		  sreloc = htab->srelplt;
+		  loc = sreloc->contents;
+		  loc += sreloc->reloc_count++
+		    * sizeof (Elf32_External_Rel);
+		  BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
+			      <= sreloc->contents + sreloc->size);
+		  bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+		  if (indx == 0)
+		    {
+		      BFD_ASSERT (! unresolved_reloc);
+		      bfd_put_32 (output_bfd,
+				  relocation - dtpoff_base (info),
+				  htab->sgotplt->contents + offplt
+				  + htab->sgotplt_jump_table_size + 4);
+		    }
+		  else
+		    {
+		      bfd_put_32 (output_bfd, 0,
+				  htab->sgotplt->contents + offplt
+				  + htab->sgotplt_jump_table_size + 4);
+		    }
+		}
+
+	      sreloc = htab->srelgot;
+
 	      outrel.r_offset = (htab->sgot->output_section->vma
 				 + htab->sgot->output_offset + off);
 
-	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
-	      if (r_type == R_386_TLS_GD)
+	      if (GOT_TLS_GD_P (tls_type))
 		dr_type = R_386_TLS_DTPMOD32;
+	      else if (GOT_TLS_GDESC_P (tls_type))
+		goto dr_done;
 	      else if (tls_type == GOT_TLS_IE_POS)
 		dr_type = R_386_TLS_TPOFF;
 	      else
 		dr_type = R_386_TLS_TPOFF32;
+
 	      if (dr_type == R_386_TLS_TPOFF && indx == 0)
 		bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
 			    htab->sgot->contents + off);
 	      else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
 		bfd_put_32 (output_bfd, dtpoff_base (info) - relocation,
 			    htab->sgot->contents + off);
-	      else
+	      else if (dr_type != R_386_TLS_DESC)
 		bfd_put_32 (output_bfd, 0,
 			    htab->sgot->contents + off);
 	      outrel.r_info = ELF32_R_INFO (indx, dr_type);
-	      loc = htab->srelgot->contents;
-	      loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
+
+	      loc = sreloc->contents;
+	      loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
+	      BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
+			  <= sreloc->contents + sreloc->size);
 	      bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
 
-	      if (r_type == R_386_TLS_GD)
+	      if (GOT_TLS_GD_P (tls_type))
 		{
 		  if (indx == 0)
 		    {
@@ -2814,8 +3071,10 @@ elf_i386_relocate_section (bfd *output_b
 		      outrel.r_info = ELF32_R_INFO (indx,
 						    R_386_TLS_DTPOFF32);
 		      outrel.r_offset += 4;
-		      htab->srelgot->reloc_count++;
+		      sreloc->reloc_count++;
 		      loc += sizeof (Elf32_External_Rel);
+		      BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
+				  <= sreloc->contents + sreloc->size);
 		      bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
 		    }
 		}
@@ -2826,25 +3085,33 @@ elf_i386_relocate_section (bfd *output_b
 			      htab->sgot->contents + off + 4);
 		  outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
 		  outrel.r_offset += 4;
-		  htab->srelgot->reloc_count++;
+		  sreloc->reloc_count++;
 		  loc += sizeof (Elf32_External_Rel);
 		  bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
 		}
 
+	    dr_done:
 	      if (h != NULL)
 		h->got.offset |= 1;
 	      else
 		local_got_offsets[r_symndx] |= 1;
 	    }
 
-	  if (off >= (bfd_vma) -2)
+	  if (off >= (bfd_vma) -2
+	      && ! GOT_TLS_GDESC_P (tls_type))
 	    abort ();
-	  if (r_type == ELF32_R_TYPE (rel->r_info))
+	  if (r_type == R_386_TLS_GOTDESC
+	      || r_type == R_386_TLS_DESC_CALL)
+	    {
+	      relocation = htab->sgotplt_jump_table_size + offplt;
+	      unresolved_reloc = FALSE;
+	    }
+	  else if (r_type == ELF32_R_TYPE (rel->r_info))
 	    {
 	      bfd_vma g_o_t = htab->sgotplt->output_section->vma
 			      + htab->sgotplt->output_offset;
 	      relocation = htab->sgot->output_section->vma
-			   + htab->sgot->output_offset + off - g_o_t;
+		+ htab->sgot->output_offset + off - g_o_t;
 	      if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
 		  && tls_type == GOT_TLS_IE_BOTH)
 		relocation += 4;
@@ -2852,7 +3119,7 @@ elf_i386_relocate_section (bfd *output_b
 		relocation += g_o_t;
 	      unresolved_reloc = FALSE;
 	    }
-	  else
+	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
 	    {
 	      unsigned int val, type;
 	      bfd_vma roff;
@@ -2916,6 +3183,97 @@ elf_i386_relocate_section (bfd *output_b
 	      rel++;
 	      continue;
 	    }
+	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
+	    {
+	      /* GDesc -> IE transition.
+		 It's originally something like:
+		 leal x@tlsdesc(%ebx), %eax
+
+		 aoliva FIXME: decide whether to change it to:
+		 movl x@gotntpoff(%ebx), %eax # before movl %eax,%eax
+		 or
+		 leal x@gotntpoff(%ebx), %eax # before movl (%eax),%eax
+		 but the latter won't work if we need to negate the
+		 loaded value.
+		     
+		 Registers other than %eax may be set up here.  */
+		  
+	      unsigned int val, type;
+	      bfd_vma roff;
+
+	      /* First, make sure it's a leal adding ebx to a 32-bit
+		 offset into any register, although it's probably
+		 almost always going to be eax.  */
+	      roff = rel->r_offset;
+	      BFD_ASSERT (roff >= 2);
+	      type = bfd_get_8 (input_bfd, contents + roff - 2);
+	      BFD_ASSERT (type == 0x8d);
+	      val = bfd_get_8 (input_bfd, contents + roff - 1);
+	      BFD_ASSERT ((val & 0xc7) == 0x83);
+	      BFD_ASSERT (roff + 4 <= input_section->size);
+
+	      /* Now modify the instruction as appropriate.  */
+	      /* To turn a leal into a movl in the form we use it, it
+		 suffices to change the first byte from 0x8d to 0x8b.
+		 aoliva FIXME: should we decide to keep the leal, all
+		 we have to do is remove the statement below, and
+		 adjust the relaxation of R_386_TLS_DESC_CALL.  */
+	      bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
+
+	      if (tls_type == GOT_TLS_IE_BOTH)
+		off += 4;
+
+	      bfd_put_32 (output_bfd,
+			  htab->sgot->output_section->vma
+			  + htab->sgot->output_offset + off
+			  - htab->sgotplt->output_section->vma
+			  - htab->sgotplt->output_offset,
+			  contents + roff);
+	      continue;
+	    }
+	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
+	    {
+	      /* GDesc -> IE transition.
+		 It's originally:
+		 calll *(%eax)
+
+		 aoliva FIXME: decide whether to change it to:
+		 movl %eax,%eax # after movl x@gotntpoff(%ebx), %eax
+		 or
+		 movl (%eax),%eax # after leal x@gotntpoff(%ebx), %eax
+
+	         Either one works unless we have to negate the
+	         offset.  */
+		  
+	      unsigned int val, type;
+	      bfd_vma roff;
+
+	      /* First, make sure it's a call *(%eax).  */
+	      roff = rel->r_offset;
+	      BFD_ASSERT (roff + 2 <= input_section->size);
+	      type = bfd_get_8 (input_bfd, contents + roff);
+	      BFD_ASSERT (type == 0xff);
+	      val = bfd_get_8 (input_bfd, contents + roff + 1);
+	      BFD_ASSERT (val == 0x10);
+
+	      /* Now modify the instruction as appropriate.  */
+	      if (tls_type != GOT_TLS_IE_NEG)
+		{
+		  /* movl %eax,%eax */
+		  bfd_put_8 (output_bfd, 0x89, contents + roff);
+		  bfd_put_8 (output_bfd, 0xc0, contents + roff + 1);
+		}
+	      else
+		{
+		  /* negl %eax */
+		  bfd_put_8 (output_bfd, 0xf7, contents + roff);
+		  bfd_put_8 (output_bfd, 0xd8, contents + roff + 1);
+		}
+
+	      continue;
+	    }
+	  else
+	    BFD_ASSERT (FALSE);
 	  break;
 
 	case R_386_TLS_LDM:
@@ -3223,7 +3581,7 @@ elf_i386_finish_dynamic_symbol (bfd *out
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && elf_i386_hash_entry(h)->tls_type != GOT_TLS_GD
+      && ! GOT_TLS_GD_ANY_P (elf_i386_hash_entry(h)->tls_type)
       && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0)
     {
       Elf_Internal_Rela rel;
@@ -3558,6 +3916,7 @@ elf_i386_plt_sym_val (bfd_vma i, const a
 #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
 #define elf_backend_relocate_section	      elf_i386_relocate_section
 #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
+#define elf_backend_always_size_sections      elf_i386_always_size_sections
 #define elf_backend_plt_sym_val		      elf_i386_plt_sym_val
 
 #include "elf32-target.h"
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/uberbaum/./bfd/elf64-x86-64.c,v
retrieving revision 1.107
diff -u -p -r1.107 elf64-x86-64.c
--- bfd/elf64-x86-64.c 31 Aug 2005 23:45:46 -0000 1.107
+++ bfd/elf64-x86-64.c 21 Sep 2005 06:12:12 -0000
@@ -112,12 +112,31 @@ static reloc_howto_type x86_64_elf_howto
   HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
 	bfd_elf_generic_reloc, "R_X86_64_GOTPC32",
 	FALSE, 0xffffffff, 0xffffffff, TRUE),
+  EMPTY_HOWTO (27),
+  EMPTY_HOWTO (28),
+  EMPTY_HOWTO (29),
+  EMPTY_HOWTO (30),
+  EMPTY_HOWTO (31),
+  EMPTY_HOWTO (32),
+  EMPTY_HOWTO (33),
+  HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, TRUE, 0,
+	complain_overflow_bitfield, bfd_elf_generic_reloc,
+	"R_X86_64_GOTPC32_TLSDESC",
+	FALSE, 0xffffffff, 0xffffffff, TRUE),
+  HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, FALSE, 0,
+	complain_overflow_dont, bfd_elf_generic_reloc,
+	"R_X86_64_TLSDESC_CALL", 
+	FALSE, 0, 0, FALSE),
+  HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0,
+	complain_overflow_bitfield, bfd_elf_generic_reloc,
+	"R_X86_64_TLSDESC",
+	FALSE, MINUS_ONE, MINUS_ONE, FALSE),
 
   /* We have a gap in the reloc numbers here.
      R_X86_64_standard counts the number up to this point, and
      R_X86_64_vt_offset is the value to subtract from a reloc type of
      R_X86_64_GNU_VT* to form an index into this table.  */
-#define R_X86_64_standard (R_X86_64_GOTPC32 + 1)
+#define R_X86_64_standard (R_X86_64_TLSDESC + 1)
 #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
 
 /* GNU extension to record C++ vtable hierarchy.  */
@@ -166,14 +185,38 @@ static const struct elf_reloc_map x86_64
   { BFD_RELOC_64_PCREL,		R_X86_64_PC64, },
   { BFD_RELOC_X86_64_GOTOFF64,	R_X86_64_GOTOFF64, },
   { BFD_RELOC_X86_64_GOTPC32,	R_X86_64_GOTPC32, },
+  { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, },
+  { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, },
+  { BFD_RELOC_X86_64_TLSDESC,	R_X86_64_TLSDESC, },
   { BFD_RELOC_VTABLE_INHERIT,	R_X86_64_GNU_VTINHERIT, },
   { BFD_RELOC_VTABLE_ENTRY,	R_X86_64_GNU_VTENTRY, },
 };
 
+static reloc_howto_type *
+elf64_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
+{
+  unsigned i;
+
+  if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
+      || r_type >= (unsigned int) R_X86_64_max)
+    {
+      if (r_type >= (unsigned int) R_X86_64_standard)
+	{
+	  (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+				 abfd, (int) r_type);
+	  r_type = R_X86_64_NONE;
+	}
+      i = r_type;
+    }
+  else
+    i = r_type - (unsigned int) R_X86_64_vt_offset;
+  BFD_ASSERT (x86_64_elf_howto_table[i].type == r_type);
+  return &x86_64_elf_howto_table[i];
+}
 
 /* Given a BFD reloc type, return a HOWTO structure.  */
 static reloc_howto_type *
-elf64_x86_64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+elf64_x86_64_reloc_type_lookup (bfd *abfd,
 				bfd_reloc_code_real_type code)
 {
   unsigned int i;
@@ -182,7 +225,8 @@ elf64_x86_64_reloc_type_lookup (bfd *abf
        i++)
     {
       if (x86_64_reloc_map[i].bfd_reloc_val == code)
-	return &x86_64_elf_howto_table[i];
+	return elf64_x86_64_rtype_to_howto (abfd,
+					    x86_64_reloc_map[i].elf_reloc_val);
     }
   return 0;
 }
@@ -193,23 +237,10 @@ static void
 elf64_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
 			    Elf_Internal_Rela *dst)
 {
-  unsigned r_type, i;
+  unsigned r_type;
 
   r_type = ELF64_R_TYPE (dst->r_info);
-  if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
-      || r_type >= (unsigned int) R_X86_64_max)
-    {
-      if (r_type >= (unsigned int) R_X86_64_standard)
-	{
-	  (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
-				 abfd, (int) r_type);
-	  r_type = R_X86_64_NONE;
-	}
-      i = r_type;
-    }
-  else
-    i = r_type - (unsigned int) R_X86_64_vt_offset;
-  cache_ptr->howto = &x86_64_elf_howto_table[i];
+  cache_ptr->howto = elf64_x86_64_rtype_to_howto (abfd, r_type);
   BFD_ASSERT (r_type == cache_ptr->howto->type);
 }
 
@@ -353,7 +384,20 @@ struct elf64_x86_64_link_hash_entry
 #define GOT_NORMAL	1
 #define GOT_TLS_GD	2
 #define GOT_TLS_IE	3
+#define GOT_TLS_GDESC	4
+#define GOT_TLS_GD_BOTH_P(type) \
+  ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
+#define GOT_TLS_GD_P(type) \
+  ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GDESC_P(type) \
+  ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GD_ANY_P(type) \
+  (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
   unsigned char tls_type;
+
+  /* Offset of the GOTPLT entry reserved for the TLS descriptor,
+     starting at the end of the jump table.  */
+  bfd_vma tlsdesc_got;
 };
 
 #define elf64_x86_64_hash_entry(ent) \
@@ -365,6 +409,9 @@ struct elf64_x86_64_obj_tdata
 
   /* tls_type for each local got entry.  */
   char *local_got_tls_type;
+
+  /* GOTPLT entries for TLS descriptors.  */
+  bfd_vma *local_tlsdesc_gotent;
 };
 
 #define elf64_x86_64_tdata(abfd) \
@@ -373,6 +420,8 @@ struct elf64_x86_64_obj_tdata
 #define elf64_x86_64_local_got_tls_type(abfd) \
   (elf64_x86_64_tdata (abfd)->local_got_tls_type)
 
+#define elf64_x86_64_local_tlsdesc_gotent(abfd) \
+  (elf64_x86_64_tdata (abfd)->local_tlsdesc_gotent)
 
 /* x86-64 ELF linker hash table.  */
 
@@ -389,11 +438,23 @@ struct elf64_x86_64_link_hash_table
   asection *sdynbss;
   asection *srelbss;
 
+  /* The offset into splt of the PLT entry for the TLS descriptor
+     resolver.  Special values are 0, if not necessary (or not found
+     to be necessary yet), and -1 if needed but not determined
+     yet.  */
+  bfd_vma tlsdesc_plt;
+  /* The offset into sgot of the GOT entry used by the PLT entry
+     above.  */
+  bfd_vma tlsdesc_got;
+
   union {
     bfd_signed_vma refcount;
     bfd_vma offset;
   } tls_ld_got;
 
+  /* The amount of space used by the jump slots in the GOT.  */
+  bfd_vma sgotplt_jump_table_size;
+
   /* Small local sym to section mapping cache.  */
   struct sym_sec_cache sym_sec;
 };
@@ -403,6 +464,9 @@ struct elf64_x86_64_link_hash_table
 #define elf64_x86_64_hash_table(p) \
   ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
 
+#define elf64_x86_64_compute_jump_table_size(htab) \
+  ((htab)->srelplt->reloc_count * GOT_ENTRY_SIZE)
+
 /* Create an entry in an x86-64 ELF linker hash table.	*/
 
 static struct bfd_hash_entry *
@@ -428,6 +492,7 @@ link_hash_newfunc (struct bfd_hash_entry
       eh = (struct elf64_x86_64_link_hash_entry *) entry;
       eh->dyn_relocs = NULL;
       eh->tls_type = GOT_UNKNOWN;
+      eh->tlsdesc_got = (bfd_vma) -1;
     }
 
   return entry;
@@ -459,7 +524,10 @@ elf64_x86_64_link_hash_table_create (bfd
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
   ret->sym_sec.abfd = NULL;
+  ret->tlsdesc_plt = 0;
+  ret->tlsdesc_got = 0;
   ret->tls_ld_got.refcount = 0;
+  ret->sgotplt_jump_table_size = 0;
 
   return &ret->elf.root;
 }
@@ -619,6 +687,8 @@ elf64_x86_64_tls_transition (struct bfd_
   switch (r_type)
     {
     case R_X86_64_TLSGD:
+    case R_X86_64_GOTPC32_TLSDESC:
+    case R_X86_64_TLSDESC_CALL:
     case R_X86_64_GOTTPOFF:
       if (is_local)
 	return R_X86_64_TPOFF32;
@@ -709,6 +779,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	case R_X86_64_GOT32:
 	case R_X86_64_GOTPCREL:
 	case R_X86_64_TLSGD:
+	case R_X86_64_GOTPC32_TLSDESC:
+	case R_X86_64_TLSDESC_CALL:
 	  /* This symbol requires a global offset table entry.	*/
 	  {
 	    int tls_type, old_tls_type;
@@ -718,6 +790,9 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	      default: tls_type = GOT_NORMAL; break;
 	      case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break;
 	      case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break;
+	      case R_X86_64_GOTPC32_TLSDESC:
+	      case R_X86_64_TLSDESC_CALL:
+		tls_type = GOT_TLS_GDESC; break;
 	      }
 
 	    if (h != NULL)
@@ -736,14 +811,17 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 		    bfd_size_type size;
 
 		    size = symtab_hdr->sh_info;
-		    size *= sizeof (bfd_signed_vma) + sizeof (char);
+		    size *= sizeof (bfd_signed_vma)
+		      + sizeof (bfd_vma) + sizeof (char);
 		    local_got_refcounts = ((bfd_signed_vma *)
 					   bfd_zalloc (abfd, size));
 		    if (local_got_refcounts == NULL)
 		      return FALSE;
 		    elf_local_got_refcounts (abfd) = local_got_refcounts;
+		    elf64_x86_64_local_tlsdesc_gotent (abfd)
+		      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
 		    elf64_x86_64_local_got_tls_type (abfd)
-		      = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+		      = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
 		  }
 		local_got_refcounts[r_symndx] += 1;
 		old_tls_type
@@ -753,10 +831,14 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	    /* 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))
+		&& (! GOT_TLS_GD_ANY_P (old_tls_type)
+		    || tls_type != GOT_TLS_IE))
 	      {
-		if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+		if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type))
 		  tls_type = old_tls_type;
+		else if (GOT_TLS_GD_ANY_P (old_tls_type)
+			 && GOT_TLS_GD_ANY_P (tls_type))
+		  tls_type |= old_tls_type;
 		else
 		  {
 		    (*_bfd_error_handler)
@@ -1104,6 +1186,8 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, s
 	  break;
 
 	case R_X86_64_TLSGD:
+	case R_X86_64_GOTPC32_TLSDESC:
+	case R_X86_64_TLSDESC_CALL:
 	case R_X86_64_GOTTPOFF:
 	case R_X86_64_GOT32:
 	case R_X86_64_GOTPCREL:
@@ -1371,6 +1455,7 @@ allocate_dynrelocs (struct elf_link_hash
 
 	  /* We also need to make an entry in the .rela.plt section.  */
 	  htab->srelplt->size += sizeof (Elf64_External_Rela);
+	  htab->srelplt->reloc_count++;
 	}
       else
 	{
@@ -1384,6 +1469,9 @@ allocate_dynrelocs (struct elf_link_hash
       h->needs_plt = 0;
     }
 
+  eh = (struct elf64_x86_64_link_hash_entry *) h;
+  eh->tlsdesc_got = (bfd_vma) -1;
+  
   /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
      make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
   if (h->got.refcount > 0
@@ -1406,31 +1494,46 @@ allocate_dynrelocs (struct elf_link_hash
 	    return FALSE;
 	}
 
-      s = htab->sgot;
-      h->got.offset = s->size;
-      s->size += GOT_ENTRY_SIZE;
-      /* R_X86_64_TLSGD needs 2 consecutive GOT slots.  */
-      if (tls_type == GOT_TLS_GD)
-	s->size += GOT_ENTRY_SIZE;
+      if (GOT_TLS_GDESC_P (tls_type))
+	{
+	  eh->tlsdesc_got = htab->sgotplt->size
+	    - elf64_x86_64_compute_jump_table_size (htab);
+	  htab->sgotplt->size += 2 * GOT_ENTRY_SIZE;
+	  h->got.offset = (bfd_vma) -2;
+	}
+      if (! GOT_TLS_GDESC_P (tls_type)
+	  || GOT_TLS_GD_P (tls_type))
+	{
+	  s = htab->sgot;
+	  h->got.offset = s->size;
+	  s->size += GOT_ENTRY_SIZE;
+	  if (GOT_TLS_GD_P (tls_type))
+	    s->size += GOT_ENTRY_SIZE;
+	}
       dyn = htab->elf.dynamic_sections_created;
       /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
 	 and two if global.
 	 R_X86_64_GOTTPOFF needs one dynamic relocation.  */
-      if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+      if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
 	  || tls_type == GOT_TLS_IE)
 	htab->srelgot->size += sizeof (Elf64_External_Rela);
-      else if (tls_type == GOT_TLS_GD)
+      else if (GOT_TLS_GD_P (tls_type))
 	htab->srelgot->size += 2 * sizeof (Elf64_External_Rela);
-      else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-		|| h->root.type != bfd_link_hash_undefweak)
+      else if (! GOT_TLS_GDESC_P (tls_type)
+	       && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+		   || h->root.type != bfd_link_hash_undefweak)
 	       && (info->shared
 		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
 	htab->srelgot->size += sizeof (Elf64_External_Rela);
+      if (GOT_TLS_GDESC_P (tls_type))
+	{
+	  htab->srelplt->size += sizeof (Elf64_External_Rela);
+	  htab->tlsdesc_plt = (bfd_vma) -1;
+	}
     }
   else
     h->got.offset = (bfd_vma) -1;
 
-  eh = (struct elf64_x86_64_link_hash_entry *) h;
   if (eh->dyn_relocs == NULL)
     return TRUE;
 
@@ -1578,6 +1681,7 @@ elf64_x86_64_size_dynamic_sections (bfd 
       bfd_signed_vma *local_got;
       bfd_signed_vma *end_local_got;
       char *local_tls_type;
+      bfd_vma *local_tlsdesc_gotent;
       bfd_size_type locsymcount;
       Elf_Internal_Shdr *symtab_hdr;
       asection *srel;
@@ -1621,20 +1725,43 @@ elf64_x86_64_size_dynamic_sections (bfd 
       locsymcount = symtab_hdr->sh_info;
       end_local_got = local_got + locsymcount;
       local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
+      local_tlsdesc_gotent = elf64_x86_64_local_tlsdesc_gotent (ibfd);
       s = htab->sgot;
       srel = htab->srelgot;
-      for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+      for (; local_got < end_local_got;
+	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
 	{
+	  *local_tlsdesc_gotent = (bfd_vma) -1;
 	  if (*local_got > 0)
 	    {
-	      *local_got = s->size;
-	      s->size += GOT_ENTRY_SIZE;
-	      if (*local_tls_type == GOT_TLS_GD)
-		s->size += GOT_ENTRY_SIZE;
+	      if (GOT_TLS_GDESC_P (*local_tls_type))
+		{
+		  *local_tlsdesc_gotent = htab->sgotplt->size
+		    - elf64_x86_64_compute_jump_table_size (htab);
+		  htab->sgotplt->size += 2 * GOT_ENTRY_SIZE;
+		  *local_got = (bfd_vma) -2;
+		}
+	      if (! GOT_TLS_GDESC_P (*local_tls_type)
+		  || GOT_TLS_GD_P (*local_tls_type))
+		{
+		  *local_got = s->size;
+		  s->size += GOT_ENTRY_SIZE;
+		  if (GOT_TLS_GD_P (*local_tls_type))
+		    s->size += GOT_ENTRY_SIZE;
+		}
 	      if (info->shared
-		  || *local_tls_type == GOT_TLS_GD
+		  || GOT_TLS_GD_ANY_P (*local_tls_type)
 		  || *local_tls_type == GOT_TLS_IE)
-		srel->size += sizeof (Elf64_External_Rela);
+		{
+		  if (GOT_TLS_GDESC_P (*local_tls_type))
+		    {
+		      htab->srelplt->size += sizeof (Elf64_External_Rela);
+		      htab->tlsdesc_plt = (bfd_vma) -1;
+		    }
+		  if (! GOT_TLS_GDESC_P (*local_tls_type)
+		      || GOT_TLS_GD_P (*local_tls_type))
+		    srel->size += sizeof (Elf64_External_Rela);
+		}
 	    }
 	  else
 	    *local_got = (bfd_vma) -1;
@@ -1656,6 +1783,34 @@ elf64_x86_64_size_dynamic_sections (bfd 
      sym dynamic relocs.  */
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
 
+  /* For every jump slot reserved in the sgotplt, reloc_count is
+     incremented.  However, when we reserve space for TLS descriptors,
+     it's not incremented, so in order to compute the space reserved
+     for them, it suffices to multiply the reloc count by the jump
+     slot size.  */
+  if (htab->srelplt)
+    htab->sgotplt_jump_table_size
+      = elf64_x86_64_compute_jump_table_size (htab);
+
+  if (htab->tlsdesc_plt)
+    {
+      /* If we're not using lazy TLS relocations, don't generate the
+	 PLT and GOT entries they require.  */
+      if ((info->flags & DF_BIND_NOW))
+	htab->tlsdesc_plt = 0;
+      else
+	{
+	  htab->tlsdesc_got = htab->sgot->size;
+	  htab->sgot->size += GOT_ENTRY_SIZE;
+	  /* Reserve room for the initial entry.
+	     FIXME: we could probably do away with it in this case.  */
+	  if (htab->splt->size == 0)
+	    htab->splt->size += PLT_ENTRY_SIZE;
+	  htab->tlsdesc_plt = htab->splt->size;
+	  htab->splt->size += PLT_ENTRY_SIZE;
+	}
+    }
+
   /* We now have determined the sizes of the various dynamic sections.
      Allocate memory for them.  */
   relocs = FALSE;
@@ -1679,7 +1834,8 @@ elf64_x86_64_size_dynamic_sections (bfd 
 
 	  /* We use the reloc_count field as a counter if we need
 	     to copy relocs into the output file.  */
-	  s->reloc_count = 0;
+	  if (s != htab->srelplt)
+	    s->reloc_count = 0;
 	}
       else
 	{
@@ -1739,6 +1895,11 @@ elf64_x86_64_size_dynamic_sections (bfd 
 	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
 	      || !add_dynamic_entry (DT_JMPREL, 0))
 	    return FALSE;
+
+	  if (htab->tlsdesc_plt
+	      && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
+		  || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
+	    return FALSE;
 	}
 
       if (relocs)
@@ -1766,6 +1927,41 @@ elf64_x86_64_size_dynamic_sections (bfd 
   return TRUE;
 }
 
+static bfd_boolean
+elf64_x86_64_always_size_sections (bfd *output_bfd,
+				   struct bfd_link_info *info)
+{
+  asection *tls_sec = elf_hash_table (info)->tls_sec;
+
+  if (tls_sec)
+    {
+      struct elf_link_hash_entry *tlsbase;
+
+      tlsbase = elf_link_hash_lookup (elf_hash_table (info),
+				      "_TLS_MODULE_BASE_",
+				      FALSE, FALSE, FALSE);
+
+      if (tlsbase && tlsbase->type == STT_TLS)
+	{
+	  struct bfd_link_hash_entry *bh = NULL;
+	  const struct elf_backend_data *bed
+	    = get_elf_backend_data (output_bfd);
+
+	  if (!(_bfd_generic_link_add_one_symbol
+		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+		 tls_sec, 0, NULL, FALSE,
+		 bed->collect, &bh)))
+	    return FALSE;
+	  tlsbase = (struct elf_link_hash_entry *)bh;
+	  tlsbase->def_regular = 1;
+	  tlsbase->other = STV_HIDDEN;
+	  (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+	}
+    }
+
+  return TRUE;
+}
+
 /* Return the base VMA address which should be subtracted from real addresses
    when resolving @dtpoff relocation.
    This is PT_TLS segment p_vaddr.  */
@@ -1824,6 +2020,7 @@ elf64_x86_64_relocate_section (bfd *outp
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
   bfd_vma *local_got_offsets;
+  bfd_vma *local_tlsdesc_gotents;
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
@@ -1834,6 +2031,7 @@ elf64_x86_64_relocate_section (bfd *outp
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   local_got_offsets = elf_local_got_offsets (input_bfd);
+  local_tlsdesc_gotents = elf64_x86_64_local_tlsdesc_gotent (input_bfd);
 
   rel = relocs;
   relend = relocs + input_section->reloc_count;
@@ -1845,7 +2043,7 @@ elf64_x86_64_relocate_section (bfd *outp
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
       asection *sec;
-      bfd_vma off;
+      bfd_vma off, offplt;
       bfd_vma relocation;
       bfd_boolean unresolved_reloc;
       bfd_reloc_status_type r;
@@ -2204,6 +2402,8 @@ elf64_x86_64_relocate_section (bfd *outp
 	  break;
 
 	case R_X86_64_TLSGD:
+	case R_X86_64_GOTPC32_TLSDESC:
+	case R_X86_64_TLSDESC_CALL:
 	case R_X86_64_GOTTPOFF:
 	  r_type = elf64_x86_64_tls_transition (info, r_type, h == NULL);
 	  tls_type = GOT_UNKNOWN;
@@ -2215,7 +2415,9 @@ elf64_x86_64_relocate_section (bfd *outp
 	      if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE)
 		r_type = R_X86_64_TPOFF32;
 	    }
-	  if (r_type == R_X86_64_TLSGD)
+	  if (r_type == R_X86_64_TLSGD
+	      || r_type == R_X86_64_GOTPC32_TLSDESC
+	      || r_type == R_X86_64_TLSDESC_CALL)
 	    {
 	      if (tls_type == GOT_TLS_IE)
 		r_type = R_X86_64_GOTTPOFF;
@@ -2257,6 +2459,67 @@ elf64_x86_64_relocate_section (bfd *outp
 		  rel++;
 		  continue;
 		}
+	      else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+		{
+		  /* GDesc -> LE transition.
+		     It's originally something like:
+		     leaq x@tlsdesc(%rip), %rax
+
+		     Change it to:
+		     movl $x@tpoff, %rax
+		     
+		     Registers other than %rax may be set up here.  */
+		  
+		  unsigned int val, type, type2;
+		  bfd_vma roff;
+
+		  /* First, make sure it's a leaq adding rip to a
+		     32-bit offset into any register, although it's
+		     probably almost always going to be rax.  */
+		  roff = rel->r_offset;
+		  BFD_ASSERT (roff >= 3);
+		  type = bfd_get_8 (input_bfd, contents + roff - 3);
+		  BFD_ASSERT ((type & 0xfb) == 0x48);
+		  type2 = bfd_get_8 (input_bfd, contents + roff - 2);
+		  BFD_ASSERT (type2 == 0x8d);
+		  val = bfd_get_8 (input_bfd, contents + roff - 1);
+		  BFD_ASSERT ((val & 0xc7) == 0x05);
+		  BFD_ASSERT (roff + 4 <= input_section->size);
+
+		  /* Now modify the instruction as appropriate.  */
+		  bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
+			     contents + roff - 3);
+		  bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
+		  bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
+			     contents + roff - 1);
+		  bfd_put_32 (output_bfd, tpoff (info, relocation),
+			      contents + roff);
+		  continue;
+		}
+	      else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+		{
+		  /* GDesc -> LE transition.
+		     It's originally:
+		     call *(%rax)
+		     Turn it into:
+		     rex64 nop.  */
+		  
+		  unsigned int val, type;
+		  bfd_vma roff;
+
+		  /* First, make sure it's a call *(%rax).  */
+		  roff = rel->r_offset;
+		  BFD_ASSERT (roff + 2 <= input_section->size);
+		  type = bfd_get_8 (input_bfd, contents + roff);
+		  BFD_ASSERT (type == 0xff);
+		  val = bfd_get_8 (input_bfd, contents + roff + 1);
+		  BFD_ASSERT (val == 0x10);
+
+		  /* Now modify the instruction as appropriate.  */
+		  bfd_put_8 (output_bfd, 0x48, contents + roff);
+		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
+		  continue;
+		}
 	      else
 		{
 		  unsigned int val, type, reg;
@@ -2322,13 +2585,17 @@ elf64_x86_64_relocate_section (bfd *outp
 	    abort ();
 
 	  if (h != NULL)
-	    off = h->got.offset;
+	    {
+	      off = h->got.offset;
+	      offplt = elf64_x86_64_hash_entry (h)->tlsdesc_got;
+	    }
 	  else
 	    {
 	      if (local_got_offsets == NULL)
 		abort ();
 
 	      off = local_got_offsets[r_symndx];
+	      offplt = local_tlsdesc_gotents[r_symndx];
 	    }
 
 	  if ((off & 1) != 0)
@@ -2338,30 +2605,61 @@ elf64_x86_64_relocate_section (bfd *outp
 	      Elf_Internal_Rela outrel;
 	      bfd_byte *loc;
 	      int dr_type, indx;
+	      asection *sreloc;
 
 	      if (htab->srelgot == NULL)
 		abort ();
 
+	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
+
+	      if (GOT_TLS_GDESC_P (tls_type))
+		{
+		  outrel.r_info = ELF64_R_INFO (indx, R_X86_64_TLSDESC);
+		  BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
+			      + 2 * GOT_ENTRY_SIZE <= htab->sgotplt->size);
+		  outrel.r_offset = (htab->sgotplt->output_section->vma
+				     + htab->sgotplt->output_offset
+				     + offplt
+				     + htab->sgotplt_jump_table_size);
+		  sreloc = htab->srelplt;
+		  loc = sreloc->contents;
+		  loc += sreloc->reloc_count++
+		    * sizeof (Elf64_External_Rela);
+		  BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
+			      <= sreloc->contents + sreloc->size);
+		  if (indx == 0)
+		    outrel.r_addend = relocation - dtpoff_base (info);
+		  else
+		    outrel.r_addend = 0;
+		  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+		}
+
+	      sreloc = htab->srelgot;
+
 	      outrel.r_offset = (htab->sgot->output_section->vma
 				 + htab->sgot->output_offset + off);
 
-	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
-	      if (r_type == R_X86_64_TLSGD)
+	      if (GOT_TLS_GD_P (tls_type))
 		dr_type = R_X86_64_DTPMOD64;
+	      else if (GOT_TLS_GDESC_P (tls_type))
+		goto dr_done;
 	      else
 		dr_type = R_X86_64_TPOFF64;
 
 	      bfd_put_64 (output_bfd, 0, htab->sgot->contents + off);
 	      outrel.r_addend = 0;
-	      if (dr_type == R_X86_64_TPOFF64 && indx == 0)
+	      if ((dr_type == R_X86_64_TPOFF64
+		   || dr_type == R_X86_64_TLSDESC) && indx == 0)
 		outrel.r_addend = relocation - dtpoff_base (info);
 	      outrel.r_info = ELF64_R_INFO (indx, dr_type);
 
-	      loc = htab->srelgot->contents;
-	      loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
+	      loc = sreloc->contents;
+	      loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+	      BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
+			  <= sreloc->contents + sreloc->size);
 	      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
-	      if (r_type == R_X86_64_TLSGD)
+	      if (GOT_TLS_GD_P (tls_type))
 		{
 		  if (indx == 0)
 		    {
@@ -2377,27 +2675,37 @@ elf64_x86_64_relocate_section (bfd *outp
 		      outrel.r_info = ELF64_R_INFO (indx,
 						    R_X86_64_DTPOFF64);
 		      outrel.r_offset += GOT_ENTRY_SIZE;
-		      htab->srelgot->reloc_count++;
+		      sreloc->reloc_count++;
 		      loc += sizeof (Elf64_External_Rela);
+		      BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
+				  <= sreloc->contents + sreloc->size);
 		      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 		    }
 		}
 
+	    dr_done:
 	      if (h != NULL)
 		h->got.offset |= 1;
 	      else
 		local_got_offsets[r_symndx] |= 1;
 	    }
 
-	  if (off >= (bfd_vma) -2)
+	  if (off >= (bfd_vma) -2
+	      && ! GOT_TLS_GDESC_P (tls_type))
 	    abort ();
 	  if (r_type == ELF64_R_TYPE (rel->r_info))
 	    {
-	      relocation = htab->sgot->output_section->vma
-			   + htab->sgot->output_offset + off;
+	      if (r_type == R_X86_64_GOTPC32_TLSDESC
+		  || r_type == R_X86_64_TLSDESC_CALL)
+		relocation = htab->sgotplt->output_section->vma
+		  + htab->sgotplt->output_offset
+		  + offplt + htab->sgotplt_jump_table_size;
+	      else
+		relocation = htab->sgot->output_section->vma
+		  + htab->sgot->output_offset + off;
 	      unresolved_reloc = FALSE;
 	    }
-	  else
+	  else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
 	    {
 	      unsigned int i;
 	      static unsigned char tlsgd[8]
@@ -2437,6 +2745,79 @@ elf64_x86_64_relocate_section (bfd *outp
 	      rel++;
 	      continue;
 	    }
+	  else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+	    {
+	      /* GDesc -> IE transition.
+		 It's originally something like:
+		 leaq x@tlsdesc(%rip), %rax
+
+		 Change it to:
+		 movq x@gottpoff(%rip), %rax # before rex64 nop
+		     
+		 Registers other than %rax may be set up here.  */
+		  
+	      unsigned int val, type, type2;
+	      bfd_vma roff;
+
+	      /* First, make sure it's a leaq adding rip to a 32-bit
+		 offset into any register, although it's probably
+		 almost always going to be rax.  */
+	      roff = rel->r_offset;
+	      BFD_ASSERT (roff >= 3);
+	      type = bfd_get_8 (input_bfd, contents + roff - 3);
+	      BFD_ASSERT ((type & 0xfb) == 0x48);
+	      type2 = bfd_get_8 (input_bfd, contents + roff - 2);
+	      BFD_ASSERT (type2 == 0x8d);
+	      val = bfd_get_8 (input_bfd, contents + roff - 1);
+	      BFD_ASSERT ((val & 0xc7) == 0x05);
+	      BFD_ASSERT (roff + 4 <= input_section->size);
+
+	      /* Now modify the instruction as appropriate.  */
+	      /* To turn a leaq into a movq in the form we use it, it
+		 suffices to change the second byte from 0x8d to 0x8b.
+		 aoliva FIXME: should we decide to keep the leaq, all
+		 we have to do is remove the statement below, and
+		 adjust the relaxation of R_X86_64_TLSDESC_CALL.  */
+	      bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
+
+	      bfd_put_32 (output_bfd,
+			  htab->sgot->output_section->vma
+			  + htab->sgot->output_offset + off
+			  - rel->r_offset
+			  - input_section->output_section->vma
+			  - input_section->output_offset
+			  - 4,
+			  contents + roff);
+	      continue;
+	    }
+	  else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+	    {
+	      /* GDesc -> IE transition.
+		 It's originally:
+		 call *(%rax)
+
+		 Change it to:
+		 rex64 nop.  */
+		  
+	      unsigned int val, type;
+	      bfd_vma roff;
+
+	      /* First, make sure it's a call *(%eax).  */
+	      roff = rel->r_offset;
+	      BFD_ASSERT (roff + 2 <= input_section->size);
+	      type = bfd_get_8 (input_bfd, contents + roff);
+	      BFD_ASSERT (type == 0xff);
+	      val = bfd_get_8 (input_bfd, contents + roff + 1);
+	      BFD_ASSERT (val == 0x10);
+
+	      /* Now modify the instruction as appropriate.  */
+	      bfd_put_8 (output_bfd, 0x48, contents + roff);
+	      bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
+
+	      continue;
+	    }
+	  else
+	    BFD_ASSERT (FALSE);
 	  break;
 
 	case R_X86_64_TLSLD:
@@ -2675,7 +3056,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd 
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_GD
+      && ! GOT_TLS_GD_ANY_P (elf64_x86_64_hash_entry (h)->tls_type)
       && elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
     {
       Elf_Internal_Rela rela;
@@ -2830,6 +3211,18 @@ elf64_x86_64_finish_dynamic_sections (bf
 		  dyn.d_un.d_val -= s->size;
 		}
 	      break;
+
+	    case DT_TLSDESC_PLT:
+	      s = htab->splt;
+	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+		+ htab->tlsdesc_plt;
+	      break;
+	      
+	    case DT_TLSDESC_GOT:
+	      s = htab->sgot;
+	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+		+ htab->tlsdesc_got;
+	      break;
 	    }
 
 	  bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
@@ -2864,6 +3257,40 @@ elf64_x86_64_finish_dynamic_sections (bf
 
 	  elf_section_data (htab->splt->output_section)->this_hdr.sh_entsize =
 	    PLT_ENTRY_SIZE;
+
+	  if (htab->tlsdesc_plt)
+	    {
+	      bfd_put_64 (output_bfd, (bfd_vma) 0,
+			  htab->sgot->contents + htab->tlsdesc_got);
+
+	      memcpy (htab->splt->contents + htab->tlsdesc_plt,
+		      elf64_x86_64_plt0_entry,
+		      PLT_ENTRY_SIZE);
+
+	      /* Add offset for pushq GOT+8(%rip), since the
+		 instruction uses 6 bytes subtract this value.  */
+	      bfd_put_32 (output_bfd,
+			  (htab->sgotplt->output_section->vma
+			   + htab->sgotplt->output_offset
+			   + 8
+			   - htab->splt->output_section->vma
+			   - htab->splt->output_offset
+			   - htab->tlsdesc_plt
+			   - 6),
+			  htab->splt->contents + htab->tlsdesc_plt + 2);
+	      /* Add offset for jmp *GOT+TDG(%rip), where TGD stands for
+		 htab->tlsdesc_got. The 12 is the offset to the end of
+		 the instruction.  */
+	      bfd_put_32 (output_bfd,
+			  (htab->sgot->output_section->vma
+			   + htab->sgot->output_offset
+			   + htab->tlsdesc_got
+			   - htab->splt->output_section->vma
+			   - htab->splt->output_offset
+			   - htab->tlsdesc_plt
+			   - 12),
+			  htab->splt->contents + htab->tlsdesc_plt + 8);
+	    }
 	}
     }
 
@@ -3135,6 +3562,7 @@ static const struct bfd_elf_special_sect
 #define elf_backend_reloc_type_class	    elf64_x86_64_reloc_type_class
 #define elf_backend_relocate_section	    elf64_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf64_x86_64_size_dynamic_sections
+#define elf_backend_always_size_sections    elf64_x86_64_always_size_sections
 #define elf_backend_plt_sym_val		    elf64_x86_64_plt_sym_val
 #define elf_backend_object_p		    elf64_x86_64_elf_object_p
 #define bfd_elf64_mkobject		    elf64_x86_64_mkobject
Index: bfd/libbfd.h
===================================================================
RCS file: /cvs/uberbaum/./bfd/libbfd.h,v
retrieving revision 1.157
diff -u -p -r1.157 libbfd.h
--- bfd/libbfd.h 8 Sep 2005 12:49:18 -0000 1.157
+++ bfd/libbfd.h 21 Sep 2005 06:12:13 -0000
@@ -1044,6 +1044,9 @@ static const char *const bfd_reloc_code_
   "BFD_RELOC_386_TLS_DTPMOD32",
   "BFD_RELOC_386_TLS_DTPOFF32",
   "BFD_RELOC_386_TLS_TPOFF32",
+  "BFD_RELOC_386_TLS_GOTDESC",
+  "BFD_RELOC_386_TLS_DESC_CALL",
+  "BFD_RELOC_386_TLS_DESC",
   "BFD_RELOC_X86_64_GOT32",
   "BFD_RELOC_X86_64_PLT32",
   "BFD_RELOC_X86_64_COPY",
@@ -1062,6 +1065,9 @@ static const char *const bfd_reloc_code_
   "BFD_RELOC_X86_64_TPOFF32",
   "BFD_RELOC_X86_64_GOTOFF64",
   "BFD_RELOC_X86_64_GOTPC32",
+  "BFD_RELOC_X86_64_GOTPC32_TLSDESC",
+  "BFD_RELOC_X86_64_TLSDESC_CALL",
+  "BFD_RELOC_X86_64_TLSDESC",
   "BFD_RELOC_NS32K_IMM_8",
   "BFD_RELOC_NS32K_IMM_16",
   "BFD_RELOC_NS32K_IMM_32",
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/uberbaum/./bfd/reloc.c,v
retrieving revision 1.138
diff -u -p -r1.138 reloc.c
--- bfd/reloc.c 8 Sep 2005 12:49:19 -0000 1.138
+++ bfd/reloc.c 21 Sep 2005 06:12:15 -0000
@@ -2329,6 +2329,12 @@ ENUMX
   BFD_RELOC_386_TLS_DTPOFF32
 ENUMX
   BFD_RELOC_386_TLS_TPOFF32
+ENUMX
+  BFD_RELOC_386_TLS_GOTDESC
+ENUMX
+  BFD_RELOC_386_TLS_DESC_CALL
+ENUMX
+  BFD_RELOC_386_TLS_DESC
 ENUMDOC
   i386/elf relocations
 
@@ -2368,6 +2374,12 @@ ENUMX
   BFD_RELOC_X86_64_GOTOFF64
 ENUMX
   BFD_RELOC_X86_64_GOTPC32
+ENUMX
+  BFD_RELOC_X86_64_GOTPC32_TLSDESC
+ENUMX
+  BFD_RELOC_X86_64_TLSDESC_CALL
+ENUMX
+  BFD_RELOC_X86_64_TLSDESC
 ENUMDOC
   x86-64/elf relocations
 
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/uberbaum/./binutils/readelf.c,v
retrieving revision 1.316
diff -u -p -r1.316 readelf.c
--- binutils/readelf.c 20 Sep 2005 17:55:13 -0000 1.316
+++ binutils/readelf.c 21 Sep 2005 06:12:22 -0000
@@ -1632,6 +1632,8 @@ get_dynamic_type (unsigned long type)
 
     case DT_VERSYM:	return "VERSYM";
 
+    case DT_TLSDESC_GOT: return "TLSDESC_GOT";
+    case DT_TLSDESC_PLT: return "TLSDESC_PLT";
     case DT_RELACOUNT:	return "RELACOUNT";
     case DT_RELCOUNT:	return "RELCOUNT";
     case DT_FLAGS_1:	return "FLAGS_1";
Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/uberbaum/./gas/config/tc-i386.c,v
retrieving revision 1.197
diff -u -p -r1.197 tc-i386.c
--- gas/config/tc-i386.c 20 Sep 2005 18:24:47 -0000 1.197
+++ gas/config/tc-i386.c 21 Sep 2005 06:12:32 -0000
@@ -1328,6 +1328,8 @@ tc_i386_fix_adjustable (fixP)
       || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE
       || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32
       || fixP->fx_r_type == BFD_RELOC_386_TLS_LE
+      || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTDESC
+      || fixP->fx_r_type == BFD_RELOC_386_TLS_DESC_CALL
       || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
       || fixP->fx_r_type == BFD_RELOC_X86_64_GOT32
       || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL
@@ -1339,6 +1341,8 @@ tc_i386_fix_adjustable (fixP)
       || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
       || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64
       || fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64
+      || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC
+      || fixP->fx_r_type == BFD_RELOC_X86_64_TLSDESC_CALL
       || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
     return 0;
@@ -2179,7 +2183,14 @@ optimize_disp ()
 		&& fits_in_signed_byte (disp))
 	      i.types[op] |= Disp8;
 	  }
-	else
+	else if (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL
+		 || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL)
+	  {
+	    fix_new_exp (frag_now, frag_more (0) - frag_now->fr_literal, 0,
+			 i.op[op].disps, 0, i.reloc[op]);
+	    i.types[op] &= ~Disp;
+	  }
+ 	else
 	  /* We only support 64bit displacement on constants.  */
 	  i.types[op] &= ~Disp64;
       }
@@ -3125,7 +3136,13 @@ build_modrm_byte ()
 		  if ((i.index_reg->reg_flags & RegRex) != 0)
 		    i.rex |= REX_EXTY;
 		}
-	      i.rm.mode = mode_from_disp_size (i.types[op]);
+
+	      if (i.disp_operands
+		  && (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL
+		      || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL))
+		i.rm.mode = 0;
+	      else
+		i.rm.mode = mode_from_disp_size (i.types[op]);
 	    }
 
 	  if (fake_zero_displacement)
@@ -3798,7 +3815,9 @@ lex_got (enum bfd_reloc_code_real *reloc
     { "DTPOFF",   { BFD_RELOC_386_TLS_LDO_32, BFD_RELOC_X86_64_DTPOFF32 }, Imm32|Imm32S|Imm64|Disp32|Disp64 },
     { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,  0                         }, 0 },
     { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE,     0                         }, 0 },
-    { "GOT",      { BFD_RELOC_386_GOT32,      BFD_RELOC_X86_64_GOT32    }, Imm32|Imm32S|Disp32 }
+    { "GOT",      { BFD_RELOC_386_GOT32,      BFD_RELOC_X86_64_GOT32    }, Imm32|Imm32S|Disp32 },
+    { "TLSDESC",  { BFD_RELOC_386_TLS_GOTDESC, BFD_RELOC_X86_64_GOTPC32_TLSDESC }, Imm32|Imm32S|Disp32 },
+    { "TLSCALL",  { BFD_RELOC_386_TLS_DESC_CALL, BFD_RELOC_X86_64_TLSDESC_CALL }, Imm32|Imm32S|Disp32 }
   };
   char *cp;
   unsigned int j;
@@ -5008,9 +5027,11 @@ md_apply_fix (fixP, valP, seg)
       case BFD_RELOC_386_TLS_IE_32:
       case BFD_RELOC_386_TLS_IE:
       case BFD_RELOC_386_TLS_GOTIE:
+      case BFD_RELOC_386_TLS_GOTDESC:
       case BFD_RELOC_X86_64_TLSGD:
       case BFD_RELOC_X86_64_TLSLD:
       case BFD_RELOC_X86_64_GOTTPOFF:
+      case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
 	value = 0; /* Fully resolved at runtime.  No addend.  */
 	/* Fallthrough */
       case BFD_RELOC_386_TLS_LE:
@@ -5023,6 +5044,13 @@ md_apply_fix (fixP, valP, seg)
 	S_SET_THREAD_LOCAL (fixP->fx_addsy);
 	break;
 
+      case BFD_RELOC_386_TLS_DESC_CALL:
+      case BFD_RELOC_X86_64_TLSDESC_CALL:
+	value = 0; /* Fully resolved at runtime.  No addend.  */
+	S_SET_THREAD_LOCAL (fixP->fx_addsy);
+	fixP->fx_done = 0;
+	return;
+
       case BFD_RELOC_386_GOT32:
       case BFD_RELOC_X86_64_GOT32:
 	value = 0; /* Fully resolved at runtime.  No addend.  */
@@ -5501,6 +5529,8 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_386_TLS_GOTIE:
     case BFD_RELOC_386_TLS_LE_32:
     case BFD_RELOC_386_TLS_LE:
+    case BFD_RELOC_386_TLS_GOTDESC:
+    case BFD_RELOC_386_TLS_DESC_CALL:
     case BFD_RELOC_X86_64_TLSGD:
     case BFD_RELOC_X86_64_TLSLD:
     case BFD_RELOC_X86_64_DTPOFF32:
@@ -5510,6 +5540,8 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_X86_64_TPOFF64:
     case BFD_RELOC_X86_64_GOTOFF64:
     case BFD_RELOC_X86_64_GOTPC32:
+    case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
+    case BFD_RELOC_X86_64_TLSDESC_CALL:
     case BFD_RELOC_RVA:
     case BFD_RELOC_VTABLE_ENTRY:
     case BFD_RELOC_VTABLE_INHERIT:
@@ -5604,6 +5636,8 @@ tc_gen_reloc (section, fixp)
 	  case BFD_RELOC_X86_64_TLSGD:
 	  case BFD_RELOC_X86_64_TLSLD:
 	  case BFD_RELOC_X86_64_GOTTPOFF:
+	  case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
+	  case BFD_RELOC_X86_64_TLSDESC_CALL:
 	    rel->addend = fixp->fx_offset - fixp->fx_size;
 	    break;
 	  default:
Index: include/elf/common.h
===================================================================
RCS file: /cvs/uberbaum/./include/elf/common.h,v
retrieving revision 1.72
diff -u -p -r1.72 common.h
--- include/elf/common.h 14 Jul 2005 22:52:15 -0000 1.72
+++ include/elf/common.h 21 Sep 2005 06:13:15 -0000
@@ -571,6 +571,8 @@
 #define DT_VALRNGHI	0x6ffffdff
 
 #define DT_ADDRRNGLO	0x6ffffe00
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
 #define DT_GNU_CONFLICT	0x6ffffef8
 #define DT_GNU_LIBLIST	0x6ffffef9
 #define DT_CONFIG	0x6ffffefa
Index: include/elf/i386.h
===================================================================
RCS file: /cvs/uberbaum/./include/elf/i386.h,v
retrieving revision 1.10
diff -u -p -r1.10 i386.h
--- include/elf/i386.h 10 May 2005 10:21:10 -0000 1.10
+++ include/elf/i386.h 21 Sep 2005 06:13:15 -0000
@@ -1,5 +1,5 @@
 /* ix86 ELF support for BFD.
-   Copyright 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -61,6 +61,10 @@ START_RELOC_NUMBERS (elf_i386_reloc_type
      RELOC_NUMBER (R_386_TLS_DTPMOD32, 35)
      RELOC_NUMBER (R_386_TLS_DTPOFF32, 36)
      RELOC_NUMBER (R_386_TLS_TPOFF32,  37)
+/* 38 */
+     RELOC_NUMBER (R_386_TLS_GOTDESC,  39)
+     RELOC_NUMBER (R_386_TLS_DESC_CALL,40)
+     RELOC_NUMBER (R_386_TLS_DESC,     41)
 
      /* Used by Intel.  */
      RELOC_NUMBER (R_386_USED_BY_INTEL_200, 200)
Index: include/elf/x86-64.h
===================================================================
RCS file: /cvs/uberbaum/./include/elf/x86-64.h,v
retrieving revision 1.8
diff -u -p -r1.8 x86-64.h
--- include/elf/x86-64.h 25 Jul 2005 15:41:07 -0000 1.8
+++ include/elf/x86-64.h 21 Sep 2005 06:13:15 -0000
@@ -1,5 +1,5 @@
 /* x86_64 ELF support for BFD.
-   Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Jan Hubicka <jh@suse.cz>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -53,6 +53,14 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_ty
      RELOC_NUMBER (R_X86_64_GOTOFF64, 25)     /* 64 bit offset to GOT */
      RELOC_NUMBER (R_X86_64_GOTPC32,  26)     /* 32 bit signed pc relative
                                                  offset to GOT */
+     /* 27 .. 33 */
+     RELOC_NUMBER (R_X86_64_GOTPC32_TLSDESC, 34)
+					      /* 32 bit signed pc relative
+						 offset to TLS descriptor
+						 in the GOT.  */
+     RELOC_NUMBER (R_X86_64_TLSDESC_CALL, 35) /* Relaxable call through TLS
+						 descriptor.  */
+     RELOC_NUMBER (R_X86_64_TLSDESC, 36)      /* 2x64-bit TLS descriptor.  */
      RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250)       /* GNU C++ hack  */
      RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251)         /* GNU C++ hack  */
 END_RELOC_NUMBERS (R_X86_64_max)
Index: ld/testsuite/ld-i386/i386.exp
===================================================================
RCS file: /cvs/uberbaum/./ld/testsuite/ld-i386/i386.exp,v
retrieving revision 1.10
diff -u -p -r1.10 i386.exp
--- ld/testsuite/ld-i386/i386.exp 18 Jul 2005 06:23:40 -0000 1.10
+++ ld/testsuite/ld-i386/i386.exp 21 Sep 2005 06:13:18 -0000
@@ -1,5 +1,5 @@
 # Expect script for ld-i386 tests
-#   Copyright (C) 2002 Free Software Foundation
+#   Copyright (C) 2002, 2005 Free Software Foundation
 #
 # This file is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -22,7 +22,9 @@
 if { !([istarget "i?86-*-elf*"]		
        || ([istarget "i?86-*-linux*"]
 	   && ![istarget "*-*-*aout*"]
-	   && ![istarget "*-*-*oldld*"])) } {
+	   && ![istarget "*-*-*oldld*"])
+       || [istarget "x86_64-*-linux*"]
+       || [istarget "amd64-*-linux*"]) } {
     return
 }
 
@@ -41,6 +43,11 @@ set i386tests {
      {{readelf -Ssrl tlspic.rd} {objdump -drj.text tlspic.dd}
       {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
       "libtlspic.so"}
+    {"TLS descriptor -fpic -shared transitions" "-shared -melf_i386"
+     "--32" {tlsdesc.s tlspic2.s}
+     {{readelf -Ssrl tlsdesc.rd} {objdump -drj.text tlsdesc.dd}
+      {objdump "-s -j.got -j.got.plt" tlsdesc.sd} {objdump -sj.tdata tlsdesc.td}}
+      "libtlsdesc.so"}
     {"Helper shared library" "-shared -melf_i386"
      "--32" {tlslib.s} {} "libtlslib.so"}
     {"TLS -fpic and -fno-pic exec transitions"
@@ -48,10 +55,19 @@ set i386tests {
      {{readelf -Ssrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
       {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
       "tlsbin"}
+    {"TLS descriptor -fpic and -fno-pic exec transitions"
+     "-melf_i386 tmpdir/libtlslib.so" "--32" {tlsbindesc.s tlsbin.s}
+     {{readelf -Ssrl tlsbindesc.rd} {objdump -drj.text tlsbindesc.dd}
+      {objdump -sj.got tlsbindesc.sd} {objdump -sj.tdata tlsbindesc.td}}
+      "tlsbindesc"}
     {"TLS -fno-pic -shared" "-shared -melf_i386"
      "--32" {tlsnopic1.s tlsnopic2.s}
      {{readelf -Ssrl tlsnopic.rd} {objdump -drj.text tlsnopic.dd}
       {objdump -sj.got tlsnopic.sd}} "libtlsnopic.so"}
+    {"TLS with global dynamic and descriptors"
+	"-shared -melf_i386" "--32" {tlsgdesc.s}
+     {{readelf -Ssrl tlsgdesc.rd} {objdump -drj.text tlsgdesc.dd}}
+      "libtlsgdesc.so"}
     {"TLS in debug sections" "-melf_i386"
      "--32" {tlsg.s}
      {{objdump -sj.debug_foobar tlsg.sd}} "tlsg"}
Index: ld/testsuite/ld-i386/pcrel16.d
===================================================================
RCS file: /cvs/uberbaum/./ld/testsuite/ld-i386/pcrel16.d,v
retrieving revision 1.2
diff -u -p -r1.2 pcrel16.d
--- ld/testsuite/ld-i386/pcrel16.d 3 Aug 2005 16:30:34 -0000 1.2
+++ ld/testsuite/ld-i386/pcrel16.d 21 Sep 2005 06:13:18 -0000
@@ -1,5 +1,6 @@
 #name: PCREL16 overflow
-#ld: -Ttext 0x0
+#as: --32
+#ld: -melf_i386 -Ttext 0x0
 #objdump: -drj.text -m i8086
 
 .*: +file format elf32-i386
Index: ld/testsuite/ld-i386/pcrel8.d
===================================================================
RCS file: /cvs/uberbaum/./ld/testsuite/ld-i386/pcrel8.d,v
retrieving revision 1.1
diff -u -p -r1.1 pcrel8.d
--- ld/testsuite/ld-i386/pcrel8.d 18 Jul 2005 06:23:40 -0000 1.1
+++ ld/testsuite/ld-i386/pcrel8.d 21 Sep 2005 06:13:18 -0000
@@ -1,3 +1,4 @@
 #name: PCREL8 overflow
-#ld:
+#as: --32
+#ld: -melf_i386
 #error: .*relocation truncated to fit: R_386_PC8 .*
Index: ld/testsuite/ld-i386/tlsbindesc.dd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsbindesc.dd
diff -N ld/testsuite/ld-i386/tlsbindesc.dd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsbindesc.dd 21 Sep 2005 06:13:18 -0000
@@ -0,0 +1,461 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#objdump: -drj.text
+#target: i?86-*-*
+
+# PT_TLS layout is:
+# Offset from	Offset from	Name
+# TCB base	TCB end
+# 0x00		-0xa0		sg1..sg8
+# 0x20		-0x80		sl1..sl8
+# 0x40		-0x60		sh1..sh8
+# 0x60		-0x40		bg1..bg8
+# 0x80		-0x20		bl1..bl8
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+[0-9a-f]+ <fn2>:
+ [0-9a-f]+:	55[ 	]+push   %ebp
+ [0-9a-f]+:	89 e5[ 	]+mov    %esp,%ebp
+ [0-9a-f]+:	53[ 	]+push   %ebx
+ [0-9a-f]+:	50[ 	]+push   %eax
+ [0-9a-f]+:	e8 00 00 00 00[ 	]+call   [0-9a-f]+ <fn2\+0xa>
+ [0-9a-f]+:	5b[ 	]+pop    %ebx
+ [0-9a-f]+:	81 c3 fa 10 00 00[ 	]+add    \$0x10fa,%ebx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is not defined in executable
+ [0-9a-f]+:	8b 83 f8 ff ff ff[ 	]+mov    0xfffffff8\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG1
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is not defined in executable where
+#  the variable is referenced through @gottpoff too
+ [0-9a-f]+:	8b 83 e8 ff ff ff[ 	]+mov    0xffffffe8\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG2
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is not defined in executable where
+#  the variable is referenced through @gotntpoff too
+ [0-9a-f]+:	8b 83 dc ff ff ff[ 	]+mov    0xffffffdc\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sG3
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is not defined in executable where
+#  the variable is referenced through @gottpoff and @gotntpoff too
+ [0-9a-f]+:	8b 83 f0 ff ff ff[ 	]+mov    0xfffffff0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG4
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> LE with global variable defined in executable
+ [0-9a-f]+:	65[ 	]+gs
+ [0-9a-f]+:	b8 00 f0 ff ff[ 	]+mov    \$0xfffff000,%eax
+#							sg1
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> LE with local variable defined in executable
+ [0-9a-f]+:	65[ 	]+gs
+ [0-9a-f]+:	b8 20 f0 ff ff[ 	]+mov    \$0xfffff020,%eax
+#							sl1
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> LE with hidden variable defined in executable
+ [0-9a-f]+:	65[ 	]+gs
+ [0-9a-f]+:	b8 40 f0 ff ff[ 	]+mov    \$0xfffff040,%eax
+#							sh1
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LD -> LE
+ [0-9a-f]+:	65[ 	]+gs
+ [0-9a-f]+:	b8 00 f0 ff ff[ 	]+mov    \$0xfffff000,%eax
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 90 20 f0 ff ff[ 	]+lea    0xfffff020\(%eax\),%edx
+#							sl1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 88 24 f0 ff ff[ 	]+lea    0xfffff024\(%eax\),%ecx
+#							sl2
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LD -> LE against hidden variables
+ [0-9a-f]+:	65[ 	]+gs
+ [0-9a-f]+:	b8 00 f0 ff ff[ 	]+mov    \$0xfffff000,%eax
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 90 40 f0 ff ff[ 	]+lea    0xfffff040\(%eax\),%edx
+#							sh1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 88 44 f0 ff ff[ 	]+lea    0xfffff044\(%eax\),%ecx
+#							sh2
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 8b e8 ff ff ff[ 	]+sub    0xffffffe8\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF32	sG2
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 83 ec ff ff ff[ 	]+sub    0xffffffec\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG4
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 8b dc ff ff ff[ 	]+add    0xffffffdc\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	sG3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 83 f0 ff ff ff[ 	]+add    0xfffffff0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sG4
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE -> LE against global var defined in exec
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 e9 00 10 00 00[ 	]+sub    \$0x1000,%ecx
+#							sg1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE -> LE against local var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 c0 20 f0 ff ff[ 	]+add    \$0xfffff020,%eax
+#							sl1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE -> LE against hidden var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 e9 c0 0f 00 00[ 	]+sub    \$0xfc0,%ecx
+#							sh1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  Direct access through %gs
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	8b 8b e0 ff ff ff[ 	]+mov    0xffffffe0\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	sG5
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 11[ 	]+mov    %gs:\(%ecx\),%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE->LE against local var
+ [0-9a-f]+:	c7 c0 30 f0 ff ff[ 	]+mov    \$0xfffff030,%eax
+#							sl5
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 10[ 	]+mov    %gs:\(%eax\),%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE->LE against hidden var
+ [0-9a-f]+:	c7 c2 50 f0 ff ff[ 	]+mov    \$0xfffff050,%edx
+#							sh5
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 12[ 	]+mov    %gs:\(%edx\),%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8b 5d fc[ 	]+mov    0xfffffffc\(%ebp\),%ebx
+ [0-9a-f]+:	c9[ 	]+leave *
+ [0-9a-f]+:	c3[ 	]+ret *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+:	55[ 	]+push   %ebp
+ [0-9a-f]+:	89 e5[ 	]+mov    %esp,%ebp
+ [0-9a-f]+:	e8 00 00 00 00[ 	]+call   [0-9a-f]+ <_start\+0x8>
+ [0-9a-f]+:	59[ 	]+pop    %ecx
+ [0-9a-f]+:	81 c1 a4 0f 00 00[ 	]+add    \$0xfa4,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 91 f4 ff ff ff[ 	]+sub    0xfffffff4\(%ecx\),%edx
+#				->R_386_TLS_TPOFF32	sG6
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff IE against global var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 05 e8 a0 04 08[ 	]+add    0x804a0e8,%eax
+#				->R_386_TLS_TPOFF	sG7
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff direct %gs access IE against global var
+ [0-9a-f]+:	8b 15 00 a1 04 08[ 	]+mov    0x804a100,%edx
+#				->R_386_TLS_TPOFF	sG8
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 02[ 	]+mov    %gs:\(%edx\),%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE -> LE against global var defined in exec
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 ea 8c 0f 00 00[ 	]+sub    \$0xf8c,%edx
+#							bg6
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff IE -> LE against global var defined in exec
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 c0 78 f0 ff ff[ 	]+add    \$0xfffff078,%eax
+#							bg7
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff direct %gs access IE -> LE against global var defined
+#  in exec
+ [0-9a-f]+:	c7 c2 7c f0 ff ff[ 	]+mov    \$0xfffff07c,%edx
+#							bg8
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 02[ 	]+mov    %gs:\(%edx\),%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE -> LE against local var
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 ea 6c 0f 00 00[ 	]+sub    \$0xf6c,%edx
+#							bl6
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff IE -> LE against local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 c0 98 f0 ff ff[ 	]+add    \$0xfffff098,%eax
+#							bl7
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff direct %gs access IE -> LE against local var
+ [0-9a-f]+:	c7 c2 9c f0 ff ff[ 	]+mov    \$0xfffff09c,%edx
+#							bl8
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 02[ 	]+mov    %gs:\(%edx\),%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE -> LE against hidden but not local var
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 ea ac 0f 00 00[ 	]+sub    \$0xfac,%edx
+#							sh6
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff IE -> LE against hidden but not local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 c0 58 f0 ff ff[ 	]+add    \$0xfffff058,%eax
+#							sh7
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @indntpoff direct %gs access IE -> LE against hidden but not
+#  local var
+ [0-9a-f]+:	c7 c2 5c f0 ff ff[ 	]+mov    \$0xfffff05c,%edx
+#							sh8
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 02[ 	]+mov    %gs:\(%edx\),%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @tpoff, global var defined in exec
+ [0-9a-f]+:	ba 00 10 00 00[ 	]+mov    \$0x1000,%edx
+#							sg1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	29 d0[ 	]+sub    %edx,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @tpoff, local var
+ [0-9a-f]+:	b8 7f 0f 00 00[ 	]+mov    \$0xf7f,%eax
+#							bl1+1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	29 c2[ 	]+sub    %eax,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @tpoff, hidden var defined in exec
+ [0-9a-f]+:	b8 bd 0f 00 00[ 	]+mov    \$0xfbd,%eax
+#							sh1+3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	29 c2[ 	]+sub    %eax,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @ntpoff, global var defined in exec
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 90 04 f0 ff ff[ 	]+lea    0xfffff004\(%eax\),%edx
+#							sg2
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @ntpoff, local var, non-canonical sequence
+ [0-9a-f]+:	b8 86 f0 ff ff[ 	]+mov    \$0xfffff086,%eax
+#							bl2+2
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	01 c2[ 	]+add    %eax,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @ntpoff, hidden var defined in exec, non-canonical sequence
+ [0-9a-f]+:	65 8b 15 00 00 00 00[ 	]+mov    %gs:0x0,%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	81 c2 45 f0 ff ff[ 	]+add    \$0xfffff045,%edx
+#							sh2+1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @ntpoff, global var defined in exec
+ [0-9a-f]+:	65 a1 08 f0 ff ff[ 	]+mov    %gs:0xfffff008,%eax
+#							sg3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @ntpoff, local var
+ [0-9a-f]+:	65 8b 15 8b f0 ff ff[ 	]+mov    %gs:0xfffff08b,%edx
+#							bl3+3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LE @ntpoff, hidden var defined in exec
+ [0-9a-f]+:	65 8b 15 49 f0 ff ff[ 	]+mov    %gs:0xfffff049,%edx
+#							sh3+1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8b 5d fc[ 	]+mov    0xfffffffc\(%ebp\),%ebx
+ [0-9a-f]+:	c9[ 	]+leave *
+ [0-9a-f]+:	c3[ 	]+ret *
Index: ld/testsuite/ld-i386/tlsbindesc.rd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsbindesc.rd
diff -N ld/testsuite/ld-i386/tlsbindesc.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsbindesc.rd 21 Sep 2005 06:13:18 -0000
@@ -0,0 +1,154 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are 15 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\] \.rel.dyn +.*
+  \[ 6\] \.text +PROGBITS +0+8049000 .*
+  \[ 7\] \.tdata +PROGBITS +0+804a000 [0-9a-f]+ 000060 00 WAT  0   0 4096
+  \[ 8\] \.tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000040 00 WAT  0   0  1
+  \[ 9\] \.dynamic +DYNAMIC +0+804a060 .*
+  \[10\] \.got +PROGBITS +0+804a0e0 .*
+  \[11\] \.got\.plt +PROGBITS +0+804a104 .*
+  \[12\] \.shstrtab +.*
+  \[13\] \.symtab +.*
+  \[14\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x8049158
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  PHDR.*
+  INTERP.*
+.*Requesting program interpreter.*
+  LOAD.*
+  LOAD.*
+  DYNAMIC.*
+  TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+a0 R +0x1000
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +
+   01 +.interp *
+   02 +.interp .hash .dynsym .dynstr .rel.dyn .text *
+   03 +.tdata .dynamic .got .got.plt *
+   04 +.dynamic *
+   05 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 9 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+0+804a0e0  0000010e R_386_TLS_TPOFF +0+ +sG3
+0+804a0e4  0000020e R_386_TLS_TPOFF +0+ +sG5
+0+804a0e8  0000030e R_386_TLS_TPOFF +0+ +sG7
+0+804a0ec  00000425 R_386_TLS_TPOFF32 0+ +sG2
+0+804a0f0  00000525 R_386_TLS_TPOFF32 0+ +sG4
+0+804a0f4  0000050e R_386_TLS_TPOFF +0+ +sG4
+0+804a0f8  00000725 R_386_TLS_TPOFF32 0+ +sG6
+0+804a0fc  00000825 R_386_TLS_TPOFF32 0+ +sG1
+0+804a100  00000b0e R_386_TLS_TPOFF +0+ +sG8
+
+Symbol table '.dynsym' contains 12 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG7
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG8
+
+Symbol table '.symtab' contains 71 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +14 *
+ +[0-9]+: 00000020 +0 TLS +LOCAL  DEFAULT +7 sl1
+ +[0-9]+: 00000024 +0 TLS +LOCAL  DEFAULT +7 sl2
+ +[0-9]+: 00000028 +0 TLS +LOCAL  DEFAULT +7 sl3
+ +[0-9]+: 0000002c +0 TLS +LOCAL  DEFAULT +7 sl4
+ +[0-9]+: 00000030 +0 TLS +LOCAL  DEFAULT +7 sl5
+ +[0-9]+: 00000034 +0 TLS +LOCAL  DEFAULT +7 sl6
+ +[0-9]+: 00000038 +0 TLS +LOCAL  DEFAULT +7 sl7
+ +[0-9]+: 0000003c +0 TLS +LOCAL  DEFAULT +7 sl8
+ +[0-9]+: 00000080 +0 TLS +LOCAL  DEFAULT +8 bl1
+ +[0-9]+: 00000084 +0 TLS +LOCAL  DEFAULT +8 bl2
+ +[0-9]+: 00000088 +0 TLS +LOCAL  DEFAULT +8 bl3
+ +[0-9]+: 0000008c +0 TLS +LOCAL  DEFAULT +8 bl4
+ +[0-9]+: 00000090 +0 TLS +LOCAL  DEFAULT +8 bl5
+ +[0-9]+: 00000094 +0 TLS +LOCAL  DEFAULT +8 bl6
+ +[0-9]+: 00000098 +0 TLS +LOCAL  DEFAULT +8 bl7
+ +[0-9]+: 0000009c +0 TLS +LOCAL  DEFAULT +8 bl8
+ +[0-9]+: 00000000 +0 TLS +LOCAL  HIDDEN +7 _TLS_MODULE_BASE_
+ +[0-9]+: 0+804a060 +0 OBJECT  LOCAL  HIDDEN    9 _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  LOCAL  HIDDEN   11 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +[0-9]+: 0000001c +0 TLS +GLOBAL DEFAULT +7 sg8
+ +[0-9]+: 0000007c +0 TLS +GLOBAL DEFAULT +8 bg8
+ +[0-9]+: 00000074 +0 TLS +GLOBAL DEFAULT +8 bg6
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 00000068 +0 TLS +GLOBAL DEFAULT +8 bg3
+ +[0-9]+: 00000008 +0 TLS +GLOBAL DEFAULT +7 sg3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG7
+ +[0-9]+: 00000048 +0 TLS +GLOBAL HIDDEN +7 sh3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0000000c +0 TLS +GLOBAL DEFAULT +7 sg4
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +[0-9]+: 00000010 +0 TLS +GLOBAL DEFAULT +7 sg5
+ +[0-9]+: 00000070 +0 TLS +GLOBAL DEFAULT +8 bg5
+ +[0-9]+: 00000058 +0 TLS +GLOBAL HIDDEN +7 sh7
+ +[0-9]+: 0000005c +0 TLS +GLOBAL HIDDEN +7 sh8
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +7 sg1
+ +[0-9]+: 0+8049158 +0 FUNC +GLOBAL DEFAULT +6 _start
+ +[0-9]+: 0000004c +0 TLS +GLOBAL HIDDEN +7 sh4
+ +[0-9]+: 00000078 +0 TLS +GLOBAL DEFAULT +8 bg7
+ +[0-9]+: 00000050 +0 TLS +GLOBAL HIDDEN +7 sh5
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: 0+8049000 +0 FUNC +GLOBAL DEFAULT +6 fn2
+ +[0-9]+: 00000004 +0 TLS +GLOBAL DEFAULT +7 sg2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: 00000040 +0 TLS +GLOBAL HIDDEN +7 sh1
+ +[0-9]+: 00000014 +0 TLS +GLOBAL DEFAULT +7 sg6
+ +[0-9]+: 00000018 +0 TLS +GLOBAL DEFAULT +7 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +[0-9]+: 00000044 +0 TLS +GLOBAL HIDDEN +7 sh2
+ +[0-9]+: 00000054 +0 TLS +GLOBAL HIDDEN +7 sh6
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG8
+ +[0-9]+: 00000064 +0 TLS +GLOBAL DEFAULT +8 bg2
+ +[0-9]+: 00000060 +0 TLS +GLOBAL DEFAULT +8 bg1
+ +[0-9]+: 0000006c +0 TLS +GLOBAL DEFAULT +8 bg4
Index: ld/testsuite/ld-i386/tlsbindesc.s
===================================================================
RCS file: ld/testsuite/ld-i386/tlsbindesc.s
diff -N ld/testsuite/ld-i386/tlsbindesc.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsbindesc.s 21 Sep 2005 06:13:18 -0000
@@ -0,0 +1,167 @@
+	/* Force .got aligned to 4K, so it very likely gets at 0x804a100
+	   (0x60 bytes .tdata and 0xa0 bytes .dynamic)  */
+	.section ".tdata", "awT", @progbits
+	.balign	4096
+	.globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+	.globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+	.hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1:	.long 17
+sg2:	.long 18
+sg3:	.long 19
+sg4:	.long 20
+sg5:	.long 21
+sg6:	.long 22
+sg7:	.long 23
+sg8:	.long 24
+sl1:	.long 65
+sl2:	.long 66
+sl3:	.long 67
+sl4:	.long 68
+sl5:	.long 69
+sl6:	.long 70
+sl7:	.long 71
+sl8:	.long 72
+sh1:	.long 257
+sh2:	.long 258
+sh3:	.long 259
+sh4:	.long 260
+sh5:	.long 261
+sh6:	.long 262
+sh7:	.long 263
+sh8:	.long 264
+	/* Force .text aligned to 4K, so it very likely gets at 0x8049000.  */
+	.text
+	.balign	4096
+	.globl	fn2
+	.type	fn2,@function
+fn2:
+	pushl	%ebp
+	movl	%esp, %ebp
+	pushl	%ebx
+	pushl	%eax
+	call	1f
+1:	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is not defined in executable */
+	leal	sG1@tlsdesc(%ebx), %eax
+	call	*sG1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is not defined in executable where
+	   the variable is referenced through @gottpoff too */
+	leal	sG2@tlsdesc(%ebx), %eax
+	call	*sG2@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is not defined in executable where
+	   the variable is referenced through @gotntpoff too */
+	leal	sG3@tlsdesc(%ebx), %eax
+	call	*sG3@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is not defined in executable where
+	   the variable is referenced through @gottpoff and @gotntpoff too */
+	leal	sG4@tlsdesc(%ebx), %eax
+	call	*sG4@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> LE with global variable defined in executable */
+	leal	sg1@tlsdesc(%ebx), %eax
+	call	*sg1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> LE with local variable defined in executable */
+	leal	sl1@tlsdesc(%ebx), %eax
+	call	*sl1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> LE with hidden variable defined in executable */
+	leal	sh1@tlsdesc(%ebx), %eax
+	call	*sh1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* LD -> LE */
+	leal	_TLS_MODULE_BASE_@tlsdesc(%ebx), %eax
+	call	*_TLS_MODULE_BASE_@tlscall(%eax)
+	nop;nop
+	leal	sl1@dtpoff(%eax), %edx
+	nop;nop
+	leal	sl2@dtpoff(%eax), %ecx
+	nop;nop;nop;nop
+
+	/* LD -> LE against hidden variables */
+	leal	_TLS_MODULE_BASE_@tlsdesc(%ebx), %eax
+	call	*_TLS_MODULE_BASE_@tlscall(%eax)
+	nop;nop
+	leal	sh1@dtpoff(%eax), %edx
+	nop;nop
+	leal	sh2@dtpoff(%eax), %ecx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sG2@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against global var  */
+	movl	%gs:0, %eax
+	nop;nop
+	subl	sG4@gottpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sG3@gotntpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against global var  */
+	movl	%gs:0, %eax
+	nop;nop
+	addl	sG4@gotntpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gottpoff IE -> LE against global var defined in exec */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sg1@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE -> LE against local var */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sl1@gotntpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gottpoff IE -> LE against hidden var */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sh1@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* Direct access through %gs  */
+
+	/* @gotntpoff IE against global var  */
+	movl	sG5@gotntpoff(%ebx), %ecx
+	nop;nop
+	movl	%gs:(%ecx), %edx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE->LE against local var  */
+	movl	sl5@gotntpoff(%ebx), %eax
+	nop;nop
+	movl	%gs:(%eax), %edx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE->LE against hidden var  */
+	movl	sh5@gotntpoff(%ebx), %edx
+	nop;nop
+	movl	%gs:(%edx), %edx
+	nop;nop;nop;nop
+
+	movl    -4(%ebp), %ebx
+	leave
+	ret
Index: ld/testsuite/ld-i386/tlsbindesc.sd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsbindesc.sd
diff -N ld/testsuite/ld-i386/tlsbindesc.sd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsbindesc.sd 21 Sep 2005 06:13:18 -0000
@@ -0,0 +1,13 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.got:
+ 804a0e0 [0-9a-f]+ 00000000 00000000 [0-9a-f]+  .*
+ 804a0f0 00000000 00000000 00000000 00000000  .*
+ 804a100 00000000  +.*
Index: ld/testsuite/ld-i386/tlsbindesc.td
===================================================================
RCS file: ld/testsuite/ld-i386/tlsbindesc.td
diff -N ld/testsuite/ld-i386/tlsbindesc.td
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsbindesc.td 21 Sep 2005 06:13:18 -0000
@@ -0,0 +1,16 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#objdump: -sj.tdata
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.tdata:
+ 804a000 11000000 12000000 13000000 14000000  .*
+ 804a010 15000000 16000000 17000000 18000000  .*
+ 804a020 41000000 42000000 43000000 44000000  .*
+ 804a030 45000000 46000000 47000000 48000000  .*
+ 804a040 01010000 02010000 03010000 04010000  .*
+ 804a050 05010000 06010000 07010000 08010000  .*
Index: ld/testsuite/ld-i386/tlsdesc.dd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsdesc.dd
diff -N ld/testsuite/ld-i386/tlsdesc.dd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsdesc.dd 21 Sep 2005 06:13:18 -0000
@@ -0,0 +1,391 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drj.text
+#target: i?86-*-*
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+[0-9a-f]+ <fn1>:
+ [0-9a-f]+:	55[ 	]+push   %ebp
+ [0-9a-f]+:	89 e5[ 	]+mov    %esp,%ebp
+ [0-9a-f]+:	53[ 	]+push   %ebx
+ [0-9a-f]+:	50[ 	]+push   %eax
+ [0-9a-f]+:	e8 00 00 00 00[ 	]+call   [0-9a-f]+ <fn1\+0xa>
+ [0-9a-f]+:	5b[ 	]+pop    %ebx
+ [0-9a-f]+:	81 c3 9a 13 00 00[ 	]+add    \$0x[0-9a-f]+,%ebx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GDesc
+ [0-9a-f]+:	8d 83 24 00 00 00[ 	]+lea    0x24\(%ebx\),%eax
+#				->R_386_TLS_DESC	sg1
+ [0-9a-f]+:	ff 10[ 	]+call   \*\(%eax\)
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through @gottpoff too
+ [0-9a-f]+:	8b 83 f8 ff ff ff[ 	]+mov    0xfffffff8\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sg2
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through @gotntpoff too
+ [0-9a-f]+:	8b 83 c4 ff ff ff[ 	]+mov    0xffffffc4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sg3
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through @gottpoff and
+ [0-9a-f]+:	8b 83 d4 ff ff ff[ 	]+mov    0xffffffd4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sg4
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD against local variable
+ [0-9a-f]+:	8d 83 0c 00 00 00[ 	]+lea    0xc\(%ebx\),%eax
+#				->R_386_TLS_DESC	sl1
+ [0-9a-f]+:	ff 10[ 	]+call   \*\(%eax\)
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against local variable referenced through @gottpoff too
+ [0-9a-f]+:	8b 83 b0 ff ff ff[ 	]+mov    0xffffffb0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sl2
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against local variable referenced through @gotntpoff
+ [0-9a-f]+:	8b 83 b4 ff ff ff[ 	]+mov    0xffffffb4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sl3
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against local variable referenced through @gottpoff and
+ [0-9a-f]+:	8b 83 bc ff ff ff[ 	]+mov    0xffffffbc\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sl4
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD against hidden and local variable
+ [0-9a-f]+:	8d 83 2c 00 00 00[ 	]+lea    0x2c\(%ebx\),%eax
+#				->R_386_TLS_DESC	sh1
+ [0-9a-f]+:	ff 10[ 	]+call   \*\(%eax\)
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden and local variable referenced through @gottpoff too
+ [0-9a-f]+:	8b 83 fc ff ff ff[ 	]+mov    0xfffffffc\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sh2
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden and local variable referenced through @gotntpoff too
+ [0-9a-f]+:	8b 83 c8 ff ff ff[ 	]+mov    0xffffffc8\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sh3
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden and local variable referenced through @gottpoff and @gotntpoff too
+ [0-9a-f]+:	8b 83 e8 ff ff ff[ 	]+mov    0xffffffe8\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sh4
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD against hidden but not local variable
+ [0-9a-f]+:	8d 83 14 00 00 00[ 	]+lea    0x14\(%ebx\),%eax
+#				->R_386_TLS_DESC	sH1
+ [0-9a-f]+:	ff 10[ 	]+call   \*\(%eax\)
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden but not local variable referenced through
+ [0-9a-f]+:	8b 83 cc ff ff ff[ 	]+mov    0xffffffcc\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sH2
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden but not local variable referenced through
+ [0-9a-f]+:	8b 83 ec ff ff ff[ 	]+mov    0xffffffec\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sH3
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden but not local variable referenced through
+ [0-9a-f]+:	8b 83 e0 ff ff ff[ 	]+mov    0xffffffe0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sH4
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LD
+ [0-9a-f]+:	8d 83 1c 00 00 00[ 	]+lea    0x1c\(%ebx\),%eax
+#				->R_386_TLS_DESC	_TLS_MODULE_BASE_
+ [0-9a-f]+:	ff 10[ 	]+call   \*\(%eax\)
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 90 20 00 00 00[ 	]+lea    0x20\(%eax\),%edx
+#							sl1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 88 26 00 00 00[ 	]+lea    0x26\(%eax\),%ecx
+#							sl2+2
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LD against hidden and local variables
+ [0-9a-f]+:	8d 90 40 00 00 00[ 	]+lea    0x40\(%eax\),%edx
+#							sh1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 88 47 00 00 00[ 	]+lea    0x47\(%eax\),%ecx
+#							sh2+3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  LD against hidden but not local variables
+ [0-9a-f]+:	8d 90 60 00 00 00[ 	]+lea    0x60\(%eax\),%edx
+#							sH1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 88 65 00 00 00[ 	]+lea    0x65\(%eax\),%ecx
+#							sH2+1
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 8b f8 ff ff ff[ 	]+sub    0xfffffff8\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF32	sg2
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 83 d0 ff ff ff[ 	]+sub    0xffffffd0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sg4
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 8b c4 ff ff ff[ 	]+add    0xffffffc4\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	sg3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 83 d4 ff ff ff[ 	]+add    0xffffffd4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sg4
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against local var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 8b b0 ff ff ff[ 	]+sub    0xffffffb0\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF32	[0xdcffffff]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 83 b8 ff ff ff[ 	]+sub    0xffffffb8\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	[0xd4ffffff]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against local var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 8b b4 ff ff ff[ 	]+add    0xffffffb4\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	[0x28000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 83 bc ff ff ff[ 	]+add    0xffffffbc\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	[0x2c000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against hidden and local var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 8b fc ff ff ff[ 	]+sub    0xfffffffc\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF32	[0xbcffffff]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against hidden and local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 83 e4 ff ff ff[ 	]+sub    0xffffffe4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	[0xb4ffffff]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against hidden and local var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 8b c8 ff ff ff[ 	]+add    0xffffffc8\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	[0x48000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against hidden and local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 83 e8 ff ff ff[ 	]+add    0xffffffe8\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	[0x4c000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against hidden but not local var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 8b cc ff ff ff[ 	]+sub    0xffffffcc\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF32	[0x9cffffff]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against hidden but not local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 83 dc ff ff ff[ 	]+sub    0xffffffdc\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	[0x94ffffff]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against hidden but not local var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 8b ec ff ff ff[ 	]+add    0xffffffec\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	[0x68000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against hidden but not local var
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 83 e0 ff ff ff[ 	]+add    0xffffffe0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	[0x6c000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  Direct access through %gs
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	8b 8b d8 ff ff ff[ 	]+mov    0xffffffd8\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	sg5
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 11[ 	]+mov    %gs:\(%ecx\),%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against local var
+ [0-9a-f]+:	8b 83 c0 ff ff ff[ 	]+mov    0xffffffc0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	[0x30000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 10[ 	]+mov    %gs:\(%eax\),%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against hidden and local var
+ [0-9a-f]+:	8b 93 f0 ff ff ff[ 	]+mov    0xfffffff0\(%ebx\),%edx
+#				->R_386_TLS_TPOFF	[0x50000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 12[ 	]+mov    %gs:\(%edx\),%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against hidden but not local var
+ [0-9a-f]+:	8b 8b f4 ff ff ff[ 	]+mov    0xfffffff4\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	[0x70000000]
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 8b 11[ 	]+mov    %gs:\(%ecx\),%edx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8b 5d fc[ 	]+mov    0xfffffffc\(%ebp\),%ebx
+ [0-9a-f]+:	c9[ 	]+leave *
+ [0-9a-f]+:	c3[ 	]+ret *
Index: ld/testsuite/ld-i386/tlsdesc.rd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsdesc.rd
diff -N ld/testsuite/ld-i386/tlsdesc.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsdesc.rd 21 Sep 2005 06:13:18 -0000
@@ -0,0 +1,155 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are [0-9]+ section headers, starting at offset 0x.*:
+
+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\] \.rel.dyn +.*
+  \[ 5\] \.rel.plt +.*
+  \[ 6\] \.text +.*
+  \[ 7\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000060 00 WAT  0   0  1
+  \[ 8\] \.tbss +NOBITS +[0-9aa-f]+ [0-9a-f]+ 000020 00 WAT  0   0  1
+  \[ 9\] \.dynamic +.*
+  \[10\] \.got +.*
+  \[11\] \.got.plt +.*
+  \[12\] \.shstrtab +.*
+  \[13\] \.symtab +.*
+  \[14\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x[0-9a-f]+
+There are [0-9]+ 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+60 0x0+80 R +0x1
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +.hash .dynsym .dynstr .rel.dyn .rel.plt .text *
+   01 +.tdata .dynamic .got .got.plt *
+   02 +.dynamic *
+   03 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 20 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+50e R_386_TLS_TPOFF   0+8   sg3
+[0-9a-f]+ +0+625 R_386_TLS_TPOFF32 0+c   sg4
+[0-9a-f]+ +0+60e R_386_TLS_TPOFF   0+c   sg4
+[0-9a-f]+ +0+70e R_386_TLS_TPOFF   0+10   sg5
+[0-9a-f]+ +0+b25 R_386_TLS_TPOFF32 0+4   sg2
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 5 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+[0-9a-f]+ +0+829 R_386_TLS_DESC * 0+   sg1
+[0-9a-f]+ +0+29 R_386_TLS_DESC *
+[0-9a-f]+ +0+29 R_386_TLS_DESC *
+[0-9a-f]+ +0+29 R_386_TLS_DESC *
+[0-9a-f]+ +0+29 R_386_TLS_DESC *
+
+Symbol table '.dynsym' contains 16 entries:
+ +Num: + Value  Size Type + Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +7 sg8
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +7 sg3
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +7 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +7 sg5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +7 sg1
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +6 fn1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +7 sg2
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +7 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +7 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+
+Symbol table '.symtab' contains 54 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +14 *
+ +[0-9]+: 0+20 +0 TLS +LOCAL  DEFAULT +7 sl1
+ +[0-9]+: 0+24 +0 TLS +LOCAL  DEFAULT +7 sl2
+ +[0-9]+: 0+28 +0 TLS +LOCAL  DEFAULT +7 sl3
+ +[0-9]+: 0+2c +0 TLS +LOCAL  DEFAULT +7 sl4
+ +[0-9]+: 0+30 +0 TLS +LOCAL  DEFAULT +7 sl5
+ +[0-9]+: 0+34 +0 TLS +LOCAL  DEFAULT +7 sl6
+ +[0-9]+: 0+38 +0 TLS +LOCAL  DEFAULT +7 sl7
+ +[0-9]+: 0+3c +0 TLS +LOCAL  DEFAULT +7 sl8
+ +[0-9]+: 0+60 +0 TLS +LOCAL  HIDDEN +8 sH1
+ +[0-9]+: 0+ +0 TLS +LOCAL  HIDDEN +7 _TLS_MODULE_BASE_
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  LOCAL  HIDDEN  ABS _DYNAMIC
+ +[0-9]+: 0+48 +0 TLS +LOCAL  HIDDEN +7 sh3
+ +[0-9]+: 0+64 +0 TLS +LOCAL  HIDDEN +8 sH2
+ +[0-9]+: 0+78 +0 TLS +LOCAL  HIDDEN +8 sH7
+ +[0-9]+: 0+58 +0 TLS +LOCAL  HIDDEN +7 sh7
+ +[0-9]+: 0+5c +0 TLS +LOCAL  HIDDEN +7 sh8
+ +[0-9]+: 0+6c +0 TLS +LOCAL  HIDDEN +8 sH4
+ +[0-9]+: 0+4c +0 TLS +LOCAL  HIDDEN +7 sh4
+ +[0-9]+: 0+68 +0 TLS +LOCAL  HIDDEN +8 sH3
+ +[0-9]+: 0+50 +0 TLS +LOCAL  HIDDEN +7 sh5
+ +[0-9]+: 0+70 +0 TLS +LOCAL  HIDDEN +8 sH5
+ +[0-9]+: 0+74 +0 TLS +LOCAL  HIDDEN +8 sH6
+ +[0-9]+: 0+7c +0 TLS +LOCAL  HIDDEN +8 sH8
+ +[0-9]+: 0+40 +0 TLS +LOCAL  HIDDEN +7 sh1
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  LOCAL  HIDDEN  ABS _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+44 +0 TLS +LOCAL  HIDDEN +7 sh2
+ +[0-9]+: 0+54 +0 TLS +LOCAL  HIDDEN +7 sh6
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +7 sg8
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +7 sg3
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +7 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +7 sg5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +7 sg1
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +6 fn1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +7 sg2
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +7 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +7 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
Index: ld/testsuite/ld-i386/tlsdesc.s
===================================================================
RCS file: ld/testsuite/ld-i386/tlsdesc.s
diff -N ld/testsuite/ld-i386/tlsdesc.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsdesc.s 21 Sep 2005 06:13:19 -0000
@@ -0,0 +1,276 @@
+	.section ".tdata", "awT", @progbits
+	.globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+	.globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+	.hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1:	.long 17
+sg2:	.long 18
+sg3:	.long 19
+sg4:	.long 20
+sg5:	.long 21
+sg6:	.long 22
+sg7:	.long 23
+sg8:	.long 24
+sl1:	.long 65
+sl2:	.long 66
+sl3:	.long 67
+sl4:	.long 68
+sl5:	.long 69
+sl6:	.long 70
+sl7:	.long 71
+sl8:	.long 72
+sh1:	.long 257
+sh2:	.long 258
+sh3:	.long 259
+sh4:	.long 260
+sh5:	.long 261
+sh6:	.long 262
+sh7:	.long 263
+sh8:	.long 264
+	.text
+	.globl	fn1
+	.type	fn1,@function
+fn1:
+	pushl	%ebp
+	movl	%esp, %ebp
+	pushl	%ebx
+	pushl	%eax
+	call	1f
+1:	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+	nop;nop;nop;nop
+
+	/* GD */
+	leal	sg1@tlsdesc(%ebx), %eax
+	call	*sg1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is referenced through @gottpoff too */
+	leal	sg2@tlsdesc(%ebx), %eax
+	call	*sg2@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is referenced through @gotntpoff too */
+	leal	sg3@tlsdesc(%ebx), %eax
+	call	*sg3@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is referenced through @gottpoff and
+	   @gotntpoff too */
+	leal	sg4@tlsdesc(%ebx), %eax
+	call	*sg4@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD against local variable */
+	leal	sl1@tlsdesc(%ebx), %eax
+	call	*sl1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against local variable referenced through @gottpoff too */
+	leal	sl2@tlsdesc(%ebx), %eax
+	call	*sl2@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against local variable referenced through @gotntpoff
+	   too */
+	leal	sl3@tlsdesc(%ebx), %eax
+	call	*sl3@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against local variable referenced through @gottpoff and
+	   @gotntpoff too */
+	leal	sl4@tlsdesc(%ebx), %eax
+	call	*sl4@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD against hidden and local variable */
+	leal	sh1@tlsdesc(%ebx), %eax
+	call	*sh1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden and local variable referenced through
+	   @gottpoff too */
+	leal	sh2@tlsdesc(%ebx), %eax
+	call	*sh2@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden and local variable referenced through
+	   @gotntpoff too */
+	leal	sh3@tlsdesc(%ebx), %eax
+	call	*sh3@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden and local variable referenced through
+	   @gottpoff and @gotntpoff too */
+	leal	sh4@tlsdesc(%ebx), %eax
+	call	*sh4@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD against hidden but not local variable */
+	leal	sH1@tlsdesc(%ebx), %eax
+	call	*sH1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden but not local variable referenced through
+	   @gottpoff too */
+	leal	sH2@tlsdesc(%ebx), %eax
+	call	*sH2@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden but not local variable referenced through
+	   @gotntpoff too */
+	leal	sH3@tlsdesc(%ebx), %eax
+	call	*sH3@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden but not local variable referenced through
+	   @gottpoff and @gotntpoff too */
+	leal	sH4@tlsdesc(%ebx), %eax
+	call	*sH4@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* LD */
+	leal	_TLS_MODULE_BASE_@tlsdesc(%ebx), %eax
+	call	*_TLS_MODULE_BASE_@tlscall(%eax)
+	nop;nop
+	leal	sl1@dtpoff(%eax), %edx
+	nop;nop
+	leal	2+sl2@dtpoff(%eax), %ecx
+	nop;nop;nop;nop
+
+	/* LD against hidden and local variables */
+	leal	sh1@dtpoff(%eax), %edx
+	nop;nop
+	leal	sh2@dtpoff+3(%eax), %ecx
+	nop;nop;nop;nop
+
+	/* LD against hidden but not local variables */
+	leal	sH1@dtpoff(%eax), %edx
+	nop;nop
+	leal	sH2@dtpoff+1(%eax), %ecx
+	nop;nop
+
+	/* @gottpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sg2@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against global var  */
+	movl	%gs:0, %eax
+	nop;nop
+	subl	sg4@gottpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sg3@gotntpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against global var  */
+	movl	%gs:0, %eax
+	nop;nop
+	addl	sg4@gotntpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against local var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sl2@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against local var  */
+	movl	%gs:0, %eax
+	nop;nop
+	subl	sl4@gottpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against local var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sl3@gotntpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against local var  */
+	movl	%gs:0, %eax
+	nop;nop
+	addl	sl4@gotntpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against hidden and local var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sh2@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against hidden and local var  */
+	movl	%gs:0, %eax
+	nop;nop
+	subl	sh4@gottpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against hidden and local var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sh3@gotntpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against hidden and local var  */
+	movl	%gs:0, %eax
+	nop;nop
+	addl	sh4@gotntpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against hidden but not local var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sH2@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against hidden but not local var  */
+	movl	%gs:0, %eax
+	nop;nop
+	subl	sH4@gottpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against hidden but not local var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sH3@gotntpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against hidden but not local var  */
+	movl	%gs:0, %eax
+	nop;nop
+	addl	sH4@gotntpoff(%ebx), %eax
+	nop;nop;nop;nop
+
+	/* Direct access through %gs  */
+
+	/* @gotntpoff IE against global var  */
+	movl	sg5@gotntpoff(%ebx), %ecx
+	nop;nop
+	movl	%gs:(%ecx), %edx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against local var  */
+	movl	sl5@gotntpoff(%ebx), %eax
+	nop;nop
+	movl	%gs:(%eax), %edx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against hidden and local var  */
+	movl	sh5@gotntpoff(%ebx), %edx
+	nop;nop
+	movl	%gs:(%edx), %edx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against hidden but not local var  */
+	movl	sH5@gotntpoff(%ebx), %ecx
+	nop;nop
+	movl	%gs:(%ecx), %edx
+	nop;nop;nop;nop
+
+	movl    -4(%ebp), %ebx
+	leave
+	ret
Index: ld/testsuite/ld-i386/tlsdesc.sd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsdesc.sd
diff -N ld/testsuite/ld-i386/tlsdesc.sd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsdesc.sd 21 Sep 2005 06:13:19 -0000
@@ -0,0 +1,20 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -s -j.got -j.got.plt
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.got:
+ [0-9a-f]+ dcffffff 28000000 d4ffffff 2c000000  .*
+ [0-9a-f]+ 30000000 00000000 48000000 9cffffff  .*
+ [0-9a-f]+ 00000000 00000000 00000000 94ffffff  .*
+ [0-9a-f]+ 6c000000 b4ffffff 4c000000 68000000  .*
+ [0-9a-f]+ 50000000 70000000 00000000 bcffffff  .*
+Contents of section \.got\.plt:
+ [0-9a-f]+ ec150000 00000000 00000000 00000000  .*
+ [0-9a-f]+ 20000000 00000000 60000000 00000000  .*
+ [0-9a-f]+ 00000000 00000000 00000000 00000000  .*
+ [0-9a-f]+ 40000000 +.*
Index: ld/testsuite/ld-i386/tlsdesc.td
===================================================================
RCS file: ld/testsuite/ld-i386/tlsdesc.td
diff -N ld/testsuite/ld-i386/tlsdesc.td
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsdesc.td 21 Sep 2005 06:13:19 -0000
@@ -0,0 +1,16 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -sj.tdata
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.tdata:
+ [0-9a-f]+ 11000000 12000000 13000000 14000000  .*
+ [0-9a-f]+ 15000000 16000000 17000000 18000000  .*
+ [0-9a-f]+ 41000000 42000000 43000000 44000000  .*
+ [0-9a-f]+ 45000000 46000000 47000000 48000000  .*
+ [0-9a-f]+ 01010000 02010000 03010000 04010000  .*
+ [0-9a-f]+ 05010000 06010000 07010000 08010000  .*
Index: ld/testsuite/ld-i386/tlsgdesc.dd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsgdesc.dd
diff -N ld/testsuite/ld-i386/tlsgdesc.dd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsgdesc.dd 21 Sep 2005 06:13:19 -0000
@@ -0,0 +1,156 @@
+#source: tlsgdesc.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drj.text
+#target: i?86-*-*
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+[0-9a-f]+ <fc1>:
+ [0-9a-f]+:	55[ 	]+push   %ebp
+ [0-9a-f]+:	89 e5[ 	]+mov    %esp,%ebp
+ [0-9a-f]+:	53[ 	]+push   %ebx
+ [0-9a-f]+:	50[ 	]+push   %eax
+ [0-9a-f]+:	e8 00 00 00 00[ 	]+call   [0-9a-f]+ <.*>
+ [0-9a-f]+:	5b[ 	]+pop    %ebx
+ [0-9a-f]+:	81 c3 be 11 00 00[ 	]+add    \$0x[0-9a-f]+,%ebx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 8b e0 ff ff ff[ 	]+sub    0xffffffe0\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF32	sG3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 8b f0 ff ff ff[ 	]+add    0xfffffff0\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	sG4
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD
+ [0-9a-f]+:	8d 04 1d f8 ff ff ff[ 	]+lea    0xfffffff8\(,%ebx,1\),%eax
+#				->R_386_TLS_DTPMOD32	sG1
+ [0-9a-f]+:	e8 a9 ff ff ff[ 	]+call   [0-9a-f]+ <___tls_get_addr@plt>
+#				->R_386_JUMP_SLOT	___tls_get_addr
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 83 18 00 00 00[ 	]+lea    0x18\(%ebx\),%eax
+#				->R_386_TLS_DESC	sG1
+ [0-9a-f]+:	ff 10[ 	]+call   \*\(%eax\)
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 83 10 00 00 00[ 	]+lea    0x10\(%ebx\),%eax
+#				->R_386_TLS_DESC	sG2
+ [0-9a-f]+:	ff 10[ 	]+call   \*\(%eax\)
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8d 04 1d e8 ff ff ff[ 	]+lea    0xffffffe8\(,%ebx,1\),%eax
+#				->R_386_TLS_DTPMOD32	sG2
+ [0-9a-f]+:	e8 81 ff ff ff[ 	]+call   [0-9a-f]+ <___tls_get_addr@plt>
+#				->R_386_JUMP_SLOT	___tls_get_addr
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through @gottpoff too
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	2b 83 e0 ff ff ff[ 	]+sub    0xffffffe0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG3
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8b 83 e0 ff ff ff[ 	]+mov    0xffffffe0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG3
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through @gotntpoff too
+ [0-9a-f]+:	8b 83 f0 ff ff ff[ 	]+mov    0xfffffff0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sG4
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	03 83 f0 ff ff ff[ 	]+add    0xfffffff0\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sG4
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through @gotntpoff too
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	03 83 e4 ff ff ff[ 	]+add    0xffffffe4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sG5
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8b 83 e4 ff ff ff[ 	]+mov    0xffffffe4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF	sG5
+ [0-9a-f]+:	89 c0[ 	]+mov    %eax,%eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through @gottpoff too
+ [0-9a-f]+:	8b 83 f4 ff ff ff[ 	]+mov    0xfffffff4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG6
+ [0-9a-f]+:	f7 d8[ 	]+neg    %eax
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	65 a1 00 00 00 00[ 	]+mov    %gs:0x0,%eax
+ [0-9a-f]+:	2b 83 f4 ff ff ff[ 	]+sub    0xfffffff4\(%ebx\),%eax
+#				->R_386_TLS_TPOFF32	sG6
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	03 8b e4 ff ff ff[ 	]+add    0xffffffe4\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF	sG5
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:	65 8b 0d 00 00 00 00[ 	]+mov    %gs:0x0,%ecx
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	2b 8b f4 ff ff ff[ 	]+sub    0xfffffff4\(%ebx\),%ecx
+#				->R_386_TLS_TPOFF32	sG6
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	90[ 	]+nop *
+ [0-9a-f]+:	8b 5d fc[ 	]+mov    0xfffffffc\(%ebp\),%ebx
+ [0-9a-f]+:	c9[ 	]+leave *
+ [0-9a-f]+:	c3[ 	]+ret *
Index: ld/testsuite/ld-i386/tlsgdesc.rd
===================================================================
RCS file: ld/testsuite/ld-i386/tlsgdesc.rd
diff -N ld/testsuite/ld-i386/tlsgdesc.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsgdesc.rd 21 Sep 2005 06:13:19 -0000
@@ -0,0 +1,107 @@
+#source: tlsgdesc.s
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are [0-9]+ section headers, starting at offset 0x.*:
+
+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\] \.rel.dyn +.*
+  \[ 5\] \.rel.plt +.*
+  \[ 6\] \.plt +.*
+  \[ 7\] \.text +.*
+  \[ 8\] \.dynamic +.*
+  \[ 9\] \.got +.*
+  \[10\] \.got.plt +.*
+  \[11\] \.shstrtab +.*
+  \[12\] \.symtab +.*
+  \[13\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x[0-9a-f]+
+There are [0-9]+ program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  LOAD.*
+  LOAD.*
+  DYNAMIC.*
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +.hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text *
+   01 +.dynamic .got .got.plt *
+   02 +.dynamic *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 8 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f]+ +0+225 R_386_TLS_TPOFF32 0+   sG3
+[0-9a-f]+ +0+30e R_386_TLS_TPOFF   0+   sG5
+[0-9a-f]+ +0+423 R_386_TLS_DTPMOD3 0+   sG2
+[0-9a-f]+ +0+424 R_386_TLS_DTPOFF3 0+   sG2
+[0-9a-f]+ +0+50e R_386_TLS_TPOFF   0+   sG4
+[0-9a-f]+ +0+725 R_386_TLS_TPOFF32 0+   sG6
+[0-9a-f]+ +0+923 R_386_TLS_DTPMOD3 0+   sG1
+[0-9a-f]+ +0+924 R_386_TLS_DTPOFF3 0+   sG1
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 3 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+[0-9a-f]+  0+c07 R_386_JUMP_SLOT   0+   ___tls_get_addr
+[0-9a-f]+  0+929 R_386_TLS_DESC    0+   sG1
+[0-9a-f]+  0+429 R_386_TLS_DESC    0+   sG2
+
+Symbol table '.dynsym' contains 13 entries:
+ +Num: + Value  Size Type + Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fc1
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +[0-9]+: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND ___tls_get_addr
+
+Symbol table '.symtab' contains 27 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  LOCAL  HIDDEN  ABS _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  LOCAL  HIDDEN  ABS _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fc1
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +[0-9]+: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND ___tls_get_addr
Index: ld/testsuite/ld-i386/tlsgdesc.s
===================================================================
RCS file: ld/testsuite/ld-i386/tlsgdesc.s
diff -N ld/testsuite/ld-i386/tlsgdesc.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/tlsgdesc.s 21 Sep 2005 06:13:19 -0000
@@ -0,0 +1,100 @@
+	.text
+	.globl	fc1
+	.type	fc1,@function
+fc1:
+	pushl	%ebp
+	movl	%esp, %ebp
+	pushl	%ebx
+	pushl	%eax
+	call	1f
+1:	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sG3@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sG4@gotntpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* GD */
+	leal	sG1@tlsgd(,%ebx,1), %eax
+	call	___tls_get_addr@plt
+	nop;nop;nop;nop
+
+	/* GD */
+	leal	sG1@tlsdesc(%ebx), %eax
+	call	*sG1@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD */
+	leal	sG2@tlsdesc(%ebx), %eax
+	call	*sG2@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD */
+	leal	sG2@tlsgd(,%ebx,1), %eax
+	call	___tls_get_addr@plt
+	nop;nop;nop;nop
+
+	/* GD -> IE tpoff */
+	leal	sG3@tlsgd(,%ebx,1), %eax
+	call	___tls_get_addr@plt
+	nop;nop;nop;nop
+
+	/* GD -> IE tpoff */
+	leal	sG3@tlsdesc(%ebx), %eax
+	call	*sG3@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE ntpoff */
+	leal	sG4@tlsdesc(%ebx), %eax
+	call	*sG4@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE ntpoff */
+	leal	sG4@tlsgd(,%ebx,1), %eax
+	call	___tls_get_addr@plt
+	nop;nop;nop;nop
+
+	/* GD -> IE ntpoff */
+	leal	sG5@tlsgd(,%ebx,1), %eax
+	call	___tls_get_addr@plt
+	nop;nop;nop;nop
+
+	/* GD -> IE ntpoff */
+	leal	sG5@tlsdesc(%ebx), %eax
+	call	*sG5@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE tpoff */
+	leal	sG6@tlsdesc(%ebx), %eax
+	call	*sG6@tlscall(%eax)
+	nop;nop;nop;nop
+
+	/* GD -> IE tpoff */
+	leal	sG6@tlsgd(,%ebx,1), %eax
+	call	___tls_get_addr@plt
+	nop;nop;nop;nop
+
+	/* @gotntpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	addl	sG5@gotntpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	/* @gottpoff IE against global var  */
+	movl	%gs:0, %ecx
+	nop;nop
+	subl	sG6@gottpoff(%ebx), %ecx
+	nop;nop;nop;nop
+
+	movl    -4(%ebp), %ebx
+	leave
+	ret
Index: ld/testsuite/ld-x86-64/tlsbindesc.dd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsbindesc.dd
diff -N ld/testsuite/ld-x86-64/tlsbindesc.dd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsbindesc.dd 21 Sep 2005 06:13:19 -0000
@@ -0,0 +1,301 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.text
+#target: x86_64-*-*
+
+# PT_TLS layout is:
+# Offset from   Offset from     Name
+# TCB base      TCB end
+# 0x00          -0xa0           sg1..sg8
+# 0x20          -0x80           sl1..sl8
+# 0x40          -0x60           sh1..sh8
+# 0x60          -0x40           bg1..bg8
+# 0x80          -0x20           bl1..bl8
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+401000 <fn2>:
+  [0-9a-f]+:	55[ 	]+push   %rbp
+  [0-9a-f]+:	48 89 e5[ 	]+mov    %rsp,%rbp
+#  GD -> IE because variable is not defined in executable
+  [0-9a-f]+:	48 8b 05 65 03 10 00[ 	]+mov    1049445\(%rip\),%rax +# 501370 <.*>
+#				-> R_X86_64_TPOFF64	sG1
+  [0-9a-f]+:	48 90[ 	]+rex64 nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is not defined in executable where
+#  the variable is referenced through IE too
+  [0-9a-f]+:	48 8b 05 48 03 10 00[ 	]+mov    1049416\(%rip\),%rax +# 501360 <.*>
+#				-> R_X86_64_TPOFF64	sG2
+  [0-9a-f]+:	48 90[ 	]+rex64 nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  GD -> LE with global variable defined in executable
+  [0-9a-f]+:	48 c7 c0 60 ff ff ff[ 	]+mov    \$0xf+60,%rax
+#							sg1
+  [0-9a-f]+:	48 90[ 	]+rex64 nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  GD -> LE with local variable defined in executable
+  [0-9a-f]+:	48 c7 c0 80 ff ff ff[ 	]+mov    \$0xf+80,%rax
+#							sl1
+  [0-9a-f]+:	48 90[ 	]+rex64 nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  GD -> LE with hidden variable defined in executable
+  [0-9a-f]+:	48 c7 c0 a0 ff ff ff[ 	]+mov    \$0xf+a0,%rax
+#							sh1
+  [0-9a-f]+:	48 90[ 	]+rex64 nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  LD -> LE
+  [0-9a-f]+:	48 c7 c0 60 ff ff ff[ 	]+mov    \$0xf+60,%rax
+  [0-9a-f]+:	48 90[ 	]+rex64 nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 8d 90 81 ff ff ff[ 	]+lea    0xf+81\(%rax\),%rdx
+#							sl1+1
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	4c 8d 88 86 ff ff ff[ 	]+lea    0xf+86\(%rax\),%r9
+#							sl2+2
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  LD -> LE against hidden variables
+  [0-9a-f]+:	48 8d 90 a0 ff ff ff[ 	]+lea    0xf+a0\(%rax\),%rdx
+#							sh1
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 8d 88 a7 ff ff ff[ 	]+lea    0xf+a7\(%rax\),%rcx
+#							sh2+3
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE against global var
+  [0-9a-f]+:	64 4c 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%r9
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	4c 03 0d d6 02 10 00[ 	]+add    1049302\(%rip\),%r9 +# 501360 <.*>
+#				-> R_X86_64_TPOFF64	sG2
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE -> LE against global var defined in exec
+  [0-9a-f]+:	64 4c 8b 14 25 00 00[ 	]+mov    %fs:0x0,%r10
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	4d 8d 92 60 ff ff ff[ 	]+lea    0xf+60\(%r10\),%r10
+#							sg1
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE -> LE against local var
+  [0-9a-f]+:	64 48 8b 04 25 00 00[ 	]+mov    %fs:0x0,%rax
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 8d 80 80 ff ff ff[ 	]+lea    0xf+80\(%rax\),%rax
+#							sl1
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE -> LE against hidden var
+  [0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 8d 89 a0 ff ff ff[ 	]+lea    0xf+a0\(%rcx\),%rcx
+#							sh1
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  Direct access through %fs
+#  IE against global var
+  [0-9a-f]+:	48 8b 0d 81 02 10 00[ 	]+mov    1049217\(%rip\),%rcx +# 501358 <.*>
+#				-> R_X86_64_TPOFF64	sG5
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	64 48 8b 11[ 	]+mov    %fs:\(%rcx\),%rdx
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE->LE against local var
+  [0-9a-f]+:	49 c7 c3 90 ff ff ff[ 	]+mov    \$0xf+90,%r11
+#							sl5
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	64 4d 8b 23[ 	]+mov    %fs:\(%r11\),%r12
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE->LE against hidden var
+  [0-9a-f]+:	48 c7 c2 b0 ff ff ff[ 	]+mov    \$0xf+b0,%rdx
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	64 48 8b 12[ 	]+mov    %fs:\(%rdx\),%rdx
+#							sh5
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	c9[ 	]+leaveq *
+  [0-9a-f]+:	c3[ 	]+retq *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+
+[0-9a-f]+ <_start>:
+  [0-9a-f]+:	55[ 	]+push   %rbp
+  [0-9a-f]+:	48 89 e5[ 	]+mov    %rsp,%rbp
+#  IE against global var
+  [0-9a-f]+:	64 4c 8b 1c 25 00 00[ 	]+mov    %fs:0x0,%r11
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	4c 03 1d 4a 02 10 00[ 	]+add    1049162\(%rip\),%r11 +# 501368 <.*>
+#				-> R_X86_64_TPOFF64	sG6
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE -> LE against global var defined in exec
+  [0-9a-f]+:	64 48 8b 14 25 00 00[ 	]+mov    %fs:0x0,%rdx
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 8d 92 d4 ff ff ff[ 	]+lea    0xf+d4\(%rdx\),%rdx
+#							bg6
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE -> LE against local var
+  [0-9a-f]+:	64 4c 8b 24 25 00 00[ 	]+mov    %fs:0x0,%r12
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	49 81 c4 f4 ff ff ff[ 	]+add    \$0xf+f4,%r12
+#							bl6
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  direct %fs access IE -> LE against local var
+  [0-9a-f]+:	48 c7 c2 fc ff ff ff[ 	]+mov    \$0xf+fc,%rdx
+#							bl8
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	64 48 8b 02[ 	]+mov    %fs:\(%rdx\),%rax
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  IE -> LE against hidden but not local var
+  [0-9a-f]+:	64 48 8b 14 25 00 00[ 	]+mov    %fs:0x0,%rdx
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 8d 92 b4 ff ff ff[ 	]+lea    0xf+b4\(%rdx\),%rdx
+#							sh6
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  direct %fs access IE -> LE against hidden but not local var
+  [0-9a-f]+:	48 c7 c2 bc ff ff ff[ 	]+mov    \$0xf+bc,%rdx
+#							sh8
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	64 48 8b 02[ 	]+mov    %fs:\(%rdx\),%rax
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  LE, global var defined in exec
+  [0-9a-f]+:	64 48 8b 04 25 00 00[ 	]+mov    %fs:0x0,%rax
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 8d 90 64 ff ff ff[ 	]+lea    0xf+64\(%rax\),%rdx
+#							sg2
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  LE, local var, non-canonical sequence
+  [0-9a-f]+:	49 c7 c1 e6 ff ff ff[ 	]+mov    \$0xf+e6,%r9
+#							bl2+2
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	64 48 8b 14 25 00 00[ 	]+mov    %fs:0x0,%rdx
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	4c 01 ca[ 	]+add    %r9,%rdx
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  LE, hidden var defined in exec, non-canonical sequence
+  [0-9a-f]+:	64 48 8b 14 25 00 00[ 	]+mov    %fs:0x0,%rdx
+  [0-9a-f]+:	00 00 *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	48 81 c2 a5 ff ff ff[ 	]+add    \$0xf+a5,%rdx
+#							sh2+1
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  Direct %fs access
+#  LE, global var defined in exec
+  [0-9a-f]+:	64 48 8b 04 25 68 ff[ 	]+mov    %fs:0xf+68,%rax
+  [0-9a-f]+:	ff ff *
+#							sg3
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  LE, local var
+  [0-9a-f]+:	64 4c 8b 14 25 eb ff[ 	]+mov    %fs:0xf+eb,%r10
+  [0-9a-f]+:	ff ff *
+#							bl3+3
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+#  LE, hidden var defined in exec
+  [0-9a-f]+:	64 48 8b 14 25 a9 ff[ 	]+mov    %fs:0xf+a9,%rdx
+  [0-9a-f]+:	ff ff *
+#							sh3+1
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	90[ 	]+nop *
+  [0-9a-f]+:	c9[ 	]+leaveq *
+  [0-9a-f]+:	c3[ 	]+retq *
Index: ld/testsuite/ld-x86-64/tlsbindesc.rd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsbindesc.rd
diff -N ld/testsuite/ld-x86-64/tlsbindesc.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsbindesc.rd 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,141 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -WSsrl
+#target: x86_64-*-*
+
+There are 15 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+  \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+  \[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
+  \[ 1\] .interp +.*
+  \[ 2\] .hash +.*
+  \[ 3\] .dynsym +.*
+  \[ 4\] .dynstr +.*
+  \[ 5\] .rela.dyn +.*
+  \[ 6\] .text +PROGBITS +0+401000 0+1000 0+1f6 00 +AX +0 +0 +4096
+  \[ 7\] .tdata +PROGBITS +0+5011f6 0+11f6 0+60 00 WAT +0 +0 +1
+  \[ 8\] .tbss +NOBITS +0+501256 0+1256 0+40 00 WAT +0 +0 +1
+  \[ 9\] .dynamic +DYNAMIC +0+501258 0+1258 0+100 10 +WA +4 +0 +8
+  \[10\] .got +PROGBITS +0+501358 0+1358 0+20 08 +WA +0 +0 +8
+  \[11\] .got.plt +PROGBITS +0+501378 0+1378 0+18 08 +WA +0 +0 +8
+  \[12\] .shstrtab +.*
+  \[13\] .symtab +.*
+  \[14\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x401108
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  PHDR.*
+  INTERP.*
+.*Requesting program interpreter.*
+  LOAD +0x0+ 0x0+400000 0x0+400000 0x0+11f6 0x0+11f6 R E 0x100000
+  LOAD +0x0+11f6 0x0+5011f6 0x0+5011f6 0x0+19a 0x0+19a RW  0x100000
+  DYNAMIC +0x0+1258 0x0+501258 0x0+501258 0x0+100 0x0+100 RW  0x8
+  TLS +0x0+11f6 0x0+5011f6 0x0+5011f6 0x0+60 0x0+a0 R +0x1
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 *
+   01 +.interp *
+   02 +.interp .hash .dynsym .dynstr .rela.dyn .text *
+   03 +.tdata .dynamic .got .got.plt *
+   04 +.dynamic *
+   05 +.tdata .tbss *
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 4 entries:
+ +Offset +Info +Type +Symbol's Value  Symbol's Name \+ Addend
+0+501358  0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
+0+501360  0+200000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0
+0+501368  0+400000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
+0+501370  0+500000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0
+
+Symbol table '.dynsym' contains 8 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+[0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: 0+[0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: 0+[0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+
+Symbol table '.symtab' contains 67 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +14 *
+ +[0-9]+: 0+20 +0 TLS +LOCAL  DEFAULT +7 sl1
+ +[0-9]+: 0+24 +0 TLS +LOCAL  DEFAULT +7 sl2
+ +[0-9]+: 0+28 +0 TLS +LOCAL  DEFAULT +7 sl3
+ +[0-9]+: 0+2c +0 TLS +LOCAL  DEFAULT +7 sl4
+ +[0-9]+: 0+30 +0 TLS +LOCAL  DEFAULT +7 sl5
+ +[0-9]+: 0+34 +0 TLS +LOCAL  DEFAULT +7 sl6
+ +[0-9]+: 0+38 +0 TLS +LOCAL  DEFAULT +7 sl7
+ +[0-9]+: 0+3c +0 TLS +LOCAL  DEFAULT +7 sl8
+ +[0-9]+: 0+80 +0 TLS +LOCAL  DEFAULT +8 bl1
+ +[0-9]+: 0+84 +0 TLS +LOCAL  DEFAULT +8 bl2
+ +[0-9]+: 0+88 +0 TLS +LOCAL  DEFAULT +8 bl3
+ +[0-9]+: 0+8c +0 TLS +LOCAL  DEFAULT +8 bl4
+ +[0-9]+: 0+90 +0 TLS +LOCAL  DEFAULT +8 bl5
+ +[0-9]+: 0+94 +0 TLS +LOCAL  DEFAULT +8 bl6
+ +[0-9]+: 0+98 +0 TLS +LOCAL  DEFAULT +8 bl7
+ +[0-9]+: 0+9c +0 TLS +LOCAL  DEFAULT +8 bl8
+ +[0-9]+: 0+0 +0 TLS +LOCAL  HIDDEN +7 _TLS_MODULE_BASE_
+ +[0-9]+: 0+501258 +0 OBJECT  LOCAL  HIDDEN    9 _DYNAMIC
+ +[0-9]+: 0+501378 +0 OBJECT  LOCAL  HIDDEN   11 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +7 sg8
+ +[0-9]+: 0+7c +0 TLS +GLOBAL DEFAULT +8 bg8
+ +[0-9]+: 0+74 +0 TLS +GLOBAL DEFAULT +8 bg6
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 0+68 +0 TLS +GLOBAL DEFAULT +8 bg3
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +7 sg3
+ +[0-9]+: 0+48 +0 TLS +GLOBAL HIDDEN +7 sh3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +7 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +7 sg5
+ +[0-9]+: 0+70 +0 TLS +GLOBAL DEFAULT +8 bg5
+ +[0-9]+: 0+58 +0 TLS +GLOBAL HIDDEN +7 sh7
+ +[0-9]+: 0+5c +0 TLS +GLOBAL HIDDEN +7 sh8
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +7 sg1
+ +[0-9]+: 0+401108 +0 FUNC +GLOBAL DEFAULT +6 _start
+ +[0-9]+: 0+4c +0 TLS +GLOBAL HIDDEN +7 sh4
+ +[0-9]+: 0+78 +0 TLS +GLOBAL DEFAULT +8 bg7
+ +[0-9]+: 0+50 +0 TLS +GLOBAL HIDDEN +7 sh5
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: 0+401000 +0 FUNC +GLOBAL DEFAULT +6 fn2
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +7 sg2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: 0+40 +0 TLS +GLOBAL HIDDEN +7 sh1
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +7 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +7 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +[0-9]+: 0+44 +0 TLS +GLOBAL HIDDEN +7 sh2
+ +[0-9]+: 0+54 +0 TLS +GLOBAL HIDDEN +7 sh6
+ +[0-9]+: 0+64 +0 TLS +GLOBAL DEFAULT +8 bg2
+ +[0-9]+: 0+60 +0 TLS +GLOBAL DEFAULT +8 bg1
+ +[0-9]+: 0+6c +0 TLS +GLOBAL DEFAULT +8 bg4
Index: ld/testsuite/ld-x86-64/tlsbindesc.s
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsbindesc.s
diff -N ld/testsuite/ld-x86-64/tlsbindesc.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsbindesc.s 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,128 @@
+	/* Force .data aligned to 4K, so that .got very likely gets at
+	   0x5021a0 (0x60 bytes .tdata and 0x140 bytes .dynamic)  */
+	.data
+	.balign	4096
+	.section ".tdata", "awT", @progbits
+	.globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+	.globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+	.hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1:	.long 17
+sg2:	.long 18
+sg3:	.long 19
+sg4:	.long 20
+sg5:	.long 21
+sg6:	.long 22
+sg7:	.long 23
+sg8:	.long 24
+sl1:	.long 65
+sl2:	.long 66
+sl3:	.long 67
+sl4:	.long 68
+sl5:	.long 69
+sl6:	.long 70
+sl7:	.long 71
+sl8:	.long 72
+sh1:	.long 257
+sh2:	.long 258
+sh3:	.long 259
+sh4:	.long 260
+sh5:	.long 261
+sh6:	.long 262
+sh7:	.long 263
+sh8:	.long 264
+	/* Force .text aligned to 4K, so it very likely gets at 0x401000.  */
+	.text
+	.balign	4096
+	.globl	fn2
+	.type	fn2,@function
+fn2:
+	pushq	%rbp
+	movq	%rsp, %rbp
+
+	/* GD -> IE because variable is not defined in executable */
+	leaq	sG1@tlsdesc(%rip), %rax
+	call	*sG1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is not defined in executable where
+	   the variable is referenced through IE too */
+	leaq	sG2@tlsdesc(%rip), %rax
+	call	*sG2@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> LE with global variable defined in executable */
+	leaq	sg1@tlsdesc(%rip), %rax
+	call	*sg1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> LE with local variable defined in executable */
+	leaq	sl1@tlsdesc(%rip), %rax
+	call	*sl1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> LE with hidden variable defined in executable */
+	leaq	sh1@tlsdesc(%rip), %rax
+	call	*sh1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* LD -> LE */
+	leaq	_TLS_MODULE_BASE_@tlsdesc(%rip), %rax
+	call	*_TLS_MODULE_BASE_@tlscall(%rax)
+	nop;nop
+	leaq	1+sl1@dtpoff(%rax), %rdx
+	nop;nop
+	leaq	sl2@dtpoff+2(%rax), %r9
+	nop;nop;nop;nop
+
+	/* LD -> LE against hidden variables */
+	leaq	sh1@dtpoff(%rax), %rdx
+	nop;nop
+	leaq	3+sh2@dtpoff(%rax), %rcx
+	nop;nop;nop;nop
+
+	/* IE against global var  */
+	movq	%fs:0, %r9
+	nop;nop
+	addq	sG2@gottpoff(%rip), %r9
+	nop;nop;nop;nop
+
+	/* IE -> LE against global var defined in exec */
+	movq	%fs:0, %r10
+	nop;nop
+	addq	sg1@gottpoff(%rip), %r10
+	nop;nop;nop;nop
+
+	/* IE -> LE against local var */
+	movq	%fs:0, %rax
+	nop;nop
+	addq	sl1@gottpoff(%rip), %rax
+	nop;nop;nop;nop
+
+	/* IE -> LE against hidden var */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sh1@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	/* Direct access through %fs  */
+
+	/* IE against global var  */
+	movq	sG5@gottpoff(%rip), %rcx
+	nop;nop
+	movq	%fs:(%rcx), %rdx
+	nop;nop;nop;nop
+
+	/* IE->LE against local var  */
+	movq	sl5@gottpoff(%rip), %r11
+	nop;nop
+	movq	%fs:(%r11), %r12
+	nop;nop;nop;nop
+
+	/* IE->LE against hidden var  */
+	movq	sh5@gottpoff(%rip), %rdx
+	nop;nop
+	movq	%fs:(%rdx), %rdx
+	nop;nop;nop;nop
+
+	leave
+	ret
Index: ld/testsuite/ld-x86-64/tlsbindesc.sd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsbindesc.sd
diff -N ld/testsuite/ld-x86-64/tlsbindesc.sd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsbindesc.sd 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,12 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -sj.got
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section .got:
+ 501358 00000000 00000000 00000000 00000000  .*
+ 501368 00000000 00000000 00000000 00000000  .*
Index: ld/testsuite/ld-x86-64/tlsbindesc.td
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsbindesc.td
diff -N ld/testsuite/ld-x86-64/tlsbindesc.td
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsbindesc.td 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,16 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -sj.tdata
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section .tdata:
+ 5011f6 11000000 12000000 13000000 14000000  .*
+ 501206 15000000 16000000 17000000 18000000  .*
+ 501216 41000000 42000000 43000000 44000000  .*
+ 501226 45000000 46000000 47000000 48000000  .*
+ 501236 01010000 02010000 03010000 04010000  .*
+ 501246 05010000 06010000 07010000 08010000  .*
Index: ld/testsuite/ld-x86-64/tlsdesc.dd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsdesc.dd
diff -N ld/testsuite/ld-x86-64/tlsdesc.dd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsdesc.dd 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,200 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.text
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+[0-9a-f]+ <fn1>:
+ +[0-9a-f]+:	55[ 	]+push   %rbp
+ +[0-9a-f]+:	48 89 e5[ 	]+mov    %rsp,%rbp
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD
+ +[0-9a-f]+:	48 8d 05 89 03 10 00[ 	]+lea    1049481\(%rip\),%rax +# 101398 <.*>
+#				-> R_X86_64_TLSDESC	sg1
+ +[0-9a-f]+:	ff 10[ 	]+callq  \*\(%rax\)
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE because variable is referenced through IE too
+ +[0-9a-f]+:	48 8b 05 1c 03 10 00[ 	]+mov    1049372\(%rip\),%rax +# 101338 <.*>
+#				-> R_X86_64_TPOFF64	sg2
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD against local variable
+ +[0-9a-f]+:	48 8d 05 3f 03 10 00[ 	]+lea    1049407\(%rip\),%rax +# 101368 <.*>
+#				-> R_X86_64_TLSDESC	[0 0x2000000000000000]
+ +[0-9a-f]+:	ff 10[ 	]+callq  \*\(%rax\)
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against local variable referenced through IE too
+ +[0-9a-f]+:	48 8b 05 d2 02 10 00[ 	]+mov    1049298\(%rip\),%rax +# 101308 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x24
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD against hidden and local variable
+ +[0-9a-f]+:	48 8d 05 65 03 10 00[ 	]+lea    1049445\(%rip\),%rax +# 1013a8 <.*>
+#				-> R_X86_64_TLSDESC	[0 0x4000000000000000]
+ +[0-9a-f]+:	ff 10[ 	]+callq  \*\(%rax\)
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden and local variable referenced through IE too
+ +[0-9a-f]+:	48 8b 05 f0 02 10 00[ 	]+mov    1049328\(%rip\),%rax +# 101340 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x44
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD against hidden but not local variable
+ +[0-9a-f]+:	48 8d 05 1b 03 10 00[ 	]+lea    1049371\(%rip\),%rax +# 101378 <.*>
+#				-> R_X86_64_TLSDESC	[0 0x6000000000000000]
+ +[0-9a-f]+:	ff 10[ 	]+callq  \*\(%rax\)
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  GD -> IE against hidden but not local variable referenced through IE too
+ +[0-9a-f]+:	48 8b 05 ae 02 10 00[ 	]+mov    1049262\(%rip\),%rax +# 101318 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x64
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  LD
+ +[0-9a-f]+:	48 8d 05 11 03 10 00[ 	]+lea    1049361\(%rip\),%rax +# 101388 <.*>
+#				-> R_X86_64_TLSDESC	[0 0x000000000000000]
+ +[0-9a-f]+:	ff 10[ 	]+callq  \*\(%rax\)
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 8d 90 20 00 00 00[ 	]+lea    0x20\(%rax\),%rdx
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	4c 8d 88 26 00 00 00[ 	]+lea    0x26\(%rax\),%r9
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  LD against hidden and local variables
+ +[0-9a-f]+:	48 8d 90 40 00 00 00[ 	]+lea    0x40\(%rax\),%rdx
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 8d 88 47 00 00 00[ 	]+lea    0x47\(%rax\),%rcx
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  LD against hidden but not local variables
+ +[0-9a-f]+:	4c 8d a0 60 00 00 00[ 	]+lea    0x60\(%rax\),%r12
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 8d 88 65 00 00 00[ 	]+lea    0x65\(%rax\),%rcx
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  IE against global var
+ +[0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 03 0d 71 02 10 00[ 	]+add    1049201\(%rip\),%rcx +# 101338 <.*>
+#				-> R_X86_64_TPOFF64	sg2
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  IE against local var
+ +[0-9a-f]+:	64 4c 8b 34 25 00 00[ 	]+mov    %fs:0x0,%r14
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	4c 03 35 2b 02 10 00[ 	]+add    1049131\(%rip\),%r14 +# 101308 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x24
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  IE against hidden and local var
+ +[0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 03 0d 4d 02 10 00[ 	]+add    1049165\(%rip\),%rcx +# 101340 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x44
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  IE against hidden but not local var
+ +[0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 03 0d 0f 02 10 00[ 	]+add    1049103\(%rip\),%rcx +# 101318 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x64
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  Direct access through %fs
+#  IE against global var
+ +[0-9a-f]+:	48 8b 0d 0c 02 10 00[ 	]+mov    1049100\(%rip\),%rcx +# 101320 <.*>
+#				-> R_X86_64_TPOFF64	sg5
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	64 48 8b 11[ 	]+mov    %fs:\(%rcx\),%rdx
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  IE against local var
+ +[0-9a-f]+:	4c 8b 15 eb 01 10 00[ 	]+mov    1049067\(%rip\),%r10 +# 101310 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x30
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	64 4d 8b 22[ 	]+mov    %fs:\(%r10\),%r12
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  IE against hidden and local var
+ +[0-9a-f]+:	48 8b 15 f2 01 10 00[ 	]+mov    1049074\(%rip\),%rdx +# 101328 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x50
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	64 48 8b 12[ 	]+mov    %fs:\(%rdx\),%rdx
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+#  IE against hidden but not local var
+ +[0-9a-f]+:	48 8b 0d e9 01 10 00[ 	]+mov    1049065\(%rip\),%rcx +# 101330 <.*>
+#				-> R_X86_64_TPOFF64	*ABS*+0x70
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	64 48 8b 11[ 	]+mov    %fs:\(%rcx\),%rdx
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	c9[ 	]+leaveq *
+ +[0-9a-f]+:	c3[ 	]+retq *
+ +[0-9a-f]+:	90[ 	]+nop *
Index: ld/testsuite/ld-x86-64/tlsdesc.pd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsdesc.pd
diff -N ld/testsuite/ld-x86-64/tlsdesc.pd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsdesc.pd 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,26 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.plt
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .plt:
+
+0000000000000470 <.*@plt-0x10>:
+ 470:	ff 35 e2 0e 10 00    	pushq  1052386\(%rip\)        # 101358 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ 476:	ff 25 e4 0e 10 00    	jmpq   \*1052388\(%rip\)        # 101360 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ 47c:	90                   	nop    
+ 47d:	90                   	nop    
+ 47e:	90                   	nop    
+ 47f:	90                   	nop    
+0000000000000480 <.*@plt>:
+ 480:	ff 35 d2 0e 10 00    	pushq  1052370\(%rip\)        # 101358 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ 486:	ff 25 bc 0e 10 00    	jmpq   \*1052348\(%rip\)        # 101348 <_DYNAMIC\+0x190>
+ 48c:	90                   	nop    
+ 48d:	90                   	nop    
+ 48e:	90                   	nop    
+ 48f:	90                   	nop    
+
Index: ld/testsuite/ld-x86-64/tlsdesc.rd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsdesc.rd
diff -N ld/testsuite/ld-x86-64/tlsdesc.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsdesc.rd 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,164 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -WSsrld
+#target: x86_64-*-*
+
+There are 16 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+  \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+  \[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
+  \[ 1\] .hash +.*
+  \[ 2\] .dynsym +.*
+  \[ 3\] .dynstr +.*
+  \[ 4\] .rela.dyn +.*
+  \[ 5\] .rela.plt +.*
+  \[ 6\] .plt +PROGBITS +0+470 0+470 0+20 10 +AX +0 +0 +4
+  \[ 7\] .text +PROGBITS +0+1000 0+1000 0+154 00 +AX +0 +0 4096
+  \[ 8\] .tdata +PROGBITS +0+101154 0+1154 0+60 00 WAT +0 +0 +1
+  \[ 9\] .tbss +NOBITS +0+1011b4 0+11b4 0+20 00 WAT +0 +0 +1
+  \[10\] .dynamic +DYNAMIC +0+1011b8 0+11b8 0+150 10 +WA +3 +0 +8
+  \[11\] .got +PROGBITS +0+101308 0+1308 0+48 08 +WA +0 +0 +8
+  \[12\] .got.plt +PROGBITS +0+101350 0+1350 0+68 08 +WA +0 +0 +8
+  \[13\] .shstrtab +.*
+  \[14\] .symtab +.*
+  \[15\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x1000
+There are 4 program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  LOAD +0x0+ 0x0+ 0x0+ 0x[0-9a-f]+ 0x[0-9a-f]+ R E 0x100000
+  LOAD +0x0+1154 0x0+101154 0x0+101154 0x0+264 0x0+264 RW +0x100000
+  DYNAMIC +0x0+11b8 0x0+1011b8 0x0+1011b8 0x0+150 0x0+150 RW +0x8
+  TLS +0x0+1154 0x0+101154 0x0+101154 0x0+60 0x0+80 R +0x1
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+   01 +.tdata .dynamic .got .got.plt *
+   02 +.dynamic *
+   03 +.tdata .tbss *
+
+Dynamic section at offset 0x[0-9a-f]+ contains 16 entries:
+ +Tag +Type +Name/Value
+ 0x[0-9a-f]+ +\(HASH\).*
+ 0x[0-9a-f]+ +\(STRTAB\).*
+ 0x[0-9a-f]+ +\(SYMTAB\).*
+ 0x[0-9a-f]+ +\(STRSZ\).*
+ 0x[0-9a-f]+ +\(SYMENT\).*
+ 0x[0-9a-f]+ +\(PLTGOT\).*
+ 0x[0-9a-f]+ +\(PLTRELSZ\).*
+ 0x[0-9a-f]+ +\(PLTREL\).*
+ 0x[0-9a-f]+ +\(JMPREL\).*
+ 0x[0-9a-f]+ +\(TLSDESC_PLT\) +0x480
+ 0x[0-9a-f]+ +\(TLSDESC_GOT\) +0x101348
+ 0x[0-9a-f]+ +\(RELA\).*
+ 0x[0-9a-f]+ +\(RELASZ\).*
+ 0x[0-9a-f]+ +\(RELAENT\).*
+ 0x[0-9a-f]+ +\(FLAGS\).*
+ 0x[0-9a-f]+ +\(NULL\).*
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 8 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+0+101308  0+12 R_X86_64_TPOFF64 +0+24
+0+101310  0+12 R_X86_64_TPOFF64 +0+30
+0+101318  0+12 R_X86_64_TPOFF64 +0+64
+0+101328  0+12 R_X86_64_TPOFF64 +0+50
+0+101330  0+12 R_X86_64_TPOFF64 +0+70
+0+101340  0+12 R_X86_64_TPOFF64 +0+44
+0+101320  0+700000012 R_X86_64_TPOFF64 +0+10 sg5 \+ 0
+0+101338  0+b00000012 R_X86_64_TPOFF64 +0+4 sg2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 5 entries:
+ +Offset +Info +Type +Symbol's Value  Symbol's Name \+ Addend
+0+101398  0+800000024 R_X86_64_TLSDESC +0+ sg1 \+ 0
+0+101368  0+24 R_X86_64_TLSDESC +0+20
+0+1013a8  0+24 R_X86_64_TLSDESC +0+40
+0+101378  0+24 R_X86_64_TLSDESC +0+60
+0+101388  0+24 R_X86_64_TLSDESC +0+
+
+Symbol table '.dynsym' contains 16 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +8 sg8
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +8 sg3
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +8 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +8 sg5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +8 sg1
+ +[0-9]+: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +8 sg2
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +8 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +8 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+
+Symbol table '.symtab' contains 55 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +14 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +15 *
+ +[0-9]+: 0+20 +0 TLS +LOCAL  DEFAULT +8 sl1
+ +[0-9]+: 0+24 +0 TLS +LOCAL  DEFAULT +8 sl2
+ +[0-9]+: 0+28 +0 TLS +LOCAL  DEFAULT +8 sl3
+ +[0-9]+: 0+2c +0 TLS +LOCAL  DEFAULT +8 sl4
+ +[0-9]+: 0+30 +0 TLS +LOCAL  DEFAULT +8 sl5
+ +[0-9]+: 0+34 +0 TLS +LOCAL  DEFAULT +8 sl6
+ +[0-9]+: 0+38 +0 TLS +LOCAL  DEFAULT +8 sl7
+ +[0-9]+: 0+3c +0 TLS +LOCAL  DEFAULT +8 sl8
+ +[0-9]+: 0+60 +0 TLS +LOCAL  HIDDEN +9 sH1
+ +[0-9]+: 0+ +0 TLS +LOCAL  HIDDEN +8 _TLS_MODULE_BASE_
+ +[0-9]+: 0+1011b8 +0 OBJECT  LOCAL  HIDDEN  ABS _DYNAMIC
+ +[0-9]+: 0+48 +0 TLS +LOCAL  HIDDEN +8 sh3
+ +[0-9]+: 0+64 +0 TLS +LOCAL  HIDDEN +9 sH2
+ +[0-9]+: 0+78 +0 TLS +LOCAL  HIDDEN +9 sH7
+ +[0-9]+: 0+58 +0 TLS +LOCAL  HIDDEN +8 sh7
+ +[0-9]+: 0+5c +0 TLS +LOCAL  HIDDEN +8 sh8
+ +[0-9]+: 0+6c +0 TLS +LOCAL  HIDDEN +9 sH4
+ +[0-9]+: 0+4c +0 TLS +LOCAL  HIDDEN +8 sh4
+ +[0-9]+: 0+68 +0 TLS +LOCAL  HIDDEN +9 sH3
+ +[0-9]+: 0+50 +0 TLS +LOCAL  HIDDEN +8 sh5
+ +[0-9]+: 0+70 +0 TLS +LOCAL  HIDDEN +9 sH5
+ +[0-9]+: 0+74 +0 TLS +LOCAL  HIDDEN +9 sH6
+ +[0-9]+: 0+7c +0 TLS +LOCAL  HIDDEN +9 sH8
+ +[0-9]+: 0+40 +0 TLS +LOCAL  HIDDEN +8 sh1
+ +[0-9]+: 0+101350 +0 OBJECT  LOCAL  HIDDEN  ABS _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+44 +0 TLS +LOCAL  HIDDEN +8 sh2
+ +[0-9]+: 0+54 +0 TLS +LOCAL  HIDDEN +8 sh6
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +8 sg8
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +8 sg3
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +8 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +8 sg5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +8 sg1
+ +[0-9]+: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +8 sg2
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +8 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +8 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
Index: ld/testsuite/ld-x86-64/tlsdesc.s
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsdesc.s
diff -N ld/testsuite/ld-x86-64/tlsdesc.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsdesc.s 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,157 @@
+	/* Force .data aligned to 4K, so .got very likely gets at 0x102190
+	   (0x60 bytes .tdata and 0x130 bytes .dynamic)  */
+        .data
+        .balign 4096
+	.section ".tdata", "awT", @progbits
+	.globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+	.globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+	.hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1:	.long 17
+sg2:	.long 18
+sg3:	.long 19
+sg4:	.long 20
+sg5:	.long 21
+sg6:	.long 22
+sg7:	.long 23
+sg8:	.long 24
+sl1:	.long 65
+sl2:	.long 66
+sl3:	.long 67
+sl4:	.long 68
+sl5:	.long 69
+sl6:	.long 70
+sl7:	.long 71
+sl8:	.long 72
+sh1:	.long 257
+sh2:	.long 258
+sh3:	.long 259
+sh4:	.long 260
+sh5:	.long 261
+sh6:	.long 262
+sh7:	.long 263
+sh8:	.long 264
+	/* Force .text aligned to 4K, so it very likely gets at 0x1000.  */
+	.text
+	.balign	4096
+	.globl	fn1
+	.type	fn1,@function
+fn1:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	nop;nop;nop;nop
+
+	/* GD */
+	leaq	sg1@tlsdesc(%rip), %rax
+	call	*sg1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> IE because variable is referenced through IE too */
+	leaq	sg2@tlsdesc(%rip), %rax
+	call	*sg2@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD against local variable */
+	leaq	sl1@tlsdesc(%rip), %rax
+	call	*sl1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against local variable referenced through IE too */
+	leaq	sl2@tlsdesc(%rip), %rax
+	call	*sl2@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD against hidden and local variable */
+	leaq	sh1@tlsdesc(%rip), %rax
+	call	*sh1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden and local variable referenced through
+	   IE too */
+	leaq	sh2@tlsdesc(%rip), %rax
+	call	*sh2@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD against hidden but not local variable */
+	leaq	sH1@tlsdesc(%rip), %rax
+	call	*sH1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> IE against hidden but not local variable referenced through
+	   IE too */
+	leaq	sH2@tlsdesc(%rip), %rax
+	call	*sH2@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* LD */
+	leaq	_TLS_MODULE_BASE_@tlsdesc(%rip), %rax
+	call	*_TLS_MODULE_BASE_@tlscall(%rax)
+	nop;nop
+	leaq	sl1@dtpoff(%rax), %rdx
+	nop;nop
+	leaq	2+sl2@dtpoff(%rax), %r9
+	nop;nop;nop;nop
+
+	/* LD against hidden and local variables */
+	leaq	sh1@dtpoff(%rax), %rdx
+	nop;nop
+	leaq	sh2@dtpoff+3(%rax), %rcx
+	nop;nop;nop;nop
+
+	/* LD against hidden but not local variables */
+	leaq	sH1@dtpoff(%rax), %r12
+	nop;nop
+	leaq	sH2@dtpoff+1(%rax), %rcx
+	nop;nop
+
+	/* IE against global var  */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sg2@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	/* IE against local var  */
+	movq	%fs:0, %r14
+	nop;nop
+	addq	sl2@gottpoff(%rip), %r14
+	nop;nop;nop;nop
+
+	/* IE against hidden and local var  */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sh2@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	/* IE against hidden but not local var  */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sH2@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	/* Direct access through %fs  */
+
+	/* IE against global var  */
+	movq	sg5@gottpoff(%rip), %rcx
+	nop;nop
+	movq	%fs:(%rcx), %rdx
+	nop;nop;nop;nop
+
+	/* IE against local var  */
+	movq	sl5@gottpoff(%rip), %r10
+	nop;nop
+	movq	%fs:(%r10), %r12
+	nop;nop;nop;nop
+
+	/* IE against hidden and local var  */
+	movq	sh5@gottpoff(%rip), %rdx
+	nop;nop
+	movq	%fs:(%rdx), %rdx
+	nop;nop;nop;nop
+
+	/* IE against hidden but not local var  */
+	movq	sH5@gottpoff(%rip), %rcx
+	nop;nop
+	movq	%fs:(%rcx), %rdx
+	nop;nop;nop;nop
+
+	leave
+	ret
Index: ld/testsuite/ld-x86-64/tlsdesc.sd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsdesc.sd
diff -N ld/testsuite/ld-x86-64/tlsdesc.sd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsdesc.sd 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,23 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -s -j.got -j.got.plt
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section \.got:
+ 101308 00000000 00000000 00000000 00000000  .*
+ 101318 00000000 00000000 00000000 00000000  .*
+ 101328 00000000 00000000 00000000 00000000  .*
+ 101338 00000000 00000000 00000000 00000000  .*
+ 101348 00000000 00000000                    .*
+Contents of section \.got\.plt:
+ 101350 b8111000 00000000 00000000 00000000  .*
+ 101360 00000000 00000000 00000000 00000000  .*
+ 101370 00000000 00000000 00000000 00000000  .*
+ 101380 00000000 00000000 00000000 00000000  .*
+ 101390 00000000 00000000 00000000 00000000  .*
+ 1013a0 00000000 00000000 00000000 00000000  .*
+ 1013b0 00000000 00000000                    .*
Index: ld/testsuite/ld-x86-64/tlsdesc.td
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsdesc.td
diff -N ld/testsuite/ld-x86-64/tlsdesc.td
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsdesc.td 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,16 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -sj.tdata
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section .tdata:
+ 101154 11000000 12000000 13000000 14000000  .*
+ 101164 15000000 16000000 17000000 18000000  .*
+ 101174 41000000 42000000 43000000 44000000  .*
+ 101184 45000000 46000000 47000000 48000000  .*
+ 101194 01010000 02010000 03010000 04010000  .*
+ 1011a4 05010000 06010000 07010000 08010000  .*
Index: ld/testsuite/ld-x86-64/tlsgdesc.dd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsgdesc.dd
diff -N ld/testsuite/ld-x86-64/tlsgdesc.dd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsgdesc.dd 21 Sep 2005 06:13:20 -0000
@@ -0,0 +1,165 @@
+#source: tlsgdesc.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.text
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+[0-9a-f]+ <fc1>:
+ +[0-9a-f]+:	55[ 	]+push   %rbp
+ +[0-9a-f]+:	48 89 e5[ 	]+mov    %rsp,%rbp
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# IE
+ +[0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 03 0d 5e 02 10 00[ 	]+add    1049182\(%rip\),%rcx +# 100660 <.*>
+#				-> R_X86_64_TPOFF64	sG3
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# IE
+ +[0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 03 0d 68 02 10 00[ 	]+add    1049192\(%rip\),%rcx +# 100680 <.*>
+#				-> R_X86_64_TPOFF64	sG4
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# GD, gd first
+ +[0-9a-f]+:	66 48 8d 3d 6c 02 10[ 	]+lea    1049196\(%rip\),%rdi +# 100690 <.*>
+ +[0-9a-f]+:	00 *
+#				-> R_X86_64_DTPMOD64	sG1
+ +[0-9a-f]+:	66[ 	]+data16
+ +[0-9a-f]+:	66[ 	]+data16
+ +[0-9a-f]+:	48 e8 9c ff ff ff[ 	]+rex64 callq  [0-9a-f]+ <.*>
+#				-> R_X86_64_JUMP_SLOT	__tls_get_addr
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 8d 05 a1 02 10 00[ 	]+lea    1049249\(%rip\),%rax +# 1006d8 <.*>
+#				-> R_X86_64_TLSDESC	sG1
+ +[0-9a-f]+:	ff 10[ 	]+callq  \*\(%rax\)
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# GD, desc first
+ +[0-9a-f]+:	48 8d 05 84 02 10 00[ 	]+lea    1049220\(%rip\),%rax +# 1006c8 <.*>
+#				-> R_X86_64_TLSDESC	sG2
+ +[0-9a-f]+:	ff 10[ 	]+callq  \*\(%rax\)
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	66 48 8d 3d 1e 02 10[ 	]+lea    1049118\(%rip\),%rdi +# 100670 <.*>
+ +[0-9a-f]+:	00 *
+#				-> R_X86_64_DTPMOD64	sG2
+ +[0-9a-f]+:	66[ 	]+data16
+ +[0-9a-f]+:	66[ 	]+data16
+ +[0-9a-f]+:	48 e8 6e ff ff ff[ 	]+rex64 callq  [0-9a-f]+ <.*>
+#				-> R_X86_64_JUMP_SLOT	__tls_get_addr
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# GD -> IE, gd first, after IE use
+ +[0-9a-f]+:	64 48 8b 04 25 00 00[ 	]+mov    %fs:0x0,%rax
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	48 03 05 f2 01 10 00[ 	]+add    1049074\(%rip\),%rax +# 100660 <.*>
+#				-> R_X86_64_TPOFF64	sG3
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 8b 05 e7 01 10 00[ 	]+mov    1049063\(%rip\),%rax +# 100660 <.*>
+#				-> R_X86_64_TPOFF64	sG3
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# GD -> IE, desc first, after IE use
+ +[0-9a-f]+:	48 8b 05 fa 01 10 00[ 	]+mov    1049082\(%rip\),%rax +# 100680 <.*>
+#				-> R_X86_64_TPOFF64	sG4
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	64 48 8b 04 25 00 00[ 	]+mov    %fs:0x0,%rax
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	48 03 05 e4 01 10 00[ 	]+add    1049060\(%rip\),%rax +# 100680 <.*>
+#				-> R_X86_64_TPOFF64	sG4
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# GD -> IE, gd first, before IE use
+ +[0-9a-f]+:	64 48 8b 04 25 00 00[ 	]+mov    %fs:0x0,%rax
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	48 03 05 b8 01 10 00[ 	]+add    1049016\(%rip\),%rax +# 100668 <.*>
+#				-> R_X86_64_TPOFF64	sG5
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 8b 05 ad 01 10 00[ 	]+mov    1049005\(%rip\),%rax +# 100668 <.*>
+#				-> R_X86_64_TPOFF64	sG5
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# GD -> IE, desc first, before IE use
+ +[0-9a-f]+:	48 8b 05 c0 01 10 00[ 	]+mov    1049024\(%rip\),%rax +# 100688 <.*>
+#				-> R_X86_64_TPOFF64	sG6
+ +[0-9a-f]+:	48 90[ 	]+rex64 nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	64 48 8b 04 25 00 00[ 	]+mov    %fs:0x0,%rax
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	48 03 05 aa 01 10 00[ 	]+add    1049002\(%rip\),%rax +# 100688 <.*>
+#				-> R_X86_64_TPOFF64	sG6
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# IE
+ +[0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 03 0d 74 01 10 00[ 	]+add    1048948\(%rip\),%rcx +# 100668 <.*>
+#				-> R_X86_64_TPOFF64	sG5
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+# IE
+ +[0-9a-f]+:	64 48 8b 0c 25 00 00[ 	]+mov    %fs:0x0,%rcx
+ +[0-9a-f]+:	00 00 *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	48 03 0d 7e 01 10 00[ 	]+add    1048958\(%rip\),%rcx +# 100688 <.*>
+#				-> R_X86_64_TPOFF64	sG6
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	90[ 	]+nop *
+ +[0-9a-f]+:	c9[ 	]+leaveq *
+ +[0-9a-f]+:	c3[ 	]+retq *
Index: ld/testsuite/ld-x86-64/tlsgdesc.rd
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsgdesc.rd
diff -N ld/testsuite/ld-x86-64/tlsgdesc.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsgdesc.rd 21 Sep 2005 06:13:21 -0000
@@ -0,0 +1,107 @@
+#source: tlsgdesc.s
+#as: --64
+#ld: -shared -melf64_x86_64
+#readelf: -WSsrl
+#target: x86_64-*-*
+
+There are [0-9]+ section headers, starting at offset 0x.*:
+
+Section Headers:
+  \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+  \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+  \[ 1\] \.hash +.*
+  \[ 2\] \.dynsym +.*
+  \[ 3\] \.dynstr +.*
+  \[ 4\] \.rela.dyn +.*
+  \[ 5\] \.rela.plt +.*
+  \[ 6\] \.plt +.*
+  \[ 7\] \.text +.*
+  \[ 8\] \.dynamic +.*
+  \[ 9\] \.got +.*
+  \[10\] \.got.plt +.*
+  \[11\] \.shstrtab +.*
+  \[12\] \.symtab +.*
+  \[13\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x[0-9a-f]+
+There are [0-9]+ program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  LOAD.*
+  LOAD.*
+  DYNAMIC.*
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+   01 +.dynamic .got .got.plt *
+   02 +.dynamic *
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 8 entries:
+ +Offset +Info +Type +Symbol's Value  Symbol's Name \+ Addend
+[0-9a-f]+  0+200000012 R_X86_64_TPOFF64 +0+ sG3 \+ 0
+[0-9a-f]+  0+300000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
+[0-9a-f]+  0+400000010 R_X86_64_DTPMOD64 +0+ sG2 \+ 0
+[0-9a-f]+  0+400000011 R_X86_64_DTPOFF64 +0+ sG2 \+ 0
+[0-9a-f]+  0+500000012 R_X86_64_TPOFF64 +0+ sG4 \+ 0
+[0-9a-f]+  0+800000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
+[0-9a-f]+  0+a00000010 R_X86_64_DTPMOD64 +0+ sG1 \+ 0
+[0-9a-f]+  0+a00000011 R_X86_64_DTPOFF64 +0+ sG1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 3 entries:
+ +Offset +Info +Type +Symbol's Value  Symbol's Name \+ Addend
+[0-9a-f]+  0+600000007 R_X86_64_JUMP_SLOT +0+ __tls_get_addr \+ 0
+[0-9a-f]+  0+a00000024 R_X86_64_TLSDESC +0+ sG1 \+ 0
+[0-9a-f]+  0+400000024 R_X86_64_TLSDESC +0+ sG2 \+ 0
+
+Symbol table '.dynsym' contains 13 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +[0-9]+: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND __tls_get_addr
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fc1
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+
+Symbol table '.symtab' contains 27 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  LOCAL  HIDDEN  ABS _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 OBJECT  LOCAL  HIDDEN  ABS _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +[0-9]+: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND __tls_get_addr
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fc1
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
Index: ld/testsuite/ld-x86-64/tlsgdesc.s
===================================================================
RCS file: ld/testsuite/ld-x86-64/tlsgdesc.s
diff -N ld/testsuite/ld-x86-64/tlsgdesc.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-x86-64/tlsgdesc.s 21 Sep 2005 06:13:21 -0000
@@ -0,0 +1,106 @@
+	.text
+	.globl	fc1
+	.type	fc1,@function
+fc1:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	nop;nop;nop;nop
+
+	/* IE against global var.  */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sG3@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	/* IE against global var.  */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sG4@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	/* GD, gd first.  */
+	.byte	0x66
+	leaq	sG1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
+	call	__tls_get_addr@plt
+	nop;nop;nop;nop
+	
+	leaq	sG1@tlsdesc(%rip), %rax
+	call	*sG1@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD, desc first.  */
+	leaq	sG2@tlsdesc(%rip), %rax
+	call	*sG2@tlscall(%rax)
+	nop;nop;nop;nop
+
+	.byte	0x66
+	leaq	sG2@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
+	call	__tls_get_addr@plt
+	nop;nop;nop;nop
+	
+	/* GD -> IE, gd first, after IE use.  */
+	.byte	0x66
+	leaq	sG3@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
+	call	__tls_get_addr@plt
+	nop;nop;nop;nop
+	
+	leaq	sG3@tlsdesc(%rip), %rax
+	call	*sG3@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> IE, desc first, after IE use.  */
+	leaq	sG4@tlsdesc(%rip), %rax
+	call	*sG4@tlscall(%rax)
+	nop;nop;nop;nop
+
+	.byte	0x66
+	leaq	sG4@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
+	call	__tls_get_addr@plt
+	nop;nop;nop;nop
+	
+	/* GD -> IE, gd first, before IE use.  */
+	.byte	0x66
+	leaq	sG5@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
+	call	__tls_get_addr@plt
+	nop;nop;nop;nop
+	
+	leaq	sG5@tlsdesc(%rip), %rax
+	call	*sG5@tlscall(%rax)
+	nop;nop;nop;nop
+
+	/* GD -> IE, desc first, before IE use.  */
+	leaq	sG6@tlsdesc(%rip), %rax
+	call	*sG6@tlscall(%rax)
+	nop;nop;nop;nop
+
+	.byte	0x66
+	leaq	sG6@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
+	call	__tls_get_addr@plt
+	nop;nop;nop;nop
+	
+	/* IE against global var.  */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sG5@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	/* IE against global var.  */
+	movq	%fs:0, %rcx
+	nop;nop
+	addq	sG6@gottpoff(%rip), %rcx
+	nop;nop;nop;nop
+
+	leave
+	ret
Index: ld/testsuite/ld-x86-64/x86-64.exp
===================================================================
RCS file: /cvs/uberbaum/./ld/testsuite/ld-x86-64/x86-64.exp,v
retrieving revision 1.4
diff -u -p -r1.4 x86-64.exp
--- ld/testsuite/ld-x86-64/x86-64.exp 18 Jul 2005 06:23:40 -0000 1.4
+++ ld/testsuite/ld-x86-64/x86-64.exp 21 Sep 2005 06:13:23 -0000
@@ -1,5 +1,5 @@
 # Expect script for ld-x86_64 tests
-#   Copyright (C) 2002 Free Software Foundation
+#   Copyright (C) 2002, 2005 Free Software Foundation
 #
 # This file is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -39,6 +39,11 @@ set x86_64tests {
      {{readelf -WSsrl tlspic.rd} {objdump -drj.text tlspic.dd}
       {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
       "libtlspic.so"}
+    {"TLS descriptor -fpic -shared transitions" "-shared -melf_x86_64"
+     "--64" {tlsdesc.s tlspic2.s}
+     {{readelf -WSsrld tlsdesc.rd} {objdump -drj.text tlsdesc.dd}
+      {objdump "-s -j.got -j.got.plt" tlsdesc.sd} {objdump -sj.tdata tlsdesc.td}
+      {objdump -drj.plt tlsdesc.pd}} "libtlsdesc.so"}
     {"Helper shared library" "-shared -melf_x86_64"
      "--64" {tlslib.s} {} "libtlslib.so"}
     {"TLS -fpic and -fno-pic exec transitions"
@@ -46,6 +51,15 @@ set x86_64tests {
      {{readelf -WSsrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
       {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
       "tlsbin"}
+    {"TLS descriptor -fpic and -fno-pic exec transitions"
+     "-melf_x86_64 tmpdir/libtlslib.so" "--64" {tlsbindesc.s tlsbin.s}
+     {{readelf -WSsrl tlsbindesc.rd} {objdump -drj.text tlsbindesc.dd}
+      {objdump -sj.got tlsbindesc.sd} {objdump -sj.tdata tlsbindesc.td}}
+      "tlsbindesc"}
+    {"TLS with global dynamic and descriptors"
+	"-shared -melf_x86_64" "--64" {tlsgdesc.s}
+     {{readelf -WSsrl tlsgdesc.rd} {objdump -drj.text tlsgdesc.dd}}
+      "libtlsgdesc.so"}
     {"TLS in debug sections" "-melf_x86_64"
      "--64" {tlsg.s}
      {{objdump -sj.debug_foobar tlsg.sd}} "tlsg"}


-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


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