15 changes: 15 additions & 0 deletions gas/testsuite/gas/i386/x86-64-gottpoff.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.text
_start:
addq foo@GOTTPOFF(%rip), %rax
movq foo@GOTTPOFF(%rip), %rax

addq foo@GOTTPOFF(%rip), %r16
movq foo@GOTTPOFF(%rip), %r20

.intel_syntax noprefix

addq rax, QWORD PTR [rip + foo@GOTTPOFF]
movq rax, QWORD PTR [rip + foo@GOTTPOFF]

addq r16, QWORD PTR [rip + foo@GOTTPOFF]
movq r20, QWORD PTR [rip + foo@GOTTPOFF]
17 changes: 17 additions & 0 deletions gas/testsuite/gas/i386/x86-64-tlsdesc.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#as:
#objdump: -dwr
#name: x86-64 tlsdesc

.*: +file format .*


Disassembly of section .text:

0+ <_start>:
+[a-f0-9]+: 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%rax # 7 <_start\+0x7> 3: R_X86_64_GOTPC32_TLSDESC foo-0x4
+[a-f0-9]+: d5 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%r16 # f <_start\+0xf> b: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
+[a-f0-9]+: d5 48 8d 25 00 00 00 00 lea 0x0\(%rip\),%r20 # 17 <_start\+0x17> 13: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
+[a-f0-9]+: 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%rax # 1e <_start\+0x1e> 1a: R_X86_64_GOTPC32_TLSDESC foo-0x4
+[a-f0-9]+: d5 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%r16 # 26 <_start\+0x26> 22: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
+[a-f0-9]+: d5 48 8d 25 00 00 00 00 lea 0x0\(%rip\),%r20 # 2e <_start\+0x2e> 2a: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
#pass
13 changes: 13 additions & 0 deletions gas/testsuite/gas/i386/x86-64-tlsdesc.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.text
_start:
leaq foo@TLSDESC(%rip), %rax

leaq foo@TLSDESC(%rip), %r16
leaq foo@TLSDESC(%rip), %r20

.intel_syntax noprefix

leaq rax, QWORD PTR [rip + foo@TLSDESC]

leaq r16, QWORD PTR [rip + foo@TLSDESC]
leaq r20, QWORD PTR [rip + foo@TLSDESC]
3 changes: 3 additions & 0 deletions gas/testsuite/gas/i386/x86-64.exp
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,9 @@ if [is_elf_format] then {
run_dump_test "x86-64-gotpcrel-no-relax"
run_dump_test "x86-64-gotpcrel-2"

run_dump_test "x86-64-gottpoff"
run_dump_test "x86-64-tlsdesc"

run_dump_test "x86-64-no-got"

run_dump_test "x86-64-addend"
Expand Down
6 changes: 6 additions & 0 deletions include/elf/x86-64.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_type)
instruction starts at 4 bytes before the relocation offset,
relaxable. */
RELOC_NUMBER (R_X86_64_CODE_4_GOTPCRELX, 43)
/* PC relative offset to IE GOT entry if the instruction starts at
4 bytes before the relocation offset. */
RELOC_NUMBER (R_X86_64_CODE_4_GOTTPOFF, 44)
/* 32 bit signed pc relative offset to TLS descriptor in the GOT if
instruction starts at 4 bytes before the relocation offset. */
RELOC_NUMBER (R_X86_64_CODE_4_GOTPC32_TLSDESC, 45)
RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack */
RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack */
END_RELOC_NUMBERS (R_X86_64_max)
Expand Down
49 changes: 49 additions & 0 deletions ld/testsuite/ld-x86-64/tlsbindesc.dd
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,55 @@ Disassembly of section .text:
+[0-9a-f]+: 90[ ]+nop *
+[0-9a-f]+: c9[ ]+leave *
+[0-9a-f]+: c3[ ]+ret *
# IE against global var
+[0-9a-f]+: d5 48 03 05 ([0-9a-f]{2} ){3}[ ]+add 0x[0-9a-f]+\(%rip\),%r16 +# [0-9a-f]+ <sG2>
# -> R_X86_64_TPOFF64 sG2
+[0-9a-f]+: 00 *
# IE -> LE against global var defined in exec
+[0-9a-f]+: d5 18 81 c1 60 ff ff[ ]+add \$0xf+60,%r17
# sg1
+[0-9a-f]+: ff *
# IE -> LE against local var
+[0-9a-f]+: d5 18 81 c2 80 ff ff[ ]+add \$0xf+80,%r18
# sl1
+[0-9a-f]+: ff *
# IE -> LE against hidden var
+[0-9a-f]+: d5 18 81 c3 a0 ff ff[ ]+add \$0xf+a0,%r19
# sh1
+[0-9a-f]+: ff *
# Direct access through %fs
# IE against global var
+[0-9a-f]+: d5 48 8b 25 ([0-9a-f]{2} ){3}[ ]+mov 0x[0-9a-f]+\(%rip\),%r20 +# [0-9a-f]+ <sG5>
# -> R_X86_64_TPOFF64 sG5
+[0-9a-f]+: 00 *
# IE->LE against local var
+[0-9a-f]+: d5 18 c7 c5 90 ff ff[ ]+mov \$0xf+90,%r21
# sl5
+[0-9a-f]+: ff *
# IE->LE against hidden var
+[0-9a-f]+: d5 18 c7 c6 b0 ff ff[ ]+mov \$0xf+b0,%r22
+[0-9a-f]+: ff *
# GD -> IE because variable is not defined in executable
+[0-9a-f]+: d5 48 8b 05 ([0-9a-f]{2} ){3}[ ]+mov 0x[0-9a-f]+\(%rip\),%r16 +# [0-9a-f]+ <sG1>
# -> R_X86_64_TPOFF64 sG1
+[0-9a-f]+: 00 *
# GD -> IE because variable is not defined in executable where
# the variable is referenced through IE too
+[0-9a-f]+: d5 48 8b 0d ([0-9a-f]{2} ){3}[ ]+mov 0x[0-9a-f]+\(%rip\),%r17 +# [0-9a-f]+ <sG2>
# -> R_X86_64_TPOFF64 sG2
+[0-9a-f]+: 00 *
# GD -> LE with global variable defined in executable
+[0-9a-f]+: d5 18 c7 c2 60 ff ff[ ]+mov \$0xf+60,%r18
# sg1
+[0-9a-f]+: ff *
# GD -> LE with local variable defined in executable
+[0-9a-f]+: d5 18 c7 c3 80 ff ff[ ]+mov \$0xf+80,%r19
# sl1
+[0-9a-f]+: ff *
# GD -> LE with hidden variable defined in executable
+[0-9a-f]+: d5 18 c7 c4 a0 ff ff[ ]+mov \$0xf+a0,%r20
# sh1
+[0-9a-f]+: ff *

[0-9a-f]+ <_start>:
+[0-9a-f]+: 55[ ]+push %rbp
Expand Down
36 changes: 18 additions & 18 deletions ld/testsuite/ld-x86-64/tlsbindesc.rd
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,31 @@ Section Headers:
+\[[ 0-9]+\] .dynsym +.*
+\[[ 0-9]+\] .dynstr +.*
+\[[ 0-9]+\] .rela.dyn +.*
+\[[ 0-9]+\] .text +PROGBITS +0+401000 0+1000 0+1fd 00 +AX +0 +0 +4096
+\[[ 0-9]+\] .tdata +PROGBITS +0+6011fd 0+11fd 0+60 00 WAT +0 +0 +1
+\[[ 0-9]+\] .tbss +NOBITS +0+60125d 0+125d 0+40 00 WAT +0 +0 +1
+\[[ 0-9]+\] .dynamic +DYNAMIC +0+601260 0+1260 0+100 10 +WA +4 +0 +8
+\[[ 0-9]+\] .got +PROGBITS +0+601360 0+1360 0+20 08 +WA +0 +0 +8
+\[[ 0-9]+\] .got.plt +PROGBITS +0+601380 0+1380 0+18 08 +WA +0 +0 +8
+\[[ 0-9]+\] .text +PROGBITS +0+401000 0+1000 0+25d 00 +AX +0 +0 +4096
+\[[ 0-9]+\] .tdata +PROGBITS +0+60125d 0+125d 0+60 00 WAT +0 +0 +1
+\[[ 0-9]+\] .tbss +NOBITS +0+6012bd 0+12bd 0+40 00 WAT +0 +0 +1
+\[[ 0-9]+\] .dynamic +DYNAMIC +0+6012c0 0+12c0 0+100 10 +WA +4 +0 +8
+\[[ 0-9]+\] .got +PROGBITS +0+6013c0 0+13c0 0+20 08 +WA +0 +0 +8
+\[[ 0-9]+\] .got.plt +PROGBITS +0+6013e0 0+13e0 0+18 08 +WA +0 +0 +8
+\[[ 0-9]+\] .symtab +.*
+\[[ 0-9]+\] .strtab +.*
+\[[ 0-9]+\] .shstrtab +.*
Key to Flags:
#...

Elf file type is EXEC \(Executable file\)
Entry point 0x401105
Entry point 0x401165
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 +0x0+ 0x0+400000 0x0+400000 0x0+11fd 0x0+11fd R E 0x200000
+LOAD +0x0+11fd 0x0+6011fd 0x0+6011fd 0x0+19b 0x0+19b RW +0x200000
+DYNAMIC +0x0+1260 0x0+601260 0x0+601260 0x0+100 0x0+100 RW +0x8
+TLS +0x0+11fd 0x0+6011fd 0x0+6011fd 0x0+60 0x0+a0 R +0x1
+LOAD +0x0+ 0x0+400000 0x0+400000 0x0+125d 0x0+125d R E 0x200000
+LOAD +0x0+125d 0x0+60125d 0x0+60125d 0x0+19b 0x0+19b RW +0x200000
+DYNAMIC +0x0+12c0 0x0+6012c0 0x0+6012c0 0x0+100 0x0+100 RW +0x8
+TLS +0x0+125d 0x0+60125d 0x0+60125d 0x0+60 0x0+a0 R +0x1

Section to Segment mapping:
+Segment Sections...
Expand All @@ -52,10 +52,10 @@ Program Headers:

Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 4 entries:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
0+601360 +0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
0+601368 +0+200000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0
0+601370 +0+300000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
0+601378 +0+400000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0
0+6013c0 +0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
0+6013c8 +0+200000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0
0+6013d0 +0+300000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
0+6013d8 +0+400000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0

Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
Expand Down Expand Up @@ -88,8 +88,8 @@ Symbol table '\.symtab' contains [0-9]+ entries:
+[0-9]+: 0+9c +0 +TLS +LOCAL +DEFAULT +8 bl8
.* FILE +LOCAL +DEFAULT +ABS
+[0-9]+: 0+a0 +0 +TLS +LOCAL +DEFAULT +7 _TLS_MODULE_BASE_
+[0-9]+: 0+601260 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
+[0-9]+: 0+601380 +0 +OBJECT +LOCAL +DEFAULT +11 _GLOBAL_OFFSET_TABLE_
+[0-9]+: 0+6012c0 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
+[0-9]+: 0+6013e0 +0 +OBJECT +LOCAL +DEFAULT +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
Expand All @@ -104,7 +104,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
+[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+401105 +0 +FUNC +GLOBAL +DEFAULT +6 _start
+[0-9]+: 0+401165 +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
Expand Down
39 changes: 39 additions & 0 deletions ld/testsuite/ld-x86-64/tlsbindesc.s
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,42 @@ fn2:

leave
ret

/* IE against global var */
addq sG2@gottpoff(%rip), %r16

/* IE -> LE against global var defined in exec */
addq sg1@gottpoff(%rip), %r17

/* IE -> LE against local var */
addq sl1@gottpoff(%rip), %r18

/* IE -> LE against hidden var */
addq sh1@gottpoff(%rip), %r19

/* Direct access through %fs */

/* IE against global var */
movq sG5@gottpoff(%rip), %r20

/* IE->LE against local var */
movq sl5@gottpoff(%rip), %r21

/* IE->LE against hidden var */
movq sh5@gottpoff(%rip), %r22

/* GD -> IE because variable is not defined in executable */
leaq sG1@tlsdesc(%rip), %r16

/* GD -> IE because variable is not defined in executable where
the variable is referenced through IE too */
leaq sG2@tlsdesc(%rip), %r17

/* GD -> LE with global variable defined in executable */
leaq sg1@tlsdesc(%rip), %r18

/* GD -> LE with local variable defined in executable */
leaq sl1@tlsdesc(%rip), %r19

/* GD -> LE with hidden variable defined in executable */
leaq sh1@tlsdesc(%rip), %r20