aboutsummaryrefslogtreecommitdiff
path: root/ld/testsuite/ld-i386
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2006-01-18 21:07:51 +0000
committerAlexandre Oliva <aoliva@redhat.com>2006-01-18 21:07:51 +0000
commit67a4f2b710581acc83afecff55424af285ecbc28 (patch)
tree2348b4780388dad65c840f222d372edc83a2088e /ld/testsuite/ld-i386
parentdd942754f0afab07734deed09d168afbc9ffb597 (diff)
downloadgdb-67a4f2b710581acc83afecff55424af285ecbc28.zip
gdb-67a4f2b710581acc83afecff55424af285ecbc28.tar.gz
gdb-67a4f2b710581acc83afecff55424af285ecbc28.tar.bz2
include/elf/ChangeLog:
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. bfd/ChangeLog: 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. binutils/ChangeLog: Introduce TLS descriptors for i386 and x86_64. * readelf.c (get_dynamic_type): Handle DT_TLSDESC_GOT and DT_TLSDESC_PLT. gas/ChangeLog: 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. ld/testsuite/ChangeLog: 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.
Diffstat (limited to 'ld/testsuite/ld-i386')
-rw-r--r--ld/testsuite/ld-i386/i386.exp20
-rw-r--r--ld/testsuite/ld-i386/pcrel16.d3
-rw-r--r--ld/testsuite/ld-i386/pcrel8.d3
-rw-r--r--ld/testsuite/ld-i386/tlsbindesc.dd463
-rw-r--r--ld/testsuite/ld-i386/tlsbindesc.rd154
-rw-r--r--ld/testsuite/ld-i386/tlsbindesc.s167
-rw-r--r--ld/testsuite/ld-i386/tlsbindesc.sd13
-rw-r--r--ld/testsuite/ld-i386/tlsbindesc.td16
-rw-r--r--ld/testsuite/ld-i386/tlsdesc.dd399
-rw-r--r--ld/testsuite/ld-i386/tlsdesc.rd155
-rw-r--r--ld/testsuite/ld-i386/tlsdesc.s276
-rw-r--r--ld/testsuite/ld-i386/tlsdesc.sd20
-rw-r--r--ld/testsuite/ld-i386/tlsdesc.td16
-rw-r--r--ld/testsuite/ld-i386/tlsgdesc.dd158
-rw-r--r--ld/testsuite/ld-i386/tlsgdesc.rd107
-rw-r--r--ld/testsuite/ld-i386/tlsgdesc.s100
16 files changed, 2066 insertions, 4 deletions
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 05343f0..4a170cd 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -1,5 +1,5 @@
# Expect script for ld-i386 tests
-# Copyright (C) 2002 Free Software Foundation
+# Copyright (C) 2002, 2005, 2006 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"}
diff --git a/ld/testsuite/ld-i386/pcrel16.d b/ld/testsuite/ld-i386/pcrel16.d
index 0c438a9..3d45afe 100644
--- a/ld/testsuite/ld-i386/pcrel16.d
+++ b/ld/testsuite/ld-i386/pcrel16.d
@@ -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
diff --git a/ld/testsuite/ld-i386/pcrel8.d b/ld/testsuite/ld-i386/pcrel8.d
index ed939a3..208c64e 100644
--- a/ld/testsuite/ld-i386/pcrel8.d
+++ b/ld/testsuite/ld-i386/pcrel8.d
@@ -1,3 +1,4 @@
#name: PCREL8 overflow
-#ld:
+#as: --32
+#ld: -melf_i386
#error: .*relocation truncated to fit: R_386_PC8 .*
diff --git a/ld/testsuite/ld-i386/tlsbindesc.dd b/ld/testsuite/ld-i386/tlsbindesc.dd
new file mode 100644
index 0000000..071a5b3
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbindesc.dd
@@ -0,0 +1,463 @@
+#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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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 @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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 8d 05 00 f0 ff ff[ ]+lea 0xfffff000,%eax
+# sg1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 8d 05 20 f0 ff ff[ ]+lea 0xfffff020,%eax
+# sl1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 8d 05 40 f0 ff ff[ ]+lea 0xfffff040,%eax
+# sh1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 8d 05 00 f0 ff ff[ ]+lea 0xfffff000,%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 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]+: 8d 05 00 f0 ff ff[ ]+lea 0xfffff000,%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 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 *
diff --git a/ld/testsuite/ld-i386/tlsbindesc.rd b/ld/testsuite/ld-i386/tlsbindesc.rd
new file mode 100644
index 0000000..27d0670
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbindesc.rd
@@ -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
diff --git a/ld/testsuite/ld-i386/tlsbindesc.s b/ld/testsuite/ld-i386/tlsbindesc.s
new file mode 100644
index 0000000..9094d08
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbindesc.s
@@ -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
diff --git a/ld/testsuite/ld-i386/tlsbindesc.sd b/ld/testsuite/ld-i386/tlsbindesc.sd
new file mode 100644
index 0000000..a87f5da
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbindesc.sd
@@ -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 +.*
diff --git a/ld/testsuite/ld-i386/tlsbindesc.td b/ld/testsuite/ld-i386/tlsbindesc.td
new file mode 100644
index 0000000..726df3e
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbindesc.td
@@ -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 .*
diff --git a/ld/testsuite/ld-i386/tlsdesc.dd b/ld/testsuite/ld-i386/tlsdesc.dd
new file mode 100644
index 0000000..666f790
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsdesc.dd
@@ -0,0 +1,399 @@
+#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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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 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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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]+: 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 *
diff --git a/ld/testsuite/ld-i386/tlsdesc.rd b/ld/testsuite/ld-i386/tlsdesc.rd
new file mode 100644
index 0000000..12fd5d4
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsdesc.rd
@@ -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
diff --git a/ld/testsuite/ld-i386/tlsdesc.s b/ld/testsuite/ld-i386/tlsdesc.s
new file mode 100644
index 0000000..8377f64
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsdesc.s
@@ -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
diff --git a/ld/testsuite/ld-i386/tlsdesc.sd b/ld/testsuite/ld-i386/tlsdesc.sd
new file mode 100644
index 0000000..2af8c2d
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsdesc.sd
@@ -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 +.*
diff --git a/ld/testsuite/ld-i386/tlsdesc.td b/ld/testsuite/ld-i386/tlsdesc.td
new file mode 100644
index 0000000..f3612b3
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsdesc.td
@@ -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 .*
diff --git a/ld/testsuite/ld-i386/tlsgdesc.dd b/ld/testsuite/ld-i386/tlsgdesc.dd
new file mode 100644
index 0000000..ca4092e
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsgdesc.dd
@@ -0,0 +1,158 @@
+#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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [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]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+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 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 *
diff --git a/ld/testsuite/ld-i386/tlsgdesc.rd b/ld/testsuite/ld-i386/tlsgdesc.rd
new file mode 100644
index 0000000..9253d22
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsgdesc.rd
@@ -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
diff --git a/ld/testsuite/ld-i386/tlsgdesc.s b/ld/testsuite/ld-i386/tlsgdesc.s
new file mode 100644
index 0000000..9502a10
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsgdesc.s
@@ -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