aboutsummaryrefslogtreecommitdiff
path: root/ld/testsuite/ld-i386
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-06-08 11:59:47 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-06-08 12:01:50 -0700
commit6eaa7fb59b32beaca017abf139a67bbe87592d9b (patch)
tree41d99fa60a1380cb5acc9290a014508f2852859b /ld/testsuite/ld-i386
parent010bc3ce6c651455e3a27c0857021c228780523c (diff)
Support i386 TLS code sequences without PLT
We can generate i386 TLS code sequences for general and local dynamic models without PLT, which uses indirect call via GOT: call *___tls_get_addr@GOT(%reg) where EBX register isn't required as GOT base, instead of direct call: call ___tls_get_addr[@PLT] which requires EBX register as GOT base. Since direct call is 4-byte long and indirect call, is 5-byte long, the extra one byte must be handled properly. For general dynamic model, 7-byte lea instruction before call instruction is replaced by 6-byte one to make room for indirect call. For local dynamic model, we simply use 5-byte indirect call. TLS linker optimization is updated to recognize new instruction patterns. For local dynamic model to local exec model transition, we generate a 6-byte lea instruction as nop, instead of a 1-byte nop plus a 4-byte lea instruction. Since linker may convert call ___tls_get_addr[@PLT] to addr32 call ____tls_get_addr when producing static executable, both patterns are recognized. bfd/ * elf64-i386.c (elf_i386_link_hash_entry): Add tls_get_addr. (elf_i386_link_hash_newfunc): Initialize tls_get_addr to 2. (elf_i386_check_tls_transition): Check indirect call and direct call with the addr32 prefix for general and local dynamic models. Set the tls_get_addr feild. (elf_i386_convert_load_reloc): Always use addr32 prefix for indirect ___tls_get_addr call via GOT. (elf_i386_relocate_section): Handle GD->LE, GD->IE and LD->LE transitions with indirect call and direct call with the addr32 prefix. ld/ * testsuite/ld-i386/i386.exp: Run libtlspic2.so, tlsbin2, tlsgd3, tlsld2, tlsgd4, tlspie3a, tlspie3b and tlspie3c. * testsuite/ld-i386/pass.out: New file. * testsuite/ld-i386/tls-def1.c: Likewise. * testsuite/ld-i386/tls-gd1.S: Likewise. * testsuite/ld-i386/tls-ld1.S: Likewise. * testsuite/ld-i386/tls-main1.c: Likewise. * testsuite/ld-i386/tls.exp: Likewise. * testsuite/ld-i386/tlsbin2-nacl.rd: Likewise. * testsuite/ld-i386/tlsbin2.dd: Likewise. * testsuite/ld-i386/tlsbin2.rd: Likewise. * testsuite/ld-i386/tlsbin2.sd: Likewise. * testsuite/ld-i386/tlsbin2.td: Likewise. * testsuite/ld-i386/tlsbinpic2.s: Likewise. * testsuite/ld-i386/tlsgd3.dd: Likewise. * testsuite/ld-i386/tlsgd3.s: Likewise. * testsuite/ld-i386/tlsgd4.d: Likewise. * testsuite/ld-i386/tlsgd4.s: Likewise. * testsuite/ld-i386/tlsld2.s: Likewise. * testsuite/ld-i386/tlspic2-nacl.rd: Likewise. * testsuite/ld-i386/tlspic2.dd: Likewise. * testsuite/ld-i386/tlspic2.rd: Likewise. * testsuite/ld-i386/tlspic2.sd: Likewise. * testsuite/ld-i386/tlspic2.td: Likewise. * testsuite/ld-i386/tlspic3.s: Likewise. * testsuite/ld-i386/tlspie3.s: Likewise. * testsuite/ld-i386/tlspie3a.d: Likewise. * testsuite/ld-i386/tlspie3b.d: Likewise. * testsuite/ld-i386/tlspie3c.d: Likewise.
Diffstat (limited to 'ld/testsuite/ld-i386')
-rw-r--r--ld/testsuite/ld-i386/i386.exp26
-rw-r--r--ld/testsuite/ld-i386/pass.out1
-rw-r--r--ld/testsuite/ld-i386/tls-def1.c1
-rw-r--r--ld/testsuite/ld-i386/tls-gd1.S65
-rw-r--r--ld/testsuite/ld-i386/tls-ld1.S71
-rw-r--r--ld/testsuite/ld-i386/tls-main1.c29
-rw-r--r--ld/testsuite/ld-i386/tls.exp125
-rw-r--r--ld/testsuite/ld-i386/tlsbin2-nacl.rd156
-rw-r--r--ld/testsuite/ld-i386/tlsbin2.dd460
-rw-r--r--ld/testsuite/ld-i386/tlsbin2.rd154
-rw-r--r--ld/testsuite/ld-i386/tlsbin2.sd13
-rw-r--r--ld/testsuite/ld-i386/tlsbin2.td16
-rw-r--r--ld/testsuite/ld-i386/tlsbinpic2.s172
-rw-r--r--ld/testsuite/ld-i386/tlsgd3.dd16
-rw-r--r--ld/testsuite/ld-i386/tlsgd3.s15
-rw-r--r--ld/testsuite/ld-i386/tlsgd4.d4
-rw-r--r--ld/testsuite/ld-i386/tlsgd4.s11
-rw-r--r--ld/testsuite/ld-i386/tlsld2.dd14
-rw-r--r--ld/testsuite/ld-i386/tlsld2.s12
-rw-r--r--ld/testsuite/ld-i386/tlspic2-nacl.rd149
-rw-r--r--ld/testsuite/ld-i386/tlspic2.dd405
-rw-r--r--ld/testsuite/ld-i386/tlspic2.rd147
-rw-r--r--ld/testsuite/ld-i386/tlspic2.sd18
-rw-r--r--ld/testsuite/ld-i386/tlspic2.td16
-rw-r--r--ld/testsuite/ld-i386/tlspic3.s282
-rw-r--r--ld/testsuite/ld-i386/tlspie3.s64
-rw-r--r--ld/testsuite/ld-i386/tlspie3a.d6
-rw-r--r--ld/testsuite/ld-i386/tlspie3b.d37
-rw-r--r--ld/testsuite/ld-i386/tlspie3c.d37
29 files changed, 2522 insertions, 0 deletions
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index d30f9fb53b..f6cbe4313c 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -133,6 +133,13 @@ set i386tests {
{{readelf -Ssrl tlspic.rd} {objdump -drj.text tlspic.dd}
{objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
"libtlspic.so"}
+ {"TLS -fpic -shared transitions without PLT"
+ "-shared -melf_i386 --no-ld-generated-unwind-info" ""
+ "-mrelax-relocations=yes --32"
+ {tlspic3.s tlspic2.s}
+ {{readelf -Ssrl tlspic2.rd} {objdump -drj.text tlspic2.dd}
+ {objdump -sj.got tlspic2.sd} {objdump -sj.tdata tlspic2.td}}
+ "libtlspic2.so"}
{"TLS descriptor -fpic -shared transitions"
"-shared -melf_i386 --no-ld-generated-unwind-info" ""
"--32" {tlsdesc.s tlspic2.s}
@@ -147,6 +154,13 @@ set i386tests {
{{readelf -Ssrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
{objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
"tlsbin"}
+ {"TLS -fpic and -fno-pic exec transitions without PLT"
+ "-melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info" ""
+ "-mrelax-relocations=yes --32"
+ {tlsbinpic2.s tlsbin.s}
+ {{readelf -Ssrl tlsbin2.rd} {objdump -drj.text tlsbin2.dd}
+ {objdump -sj.got tlsbin2.sd} {objdump -sj.tdata tlsbin2.td}}
+ "tlsbin2"}
{"TLS descriptor -fpic and -fno-pic exec transitions"
"-melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info" ""
"--32" {tlsbindesc.s tlsbin.s}
@@ -177,9 +191,17 @@ set i386tests {
{"TLS GD->LE transition" "-melf_i386" ""
"--32" {tlsgd1.s}
{{objdump -dwr tlsgd1.dd}} "tlsgd1"}
+ {"TLS GD->LE transition without PLT" "-melf_i386" ""
+ "-mrelax-relocations=yes --32"
+ {tlsgd3.s}
+ {{objdump -dwr tlsgd3.dd}} "tlsgd3"}
{"TLS LD->LE transition" "-melf_i386" ""
"--32" {tlsld1.s}
{{objdump -dwr tlsld1.dd}} "tlsld1"}
+ {"TLS LD->LE transition without PLT" "-melf_i386" ""
+ "-mrelax-relocations=yes --32"
+ {tlsld2.s}
+ {{objdump -dwr tlsld2.dd}} "tlsld2"}
{"TLS IE->LE transition" "-melf_i386" ""
"--32" {tlsie1.s}
{{objdump -dwr tlsie1.dd}} "tlsie1"}
@@ -270,6 +292,7 @@ run_dump_test "pcrel16abs"
run_dump_test "alloc"
run_dump_test "warn1"
run_dump_test "tlsgd2"
+run_dump_test "tlsgd4"
run_dump_test "tlsie2"
run_dump_test "tlsie3"
run_dump_test "tlsie4"
@@ -286,6 +309,9 @@ run_dump_test "protected6a"
run_dump_test "protected6b"
run_dump_test "tlspie1"
run_dump_test "tlspie2"
+run_dump_test "tlspie3a"
+run_dump_test "tlspie3b"
+run_dump_test "tlspie3c"
run_dump_test "nogot1"
run_dump_test "nogot2"
run_dump_test "discarded1"
diff --git a/ld/testsuite/ld-i386/pass.out b/ld/testsuite/ld-i386/pass.out
new file mode 100644
index 0000000000..7ef22e9a43
--- /dev/null
+++ b/ld/testsuite/ld-i386/pass.out
@@ -0,0 +1 @@
+PASS
diff --git a/ld/testsuite/ld-i386/tls-def1.c b/ld/testsuite/ld-i386/tls-def1.c
new file mode 100644
index 0000000000..62470a93cc
--- /dev/null
+++ b/ld/testsuite/ld-i386/tls-def1.c
@@ -0,0 +1 @@
+__thread int gd = 1;
diff --git a/ld/testsuite/ld-i386/tls-gd1.S b/ld/testsuite/ld-i386/tls-gd1.S
new file mode 100644
index 0000000000..3b16eab6aa
--- /dev/null
+++ b/ld/testsuite/ld-i386/tls-gd1.S
@@ -0,0 +1,65 @@
+ .text
+ .p2align 4,,15
+ .globl get_gd
+ .type get_gd, @function
+get_gd:
+ pushl %ebx
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $8, %esp
+ leal gd@tlsgd(,%ebx,1), %eax
+ call ___tls_get_addr@PLT
+ addl $8, %esp
+ popl %ebx
+ ret
+ .size get_gd, .-get_gd
+ .p2align 4,,15
+ .globl set_gd
+ .type set_gd, @function
+set_gd:
+ pushl %ebx
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $8, %esp
+ leal gd@tlsgd(%ebx), %eax
+ call ___tls_get_addr@PLT
+ nop
+ movl 16(%esp), %edx
+ movl %edx, (%eax)
+ addl $8, %esp
+ popl %ebx
+ ret
+ .size set_gd, .-set_gd
+ .text
+ .p2align 4,,15
+ .globl test_gd
+ .type test_gd, @function
+test_gd:
+ call __x86.get_pc_thunk.cx
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx
+ subl $12, %esp
+ leal gd@tlsgd(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ movl 16(%esp), %ecx
+ cmpl %ecx, (%eax)
+ sete %al
+ addl $12, %esp
+ movzbl %al, %eax
+ ret
+ .size test_gd, .-test_gd
+ .section .text.unlikely
+ .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+ movl (%esp), %ebx
+ ret
+ .section .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat
+ .globl __x86.get_pc_thunk.cx
+ .hidden __x86.get_pc_thunk.cx
+ .type __x86.get_pc_thunk.cx, @function
+__x86.get_pc_thunk.cx:
+ movl (%esp), %ecx
+ ret
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/tls-ld1.S b/ld/testsuite/ld-i386/tls-ld1.S
new file mode 100644
index 0000000000..f1295cfba6
--- /dev/null
+++ b/ld/testsuite/ld-i386/tls-ld1.S
@@ -0,0 +1,71 @@
+ .text
+ .p2align 4,,15
+ .globl get_ld
+ .type get_ld, @function
+get_ld:
+ pushl %ebx
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $8, %esp
+ leal ld@tlsldm(%ebx), %eax
+ call ___tls_get_addr@PLT
+ leal ld@dtpoff(%eax), %eax
+ addl $8, %esp
+ popl %ebx
+ ret
+ .size get_ld, .-get_ld
+ .p2align 4,,15
+ .globl set_ld
+ .type set_ld, @function
+set_ld:
+ pushl %ebx
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $8, %esp
+ leal ld@tlsldm(%ebx), %eax
+ call ___tls_get_addr@PLT
+ movl 16(%esp), %edx
+ leal ld@dtpoff(%eax), %eax
+ movl %edx, (%eax)
+ addl $8, %esp
+ popl %ebx
+ ret
+ .size set_ld, .-set_ld
+ .p2align 4,,15
+ .globl test_ld
+ .type test_ld, @function
+test_ld:
+ call __x86.get_pc_thunk.cx
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx
+ subl $12, %esp
+ leal ld@tlsldm(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ movl 16(%esp), %ecx
+ leal ld@dtpoff(%eax), %eax
+ cmpl %ecx, (%eax)
+ sete %al
+ addl $12, %esp
+ movzbl %al, %eax
+ ret
+ .size test_ld, .-test_ld
+ .section .tbss,"awT",@nobits
+ .align 4
+ .type ld, @object
+ .size ld, 4
+ld:
+ .zero 4
+ .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+ movl (%esp), %ebx
+ ret
+ .section .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat
+ .globl __x86.get_pc_thunk.cx
+ .hidden __x86.get_pc_thunk.cx
+ .type __x86.get_pc_thunk.cx, @function
+__x86.get_pc_thunk.cx:
+ movl (%esp), %ecx
+ ret
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/tls-main1.c b/ld/testsuite/ld-i386/tls-main1.c
new file mode 100644
index 0000000000..5c33744a33
--- /dev/null
+++ b/ld/testsuite/ld-i386/tls-main1.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int * get_gd (void);
+extern void set_gd (int);
+extern int test_gd (int);
+extern int * get_ld (void);
+extern void set_ld (int);
+extern int test_ld (int);
+
+int
+main ()
+{
+ int *p;
+
+ p = get_gd ();
+ set_gd (3);
+ if (*p != 3 || !test_gd (3))
+ abort ();
+
+ p = get_ld ();
+ set_ld (4);
+ if (*p != 4 || !test_ld (4))
+ abort ();
+
+ printf ("PASS\n");
+
+ return 0;
+}
diff --git a/ld/testsuite/ld-i386/tls.exp b/ld/testsuite/ld-i386/tls.exp
new file mode 100644
index 0000000000..593c0e8016
--- /dev/null
+++ b/ld/testsuite/ld-i386/tls.exp
@@ -0,0 +1,125 @@
+# Expect script for i386 TLS tests.
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+# The following tests require running the executable generated by ld,
+# or enough of a build environment to create a fully linked executable.
+# This is not commonly available when testing a cross-built linker.
+if ![isnative] {
+ return
+}
+
+# Only on Linux for now.
+if ![istarget "i?86-*-linux*"] {
+ return
+}
+
+# Check to see if the C compiler works
+if { [which $CC] == 0 } {
+ return
+}
+
+run_cc_link_tests [list \
+ [list \
+ "Build tls-def1.o tls-main1.o" \
+ "" \
+ "-fPIE" \
+ {tls-def1.c tls-main1.c} \
+ ] \
+ [list \
+ "Build tls-gd1.o tls-ld1.o" \
+ "" \
+ "-fPIC -Wa,-mrelax-relocations=yes" \
+ {tls-gd1.S tls-ld1.S} \
+ ] \
+ [list \
+ "Build libtls-1a.so" \
+ "-shared tmpdir/tls-def1.o" \
+ "" \
+ {dummy.s} \
+ {} \
+ "libtls-1a.so" \
+ ] \
+ [list \
+ "Build libtls-1b.so" \
+ "-shared tmpdir/tls-gd1.o tmpdir/tls-ld1.o" \
+ "" \
+ {dummy.s} \
+ {} \
+ "libtls-1b.so" \
+ ] \
+]
+
+run_ld_link_exec_tests [] [list \
+ [list \
+ "TLS GD/LD -> LE transition without PLT (dynamic)" \
+ "tmpdir/tls-def1.o tmpdir/tls-main1.o tmpdir/tls-gd1.o \
+ tmpdir/tls-ld1.o" \
+ "" \
+ { dummy.s } \
+ "tls-1a" \
+ "pass.out" \
+ ] \
+ [list \
+ "TLS GD/LD -> LE transition without PLT (PIE)" \
+ "-pie tmpdir/tls-def1.o tmpdir/tls-main1.o tmpdir/tls-gd1.o \
+ tmpdir/tls-ld1.o" \
+ "" \
+ { dummy.s } \
+ "tls-1b" \
+ "pass.out" \
+ ] \
+ [list \
+ "TLS GD/LD -> LE transition without PLT (static)" \
+ "-static tmpdir/tls-def1.o tmpdir/tls-main1.o tmpdir/tls-gd1.o \
+ tmpdir/tls-ld1.o" \
+ "" \
+ { dummy.s } \
+ "tls-1c" \
+ "pass.out" \
+ ] \
+ [list \
+ "TLS GD/LD -> IE transition without PLT" \
+ "tmpdir/tls-main1.o tmpdir/tls-gd1.o tmpdir/tls-ld1.o \
+ tmpdir/libtls-1a.so -R tmpdir" \
+ "" \
+ { dummy.s } \
+ "tls-1d" \
+ "pass.out" \
+ ] \
+ [list \
+ "TLS without PLT (1)" \
+ "tmpdir/tls-main1.o \
+ tmpdir/libtls-1a.so tmpdir/libtls-1b.so -R tmpdir" \
+ "" \
+ { dummy.s } \
+ "tls-1e" \
+ "pass.out" \
+ ] \
+ [list \
+ "TLS without PLT (2)" \
+ "tmpdir/tls-main1.o tmpdir/tls-def1.o \
+ tmpdir/libtls-1b.so -R tmpdir" \
+ "" \
+ { dummy.s } \
+ "tls-1f" \
+ "pass.out" \
+ ] \
+]
diff --git a/ld/testsuite/ld-i386/tlsbin2-nacl.rd b/ld/testsuite/ld-i386/tlsbin2-nacl.rd
new file mode 100644
index 0000000000..b23bfe0457
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbin2-nacl.rd
@@ -0,0 +1,156 @@
+#source: tlsbinpic2.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386_nacl tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-nacl*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.text +PROGBITS +0+20000 .*
+ +\[[ 0-9]+\] \.interp +.*
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +0*10031000 [0-9a-f]+ 000060 00 WAT +0 +0 4096
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000040 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC +0*10031060 .*
+ +\[[ 0-9]+\] \.got +PROGBITS +0*100310e0 .*
+ +\[[ 0-9]+\] \.got\.plt +PROGBITS +0*10031108 .*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.strtab +.*
+Key to Flags:
+#...
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x0*20188
+There are [0-9]+ program headers, starting at offset [0-9]+
+
+Program Headers:
+ +Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ +PHDR.*
+ +INTERP.*
+.*Requesting program interpreter.*
+ +LOAD.*
+ +LOAD.*
+ +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 +.text *
+ +03 +.interp .hash .dynsym .dynstr .rel.dyn *
+ +04 +.tdata .dynamic .got .got.plt *
+ +05 +.dynamic *
+ +06 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 10 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG3
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG5
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG7
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG2
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG6
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG1
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG8
+[0-9a-f ]+R_386_GLOB_DAT +[0-9a-f]+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ 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 +11 __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 +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _end
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG8
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ 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 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbinpic2.o
+ +[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
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbin.o
+ +[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
+.* FILE +LOCAL +DEFAULT +ABS
+ +[0-9]+: 0*10031060 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +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+20188 +0 +FUNC +GLOBAL +DEFAULT +1 _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 +11 __bss_start
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG6
+ +[0-9]+: 0+20000 +0 +FUNC +GLOBAL +DEFAULT +1 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 +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _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]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+ +[0-9]+: 0000006c +0 +TLS +GLOBAL +DEFAULT +8 bg4
diff --git a/ld/testsuite/ld-i386/tlsbin2.dd b/ld/testsuite/ld-i386/tlsbin2.dd
new file mode 100644
index 0000000000..18793169a3
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbin2.dd
@@ -0,0 +1,460 @@
+#source: tlsbinpic2.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#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 ([0-9a-f]{2} ){4}[ ]+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 *
+# GD -> IE because variable is not defined in executable
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b 83 f4 ff ff ff[ ]+sub -0xc\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32 sG1
+ +[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]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b 81 e4 ff ff ff[ ]+sub -0x1c\(%ecx\),%eax
+# ->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 *
+# GD -> IE because variable is not defined in executable where
+# the variable is referenced through @gotntpoff too
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 03 82 d8 ff ff ff[ ]+add -0x28\(%edx\),%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 *
+# GD -> IE because variable is not defined in executable where
+# the variable is referenced through @gottpoff and @gotntpoff too
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b 87 e8 ff ff ff[ ]+sub -0x18\(%edi\),%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 *
+# GD -> LE with global variable defined in executable
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 81 e8 00 10 00 00[ ]+sub \$0x1000,%eax
+# sg1
+ +[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 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 81 e8 e0 0f 00 00[ ]+sub \$0xfe0,%eax
+# sl1
+ +[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 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 81 e8 c0 0f 00 00[ ]+sub \$0xfc0,%eax
+# sh1
+ +[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 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 8d b6 00 00 00 00[ ]+lea 0x0\(%esi\),%esi
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 8d 90 20 f0 ff ff[ ]+lea -0xfe0\(%eax\),%edx
+# sl1
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 8d 88 24 f0 ff ff[ ]+lea -0xfdc\(%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 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 8d b6 00 00 00 00[ ]+lea 0x0\(%esi\),%esi
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 8d 90 40 f0 ff ff[ ]+lea -0xfc0\(%eax\),%edx
+# sh1
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 8d 88 44 f0 ff ff[ ]+lea -0xfbc\(%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 e4 ff ff ff[ ]+sub -0x1c\(%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 e8 ff ff ff[ ]+sub -0x18\(%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 d8 ff ff ff[ ]+add -0x28\(%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 ec ff ff ff[ ]+add -0x14\(%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 dc ff ff ff[ ]+mov -0x24\(%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 *
+# GD -> IE because variable is not defined in executable
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b 87 f4 ff ff ff[ ]+sub -0xc\(%edi\),%eax
+# ->R_386_TLS_TPOFF32 sG1
+ +[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 -0x4\(%ebp\),%ebx
+ +[0-9a-f]+: c9[ ]+leave *
+ +[0-9a-f]+: c3[ ]+ret *
+
+[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 ([0-9a-f]{2} ){4}[ ]+add \$0x[0-9a-f]+,%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 f0 ff ff ff[ ]+sub -0x10\(%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 ([0-9a-f]{2} ){4}[ ]+add 0x[0-9a-f]+,%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 ([0-9a-f]{2} ){4}[ ]+mov 0x[0-9a-f]+,%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 -0xffc\(%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 -0x4\(%ebp\),%ebx
+ +[0-9a-f]+: c9[ ]+leave *
+ +[0-9a-f]+: c3[ ]+ret *
diff --git a/ld/testsuite/ld-i386/tlsbin2.rd b/ld/testsuite/ld-i386/tlsbin2.rd
new file mode 100644
index 0000000000..05d4ddb817
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbin2.rd
@@ -0,0 +1,154 @@
+#source: tlsbinpic2.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.interp +.*
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.text +PROGBITS +0+8049000 .*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +0+804a000 [0-9a-f]+ 000060 00 WAT +0 +0 4096
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000040 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC +0+804a060 .*
+ +\[[ 0-9]+\] \.got +PROGBITS +0+804a0e0 .*
+ +\[[ 0-9]+\] \.got\.plt +PROGBITS +0+804a108 .*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.strtab +.*
+Key to Flags:
+#...
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x8049188
+There are [0-9]+ program headers, starting at offset [0-9]+
+
+Program Headers:
+ +Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ +PHDR.*
+ +INTERP.*
+.*Requesting program interpreter.*
+ +LOAD.*
+ +LOAD.*
+ +DYNAMIC.*
+ +TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+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 10 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG3
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG5
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG7
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG2
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG6
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG1
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG8
+[0-9a-f ]+R_386_GLOB_DAT +[0-9a-f]+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ 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 +11 __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 +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _end
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG8
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ 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 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbinpic2.o
+ +[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
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbin.o
+ +[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
+.* FILE +LOCAL +DEFAULT +ABS
+ +[0-9]+: 0+804a060 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +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+8049188 +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 +11 __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 +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _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]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+ +[0-9]+: 0000006c +0 +TLS +GLOBAL +DEFAULT +8 bg4
diff --git a/ld/testsuite/ld-i386/tlsbin2.sd b/ld/testsuite/ld-i386/tlsbin2.sd
new file mode 100644
index 0000000000..519e469d99
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbin2.sd
@@ -0,0 +1,13 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*: file format elf32-i386.*
+
+Contents of section \.got:
+ [0-9a-f]+ 00000000 00000000 00000000 00000000 .*
+ [0-9a-f]+ 00000000 00000000 00000000 00000000 .*
+ [0-9a-f]+ 00000000 00000000 +.*
diff --git a/ld/testsuite/ld-i386/tlsbin2.td b/ld/testsuite/ld-i386/tlsbin2.td
new file mode 100644
index 0000000000..d9602959b8
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbin2.td
@@ -0,0 +1,16 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#objdump: -sj.tdata
+#target: i?86-*-*
+
+.*: file format elf32-i386.*
+
+Contents of section \.tdata:
+ [0-9a-f]+000 11000000 12000000 13000000 14000000 .*
+ [0-9a-f]+010 15000000 16000000 17000000 18000000 .*
+ [0-9a-f]+020 41000000 42000000 43000000 44000000 .*
+ [0-9a-f]+030 45000000 46000000 47000000 48000000 .*
+ [0-9a-f]+040 01010000 02010000 03010000 04010000 .*
+ [0-9a-f]+050 05010000 06010000 07010000 08010000 .*
diff --git a/ld/testsuite/ld-i386/tlsbinpic2.s b/ld/testsuite/ld-i386/tlsbinpic2.s
new file mode 100644
index 0000000000..ebfcc6e6b9
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsbinpic2.s
@@ -0,0 +1,172 @@
+ /* 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@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is not defined in executable where
+ the variable is referenced through @gottpoff too */
+ leal sG2@tlsgd(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is not defined in executable where
+ the variable is referenced through @gotntpoff too */
+ leal sG3@tlsgd(%edx), %eax
+ call *___tls_get_addr@GOT(%edx)
+ 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@tlsgd(%edi), %eax
+ call *___tls_get_addr@GOT(%edi)
+ nop;nop;nop;nop
+
+ /* GD -> LE with global variable defined in executable */
+ leal sg1@tlsgd(%esi), %eax
+ call *___tls_get_addr@GOT(%esi)
+ nop;nop;nop;nop
+
+ /* GD -> LE with local variable defined in executable */
+ leal sl1@tlsgd(%ebp), %eax
+ call *___tls_get_addr@GOT(%ebp)
+ nop;nop;nop;nop
+
+ /* GD -> LE with hidden variable defined in executable */
+ leal sh1@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* LD -> LE */
+ leal sl1@tlsldm(%edi), %eax
+ call *___tls_get_addr@GOT(%edi)
+ nop
+ leal sl1@dtpoff(%eax), %edx
+ nop;nop
+ leal sl2@dtpoff(%eax), %ecx
+ nop;nop;nop;nop
+
+ /* LD -> LE against hidden variables */
+ leal sh1@tlsldm(%esi), %eax
+ call *___tls_get_addr@GOT(%esi)
+ 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
+
+ /* GD -> IE because variable is not defined in executable */
+ leal sG1@tlsgd(%edi), %eax
+ call *___tls_get_addr@GOT(%edi)
+ nop;nop;nop;nop
+
+ movl -4(%ebp), %ebx
+ leave
+ ret
diff --git a/ld/testsuite/ld-i386/tlsgd3.dd b/ld/testsuite/ld-i386/tlsgd3.dd
new file mode 100644
index 0000000000..c2c60baaa6
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsgd3.dd
@@ -0,0 +1,16 @@
+#source: tlsgd3.s
+#as: --32
+#ld: -melf_i386 tmpdir/tlsgd3
+#objdump: -drw
+#target: i?86-*-linux*
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
+[ ]*[a-f0-9]+: 81 e8 04 00 00 00 sub \$0x4,%eax
+[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
+[ ]*[a-f0-9]+: 81 e8 04 00 00 00 sub \$0x4,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/tlsgd3.s b/ld/testsuite/ld-i386/tlsgd3.s
new file mode 100644
index 0000000000..df547d2e9f
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsgd3.s
@@ -0,0 +1,15 @@
+ .text
+ .globl _start
+_start:
+ leal foo@TLSGD(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ leal foo@TLSGD(%edx), %eax
+ call *___tls_get_addr@GOT(%edx)
+ nop
+ .globl foo
+ .section .tdata,"awT",@progbits
+ .align 4
+ .type foo, @object
+ .size foo, 4
+foo:
+ .long 100
diff --git a/ld/testsuite/ld-i386/tlsgd4.d b/ld/testsuite/ld-i386/tlsgd4.d
new file mode 100644
index 0000000000..a7083d3aa8
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsgd4.d
@@ -0,0 +1,4 @@
+#name: TLS GD->LE transition check without PLT
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386
+#error: .*TLS transition from R_386_TLS_GD to R_386_TLS_LE_32 against `foo'.*failed.*
diff --git a/ld/testsuite/ld-i386/tlsgd4.s b/ld/testsuite/ld-i386/tlsgd4.s
new file mode 100644
index 0000000000..8ad3e1d918
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsgd4.s
@@ -0,0 +1,11 @@
+ .text
+ .globl _start
+_start:
+ leal foo@TLSGD(%edx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ .section .tdata,"awT",@progbits
+ .align 4
+ .type foo, @object
+ .size foo, 4
+foo:
+ .long 100
diff --git a/ld/testsuite/ld-i386/tlsld2.dd b/ld/testsuite/ld-i386/tlsld2.dd
new file mode 100644
index 0000000000..b7e082f489
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsld2.dd
@@ -0,0 +1,14 @@
+#source: tlsld2.s
+#as: --32
+#ld: -melf_i386 tmpdir/tlsld1
+#objdump: -drw
+#target: i?86-*-linux*
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
+[ ]*[a-f0-9]+: 8d b6 00 00 00 00 lea 0x0\(%esi\),%esi
+#pass
diff --git a/ld/testsuite/ld-i386/tlsld2.s b/ld/testsuite/ld-i386/tlsld2.s
new file mode 100644
index 0000000000..476267eb2e
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlsld2.s
@@ -0,0 +1,12 @@
+ .text
+ .globl _start
+_start:
+ leal foo@TLSLDM(%edi), %eax
+ call *___tls_get_addr@GOT(%edi)
+ .globl foo
+ .section .tdata,"awT",@progbits
+ .align 4
+ .type foo, @object
+ .size foo, 4
+foo:
+ .long 100
diff --git a/ld/testsuite/ld-i386/tlspic2-nacl.rd b/ld/testsuite/ld-i386/tlspic2-nacl.rd
new file mode 100644
index 0000000000..560e840afb
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspic2-nacl.rd
@@ -0,0 +1,149 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386_nacl --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-nacl*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.text +.*
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000060 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9aa-f]+ [0-9a-f]+ 000020 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +.*
+ +\[[ 0-9]+\] \.got +.*
+ +\[[ 0-9]+\] \.got.plt +.*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.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.*
+ +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 +.text *
+ +01 +.hash .dynsym .dynstr .rel.dyn *
+ +02 +.tdata .dynamic .got .got.plt *
+ +03 +.dynamic *
+ +04 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 27 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF +0+8 +sg3
+[0-9a-f ]+R_386_TLS_TPOFF32 0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+10 +sg5
+[0-9a-f ]+R_386_TLS_DTPMOD3 0+ +sg1
+[0-9a-f ]+R_386_TLS_DTPOFF3 0+ +sg1
+[0-9a-f ]+R_386_TLS_TPOFF32 0+4 +sg2
+[0-9a-f ]+R_386_GLOB_DAT +0+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +1 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ 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 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlspic3.o
+ +[0-9]+: 0+20 +0 +TLS +LOCAL +DEFAULT +6 sl1
+ +[0-9]+: 0+24 +0 +TLS +LOCAL +DEFAULT +6 sl2
+ +[0-9]+: 0+28 +0 +TLS +LOCAL +DEFAULT +6 sl3
+ +[0-9]+: 0+2c +0 +TLS +LOCAL +DEFAULT +6 sl4
+ +[0-9]+: 0+30 +0 +TLS +LOCAL +DEFAULT +6 sl5
+ +[0-9]+: 0+34 +0 +TLS +LOCAL +DEFAULT +6 sl6
+ +[0-9]+: 0+38 +0 +TLS +LOCAL +DEFAULT +6 sl7
+ +[0-9]+: 0+3c +0 +TLS +LOCAL +DEFAULT +6 sl8
+.* FILE +LOCAL +DEFAULT +ABS
+ +[0-9]+: 0+60 +0 +TLS +LOCAL +DEFAULT +7 sH1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +8 _DYNAMIC
+ +[0-9]+: 0+48 +0 +TLS +LOCAL +DEFAULT +6 sh3
+ +[0-9]+: 0+64 +0 +TLS +LOCAL +DEFAULT +7 sH2
+ +[0-9]+: 0+78 +0 +TLS +LOCAL +DEFAULT +7 sH7
+ +[0-9]+: 0+58 +0 +TLS +LOCAL +DEFAULT +6 sh7
+ +[0-9]+: 0+5c +0 +TLS +LOCAL +DEFAULT +6 sh8
+ +[0-9]+: 0+6c +0 +TLS +LOCAL +DEFAULT +7 sH4
+ +[0-9]+: 0+4c +0 +TLS +LOCAL +DEFAULT +6 sh4
+ +[0-9]+: 0+68 +0 +TLS +LOCAL +DEFAULT +7 sH3
+ +[0-9]+: 0+50 +0 +TLS +LOCAL +DEFAULT +6 sh5
+ +[0-9]+: 0+70 +0 +TLS +LOCAL +DEFAULT +7 sH5
+ +[0-9]+: 0+74 +0 +TLS +LOCAL +DEFAULT +7 sH6
+ +[0-9]+: 0+7c +0 +TLS +LOCAL +DEFAULT +7 sH8
+ +[0-9]+: 0+40 +0 +TLS +LOCAL +DEFAULT +6 sh1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +10 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+44 +0 +TLS +LOCAL +DEFAULT +6 sh2
+ +[0-9]+: 0+54 +0 +TLS +LOCAL +DEFAULT +6 sh6
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +1 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
diff --git a/ld/testsuite/ld-i386/tlspic2.dd b/ld/testsuite/ld-i386/tlspic2.dd
new file mode 100644
index 0000000000..2524a312df
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspic2.dd
@@ -0,0 +1,405 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#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]+ <.*>
+ +[0-9a-f]+: 5b[ ]+pop %ebx
+ +[0-9a-f]+: 81 c3 ([0-9a-f]{2} ){4}[ ]+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 *
+# GD
+ +[0-9a-f]+: 8d ([0-9a-f]{2} ){5}[ ]+lea -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_DTPMOD32 sg1
+ +[0-9a-f]+: ff ([0-9a-f]{2} ){5}[ ]+call \*-0x[0-9a-f]+\(%ebx\)
+# ->R_386_GLOB_DAT ___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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ecx\),%eax
+# ->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 *
+# 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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%edx\),%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 *
+# GD -> IE because variable is referenced through @gottpoff and
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%edi\),%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 *
+# GD against local variable
+ +[0-9a-f]+: 8d ([0-9a-f]{2} ){5}[ ]+lea -0x[0-9a-f]+\(%esi\),%eax
+# ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+: ff ([0-9a-f]{2} ){5}[ ]+call \*-0x[0-9a-f]+\(%esi\)
+# ->R_386_GLOB_DAT ___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 against local variable referenced through @gottpoff too
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebp\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 03 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF
+ +[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]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+lea -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+: ff ([0-9a-f]{2} ){5}[ ]+call \*-0x[0-9a-f]+\(%ebx\)
+# ->R_386_GLOB_DAT ___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 against hidden and local variable referenced through @gottpoff too
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 03 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF
+ +[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]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+lea -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+: ff ([0-9a-f]{2} ){5}[ ]+call \*-0x[0-9a-f]+\(%ebx\)
+# ->R_386_GLOB_DAT ___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 against hidden but not local variable referenced through
+ +[0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 03 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF
+ +[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]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax
+ +[0-9a-f]+: 2b ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+lea -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+: ff ([0-9a-f]{2} ){5}[ ]+call \*-0x[0-9a-f]+\(%ebx\)
+# ->R_386_GLOB_DAT ___tls_get_addr
+ +[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 ([0-9a-f]{2} ){5}[ ]+lea -0x[0-9a-f]+\(%ecx\),%eax
+# ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+: ff ([0-9a-f]{2} ){5}[ ]+call \*-0x[0-9a-f]+\(%ecx\)
+# ->R_386_GLOB_DAT ___tls_get_addr
+ +[0-9a-f]+: 90[ ]+nop *
+ +[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 ([0-9a-f]{2} ){5}[ ]+lea -0x[0-9a-f]+\(%edx\),%eax
+# ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+: ff ([0-9a-f]{2} ){5}[ ]+call \*-0x[0-9a-f]+\(%edx\)
+# ->R_386_GLOB_DAT ___tls_get_addr
+ +[0-9a-f]+: 90[ ]+nop *
+ +[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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%ecx
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%ecx
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%ecx
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%ecx
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+sub -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%ecx
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+add -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+mov -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[ ]+mov -0x[0-9a-f]+\(%ebx\),%eax
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+mov -0x[0-9a-f]+\(%ebx\),%edx
+# ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[ ]+mov -0x[0-9a-f]+\(%ebx\),%ecx
+# ->R_386_TLS_TPOFF
+ +[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 -0x4\(%ebp\),%ebx
+ +[0-9a-f]+: c9[ ]+leave *
+ +[0-9a-f]+: c3[ ]+ret *
diff --git a/ld/testsuite/ld-i386/tlspic2.rd b/ld/testsuite/ld-i386/tlspic2.rd
new file mode 100644
index 0000000000..a13554712e
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspic2.rd
@@ -0,0 +1,147 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.text +.*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000060 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9aa-f]+ [0-9a-f]+ 000020 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +.*
+ +\[[ 0-9]+\] \.got +.*
+ +\[[ 0-9]+\] \.got.plt +.*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.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 .text *
+ +01 +.tdata .dynamic .got .got.plt *
+ +02 +.dynamic *
+ +03 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 27 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF +0+8 +sg3
+[0-9a-f ]+R_386_TLS_TPOFF32 0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+10 +sg5
+[0-9a-f ]+R_386_TLS_DTPMOD3 0+ +sg1
+[0-9a-f ]+R_386_TLS_DTPOFF3 0+ +sg1
+[0-9a-f ]+R_386_TLS_TPOFF32 0+4 +sg2
+[0-9a-f ]+R_386_GLOB_DAT +0+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +5 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ 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 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlspic3.o
+ +[0-9]+: 0+20 +0 +TLS +LOCAL +DEFAULT +6 sl1
+ +[0-9]+: 0+24 +0 +TLS +LOCAL +DEFAULT +6 sl2
+ +[0-9]+: 0+28 +0 +TLS +LOCAL +DEFAULT +6 sl3
+ +[0-9]+: 0+2c +0 +TLS +LOCAL +DEFAULT +6 sl4
+ +[0-9]+: 0+30 +0 +TLS +LOCAL +DEFAULT +6 sl5
+ +[0-9]+: 0+34 +0 +TLS +LOCAL +DEFAULT +6 sl6
+ +[0-9]+: 0+38 +0 +TLS +LOCAL +DEFAULT +6 sl7
+ +[0-9]+: 0+3c +0 +TLS +LOCAL +DEFAULT +6 sl8
+.* FILE +LOCAL +DEFAULT +ABS
+ +[0-9]+: 0+60 +0 +TLS +LOCAL +DEFAULT +7 sH1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +8 _DYNAMIC
+ +[0-9]+: 0+48 +0 +TLS +LOCAL +DEFAULT +6 sh3
+ +[0-9]+: 0+64 +0 +TLS +LOCAL +DEFAULT +7 sH2
+ +[0-9]+: 0+78 +0 +TLS +LOCAL +DEFAULT +7 sH7
+ +[0-9]+: 0+58 +0 +TLS +LOCAL +DEFAULT +6 sh7
+ +[0-9]+: 0+5c +0 +TLS +LOCAL +DEFAULT +6 sh8
+ +[0-9]+: 0+6c +0 +TLS +LOCAL +DEFAULT +7 sH4
+ +[0-9]+: 0+4c +0 +TLS +LOCAL +DEFAULT +6 sh4
+ +[0-9]+: 0+68 +0 +TLS +LOCAL +DEFAULT +7 sH3
+ +[0-9]+: 0+50 +0 +TLS +LOCAL +DEFAULT +6 sh5
+ +[0-9]+: 0+70 +0 +TLS +LOCAL +DEFAULT +7 sH5
+ +[0-9]+: 0+74 +0 +TLS +LOCAL +DEFAULT +7 sH6
+ +[0-9]+: 0+7c +0 +TLS +LOCAL +DEFAULT +7 sH8
+ +[0-9]+: 0+40 +0 +TLS +LOCAL +DEFAULT +6 sh1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +10 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+44 +0 +TLS +LOCAL +DEFAULT +6 sh2
+ +[0-9]+: 0+54 +0 +TLS +LOCAL +DEFAULT +6 sh6
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +5 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
diff --git a/ld/testsuite/ld-i386/tlspic2.sd b/ld/testsuite/ld-i386/tlspic2.sd
new file mode 100644
index 0000000000..f72febfeca
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspic2.sd
@@ -0,0 +1,18 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*: file format elf32-i386.*
+
+Contents of section \.got:
+ [0-9a-f]+ 00000000 20000000 dcffffff 28000000 .*
+ [0-9a-f]+ d4ffffff 2c000000 30000000 00000000 .*
+ [0-9a-f]+ 00000000 00000000 60000000 00000000 .*
+ [0-9a-f]+ 48000000 9cffffff 00000000 00000000 .*
+ [0-9a-f]+ 00000000 94ffffff 6c000000 00000000 .*
+ [0-9a-f]+ 00000000 b4ffffff 4c000000 68000000 .*
+ [0-9a-f]+ 50000000 70000000 00000000 00000000 .*
+ [0-9a-f]+ 40000000 bcffffff 00000000 +.*
diff --git a/ld/testsuite/ld-i386/tlspic2.td b/ld/testsuite/ld-i386/tlspic2.td
new file mode 100644
index 0000000000..e1bd95914c
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspic2.td
@@ -0,0 +1,16 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#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/tlspic3.s b/ld/testsuite/ld-i386/tlspic3.s
new file mode 100644
index 0000000000..4268045fd2
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspic3.s
@@ -0,0 +1,282 @@
+ .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@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is referenced through @gottpoff too */
+ leal sg2@tlsgd(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is referenced through @gotntpoff too */
+ leal sg3@tlsgd(%edx), %eax
+ call *___tls_get_addr@GOT(%edx)
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is referenced through @gottpoff and
+ @gotntpoff too */
+ leal sg4@tlsgd(%edi), %eax
+ call *___tls_get_addr@GOT(%edi)
+ nop;nop;nop;nop
+
+ /* GD against local variable */
+ leal sl1@tlsgd(%esi), %eax
+ call *___tls_get_addr@GOT(%esi)
+ nop;nop;nop;nop
+
+ /* GD -> IE against local variable referenced through @gottpoff too */
+ leal sl2@tlsgd(%ebp), %eax
+ call *___tls_get_addr@GOT(%ebp)
+ nop;nop;nop;nop
+
+ /* GD -> IE against local variable referenced through @gotntpoff
+ too */
+ leal sl3@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE against local variable referenced through @gottpoff and
+ @gotntpoff too */
+ leal sl4@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD against hidden and local variable */
+ leal sh1@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden and local variable referenced through
+ @gottpoff too */
+ leal sh2@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden and local variable referenced through
+ @gotntpoff too */
+ leal sh3@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden and local variable referenced through
+ @gottpoff and @gotntpoff too */
+ leal sh4@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD against hidden but not local variable */
+ leal sH1@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden but not local variable referenced through
+ @gottpoff too */
+ leal sH2@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden but not local variable referenced through
+ @gotntpoff too */
+ leal sH3@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden but not local variable referenced through
+ @gottpoff and @gotntpoff too */
+ leal sH4@tlsgd(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ nop;nop;nop;nop
+
+ /* LD */
+ leal sl1@tlsldm(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ 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@tlsldm(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ nop
+ 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@tlsldm(%edx), %eax
+ call *___tls_get_addr@GOT(%edx)
+ nop
+ 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/tlspie3.s b/ld/testsuite/ld-i386/tlspie3.s
new file mode 100644
index 0000000000..b934f09b35
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspie3.s
@@ -0,0 +1,64 @@
+ .text
+ .globl ___tls_get_addr
+ .type ___tls_get_addr, @function
+___tls_get_addr:
+ ret
+ .size ___tls_get_addr, .-___tls_get_addr
+.globl _start
+ .type _start, @function
+_start:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+ pushl %ebx
+ call .L3
+.L3:
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L3], %ebx
+ movl %gs:foo2@NTPOFF, %esi
+ addl %gs:foo1@NTPOFF, %esi
+ movl foo3@GOTNTPOFF(%ebx), %eax
+ addl %gs:(%eax), %esi
+ leal foo4@TLSLDM(%edx), %eax
+ call *___tls_get_addr@GOT(%edx)
+ addl (%eax), %esi
+ leal foo5@TLSGD(%ebx), %eax
+ call *___tls_get_addr@GOT(%ebx)
+ addl (%eax), %esi
+ movl %esi, %eax
+ popl %ebx
+ popl %esi
+ leave
+ ret
+ .size _start, .-_start
+.globl foo1
+ .section .tbss,"awT",@nobits
+ .align 4
+ .type foo1, @object
+ .size foo1, 4
+foo1:
+ .zero 4
+.globl foo2
+ .align 4
+ .type foo2, @object
+ .size foo2, 4
+foo2:
+ .zero 4
+.globl foo3
+ .align 4
+ .type foo3, @object
+ .size foo3, 4
+foo3:
+ .zero 4
+.globl foo4
+ .align 4
+ .type foo4, @object
+ .size foo4, 4
+foo4:
+ .zero 4
+.globl foo5
+ .align 4
+ .type foo5, @object
+ .size foo5, 4
+foo5:
+ .zero 4
diff --git a/ld/testsuite/ld-i386/tlspie3a.d b/ld/testsuite/ld-i386/tlspie3a.d
new file mode 100644
index 0000000000..f540c5a43b
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspie3a.d
@@ -0,0 +1,6 @@
+#source: tlspie3.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -pie
+#readelf: -r
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/tlspie3b.d b/ld/testsuite/ld-i386/tlspie3b.d
new file mode 100644
index 0000000000..7de0472fc5
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspie3b.d
@@ -0,0 +1,37 @@
+#source: tlspie3.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -pie
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <___tls_get_addr>:
+[ ]*[a-f0-9]+: c3 ret
+
+[0-9a-f]+ <_start>:
+[ ]*[a-f0-9]+: 55 push %ebp
+[ ]*[a-f0-9]+: 89 e5 mov %esp,%ebp
+[ ]*[a-f0-9]+: 56 push %esi
+[ ]*[a-f0-9]+: 53 push %ebx
+[ ]*[a-f0-9]+: e8 00 00 00 00 call [0-9a-f]+ .*
+[ ]*[a-f0-9]+: 5b pop %ebx
+[ ]*[a-f0-9]+: 81 c3 ([0-9a-f]{2} ){4}[ ]+add \$0x[0-9a-f]+,%ebx
+[ ]*[a-f0-9]+: 65 8b 35 f0 ff ff ff mov %gs:0xfffffff0,%esi
+[ ]*[a-f0-9]+: 65 03 35 ec ff ff ff add %gs:0xffffffec,%esi
+[ ]*[a-f0-9]+: c7 c0 f4 ff ff ff mov \$0xfffffff4,%eax
+[ ]*[a-f0-9]+: 65 03 30 add %gs:\(%eax\),%esi
+[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
+[ ]*[a-f0-9]+: 8d b6 00 00 00 00 lea 0x0\(%esi\),%esi
+[ ]*[a-f0-9]+: 03 30 add \(%eax\),%esi
+[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
+[ ]*[a-f0-9]+: 81 e8 04 00 00 00 sub \$0x4,%eax
+[ ]*[a-f0-9]+: 03 30 add \(%eax\),%esi
+[ ]*[a-f0-9]+: 89 f0 mov %esi,%eax
+[ ]*[a-f0-9]+: 5b pop %ebx
+[ ]*[a-f0-9]+: 5e pop %esi
+[ ]*[a-f0-9]+: c9 leave
+[ ]*[a-f0-9]+: c3 ret
+#pass
diff --git a/ld/testsuite/ld-i386/tlspie3c.d b/ld/testsuite/ld-i386/tlspie3c.d
new file mode 100644
index 0000000000..aa02f571e7
--- /dev/null
+++ b/ld/testsuite/ld-i386/tlspie3c.d
@@ -0,0 +1,37 @@
+#source: tlspie3.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -pie -z call-nop=suffix-nop
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <___tls_get_addr>:
+[ ]*[a-f0-9]+: c3 ret
+
+[0-9a-f]+ <_start>:
+[ ]*[a-f0-9]+: 55 push %ebp
+[ ]*[a-f0-9]+: 89 e5 mov %esp,%ebp
+[ ]*[a-f0-9]+: 56 push %esi
+[ ]*[a-f0-9]+: 53 push %ebx
+[ ]*[a-f0-9]+: e8 00 00 00 00 call [0-9a-f]+ .*
+[ ]*[a-f0-9]+: 5b pop %ebx
+[ ]*[a-f0-9]+: 81 c3 ([0-9a-f]{2} ){4}[ ]+add \$0x[0-9a-f]+,%ebx
+[ ]*[a-f0-9]+: 65 8b 35 f0 ff ff ff mov %gs:0xfffffff0,%esi
+[ ]*[a-f0-9]+: 65 03 35 ec ff ff ff add %gs:0xffffffec,%esi
+[ ]*[a-f0-9]+: c7 c0 f4 ff ff ff mov \$0xfffffff4,%eax
+[ ]*[a-f0-9]+: 65 03 30 add %gs:\(%eax\),%esi
+[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
+[ ]*[a-f0-9]+: 8d b6 00 00 00 00 lea 0x0\(%esi\),%esi
+[ ]*[a-f0-9]+: 03 30 add \(%eax\),%esi
+[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
+[ ]*[a-f0-9]+: 81 e8 04 00 00 00 sub \$0x4,%eax
+[ ]*[a-f0-9]+: 03 30 add \(%eax\),%esi
+[ ]*[a-f0-9]+: 89 f0 mov %esi,%eax
+[ ]*[a-f0-9]+: 5b pop %ebx
+[ ]*[a-f0-9]+: 5e pop %esi
+[ ]*[a-f0-9]+: c9 leave
+[ ]*[a-f0-9]+: c3 ret
+#pass