aboutsummaryrefslogtreecommitdiff
path: root/ld/testsuite/ld-x86-64
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-x86-64
parentdd942754f0afab07734deed09d168afbc9ffb597 (diff)
downloadfsf-binutils-gdb-67a4f2b710581acc83afecff55424af285ecbc28.zip
fsf-binutils-gdb-67a4f2b710581acc83afecff55424af285ecbc28.tar.gz
fsf-binutils-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-x86-64')
-rw-r--r--ld/testsuite/ld-x86-64/tlsbindesc.dd307
-rw-r--r--ld/testsuite/ld-x86-64/tlsbindesc.rd141
-rw-r--r--ld/testsuite/ld-x86-64/tlsbindesc.s128
-rw-r--r--ld/testsuite/ld-x86-64/tlsbindesc.sd12
-rw-r--r--ld/testsuite/ld-x86-64/tlsbindesc.td16
-rw-r--r--ld/testsuite/ld-x86-64/tlsdesc.dd204
-rw-r--r--ld/testsuite/ld-x86-64/tlsdesc.pd26
-rw-r--r--ld/testsuite/ld-x86-64/tlsdesc.rd164
-rw-r--r--ld/testsuite/ld-x86-64/tlsdesc.s157
-rw-r--r--ld/testsuite/ld-x86-64/tlsdesc.sd23
-rw-r--r--ld/testsuite/ld-x86-64/tlsdesc.td16
-rw-r--r--ld/testsuite/ld-x86-64/tlsgdesc.dd167
-rw-r--r--ld/testsuite/ld-x86-64/tlsgdesc.rd107
-rw-r--r--ld/testsuite/ld-x86-64/tlsgdesc.s106
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp16
15 files changed, 1589 insertions, 1 deletions
diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.dd b/ld/testsuite/ld-x86-64/tlsbindesc.dd
new file mode 100644
index 0000000..c41efec
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbindesc.dd
@@ -0,0 +1,307 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.text
+#target: x86_64-*-*
+
+# PT_TLS layout is:
+# Offset from Offset from Name
+# TCB base TCB end
+# 0x00 -0xa0 sg1..sg8
+# 0x20 -0x80 sl1..sl8
+# 0x40 -0x60 sh1..sh8
+# 0x60 -0x40 bg1..bg8
+# 0x80 -0x20 bl1..bl8
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+401000 <fn2>:
+ [0-9a-f]+: 55[ ]+push %rbp
+ [0-9a-f]+: 48 89 e5[ ]+mov %rsp,%rbp
+# GD -> IE because variable is not defined in executable
+ [0-9a-f]+: 48 8b 05 65 03 10 00[ ]+mov 1049445\(%rip\),%rax +# 501370 <.*>
+# -> R_X86_64_TPOFF64 sG1
+ [0-9a-f]+: 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 IE too
+ [0-9a-f]+: 48 8b 05 48 03 10 00[ ]+mov 1049416\(%rip\),%rax +# 501360 <.*>
+# -> R_X86_64_TPOFF64 sG2
+ [0-9a-f]+: 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]+: 48 c7 c0 60 ff ff ff[ ]+mov \$0xf+60,%rax
+# 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]+: 48 c7 c0 80 ff ff ff[ ]+mov \$0xf+80,%rax
+# 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]+: 48 c7 c0 a0 ff ff ff[ ]+mov \$0xf+a0,%rax
+# 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]+: 48 c7 c0 60 ff ff ff[ ]+mov \$0xf+60,%rax
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 8d 90 81 ff ff ff[ ]+lea 0xf+81\(%rax\),%rdx
+# sl1+1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 4c 8d 88 86 ff ff ff[ ]+lea 0xf+86\(%rax\),%r9
+# sl2+2
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# LD -> LE against hidden variables
+ [0-9a-f]+: 48 8d 90 a0 ff ff ff[ ]+lea 0xf+a0\(%rax\),%rdx
+# sh1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 8d 88 a7 ff ff ff[ ]+lea 0xf+a7\(%rax\),%rcx
+# sh2+3
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE against global var
+ [0-9a-f]+: 64 4c 8b 0c 25 00 00[ ]+mov %fs:0x0,%r9
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 4c 03 0d d6 02 10 00[ ]+add 1049302\(%rip\),%r9 +# 501360 <.*>
+# -> R_X86_64_TPOFF64 sG2
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE -> LE against global var defined in exec
+ [0-9a-f]+: 64 4c 8b 14 25 00 00[ ]+mov %fs:0x0,%r10
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 4d 8d 92 60 ff ff ff[ ]+lea 0xf+60\(%r10\),%r10
+# sg1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE -> LE against local var
+ [0-9a-f]+: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 8d 80 80 ff ff ff[ ]+lea 0xf+80\(%rax\),%rax
+# sl1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE -> LE against hidden var
+ [0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 8d 89 a0 ff ff ff[ ]+lea 0xf+a0\(%rcx\),%rcx
+# sh1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# Direct access through %fs
+# IE against global var
+ [0-9a-f]+: 48 8b 0d 81 02 10 00[ ]+mov 1049217\(%rip\),%rcx +# 501358 <.*>
+# -> R_X86_64_TPOFF64 sG5
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE->LE against local var
+ [0-9a-f]+: 49 c7 c3 90 ff ff ff[ ]+mov \$0xf+90,%r11
+# sl5
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 64 4d 8b 23[ ]+mov %fs:\(%r11\),%r12
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE->LE against hidden var
+ [0-9a-f]+: 48 c7 c2 b0 ff ff ff[ ]+mov \$0xf+b0,%rdx
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 64 48 8b 12[ ]+mov %fs:\(%rdx\),%rdx
+# sh5
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: c9[ ]+leaveq *
+ [0-9a-f]+: c3[ ]+retq *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+: 55[ ]+push %rbp
+ [0-9a-f]+: 48 89 e5[ ]+mov %rsp,%rbp
+# IE against global var
+ [0-9a-f]+: 64 4c 8b 1c 25 00 00[ ]+mov %fs:0x0,%r11
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 4c 03 1d 4a 02 10 00[ ]+add 1049162\(%rip\),%r11 +# 501368 <.*>
+# -> R_X86_64_TPOFF64 sG6
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE -> LE against global var defined in exec
+ [0-9a-f]+: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 8d 92 d4 ff ff ff[ ]+lea 0xf+d4\(%rdx\),%rdx
+# bg6
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE -> LE against local var
+ [0-9a-f]+: 64 4c 8b 24 25 00 00[ ]+mov %fs:0x0,%r12
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 49 81 c4 f4 ff ff ff[ ]+add \$0xf+f4,%r12
+# bl6
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# direct %fs access IE -> LE against local var
+ [0-9a-f]+: 48 c7 c2 fc ff ff ff[ ]+mov \$0xf+fc,%rdx
+# bl8
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 64 48 8b 02[ ]+mov %fs:\(%rdx\),%rax
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# IE -> LE against hidden but not local var
+ [0-9a-f]+: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 8d 92 b4 ff ff ff[ ]+lea 0xf+b4\(%rdx\),%rdx
+# sh6
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# direct %fs access IE -> LE against hidden but not local var
+ [0-9a-f]+: 48 c7 c2 bc ff ff ff[ ]+mov \$0xf+bc,%rdx
+# sh8
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 64 48 8b 02[ ]+mov %fs:\(%rdx\),%rax
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# LE, global var defined in exec
+ [0-9a-f]+: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 8d 90 64 ff ff ff[ ]+lea 0xf+64\(%rax\),%rdx
+# sg2
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# LE, local var, non-canonical sequence
+ [0-9a-f]+: 49 c7 c1 e6 ff ff ff[ ]+mov \$0xf+e6,%r9
+# bl2+2
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 4c 01 ca[ ]+add %r9,%rdx
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# LE, hidden var defined in exec, non-canonical sequence
+ [0-9a-f]+: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ [0-9a-f]+: 00 00 *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 48 81 c2 a5 ff ff ff[ ]+add \$0xf+a5,%rdx
+# sh2+1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# Direct %fs access
+# LE, global var defined in exec
+ [0-9a-f]+: 64 48 8b 04 25 68 ff[ ]+mov %fs:0xf+68,%rax
+ [0-9a-f]+: ff ff *
+# sg3
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# LE, local var
+ [0-9a-f]+: 64 4c 8b 14 25 eb ff[ ]+mov %fs:0xf+eb,%r10
+ [0-9a-f]+: ff ff *
+# bl3+3
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+# LE, hidden var defined in exec
+ [0-9a-f]+: 64 48 8b 14 25 a9 ff[ ]+mov %fs:0xf+a9,%rdx
+ [0-9a-f]+: ff ff *
+# sh3+1
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: 90[ ]+nop *
+ [0-9a-f]+: c9[ ]+leaveq *
+ [0-9a-f]+: c3[ ]+retq *
diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.rd b/ld/testsuite/ld-x86-64/tlsbindesc.rd
new file mode 100644
index 0000000..787002d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbindesc.rd
@@ -0,0 +1,141 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -WSsrl
+#target: x86_64-*-*
+
+There are 15 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+ \[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
+ \[ 1\] .interp +.*
+ \[ 2\] .hash +.*
+ \[ 3\] .dynsym +.*
+ \[ 4\] .dynstr +.*
+ \[ 5\] .rela.dyn +.*
+ \[ 6\] .text +PROGBITS +0+401000 0+1000 0+1f6 00 +AX +0 +0 +4096
+ \[ 7\] .tdata +PROGBITS +0+5011f6 0+11f6 0+60 00 WAT +0 +0 +1
+ \[ 8\] .tbss +NOBITS +0+501256 0+1256 0+40 00 WAT +0 +0 +1
+ \[ 9\] .dynamic +DYNAMIC +0+501258 0+1258 0+100 10 +WA +4 +0 +8
+ \[10\] .got +PROGBITS +0+501358 0+1358 0+20 08 +WA +0 +0 +8
+ \[11\] .got.plt +PROGBITS +0+501378 0+1378 0+18 08 +WA +0 +0 +8
+ \[12\] .shstrtab +.*
+ \[13\] .symtab +.*
+ \[14\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x401108
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ PHDR.*
+ INTERP.*
+.*Requesting program interpreter.*
+ LOAD +0x0+ 0x0+400000 0x0+400000 0x0+11f6 0x0+11f6 R E 0x100000
+ LOAD +0x0+11f6 0x0+5011f6 0x0+5011f6 0x0+19a 0x0+19a RW 0x100000
+ DYNAMIC +0x0+1258 0x0+501258 0x0+501258 0x0+100 0x0+100 RW 0x8
+ TLS +0x0+11f6 0x0+5011f6 0x0+5011f6 0x0+60 0x0+a0 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 *
+ 01 +.interp *
+ 02 +.interp .hash .dynsym .dynstr .rela.dyn .text *
+ 03 +.tdata .dynamic .got .got.plt *
+ 04 +.dynamic *
+ 05 +.tdata .tbss *
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 4 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+0+501358 0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
+0+501360 0+200000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0
+0+501368 0+400000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
+0+501370 0+500000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0
+
+Symbol table '.dynsym' contains 8 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +[0-9]+: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +[0-9]+: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +[0-9]+: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 67 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14 *
+ +[0-9]+: 0+20 +0 TLS +LOCAL DEFAULT +7 sl1
+ +[0-9]+: 0+24 +0 TLS +LOCAL DEFAULT +7 sl2
+ +[0-9]+: 0+28 +0 TLS +LOCAL DEFAULT +7 sl3
+ +[0-9]+: 0+2c +0 TLS +LOCAL DEFAULT +7 sl4
+ +[0-9]+: 0+30 +0 TLS +LOCAL DEFAULT +7 sl5
+ +[0-9]+: 0+34 +0 TLS +LOCAL DEFAULT +7 sl6
+ +[0-9]+: 0+38 +0 TLS +LOCAL DEFAULT +7 sl7
+ +[0-9]+: 0+3c +0 TLS +LOCAL DEFAULT +7 sl8
+ +[0-9]+: 0+80 +0 TLS +LOCAL DEFAULT +8 bl1
+ +[0-9]+: 0+84 +0 TLS +LOCAL DEFAULT +8 bl2
+ +[0-9]+: 0+88 +0 TLS +LOCAL DEFAULT +8 bl3
+ +[0-9]+: 0+8c +0 TLS +LOCAL DEFAULT +8 bl4
+ +[0-9]+: 0+90 +0 TLS +LOCAL DEFAULT +8 bl5
+ +[0-9]+: 0+94 +0 TLS +LOCAL DEFAULT +8 bl6
+ +[0-9]+: 0+98 +0 TLS +LOCAL DEFAULT +8 bl7
+ +[0-9]+: 0+9c +0 TLS +LOCAL DEFAULT +8 bl8
+ +[0-9]+: 0+0 +0 TLS +LOCAL HIDDEN +7 _TLS_MODULE_BASE_
+ +[0-9]+: 0+501258 +0 OBJECT LOCAL HIDDEN 9 _DYNAMIC
+ +[0-9]+: 0+501378 +0 OBJECT LOCAL HIDDEN 11 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +7 sg8
+ +[0-9]+: 0+7c +0 TLS +GLOBAL DEFAULT +8 bg8
+ +[0-9]+: 0+74 +0 TLS +GLOBAL DEFAULT +8 bg6
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
+ +[0-9]+: 0+68 +0 TLS +GLOBAL DEFAULT +8 bg3
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +7 sg3
+ +[0-9]+: 0+48 +0 TLS +GLOBAL HIDDEN +7 sh3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +7 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +7 sg5
+ +[0-9]+: 0+70 +0 TLS +GLOBAL DEFAULT +8 bg5
+ +[0-9]+: 0+58 +0 TLS +GLOBAL HIDDEN +7 sh7
+ +[0-9]+: 0+5c +0 TLS +GLOBAL HIDDEN +7 sh8
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +7 sg1
+ +[0-9]+: 0+401108 +0 FUNC +GLOBAL DEFAULT +6 _start
+ +[0-9]+: 0+4c +0 TLS +GLOBAL HIDDEN +7 sh4
+ +[0-9]+: 0+78 +0 TLS +GLOBAL DEFAULT +8 bg7
+ +[0-9]+: 0+50 +0 TLS +GLOBAL HIDDEN +7 sh5
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +[0-9]+: 0+401000 +0 FUNC +GLOBAL DEFAULT +6 fn2
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +7 sg2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +[0-9]+: 0+40 +0 TLS +GLOBAL HIDDEN +7 sh1
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +7 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +7 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+ +[0-9]+: 0+44 +0 TLS +GLOBAL HIDDEN +7 sh2
+ +[0-9]+: 0+54 +0 TLS +GLOBAL HIDDEN +7 sh6
+ +[0-9]+: 0+64 +0 TLS +GLOBAL DEFAULT +8 bg2
+ +[0-9]+: 0+60 +0 TLS +GLOBAL DEFAULT +8 bg1
+ +[0-9]+: 0+6c +0 TLS +GLOBAL DEFAULT +8 bg4
diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.s b/ld/testsuite/ld-x86-64/tlsbindesc.s
new file mode 100644
index 0000000..cbebf02
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbindesc.s
@@ -0,0 +1,128 @@
+ /* Force .data aligned to 4K, so that .got very likely gets at
+ 0x5021a0 (0x60 bytes .tdata and 0x140 bytes .dynamic) */
+ .data
+ .balign 4096
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+ .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1: .long 17
+sg2: .long 18
+sg3: .long 19
+sg4: .long 20
+sg5: .long 21
+sg6: .long 22
+sg7: .long 23
+sg8: .long 24
+sl1: .long 65
+sl2: .long 66
+sl3: .long 67
+sl4: .long 68
+sl5: .long 69
+sl6: .long 70
+sl7: .long 71
+sl8: .long 72
+sh1: .long 257
+sh2: .long 258
+sh3: .long 259
+sh4: .long 260
+sh5: .long 261
+sh6: .long 262
+sh7: .long 263
+sh8: .long 264
+ /* Force .text aligned to 4K, so it very likely gets at 0x401000. */
+ .text
+ .balign 4096
+ .globl fn2
+ .type fn2,@function
+fn2:
+ pushq %rbp
+ movq %rsp, %rbp
+
+ /* GD -> IE because variable is not defined in executable */
+ leaq sG1@tlsdesc(%rip), %rax
+ call *sG1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is not defined in executable where
+ the variable is referenced through IE too */
+ leaq sG2@tlsdesc(%rip), %rax
+ call *sG2@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> LE with global variable defined in executable */
+ leaq sg1@tlsdesc(%rip), %rax
+ call *sg1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> LE with local variable defined in executable */
+ leaq sl1@tlsdesc(%rip), %rax
+ call *sl1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> LE with hidden variable defined in executable */
+ leaq sh1@tlsdesc(%rip), %rax
+ call *sh1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* LD -> LE */
+ leaq _TLS_MODULE_BASE_@tlsdesc(%rip), %rax
+ call *_TLS_MODULE_BASE_@tlscall(%rax)
+ nop;nop
+ leaq 1+sl1@dtpoff(%rax), %rdx
+ nop;nop
+ leaq sl2@dtpoff+2(%rax), %r9
+ nop;nop;nop;nop
+
+ /* LD -> LE against hidden variables */
+ leaq sh1@dtpoff(%rax), %rdx
+ nop;nop
+ leaq 3+sh2@dtpoff(%rax), %rcx
+ nop;nop;nop;nop
+
+ /* IE against global var */
+ movq %fs:0, %r9
+ nop;nop
+ addq sG2@gottpoff(%rip), %r9
+ nop;nop;nop;nop
+
+ /* IE -> LE against global var defined in exec */
+ movq %fs:0, %r10
+ nop;nop
+ addq sg1@gottpoff(%rip), %r10
+ nop;nop;nop;nop
+
+ /* IE -> LE against local var */
+ movq %fs:0, %rax
+ nop;nop
+ addq sl1@gottpoff(%rip), %rax
+ nop;nop;nop;nop
+
+ /* IE -> LE against hidden var */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sh1@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ /* Direct access through %fs */
+
+ /* IE against global var */
+ movq sG5@gottpoff(%rip), %rcx
+ nop;nop
+ movq %fs:(%rcx), %rdx
+ nop;nop;nop;nop
+
+ /* IE->LE against local var */
+ movq sl5@gottpoff(%rip), %r11
+ nop;nop
+ movq %fs:(%r11), %r12
+ nop;nop;nop;nop
+
+ /* IE->LE against hidden var */
+ movq sh5@gottpoff(%rip), %rdx
+ nop;nop
+ movq %fs:(%rdx), %rdx
+ nop;nop;nop;nop
+
+ leave
+ ret
diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.sd b/ld/testsuite/ld-x86-64/tlsbindesc.sd
new file mode 100644
index 0000000..fd0519f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbindesc.sd
@@ -0,0 +1,12 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -sj.got
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section .got:
+ 501358 00000000 00000000 00000000 00000000 .*
+ 501368 00000000 00000000 00000000 00000000 .*
diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.td b/ld/testsuite/ld-x86-64/tlsbindesc.td
new file mode 100644
index 0000000..226e52e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbindesc.td
@@ -0,0 +1,16 @@
+#source: tlsbindesc.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -sj.tdata
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section .tdata:
+ 5011f6 11000000 12000000 13000000 14000000 .*
+ 501206 15000000 16000000 17000000 18000000 .*
+ 501216 41000000 42000000 43000000 44000000 .*
+ 501226 45000000 46000000 47000000 48000000 .*
+ 501236 01010000 02010000 03010000 04010000 .*
+ 501246 05010000 06010000 07010000 08010000 .*
diff --git a/ld/testsuite/ld-x86-64/tlsdesc.dd b/ld/testsuite/ld-x86-64/tlsdesc.dd
new file mode 100644
index 0000000..656e241
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsdesc.dd
@@ -0,0 +1,204 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.text
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+[0-9a-f]+ <fn1>:
+ +[0-9a-f]+: 55[ ]+push %rbp
+ +[0-9a-f]+: 48 89 e5[ ]+mov %rsp,%rbp
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD
+ +[0-9a-f]+: 48 8d 05 89 03 10 00[ ]+lea 1049481\(%rip\),%rax +# 101398 <.*>
+# -> R_X86_64_TLSDESC sg1
+ +[0-9a-f]+: ff 10[ ]+callq \*\(%rax\)
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD -> IE because variable is referenced through IE too
+ +[0-9a-f]+: 48 8b 05 1c 03 10 00[ ]+mov 1049372\(%rip\),%rax +# 101338 <.*>
+# -> R_X86_64_TPOFF64 sg2
+ +[0-9a-f]+: 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]+: 48 8d 05 3f 03 10 00[ ]+lea 1049407\(%rip\),%rax +# 101368 <.*>
+# -> R_X86_64_TLSDESC [0 0x2000000000000000]
+ +[0-9a-f]+: ff 10[ ]+callq \*\(%rax\)
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD -> IE against local variable referenced through IE too
+ +[0-9a-f]+: 48 8b 05 d2 02 10 00[ ]+mov 1049298\(%rip\),%rax +# 101308 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x24
+ +[0-9a-f]+: 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]+: 48 8d 05 65 03 10 00[ ]+lea 1049445\(%rip\),%rax +# 1013a8 <.*>
+# -> R_X86_64_TLSDESC [0 0x4000000000000000]
+ +[0-9a-f]+: ff 10[ ]+callq \*\(%rax\)
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD -> IE against hidden and local variable referenced through IE too
+ +[0-9a-f]+: 48 8b 05 f0 02 10 00[ ]+mov 1049328\(%rip\),%rax +# 101340 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x44
+ +[0-9a-f]+: 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]+: 48 8d 05 1b 03 10 00[ ]+lea 1049371\(%rip\),%rax +# 101378 <.*>
+# -> R_X86_64_TLSDESC [0 0x6000000000000000]
+ +[0-9a-f]+: ff 10[ ]+callq \*\(%rax\)
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD -> IE against hidden but not local variable referenced through IE too
+ +[0-9a-f]+: 48 8b 05 ae 02 10 00[ ]+mov 1049262\(%rip\),%rax +# 101318 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x64
+ +[0-9a-f]+: 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]+: 48 8d 05 11 03 10 00[ ]+lea 1049361\(%rip\),%rax +# 101388 <.*>
+# -> R_X86_64_TLSDESC [0 0x000000000000000]
+ +[0-9a-f]+: ff 10[ ]+callq \*\(%rax\)
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 8d 90 20 00 00 00[ ]+lea 0x20\(%rax\),%rdx
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 4c 8d 88 26 00 00 00[ ]+lea 0x26\(%rax\),%r9
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# LD against hidden and local variables
+ +[0-9a-f]+: 48 8d 90 40 00 00 00[ ]+lea 0x40\(%rax\),%rdx
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 8d 88 47 00 00 00[ ]+lea 0x47\(%rax\),%rcx
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# LD against hidden but not local variables
+ +[0-9a-f]+: 4c 8d a0 60 00 00 00[ ]+lea 0x60\(%rax\),%r12
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 8d 88 65 00 00 00[ ]+lea 0x65\(%rax\),%rcx
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE against global var
+ +[0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 03 0d 71 02 10 00[ ]+add 1049201\(%rip\),%rcx +# 101338 <.*>
+# -> R_X86_64_TPOFF64 sg2
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE against local var
+ +[0-9a-f]+: 64 4c 8b 34 25 00 00[ ]+mov %fs:0x0,%r14
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 4c 03 35 2b 02 10 00[ ]+add 1049131\(%rip\),%r14 +# 101308 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x24
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE against hidden and local var
+ +[0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 03 0d 4d 02 10 00[ ]+add 1049165\(%rip\),%rcx +# 101340 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x44
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE against hidden but not local var
+ +[0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 03 0d 0f 02 10 00[ ]+add 1049103\(%rip\),%rcx +# 101318 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x64
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# Direct access through %fs
+# IE against global var
+ +[0-9a-f]+: 48 8b 0d 0c 02 10 00[ ]+mov 1049100\(%rip\),%rcx +# 101320 <.*>
+# -> R_X86_64_TPOFF64 sg5
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE against local var
+ +[0-9a-f]+: 4c 8b 15 eb 01 10 00[ ]+mov 1049067\(%rip\),%r10 +# 101310 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x30
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 64 4d 8b 22[ ]+mov %fs:\(%r10\),%r12
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE against hidden and local var
+ +[0-9a-f]+: 48 8b 15 f2 01 10 00[ ]+mov 1049074\(%rip\),%rdx +# 101328 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x50
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 64 48 8b 12[ ]+mov %fs:\(%rdx\),%rdx
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE against hidden but not local var
+ +[0-9a-f]+: 48 8b 0d e9 01 10 00[ ]+mov 1049065\(%rip\),%rcx +# 101330 <.*>
+# -> R_X86_64_TPOFF64 *ABS*+0x70
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: c9[ ]+leaveq *
+ +[0-9a-f]+: c3[ ]+retq *
+ +[0-9a-f]+: 90[ ]+nop *
diff --git a/ld/testsuite/ld-x86-64/tlsdesc.pd b/ld/testsuite/ld-x86-64/tlsdesc.pd
new file mode 100644
index 0000000..aea1bab
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsdesc.pd
@@ -0,0 +1,26 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.plt
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .plt:
+
+0000000000000470 <.*@plt-0x10>:
+ 470: ff 35 e2 0e 10 00 pushq 1052386\(%rip\) # 101358 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ 476: ff 25 e4 0e 10 00 jmpq \*1052388\(%rip\) # 101360 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ 47c: 90 nop *
+ 47d: 90 nop *
+ 47e: 90 nop *
+ 47f: 90 nop *
+0000000000000480 <.*@plt>:
+ 480: ff 35 d2 0e 10 00 pushq 1052370\(%rip\) # 101358 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ 486: ff 25 bc 0e 10 00 jmpq \*1052348\(%rip\) # 101348 <_DYNAMIC\+0x190>
+ 48c: 90 nop *
+ 48d: 90 nop *
+ 48e: 90 nop *
+ 48f: 90 nop *
+
diff --git a/ld/testsuite/ld-x86-64/tlsdesc.rd b/ld/testsuite/ld-x86-64/tlsdesc.rd
new file mode 100644
index 0000000..e7e21ed
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsdesc.rd
@@ -0,0 +1,164 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -WSsrld
+#target: x86_64-*-*
+
+There are 16 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+ \[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
+ \[ 1\] .hash +.*
+ \[ 2\] .dynsym +.*
+ \[ 3\] .dynstr +.*
+ \[ 4\] .rela.dyn +.*
+ \[ 5\] .rela.plt +.*
+ \[ 6\] .plt +PROGBITS +0+470 0+470 0+20 10 +AX +0 +0 +4
+ \[ 7\] .text +PROGBITS +0+1000 0+1000 0+154 00 +AX +0 +0 4096
+ \[ 8\] .tdata +PROGBITS +0+101154 0+1154 0+60 00 WAT +0 +0 +1
+ \[ 9\] .tbss +NOBITS +0+1011b4 0+11b4 0+20 00 WAT +0 +0 +1
+ \[10\] .dynamic +DYNAMIC +0+1011b8 0+11b8 0+150 10 +WA +3 +0 +8
+ \[11\] .got +PROGBITS +0+101308 0+1308 0+48 08 +WA +0 +0 +8
+ \[12\] .got.plt +PROGBITS +0+101350 0+1350 0+68 08 +WA +0 +0 +8
+ \[13\] .shstrtab +.*
+ \[14\] .symtab +.*
+ \[15\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x1000
+There are 4 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ LOAD +0x0+ 0x0+ 0x0+ 0x[0-9a-f]+ 0x[0-9a-f]+ R E 0x100000
+ LOAD +0x0+1154 0x0+101154 0x0+101154 0x0+264 0x0+264 RW +0x100000
+ DYNAMIC +0x0+11b8 0x0+1011b8 0x0+1011b8 0x0+150 0x0+150 RW +0x8
+ TLS +0x0+1154 0x0+101154 0x0+101154 0x0+60 0x0+80 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+ 01 +.tdata .dynamic .got .got.plt *
+ 02 +.dynamic *
+ 03 +.tdata .tbss *
+
+Dynamic section at offset 0x[0-9a-f]+ contains 16 entries:
+ +Tag +Type +Name/Value
+ 0x[0-9a-f]+ +\(HASH\).*
+ 0x[0-9a-f]+ +\(STRTAB\).*
+ 0x[0-9a-f]+ +\(SYMTAB\).*
+ 0x[0-9a-f]+ +\(STRSZ\).*
+ 0x[0-9a-f]+ +\(SYMENT\).*
+ 0x[0-9a-f]+ +\(PLTGOT\).*
+ 0x[0-9a-f]+ +\(PLTRELSZ\).*
+ 0x[0-9a-f]+ +\(PLTREL\).*
+ 0x[0-9a-f]+ +\(JMPREL\).*
+ 0x[0-9a-f]+ +\(TLSDESC_PLT\) +0x480
+ 0x[0-9a-f]+ +\(TLSDESC_GOT\) +0x101348
+ 0x[0-9a-f]+ +\(RELA\).*
+ 0x[0-9a-f]+ +\(RELASZ\).*
+ 0x[0-9a-f]+ +\(RELAENT\).*
+ 0x[0-9a-f]+ +\(FLAGS\).*
+ 0x[0-9a-f]+ +\(NULL\).*
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 8 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+0+101308 0+12 R_X86_64_TPOFF64 +0+24
+0+101310 0+12 R_X86_64_TPOFF64 +0+30
+0+101318 0+12 R_X86_64_TPOFF64 +0+64
+0+101328 0+12 R_X86_64_TPOFF64 +0+50
+0+101330 0+12 R_X86_64_TPOFF64 +0+70
+0+101340 0+12 R_X86_64_TPOFF64 +0+44
+0+101320 0+700000012 R_X86_64_TPOFF64 +0+10 sg5 \+ 0
+0+101338 0+b00000012 R_X86_64_TPOFF64 +0+4 sg2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 5 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+0+101398 0+800000024 R_X86_64_TLSDESC +0+ sg1 \+ 0
+0+101368 0+24 R_X86_64_TLSDESC +0+20
+0+1013a8 0+24 R_X86_64_TLSDESC +0+40
+0+101378 0+24 R_X86_64_TLSDESC +0+60
+0+101388 0+24 R_X86_64_TLSDESC +0+
+
+Symbol table '.dynsym' contains 16 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 *
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +8 sg8
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +8 sg3
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +8 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +8 sg5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +8 sg1
+ +[0-9]+: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +8 sg2
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +8 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +8 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 55 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +15 *
+ +[0-9]+: 0+20 +0 TLS +LOCAL DEFAULT +8 sl1
+ +[0-9]+: 0+24 +0 TLS +LOCAL DEFAULT +8 sl2
+ +[0-9]+: 0+28 +0 TLS +LOCAL DEFAULT +8 sl3
+ +[0-9]+: 0+2c +0 TLS +LOCAL DEFAULT +8 sl4
+ +[0-9]+: 0+30 +0 TLS +LOCAL DEFAULT +8 sl5
+ +[0-9]+: 0+34 +0 TLS +LOCAL DEFAULT +8 sl6
+ +[0-9]+: 0+38 +0 TLS +LOCAL DEFAULT +8 sl7
+ +[0-9]+: 0+3c +0 TLS +LOCAL DEFAULT +8 sl8
+ +[0-9]+: 0+60 +0 TLS +LOCAL HIDDEN +9 sH1
+ +[0-9]+: 0+ +0 TLS +LOCAL HIDDEN +8 _TLS_MODULE_BASE_
+ +[0-9]+: 0+1011b8 +0 OBJECT LOCAL HIDDEN ABS _DYNAMIC
+ +[0-9]+: 0+48 +0 TLS +LOCAL HIDDEN +8 sh3
+ +[0-9]+: 0+64 +0 TLS +LOCAL HIDDEN +9 sH2
+ +[0-9]+: 0+78 +0 TLS +LOCAL HIDDEN +9 sH7
+ +[0-9]+: 0+58 +0 TLS +LOCAL HIDDEN +8 sh7
+ +[0-9]+: 0+5c +0 TLS +LOCAL HIDDEN +8 sh8
+ +[0-9]+: 0+6c +0 TLS +LOCAL HIDDEN +9 sH4
+ +[0-9]+: 0+4c +0 TLS +LOCAL HIDDEN +8 sh4
+ +[0-9]+: 0+68 +0 TLS +LOCAL HIDDEN +9 sH3
+ +[0-9]+: 0+50 +0 TLS +LOCAL HIDDEN +8 sh5
+ +[0-9]+: 0+70 +0 TLS +LOCAL HIDDEN +9 sH5
+ +[0-9]+: 0+74 +0 TLS +LOCAL HIDDEN +9 sH6
+ +[0-9]+: 0+7c +0 TLS +LOCAL HIDDEN +9 sH8
+ +[0-9]+: 0+40 +0 TLS +LOCAL HIDDEN +8 sh1
+ +[0-9]+: 0+101350 +0 OBJECT LOCAL HIDDEN ABS _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+44 +0 TLS +LOCAL HIDDEN +8 sh2
+ +[0-9]+: 0+54 +0 TLS +LOCAL HIDDEN +8 sh6
+ +[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +8 sg8
+ +[0-9]+: 0+8 +0 TLS +GLOBAL DEFAULT +8 sg3
+ +[0-9]+: 0+c +0 TLS +GLOBAL DEFAULT +8 sg4
+ +[0-9]+: 0+10 +0 TLS +GLOBAL DEFAULT +8 sg5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +8 sg1
+ +[0-9]+: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +[0-9]+: 0+4 +0 TLS +GLOBAL DEFAULT +8 sg2
+ +[0-9]+: 0+14 +0 TLS +GLOBAL DEFAULT +8 sg6
+ +[0-9]+: 0+18 +0 TLS +GLOBAL DEFAULT +8 sg7
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
diff --git a/ld/testsuite/ld-x86-64/tlsdesc.s b/ld/testsuite/ld-x86-64/tlsdesc.s
new file mode 100644
index 0000000..ec6d190
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsdesc.s
@@ -0,0 +1,157 @@
+ /* Force .data aligned to 4K, so .got very likely gets at 0x102190
+ (0x60 bytes .tdata and 0x130 bytes .dynamic) */
+ .data
+ .balign 4096
+ .section ".tdata", "awT", @progbits
+ .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+ .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+ .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1: .long 17
+sg2: .long 18
+sg3: .long 19
+sg4: .long 20
+sg5: .long 21
+sg6: .long 22
+sg7: .long 23
+sg8: .long 24
+sl1: .long 65
+sl2: .long 66
+sl3: .long 67
+sl4: .long 68
+sl5: .long 69
+sl6: .long 70
+sl7: .long 71
+sl8: .long 72
+sh1: .long 257
+sh2: .long 258
+sh3: .long 259
+sh4: .long 260
+sh5: .long 261
+sh6: .long 262
+sh7: .long 263
+sh8: .long 264
+ /* Force .text aligned to 4K, so it very likely gets at 0x1000. */
+ .text
+ .balign 4096
+ .globl fn1
+ .type fn1,@function
+fn1:
+ pushq %rbp
+ movq %rsp, %rbp
+ nop;nop;nop;nop
+
+ /* GD */
+ leaq sg1@tlsdesc(%rip), %rax
+ call *sg1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is referenced through IE too */
+ leaq sg2@tlsdesc(%rip), %rax
+ call *sg2@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD against local variable */
+ leaq sl1@tlsdesc(%rip), %rax
+ call *sl1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> IE against local variable referenced through IE too */
+ leaq sl2@tlsdesc(%rip), %rax
+ call *sl2@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD against hidden and local variable */
+ leaq sh1@tlsdesc(%rip), %rax
+ call *sh1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden and local variable referenced through
+ IE too */
+ leaq sh2@tlsdesc(%rip), %rax
+ call *sh2@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD against hidden but not local variable */
+ leaq sH1@tlsdesc(%rip), %rax
+ call *sH1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden but not local variable referenced through
+ IE too */
+ leaq sH2@tlsdesc(%rip), %rax
+ call *sH2@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* LD */
+ leaq _TLS_MODULE_BASE_@tlsdesc(%rip), %rax
+ call *_TLS_MODULE_BASE_@tlscall(%rax)
+ nop;nop
+ leaq sl1@dtpoff(%rax), %rdx
+ nop;nop
+ leaq 2+sl2@dtpoff(%rax), %r9
+ nop;nop;nop;nop
+
+ /* LD against hidden and local variables */
+ leaq sh1@dtpoff(%rax), %rdx
+ nop;nop
+ leaq sh2@dtpoff+3(%rax), %rcx
+ nop;nop;nop;nop
+
+ /* LD against hidden but not local variables */
+ leaq sH1@dtpoff(%rax), %r12
+ nop;nop
+ leaq sH2@dtpoff+1(%rax), %rcx
+ nop;nop
+
+ /* IE against global var */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sg2@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ /* IE against local var */
+ movq %fs:0, %r14
+ nop;nop
+ addq sl2@gottpoff(%rip), %r14
+ nop;nop;nop;nop
+
+ /* IE against hidden and local var */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sh2@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ /* IE against hidden but not local var */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sH2@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ /* Direct access through %fs */
+
+ /* IE against global var */
+ movq sg5@gottpoff(%rip), %rcx
+ nop;nop
+ movq %fs:(%rcx), %rdx
+ nop;nop;nop;nop
+
+ /* IE against local var */
+ movq sl5@gottpoff(%rip), %r10
+ nop;nop
+ movq %fs:(%r10), %r12
+ nop;nop;nop;nop
+
+ /* IE against hidden and local var */
+ movq sh5@gottpoff(%rip), %rdx
+ nop;nop
+ movq %fs:(%rdx), %rdx
+ nop;nop;nop;nop
+
+ /* IE against hidden but not local var */
+ movq sH5@gottpoff(%rip), %rcx
+ nop;nop
+ movq %fs:(%rcx), %rdx
+ nop;nop;nop;nop
+
+ leave
+ ret
diff --git a/ld/testsuite/ld-x86-64/tlsdesc.sd b/ld/testsuite/ld-x86-64/tlsdesc.sd
new file mode 100644
index 0000000..8eb5d9c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsdesc.sd
@@ -0,0 +1,23 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -s -j.got -j.got.plt
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section \.got:
+ 101308 00000000 00000000 00000000 00000000 .*
+ 101318 00000000 00000000 00000000 00000000 .*
+ 101328 00000000 00000000 00000000 00000000 .*
+ 101338 00000000 00000000 00000000 00000000 .*
+ 101348 00000000 00000000 .*
+Contents of section \.got\.plt:
+ 101350 b8111000 00000000 00000000 00000000 .*
+ 101360 00000000 00000000 00000000 00000000 .*
+ 101370 00000000 00000000 00000000 00000000 .*
+ 101380 00000000 00000000 00000000 00000000 .*
+ 101390 00000000 00000000 00000000 00000000 .*
+ 1013a0 00000000 00000000 00000000 00000000 .*
+ 1013b0 00000000 00000000 .*
diff --git a/ld/testsuite/ld-x86-64/tlsdesc.td b/ld/testsuite/ld-x86-64/tlsdesc.td
new file mode 100644
index 0000000..dd79816
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsdesc.td
@@ -0,0 +1,16 @@
+#source: tlsdesc.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -sj.tdata
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section .tdata:
+ 101154 11000000 12000000 13000000 14000000 .*
+ 101164 15000000 16000000 17000000 18000000 .*
+ 101174 41000000 42000000 43000000 44000000 .*
+ 101184 45000000 46000000 47000000 48000000 .*
+ 101194 01010000 02010000 03010000 04010000 .*
+ 1011a4 05010000 06010000 07010000 08010000 .*
diff --git a/ld/testsuite/ld-x86-64/tlsgdesc.dd b/ld/testsuite/ld-x86-64/tlsgdesc.dd
new file mode 100644
index 0000000..b0e7c05
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsgdesc.dd
@@ -0,0 +1,167 @@
+#source: tlsgdesc.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drj.text
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+[0-9a-f]+ <fc1>:
+ +[0-9a-f]+: 55[ ]+push %rbp
+ +[0-9a-f]+: 48 89 e5[ ]+mov %rsp,%rbp
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE
+ +[0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 03 0d 5e 02 10 00[ ]+add 1049182\(%rip\),%rcx +# 100660 <.*>
+# -> R_X86_64_TPOFF64 sG3
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE
+ +[0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 03 0d 68 02 10 00[ ]+add 1049192\(%rip\),%rcx +# 100680 <.*>
+# -> R_X86_64_TPOFF64 sG4
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD, gd first
+ +[0-9a-f]+: 66 48 8d 3d 6c 02 10[ ]+lea 1049196\(%rip\),%rdi +# 100690 <.*>
+ +[0-9a-f]+: 00 *
+# -> R_X86_64_DTPMOD64 sG1
+ +[0-9a-f]+: 66 66 48 e8 9c ff ff[ ]+callq [0-9a-f]+ <.*>
+ +[0-9a-f]+: ff[ ]+
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 8d 05 a1 02 10 00[ ]+lea 1049249\(%rip\),%rax +# 1006d8 <.*>
+# -> R_X86_64_TLSDESC sG1
+ +[0-9a-f]+: ff 10[ ]+callq \*\(%rax\)
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD, desc first
+ +[0-9a-f]+: 48 8d 05 84 02 10 00[ ]+lea 1049220\(%rip\),%rax +# 1006c8 <.*>
+# -> R_X86_64_TLSDESC sG2
+ +[0-9a-f]+: ff 10[ ]+callq \*\(%rax\)
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 66 48 8d 3d 1e 02 10[ ]+lea 1049118\(%rip\),%rdi +# 100670 <.*>
+ +[0-9a-f]+: 00 *
+# -> R_X86_64_DTPMOD64 sG2
+ +[0-9a-f]+: 66 66 48 e8 6e ff ff[ ]+callq [0-9a-f]+ <.*>
+ +[0-9a-f]+: ff[ ]+
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD -> IE, gd first, after IE use
+ +[0-9a-f]+: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 48 03 05 f2 01 10 00[ ]+add 1049074\(%rip\),%rax +# 100660 <.*>
+# -> R_X86_64_TPOFF64 sG3
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 8b 05 e7 01 10 00[ ]+mov 1049063\(%rip\),%rax +# 100660 <.*>
+# -> R_X86_64_TPOFF64 sG3
+ +[0-9a-f]+: 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, desc first, after IE use
+ +[0-9a-f]+: 48 8b 05 fa 01 10 00[ ]+mov 1049082\(%rip\),%rax +# 100680 <.*>
+# -> R_X86_64_TPOFF64 sG4
+ +[0-9a-f]+: 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]+: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 48 03 05 e4 01 10 00[ ]+add 1049060\(%rip\),%rax +# 100680 <.*>
+# -> R_X86_64_TPOFF64 sG4
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# GD -> IE, gd first, before IE use
+ +[0-9a-f]+: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 48 03 05 b8 01 10 00[ ]+add 1049016\(%rip\),%rax +# 100668 <.*>
+# -> R_X86_64_TPOFF64 sG5
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 8b 05 ad 01 10 00[ ]+mov 1049005\(%rip\),%rax +# 100668 <.*>
+# -> R_X86_64_TPOFF64 sG5
+ +[0-9a-f]+: 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, desc first, before IE use
+ +[0-9a-f]+: 48 8b 05 c0 01 10 00[ ]+mov 1049024\(%rip\),%rax +# 100688 <.*>
+# -> R_X86_64_TPOFF64 sG6
+ +[0-9a-f]+: 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]+: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 48 03 05 aa 01 10 00[ ]+add 1049002\(%rip\),%rax +# 100688 <.*>
+# -> R_X86_64_TPOFF64 sG6
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE
+ +[0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 03 0d 74 01 10 00[ ]+add 1048948\(%rip\),%rcx +# 100668 <.*>
+# -> R_X86_64_TPOFF64 sG5
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+# IE
+ +[0-9a-f]+: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +[0-9a-f]+: 00 00 *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 48 03 0d 7e 01 10 00[ ]+add 1048958\(%rip\),%rcx +# 100688 <.*>
+# -> R_X86_64_TPOFF64 sG6
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: 90[ ]+nop *
+ +[0-9a-f]+: c9[ ]+leaveq *
+ +[0-9a-f]+: c3[ ]+retq *
diff --git a/ld/testsuite/ld-x86-64/tlsgdesc.rd b/ld/testsuite/ld-x86-64/tlsgdesc.rd
new file mode 100644
index 0000000..2f7621b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsgdesc.rd
@@ -0,0 +1,107 @@
+#source: tlsgdesc.s
+#as: --64
+#ld: -shared -melf64_x86_64
+#readelf: -WSsrl
+#target: x86_64-*-*
+
+There are [0-9]+ section headers, starting at offset 0x.*:
+
+Section Headers:
+ \[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
+ \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ \[ 1\] \.hash +.*
+ \[ 2\] \.dynsym +.*
+ \[ 3\] \.dynstr +.*
+ \[ 4\] \.rela.dyn +.*
+ \[ 5\] \.rela.plt +.*
+ \[ 6\] \.plt +.*
+ \[ 7\] \.text +.*
+ \[ 8\] \.dynamic +.*
+ \[ 9\] \.got +.*
+ \[10\] \.got.plt +.*
+ \[11\] \.shstrtab +.*
+ \[12\] \.symtab +.*
+ \[13\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x[0-9a-f]+
+There are [0-9]+ program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ LOAD.*
+ LOAD.*
+ DYNAMIC.*
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+ 01 +.dynamic .got .got.plt *
+ 02 +.dynamic *
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 8 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+[0-9a-f]+ 0+200000012 R_X86_64_TPOFF64 +0+ sG3 \+ 0
+[0-9a-f]+ 0+300000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
+[0-9a-f]+ 0+400000010 R_X86_64_DTPMOD64 +0+ sG2 \+ 0
+[0-9a-f]+ 0+400000011 R_X86_64_DTPOFF64 +0+ sG2 \+ 0
+[0-9a-f]+ 0+500000012 R_X86_64_TPOFF64 +0+ sG4 \+ 0
+[0-9a-f]+ 0+800000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
+[0-9a-f]+ 0+a00000010 R_X86_64_DTPMOD64 +0+ sG1 \+ 0
+[0-9a-f]+ 0+a00000011 R_X86_64_DTPOFF64 +0+ sG1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 3 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+[0-9a-f]+ 0+600000007 R_X86_64_JUMP_SLOT +0+ __tls_get_addr \+ 0
+[0-9a-f]+ 0+a00000024 R_X86_64_TLSDESC +0+ sG1 \+ 0
+[0-9a-f]+ 0+400000024 R_X86_64_TLSDESC +0+ sG2 \+ 0
+
+Symbol table '.dynsym' contains 13 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG4
+ +[0-9]+: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fc1
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 27 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +[0-9]+: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 *
+ +[0-9]+: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 *
+ +[0-9]+: [0-9a-f]+ +0 OBJECT LOCAL HIDDEN ABS _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 OBJECT LOCAL HIDDEN ABS _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG3
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG4
+ +[0-9]+: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +[0-9]+: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fc1
+ +[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +[0-9]+: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
diff --git a/ld/testsuite/ld-x86-64/tlsgdesc.s b/ld/testsuite/ld-x86-64/tlsgdesc.s
new file mode 100644
index 0000000..6657e72
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsgdesc.s
@@ -0,0 +1,106 @@
+ .text
+ .globl fc1
+ .type fc1,@function
+fc1:
+ pushq %rbp
+ movq %rsp, %rbp
+ nop;nop;nop;nop
+
+ /* IE against global var. */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sG3@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ /* IE against global var. */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sG4@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ /* GD, gd first. */
+ .byte 0x66
+ leaq sG1@tlsgd(%rip), %rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ leaq sG1@tlsdesc(%rip), %rax
+ call *sG1@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD, desc first. */
+ leaq sG2@tlsdesc(%rip), %rax
+ call *sG2@tlscall(%rax)
+ nop;nop;nop;nop
+
+ .byte 0x66
+ leaq sG2@tlsgd(%rip), %rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> IE, gd first, after IE use. */
+ .byte 0x66
+ leaq sG3@tlsgd(%rip), %rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ leaq sG3@tlsdesc(%rip), %rax
+ call *sG3@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> IE, desc first, after IE use. */
+ leaq sG4@tlsdesc(%rip), %rax
+ call *sG4@tlscall(%rax)
+ nop;nop;nop;nop
+
+ .byte 0x66
+ leaq sG4@tlsgd(%rip), %rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> IE, gd first, before IE use. */
+ .byte 0x66
+ leaq sG5@tlsgd(%rip), %rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ leaq sG5@tlsdesc(%rip), %rax
+ call *sG5@tlscall(%rax)
+ nop;nop;nop;nop
+
+ /* GD -> IE, desc first, before IE use. */
+ leaq sG6@tlsdesc(%rip), %rax
+ call *sG6@tlscall(%rax)
+ nop;nop;nop;nop
+
+ .byte 0x66
+ leaq sG6@tlsgd(%rip), %rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* IE against global var. */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sG5@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ /* IE against global var. */
+ movq %fs:0, %rcx
+ nop;nop
+ addq sG6@gottpoff(%rip), %rcx
+ nop;nop;nop;nop
+
+ leave
+ ret
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 409a65d..5285f3e 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -1,5 +1,5 @@
# Expect script for ld-x86_64 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
@@ -39,6 +39,11 @@ set x86_64tests {
{{readelf -WSsrl tlspic.rd} {objdump -drj.text tlspic.dd}
{objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
"libtlspic.so"}
+ {"TLS descriptor -fpic -shared transitions" "-shared -melf_x86_64"
+ "--64" {tlsdesc.s tlspic2.s}
+ {{readelf -WSsrld tlsdesc.rd} {objdump -drj.text tlsdesc.dd}
+ {objdump "-s -j.got -j.got.plt" tlsdesc.sd} {objdump -sj.tdata tlsdesc.td}
+ {objdump -drj.plt tlsdesc.pd}} "libtlsdesc.so"}
{"Helper shared library" "-shared -melf_x86_64"
"--64" {tlslib.s} {} "libtlslib.so"}
{"TLS -fpic and -fno-pic exec transitions"
@@ -46,6 +51,15 @@ set x86_64tests {
{{readelf -WSsrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
{objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
"tlsbin"}
+ {"TLS descriptor -fpic and -fno-pic exec transitions"
+ "-melf_x86_64 tmpdir/libtlslib.so" "--64" {tlsbindesc.s tlsbin.s}
+ {{readelf -WSsrl tlsbindesc.rd} {objdump -drj.text tlsbindesc.dd}
+ {objdump -sj.got tlsbindesc.sd} {objdump -sj.tdata tlsbindesc.td}}
+ "tlsbindesc"}
+ {"TLS with global dynamic and descriptors"
+ "-shared -melf_x86_64" "--64" {tlsgdesc.s}
+ {{readelf -WSsrl tlsgdesc.rd} {objdump -drj.text tlsgdesc.dd}}
+ "libtlsgdesc.so"}
{"TLS in debug sections" "-melf_x86_64"
"--64" {tlsg.s}
{{objdump -sj.debug_foobar tlsg.sd}} "tlsg"}