aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/testsuite/ChangeLog22
-rw-r--r--ld/testsuite/ld-i386/i386.exp129
-rw-r--r--ld/testsuite/ld-sh/sh64/sh64.exp294
-rw-r--r--ld/testsuite/ld-x86-64/tlsbin.dd310
-rw-r--r--ld/testsuite/ld-x86-64/tlsbin.rd154
-rw-r--r--ld/testsuite/ld-x86-64/tlsbin.s97
-rw-r--r--ld/testsuite/ld-x86-64/tlsbin.sd14
-rw-r--r--ld/testsuite/ld-x86-64/tlsbin.td16
-rw-r--r--ld/testsuite/ld-x86-64/tlsbinpic.s136
-rw-r--r--ld/testsuite/ld-x86-64/tlslib.s18
-rw-r--r--ld/testsuite/ld-x86-64/tlspic.dd226
-rw-r--r--ld/testsuite/ld-x86-64/tlspic.rd162
-rw-r--r--ld/testsuite/ld-x86-64/tlspic.sd21
-rw-r--r--ld/testsuite/ld-x86-64/tlspic.td16
-rw-r--r--ld/testsuite/ld-x86-64/tlspic1.s171
-rw-r--r--ld/testsuite/ld-x86-64/tlspic2.s11
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp51
-rw-r--r--ld/testsuite/lib/ld-lib.exp130
18 files changed, 1584 insertions, 394 deletions
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index ec1aad9..7b830dc 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,25 @@
+2002-09-27 Jakub Jelinek <jakub@redhat.com>
+
+ * lib/ld-lib.exp (run_ld_link_tests): Add.
+ * ld-sh/sh64/sh64.exp (run_ld_link_tests, regexp_diff,
+ file_contents): Remove.
+ (sh64tests): Add 6th field to the tests array.
+ * ld-i386/i386.exp (run_ld_link_tests): Remove.
+ * ld-x86-64/x86-64.exp: New.
+ * ld-x86-64/tlsbin.dd: New test.
+ * ld-x86-64/tlsbinpic.s: New test.
+ * ld-x86-64/tlsbin.rd: New test.
+ * ld-x86-64/tlsbin.s: New test.
+ * ld-x86-64/tlsbin.sd: New test.
+ * ld-x86-64/tlsbin.td: New test.
+ * ld-x86-64/tlslib.s: New test.
+ * ld-x86-64/tlspic1.s: New test.
+ * ld-x86-64/tlspic2.s: New test.
+ * ld-x86-64/tlspic.dd: New test.
+ * ld-x86-64/tlspic.rd: New test.
+ * ld-x86-64/tlspic.sd: New test.
+ * ld-x86-64/tlspic.td: New test.
+
2002-09-21 Alan Modra <amodra@bigpond.net.au>
* ld-undefined/undefined.exp: Adjust function test.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 09526f8..4ccb9f6 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -1,5 +1,5 @@
# Expect script for ld-i386 tests
-# Copyright (C) 2000, 2001, 2002 Free Software Foundation
+# Copyright (C) 2002 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
@@ -26,11 +26,6 @@ if { !([istarget "i?86-*-elf*"]
return
}
-# FIXME: This isn't set by testsuite/config/default.exp; make it.
-if ![info exists readelf] then {
- set readelf [findfile $base_dir/../binutils/readelf]
-}
-
# List contains test-items with 3 items followed by 2 lists:
# 0:name 1:ld options 2:assembler options
# 3:filenames of assembler files 4: action and options. 5: name of output file
@@ -59,126 +54,4 @@ set i386tests {
{objdump -sj.got tlsnopic.sd}} "libtlsnopic.so"}
}
-# FIXME: Generalize and move this to ld-lib.exp
-
-proc run_ld_link_tests { ldtests } {
- global ld
- global as
- global nm
- global objdump
- global readelf
- global srcdir
- global subdir
- global env
-
- foreach testitem $ldtests {
- set testname [lindex $testitem 0]
- set ld_options [lindex $testitem 1]
- set as_options [lindex $testitem 2]
- set as_files [lindex $testitem 3]
- set actions [lindex $testitem 4]
- set binfile tmpdir/[lindex $testitem 5]
- set objfiles {}
- set is_unresolved 0
- set failed 0
-
-# verbose -log "Testname is $testname"
-# verbose -log "ld_options is $ld_options"
-# verbose -log "as_options is $as_options"
-# verbose -log "as_files is $as_files"
-# verbose -log "actions is $actions"
-# verbose -log "binfile is $binfile"
-
- # Assemble each file in the test.
- foreach as_file $as_files {
- set objfile "tmpdir/[file rootname $as_file].o"
- lappend objfiles $objfile
-
- if ![ld_assemble $as "$as_options $srcdir/$subdir/$as_file" $objfile] {
- set is_unresolved 1
- break
- }
- }
-
- # Catch assembler errors.
- if { $is_unresolved != 0 } {
- unresolved $testname
- continue
- }
-
- if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
- fail $testname
- } else {
- set failed 0
- foreach actionlist $actions {
- set action [lindex $actionlist 0]
- set progopts [lindex $actionlist 1]
-
- # There are actions where we run regexp_diff on the
- # output, and there are other actions (presumably).
- # Handling of the former look the same.
- set dump_prog ""
- switch -- $action {
- objdump
- { set dump_prog $objdump }
- nm
- { set dump_prog $nm }
- readelf
- { set dump_prog $readelf }
- default
- {
- perror "Unrecognized action $action"
- set is_unresolved 1
- break
- }
- }
-
- if { $dump_prog != "" } {
- set dumpfile [lindex $actionlist 2]
- set binary $dump_prog
-
- # Ensure consistent sorting of symbols
- if {[info exists env(LC_ALL)]} {
- set old_lc_all $env(LC_ALL)
- }
- set env(LC_ALL) "C"
- set cmd "$binary $progopts $binfile > dump.out"
- send_log "$cmd\n"
- catch "exec $cmd" comp_output
- if {[info exists old_lc_all]} {
- set env(LC_ALL) $old_lc_all
- } else {
- unset env(LC_ALL)
- }
- set comp_output [prune_warnings $comp_output]
-
- if ![string match "" $comp_output] then {
- send_log "$comp_output\n"
- set failed 1
- break
- }
-
- if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
- verbose "output is [file_contents "dump.out"]" 2
- set failed 1
- break
- }
- }
- }
-
- if { $failed != 0 } {
- fail $testname
- } else { if { $is_unresolved == 0 } {
- pass $testname
- } }
- }
-
- # Catch action errors.
- if { $is_unresolved != 0 } {
- unresolved $testname
- continue
- }
- }
-}
-
run_ld_link_tests $i386tests
diff --git a/ld/testsuite/ld-sh/sh64/sh64.exp b/ld/testsuite/ld-sh/sh64/sh64.exp
index f939441..557542d 100644
--- a/ld/testsuite/ld-sh/sh64/sh64.exp
+++ b/ld/testsuite/ld-sh/sh64/sh64.exp
@@ -23,18 +23,14 @@ if ![istarget sh64-*-*] {
return
}
-# FIXME: This isn't set by testsuite/config/default.exp; make it.
-if ![info exists readelf] then {
- set readelf [findfile $base_dir/../binutils/readelf]
-}
-
# List contains test-items with 3 items followed by 2 lists:
# 0:name 1:ld options 2:assembler options
-# 3:filenames of assembler files 4: action and options.
+# 3:filenames of assembler files 4: action and options. 5: name of output file
# Actions:
# objdump: Apply objdump options on result. Compare with regex (last arg).
# nm: Apply nm options on result. Compare with regex (last arg).
+# readelf: Apply readelf options on result. Compare with regex (last arg).
# Note that the contents dump is the same for "inter-file datalabel
# references, 64-bit ABI" as for 32-bit ABI and ELF so we re-use it.
@@ -42,323 +38,89 @@ if ![info exists readelf] then {
set sh64tests {
{"SH64 linking, 64-bit ABI" "-mshelf64"
"--abi=64" {sh64-1.s sh64-2.s}
- {{objdump -sr abi64.sd} {objdump -x abi64.xd}}}
+ {{objdump -sr abi64.sd} {objdump -x abi64.xd}} "abi64.bin" }
{"SH64 linking, 64-bit ABI, -no-expand" "-mshelf64"
"--abi=64 -no-expand" {sh64-1.s sh64-2.s}
- {{objdump -sr abixx-noexp.sd}}}
+ {{objdump -sr abixx-noexp.sd}} "abi64-noexp.bin" }
{"SH64 linking, 32-bit ABI" "-mshelf32"
"--abi=32" {sh64-1.s sh64-2.s}
- {{objdump -sr abi32.sd} {objdump -x abi32.xd}}}
+ {{objdump -sr abi32.sd} {objdump -x abi32.xd}} "abi32.bin" }
{"SH64 linking, 32-bit ABI, -no-expand" "-mshelf32"
"--abi=32 -no-expand" {sh64-1.s sh64-2.s}
- {{objdump -sr abixx-noexp.sd}}}
+ {{objdump -sr abixx-noexp.sd}} "abi32-noexp.bin" }
{"SH64 linking, single multi-ISA object" "-mshelf32"
"--abi=32" {shmix-1.s}
- {{objdump -sr mix1.sd} {objdump -x mix1.xd}}}
+ {{objdump -sr mix1.sd} {objdump -x mix1.xd}} "mix1.bin" }
{"SH64 linking, single multi-ISA object, -no-expand" "-mshelf32"
"--abi=32 -no-expand" {shmix-1.s}
- {{objdump -sr mix1-noexp.sd}}}
+ {{objdump -sr mix1-noexp.sd}} "mix1-noexp.bin" }
{"SH64 linking, two different-ISA objects" "-mshelf32"
"--abi=32" {shmix-2.s shmix-3.s}
- {{objdump -sr mix2.sd} {objdump -x mix2.xd}}}
+ {{objdump -sr mix2.sd} {objdump -x mix2.xd}} "mix2.bin" }
{"SH64 linking, two different-ISA objects, -no-expand" "-mshelf32"
"--abi=32 -no-expand" {shmix-2.s shmix-3.s}
- {{objdump -sr mix2-noexp.sd}}}
+ {{objdump -sr mix2-noexp.sd}} "mix2-noexp.bin" }
{"SH64 linking, single SHcompact" "-mshelf32"
"--isa=SHcompact" {shcmp-1.s}
- {{objdump -sr cmpct1.sd} {objdump -x cmpct1.xd}}}
+ {{objdump -sr cmpct1.sd} {objdump -x cmpct1.xd}} "cmpct1.bin" }
{"SH64 inter-file datalabel references, 64-bit ABI" "-mshelf64"
"--abi=64" {shdl-1.s shdl-2.s}
- {{objdump -sr shdl64.sd} {objdump -x shdl64.xd}}}
+ {{objdump -sr shdl64.sd} {objdump -x shdl64.xd}} "shdl64.bin" }
{"SH64 inter-file datalabel references, 32-bit ABI" "-mshelf32"
"--abi=32" {shdl-1.s shdl-2.s}
- {{objdump -sr shdl64.sd} {objdump -x shdl32.xd}}}
+ {{objdump -sr shdl64.sd} {objdump -x shdl32.xd}} "shdl32.bin" }
{"SH64 inter-file datalabel references and gc-sections, 32-bit ABI" "-mshelf32 --gc-sections"
"--abi=32" {dlsection-1.s }
- {{objdump -sr dlsection.sd}}}
+ {{objdump -sr dlsection.sd}} "dlsection32.bin" }
{"SH64 inter-file datalabel references and gc-sections, 64-bit ABI" "-mshelf64 --gc-sections"
"--abi=64" {dlsection-1.s }
- {{objdump -sr dlsection.sd}}}
+ {{objdump -sr dlsection.sd}} "dlsection64.bin" }
{"SH64 simple partial linking, 32-bit ABI" "-mshelf32 -r"
"--abi=32" {rel-1.s rel-2.s}
- {{objdump -sx rel32.xd}}}
+ {{objdump -sx rel32.xd}} "rel32.bin" }
{"SH64 simple partial linking, 64-bit ABI" "-mshelf64 -r"
"--abi=64" {rel-1.s rel-2.s}
- {{objdump -sx rel64.xd}}}
+ {{objdump -sx rel64.xd}} "rel64.bin" }
{"SH64 partial linking with datalabel references, 32-bit ABI" "-mshelf32 -r"
"--abi=32" {reldl-1.s reldl-2.s}
- {{readelf {-s -r -x 1 -x 3} reldl32.rd}}}
+ {{readelf {-s -r -x 1 -x 3} reldl32.rd}} "reldl32.bin" }
{"SH64 partial linking with datalabel references, 64-bit ABI" "-mshelf64 -r"
"--abi=64" {reldl-1.s reldl-2.s}
- {{readelf {-s -r -x 1 -x 3} reldl64.rd}}}
+ {{readelf {-s -r -x 1 -x 3} reldl64.rd}} "reldl64.bin" }
{"Handling SH64 assembler-generated .cranges" "-mshelf32"
"--abi=32" {crange-2a.s crange-1.s}
- {{readelf {-S -s -r -x 1 -x 2 -x 9} crange1.rd}}}
+ {{readelf {-S -s -r -x 1 -x 2 -x 9} crange1.rd}} "crange1.bin" }
{"Handling SH64 assembler-generated .cranges, partial linking" "-mshelf32 -r"
"--abi=32" {crange-2a.s}
- {{readelf {-S -s -r -x 2 -x 5} crangerel1.rd}}}
+ {{readelf {-S -s -r -x 2 -x 5} crangerel1.rd}} "crangerel1.bin" }
{"Mixing SH64 assembler-generated with linker-generated .cranges" "-mshelf32"
"--abi=32" {crange-2a.s crange-2b.s crange-1.s}
- {{readelf {-S -s -r -x 2 -x 9} crange2.rd}}}
+ {{readelf {-S -s -r -x 2 -x 9} crange2.rd}} "crange2.bin" }
{"Mixing SH64 assembler-generated with linker-generated .cranges, partial linking"
"-mshelf32 -r"
"--abi=32" {crange-2a.s crange-2c.s crange-2d.s crange-2e.s}
- {{readelf {-S -s -r -x 2 -x 5} crangerel2.rd}}}
+ {{readelf {-S -s -r -x 2 -x 5} crangerel2.rd}} "crangerel2.bin" }
{"Merge and use of SH64 .cranges, some not originally in order" "-mshelf32"
"--abi=32"
{crange-2e.s crange-2f.s crange-2g.s crange-2a.s crange-2d.s crange-2i.s
crange-2h.s crange-1.s}
- {{readelf {-S -s -x 2 -x 9} crange3.rd} {objdump -d crange3.dd}}}
+ {{readelf {-S -s -x 2 -x 9} crange3.rd} {objdump -d crange3.dd}} "crange3.bin" }
{"Sorted SH64 .cranges, entry at SHcompact code" "-mshelf32 --entry diversion"
"--abi=32"
{crange-2e.s crange-2f.s crange-2g.s crange-2a.s crange-2d.s crange-2i.s
crange-2h.s crange-1.s}
- {{readelf {-h -S -s -x 2 -x 9} crange3-cmpct.rd}}}
+ {{readelf {-h -S -s -x 2 -x 9} crange3-cmpct.rd}} "crange3-cmpct.bin" }
{"Sorted SH64 .cranges, entry at SHmedia code" "-mshelf32 --entry diversion2"
"--abi=32"
{crange-2e.s crange-2f.s crange-2g.s crange-2a.s crange-2d.s crange-2i.s
crange-2h.s crange-1.s}
- {{readelf {-h -S -s -x 2 -x 9} crange3-media.rd}}}
+ {{readelf {-h -S -s -x 2 -x 9} crange3-media.rd}} "crange3-media.bin" }
{"SH64 Big Endianness" "-mshelf64 -Tendian.ld"
"--abi=64" {endian.s}
- {{objdump -s endian.sbd} {objdump -d endian.dbd}}}
+ {{objdump -s endian.sbd} {objdump -d endian.dbd}} "endianb.bin" }
{"SH64 Little Endianness" "-mshlelf64 -Tendian.ld"
"--abi=64 --little" {endian.s}
- {{objdump -s endian.sld} {objdump -d endian.dld}}}
-
-}
-
-# FIXME: Generalize and move this to ld-lib.exp
-
-proc run_ld_link_tests { ldtests } {
- global ld
- global as
- global nm
- global objdump
- global readelf
- global srcdir
- global subdir
- global env
-
- set binfile "tmpdir/linked"
-
- foreach testitem $ldtests {
- set testname [lindex $testitem 0]
- set ld_options [lindex $testitem 1]
- set as_options [lindex $testitem 2]
- set as_files [lindex $testitem 3]
- set actions [lindex $testitem 4]
- set objfiles {}
- set is_unresolved 0
- set failed 0
-
-# verbose -log "Testname is $testname"
-# verbose -log "ld_options is $ld_options"
-# verbose -log "as_options is $as_options"
-# verbose -log "as_files is $as_files"
-# verbose -log "actions is $actions"
-
- # Assemble each file in the test.
- foreach as_file $as_files {
- set objfile "tmpdir/[file rootname $as_file].o"
- lappend objfiles $objfile
-
- if ![ld_assemble $as "$as_options $srcdir/$subdir/$as_file" $objfile] {
- set is_unresolved 1
- break
- }
- }
-
- # Catch assembler errors.
- if { $is_unresolved != 0 } {
- unresolved $testname
- continue
- }
-
- if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
- fail $testname
- } else {
- set failed 0
- foreach actionlist $actions {
- set action [lindex $actionlist 0]
- set progopts [lindex $actionlist 1]
-
- # There are actions where we run regexp_diff on the
- # output, and there are other actions (presumably).
- # Handling of the former look the same.
- set dump_prog ""
- switch -- $action {
- objdump
- { set dump_prog $objdump }
- nm
- { set dump_prog $nm }
- readelf
- { set dump_prog $readelf }
- default
- {
- perror "Unrecognized action $action"
- set is_unresolved 1
- break
- }
- }
-
- if { $dump_prog != "" } {
- set dumpfile [lindex $actionlist 2]
- set binary $dump_prog
-
- # Ensure consistent sorting of symbols
- if {[info exists env(LC_ALL)]} {
- set old_lc_all $env(LC_ALL)
- }
- set env(LC_ALL) "C"
- set cmd "$binary $progopts $binfile > dump.out"
- send_log "$cmd\n"
- catch "exec $cmd" comp_output
- if {[info exists old_lc_all]} {
- set env(LC_ALL) $old_lc_all
- } else {
- unset env(LC_ALL)
- }
- set comp_output [prune_warnings $comp_output]
-
- if ![string match "" $comp_output] then {
- send_log "$comp_output\n"
- set failed 1
- break
- }
-
- if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
- verbose "output is [file_contents "dump.out"]" 2
- set failed 1
- break
- }
- }
- }
-
- if { $failed != 0 } {
- fail $testname
- } else { if { $is_unresolved == 0 } {
- pass $testname
- } }
- }
-
- # Catch action errors.
- if { $is_unresolved != 0 } {
- unresolved $testname
- continue
- }
- }
-}
-
-# FIXME: Move this to ld-lib.exp or higher up.
-
-# regexp_diff, based on simple_diff taken from ld test suite
-# compares two files line-by-line
-# file1 contains strings, file2 contains regexps and #-comments
-# blank lines are ignored in either file
-# returns non-zero if differences exist
-#
-proc regexp_diff { file_1 file_2 } {
-
- set eof -1
- set end_1 0
- set end_2 0
- set differences 0
- set diff_pass 0
-
- if [file exists $file_1] then {
- set file_a [open $file_1 r]
- } else {
- warning "$file_1 doesn't exist"
- return 1
- }
-
- if [file exists $file_2] then {
- set file_b [open $file_2 r]
- } else {
- fail "$file_2 doesn't exist"
- close $file_a
- return 1
- }
-
- verbose " Regexp-diff'ing: $file_1 $file_2" 2
-
- while { 1 } {
- set line_a ""
- set line_b ""
- while { [string length $line_a] == 0 } {
- if { [gets $file_a line_a] == $eof } {
- set end_1 1
- break
- }
- }
- while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
- if [ string match "#pass" $line_b ] {
- set end_2 1
- set diff_pass 1
- break
- } elseif [ string match "#..." $line_b ] {
- if { [gets $file_b line_b] == $eof } {
- set end_2 1
- break
- }
- verbose "looking for \"^$line_b$\"" 3
- while { ![regexp "^$line_b$" "$line_a"] } {
- verbose "skipping \"$line_a\"" 3
- if { [gets $file_a line_a] == $eof } {
- set end_1 1
- break
- }
- }
- break
- }
- if { [gets $file_b line_b] == $eof } {
- set end_2 1
- break
- }
- }
-
- if { $diff_pass } {
- break
- } elseif { $end_1 && $end_2 } {
- break
- } elseif { $end_1 } {
- send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
- verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
- set differences 1
- break
- } elseif { $end_2 } {
- send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
- verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
- set differences 1
- break
- } else {
- verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
- if ![regexp "^$line_b$" "$line_a"] {
- send_log "regexp_diff match failure\n"
- send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
- set differences 1
- }
- }
- }
-
- if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
- send_log "$file_1 and $file_2 are different lengths\n"
- verbose "$file_1 and $file_2 are different lengths" 3
- set differences 1
- }
-
- close $file_a
- close $file_b
-
- return $differences
-}
-
-proc file_contents { filename } {
- set file [open $filename r]
- set contents [read $file]
- close $file
- return $contents
+ {{objdump -s endian.sld} {objdump -d endian.dld}} "endinanl.bin" }
}
run_ld_link_tests $sh64tests
diff --git a/ld/testsuite/ld-x86-64/tlsbin.dd b/ld/testsuite/ld-x86-64/tlsbin.dd
new file mode 100644
index 0000000..288b2cd
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbin.dd
@@ -0,0 +1,310 @@
+#source: tlsbinpic.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>:
+ 401000: 55[ ]+push %rbp
+ 401001: 48 89 e5[ ]+mov %rsp,%rbp
+# GD -> IE because variable is not defined in executable
+ 401004: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ 40100b: 00 00 *
+ 40100d: 48 03 05 c4 11 10 00[ ]+add 1053124\(%rip\),%rax +# 5021d8 <_GLOBAL_OFFSET_TABLE_\+0x38>
+# -> R_X86_64_TPOFF64 sG1
+ 401014: 90[ ]+nop *
+ 401015: 90[ ]+nop *
+ 401016: 90[ ]+nop *
+ 401017: 90[ ]+nop *
+# GD -> IE because variable is not defined in executable where
+# the variable is referenced through IE too
+ 401018: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ 40101f: 00 00 *
+ 401021: 48 03 05 a0 11 10 00[ ]+add 1053088\(%rip\),%rax +# 5021c8 <_GLOBAL_OFFSET_TABLE_\+0x28>
+# -> R_X86_64_TPOFF64 sG2
+ 401028: 90[ ]+nop *
+ 401029: 90[ ]+nop *
+ 40102a: 90[ ]+nop *
+ 40102b: 90[ ]+nop *
+# GD -> LE with global variable defined in executable
+ 40102c: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ 401033: 00 00 *
+ 401035: 48 8d 80 60 ff ff ff[ ]+lea 0xf+60\(%rax\),%rax
+# sg1
+ 40103c: 90[ ]+nop *
+ 40103d: 90[ ]+nop *
+ 40103e: 90[ ]+nop *
+ 40103f: 90[ ]+nop *
+# GD -> LE with local variable defined in executable
+ 401040: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ 401047: 00 00 *
+ 401049: 48 8d 80 80 ff ff ff[ ]+lea 0xf+80\(%rax\),%rax
+# sl1
+ 401050: 90[ ]+nop *
+ 401051: 90[ ]+nop *
+ 401052: 90[ ]+nop *
+ 401053: 90[ ]+nop *
+# GD -> LE with hidden variable defined in executable
+ 401054: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ 40105b: 00 00 *
+ 40105d: 48 8d 80 a0 ff ff ff[ ]+lea 0xf+a0\(%rax\),%rax
+# sh1
+ 401064: 90[ ]+nop *
+ 401065: 90[ ]+nop *
+ 401066: 90[ ]+nop *
+ 401067: 90[ ]+nop *
+# LD
+ 401068: 66 66 66 64 48 8b 04[ ]+mov %fs:0x0,%rax
+ 40106f: 25 00 00 00 00 *
+ 401074: 90[ ]+nop *
+ 401075: 90[ ]+nop *
+ 401076: 48 8d 90 81 ff ff ff[ ]+lea 0xf+81\(%rax\),%rdx
+# sl1+1
+ 40107d: 90[ ]+nop *
+ 40107e: 90[ ]+nop *
+ 40107f: 4c 8d 88 86 ff ff ff[ ]+lea 0xf+86\(%rax\),%r9
+# sl2+2
+ 401086: 90[ ]+nop *
+ 401087: 90[ ]+nop *
+ 401088: 90[ ]+nop *
+ 401089: 90[ ]+nop *
+# LD against hidden variables
+ 40108a: 66 66 66 64 48 8b 04[ ]+mov %fs:0x0,%rax
+ 401091: 25 00 00 00 00 *
+ 401096: 90[ ]+nop *
+ 401097: 90[ ]+nop *
+ 401098: 48 8d 90 a0 ff ff ff[ ]+lea 0xf+a0\(%rax\),%rdx
+# sh1
+ 40109f: 90[ ]+nop *
+ 4010a0: 90[ ]+nop *
+ 4010a1: 48 8d 88 a7 ff ff ff[ ]+lea 0xf+a7\(%rax\),%rcx
+# sh2+3
+ 4010a8: 90[ ]+nop *
+ 4010a9: 90[ ]+nop *
+ 4010aa: 90[ ]+nop *
+ 4010ab: 90[ ]+nop *
+# IE against global var
+ 4010ac: 64 4c 8b 0c 25 00 00[ ]+mov %fs:0x0,%r9
+ 4010b3: 00 00 *
+ 4010b5: 90[ ]+nop *
+ 4010b6: 90[ ]+nop *
+ 4010b7: 4c 03 0d 0a 11 10 00[ ]+add 1052938\(%rip\),%r9 +# 5021c8 <_GLOBAL_OFFSET_TABLE_\+0x28>
+# -> R_X86_64_TPOFF64 sG2
+ 4010be: 90[ ]+nop *
+ 4010bf: 90[ ]+nop *
+ 4010c0: 90[ ]+nop *
+ 4010c1: 90[ ]+nop *
+# IE -> LE against global var defined in exec
+ 4010c2: 64 4c 8b 14 25 00 00[ ]+mov %fs:0x0,%r10
+ 4010c9: 00 00 *
+ 4010cb: 90[ ]+nop *
+ 4010cc: 90[ ]+nop *
+ 4010cd: 4d 8d 92 60 ff ff ff[ ]+lea 0xf+60\(%r10\),%r10
+# sg1
+ 4010d4: 90[ ]+nop *
+ 4010d5: 90[ ]+nop *
+ 4010d6: 90[ ]+nop *
+ 4010d7: 90[ ]+nop *
+# IE -> LE against local var
+ 4010d8: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ 4010df: 00 00 *
+ 4010e1: 90[ ]+nop *
+ 4010e2: 90[ ]+nop *
+ 4010e3: 48 8d 80 80 ff ff ff[ ]+lea 0xf+80\(%rax\),%rax
+# sl1
+ 4010ea: 90[ ]+nop *
+ 4010eb: 90[ ]+nop *
+ 4010ec: 90[ ]+nop *
+ 4010ed: 90[ ]+nop *
+# IE -> LE against hidden var
+ 4010ee: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ 4010f5: 00 00 *
+ 4010f7: 90[ ]+nop *
+ 4010f8: 90[ ]+nop *
+ 4010f9: 48 8d 89 a0 ff ff ff[ ]+lea 0xf+a0\(%rcx\),%rcx
+# sh1
+ 401100: 90[ ]+nop *
+ 401101: 90[ ]+nop *
+ 401102: 90[ ]+nop *
+ 401103: 90[ ]+nop *
+# Direct access through %fs
+# IE against global var
+ 401104: 48 8b 0d b5 10 10 00[ ]+mov 1052853\(%rip\),%rcx +# 5021c0 <_GLOBAL_OFFSET_TABLE_\+0x20>
+# -> R_X86_64_TPOFF64 sG5
+ 40110b: 90[ ]+nop *
+ 40110c: 90[ ]+nop *
+ 40110d: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
+ 401111: 90[ ]+nop *
+ 401112: 90[ ]+nop *
+ 401113: 90[ ]+nop *
+ 401114: 90[ ]+nop *
+# IE->LE against local var
+ 401115: 49 c7 c3 90 ff ff ff[ ]+mov \$0xf+90,%r11
+# sl5
+ 40111c: 90[ ]+nop *
+ 40111d: 90[ ]+nop *
+ 40111e: 64 4d 8b 23[ ]+mov %fs:\(%r11\),%r12
+ 401122: 90[ ]+nop *
+ 401123: 90[ ]+nop *
+ 401124: 90[ ]+nop *
+ 401125: 90[ ]+nop *
+# IE->LE against hidden var
+ 401126: 48 c7 c2 b0 ff ff ff[ ]+mov \$0xf+b0,%rdx
+ 40112d: 90[ ]+nop *
+ 40112e: 90[ ]+nop *
+ 40112f: 64 48 8b 12[ ]+mov %fs:\(%rdx\),%rdx
+# sh5
+ 401133: 90[ ]+nop *
+ 401134: 90[ ]+nop *
+ 401135: 90[ ]+nop *
+ 401136: 90[ ]+nop *
+ 401137: c9[ ]+leaveq *
+ 401138: c3[ ]+retq *
+ 401139: 90[ ]+nop *
+ 40113a: 90[ ]+nop *
+ 40113b: 90[ ]+nop *
+
+0+40113c <_start>:
+ 40113c: 55[ ]+push %rbp
+ 40113d: 48 89 e5[ ]+mov %rsp,%rbp
+# IE against global var
+ 401140: 64 4c 8b 1c 25 00 00[ ]+mov %fs:0x0,%r11
+ 401147: 00 00 *
+ 401149: 90[ ]+nop *
+ 40114a: 90[ ]+nop *
+ 40114b: 4c 03 1d 7e 10 10 00[ ]+add 1052798\(%rip\),%r11 +# 5021d0 <_GLOBAL_OFFSET_TABLE_\+0x30>
+# -> R_X86_64_TPOFF64 sG6
+ 401152: 90[ ]+nop *
+ 401153: 90[ ]+nop *
+ 401154: 90[ ]+nop *
+ 401155: 90[ ]+nop *
+# IE -> LE against global var defined in exec
+ 401156: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ 40115d: 00 00 *
+ 40115f: 90[ ]+nop *
+ 401160: 90[ ]+nop *
+ 401161: 48 8d 92 d4 ff ff ff[ ]+lea 0xf+d4\(%rdx\),%rdx
+# bg6
+ 401168: 90[ ]+nop *
+ 401169: 90[ ]+nop *
+ 40116a: 90[ ]+nop *
+ 40116b: 90[ ]+nop *
+# IE -> LE against local var
+ 40116c: 64 4c 8b 24 25 00 00[ ]+mov %fs:0x0,%r12
+ 401173: 00 00 *
+ 401175: 90[ ]+nop *
+ 401176: 90[ ]+nop *
+ 401177: 49 81 c4 f4 ff ff ff[ ]+add \$0xf+f4,%r12
+# bl6
+ 40117e: 90[ ]+nop *
+ 40117f: 90[ ]+nop *
+ 401180: 90[ ]+nop *
+ 401181: 90[ ]+nop *
+# direct %fs access IE -> LE against local var
+ 401182: 48 c7 c2 fc ff ff ff[ ]+mov \$0xf+fc,%rdx
+# bl8
+ 401189: 90[ ]+nop *
+ 40118a: 90[ ]+nop *
+ 40118b: 64 48 8b 02[ ]+mov %fs:\(%rdx\),%rax
+ 40118f: 90[ ]+nop *
+ 401190: 90[ ]+nop *
+ 401191: 90[ ]+nop *
+ 401192: 90[ ]+nop *
+# IE -> LE against hidden but not local var
+ 401193: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ 40119a: 00 00 *
+ 40119c: 90[ ]+nop *
+ 40119d: 90[ ]+nop *
+ 40119e: 48 8d 92 b4 ff ff ff[ ]+lea 0xf+b4\(%rdx\),%rdx
+# sh6
+ 4011a5: 90[ ]+nop *
+ 4011a6: 90[ ]+nop *
+ 4011a7: 90[ ]+nop *
+ 4011a8: 90[ ]+nop *
+# direct %fs access IE -> LE against hidden but not local var
+ 4011a9: 48 c7 c2 bc ff ff ff[ ]+mov \$0xf+bc,%rdx
+# sh8
+ 4011b0: 90[ ]+nop *
+ 4011b1: 90[ ]+nop *
+ 4011b2: 64 48 8b 02[ ]+mov %fs:\(%rdx\),%rax
+ 4011b6: 90[ ]+nop *
+ 4011b7: 90[ ]+nop *
+ 4011b8: 90[ ]+nop *
+ 4011b9: 90[ ]+nop *
+# LE, global var defined in exec
+ 4011ba: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ 4011c1: 00 00 *
+ 4011c3: 90[ ]+nop *
+ 4011c4: 90[ ]+nop *
+ 4011c5: 48 8d 90 64 ff ff ff[ ]+lea 0xf+64\(%rax\),%rdx
+# sg2
+ 4011cc: 90[ ]+nop *
+ 4011cd: 90[ ]+nop *
+ 4011ce: 90[ ]+nop *
+ 4011cf: 90[ ]+nop *
+# LE, local var, non-canonical sequence
+ 4011d0: 49 c7 c1 e6 ff ff ff[ ]+mov \$0xf+e6,%r9
+# bl2+2
+ 4011d7: 90[ ]+nop *
+ 4011d8: 90[ ]+nop *
+ 4011d9: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ 4011e0: 00 00 *
+ 4011e2: 90[ ]+nop *
+ 4011e3: 90[ ]+nop *
+ 4011e4: 4c 01 ca[ ]+add %r9,%rdx
+ 4011e7: 90[ ]+nop *
+ 4011e8: 90[ ]+nop *
+ 4011e9: 90[ ]+nop *
+ 4011ea: 90[ ]+nop *
+# LE, hidden var defined in exec, non-canonical sequence
+ 4011eb: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
+ 4011f2: 00 00 *
+ 4011f4: 90[ ]+nop *
+ 4011f5: 90[ ]+nop *
+ 4011f6: 48 81 c2 a5 ff ff ff[ ]+add \$0xf+a5,%rdx
+# sh2+1
+ 4011fd: 90[ ]+nop *
+ 4011fe: 90[ ]+nop *
+ 4011ff: 90[ ]+nop *
+ 401200: 90[ ]+nop *
+# Direct %fs access
+# LE, global var defined in exec
+ 401201: 64 48 8b 04 25 68 ff[ ]+mov %fs:0xf+68,%rax
+ 401208: ff ff *
+# sg3
+ 40120a: 90[ ]+nop *
+ 40120b: 90[ ]+nop *
+ 40120c: 90[ ]+nop *
+ 40120d: 90[ ]+nop *
+# LE, local var
+ 40120e: 64 4c 8b 14 25 eb ff[ ]+mov %fs:0xf+eb,%r10
+ 401215: ff ff *
+# bl3+3
+ 401217: 90[ ]+nop *
+ 401218: 90[ ]+nop *
+ 401219: 90[ ]+nop *
+ 40121a: 90[ ]+nop *
+# LE, hidden var defined in exec
+ 40121b: 64 48 8b 14 25 a9 ff[ ]+mov %fs:0xf+a9,%rdx
+ 401222: ff ff *
+# sh3+1
+ 401224: 90[ ]+nop *
+ 401225: 90[ ]+nop *
+ 401226: 90[ ]+nop *
+ 401227: 90[ ]+nop *
+ 401228: c9[ ]+leaveq *
+ 401229: c3[ ]+retq *
diff --git a/ld/testsuite/ld-x86-64/tlsbin.rd b/ld/testsuite/ld-x86-64/tlsbin.rd
new file mode 100644
index 0000000..9f163d9
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbin.rd
@@ -0,0 +1,154 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -WSsrl
+#target: x86_64-*-*
+
+There are 18 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\] .rela.plt +.*
+ \[ 7\] .plt +.*
+ \[ 8\] .text +PROGBITS +0+401000 0+1000 0+22a 00 +AX +0 +0 +4096
+ \[ 9\] .data +.*
+ \[10\] .tdata +PROGBITS +0+502000 0+2000 0+60 00 WAT +0 +0 +1
+ \[11\] .tbss +NOBITS +0+502060 0+2060 0+40 00 WAT +0 +0 +1
+ \[12\] .dynamic +DYNAMIC +0+502060 0+2060 0+140 10 +WA +4 +0 +8
+ \[13\] .got +PROGBITS +0+5021a0 0+21a0 0+40 08 +WA +0 +0 +8
+ \[14\] .bss +.*
+ \[15\] .shstrtab +.*
+ \[16\] .symtab +.*
+ \[17\] .strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x40113c
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+ Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ PHDR +0x0+40 0x0+400040 0x0+400040 0x0+150 0x0+150 R E 0x8
+ INTERP +0x0+190 0x0+400190 0x0+400190 0x0+f 0x0+f R +0x1
+.*Requesting program interpreter.*
+ LOAD +0x0+ 0x0+400000 0x0+400000 0x0+122a 0x0+122a R E 0x100000
+ LOAD +0x0+2000 0x0+502000 0x0+502000 0x0+1e0 0x0+1e0 RW 0x100000
+ DYNAMIC +0x0+2060 0x0+502060 0x0+502060 0x0+140 0x0+140 RW 0x8
+ TLS +0x0+2000 0x0+502000 0x0+502000 0x0+60 0x0+a0 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 *
+ 01 +.interp *
+ 02 +.interp .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+ 03 +.tdata .tbss .dynamic .got *
+ 04 +.tbss .dynamic *
+ 05 +.tdata .tbss *
+
+Relocation section '.rela.dyn' at offset 0x358 contains 4 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+0+5021c0 0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
+0+5021c8 0+300000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0
+0+5021d0 0+600000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
+0+5021d8 0+700000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x3b8 contains 1 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+0+[0-9a-f]+ 0+400000007 R_X86_64_JUMP_SLOT +0+[0-9a-f]+ __tls_get_addr \+ 0
+
+Symbol table '.dynsym' contains 11 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +1: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
+ +2: 0+502060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +3: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +4: 0+[0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_addr
+ +5: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +6: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +7: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +8: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +9: 0+5021a0 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +10: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 70 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 *
+ +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 *
+ +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 *
+ +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 *
+ +14: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14 *
+ +15: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +15 *
+ +16: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +16 *
+ +17: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +17 *
+ +18: 0+20 +0 TLS +LOCAL DEFAULT +10 sl1
+ +19: 0+24 +0 TLS +LOCAL DEFAULT +10 sl2
+ +20: 0+28 +0 TLS +LOCAL DEFAULT +10 sl3
+ +21: 0+2c +0 TLS +LOCAL DEFAULT +10 sl4
+ +22: 0+30 +0 TLS +LOCAL DEFAULT +10 sl5
+ +23: 0+34 +0 TLS +LOCAL DEFAULT +10 sl6
+ +24: 0+38 +0 TLS +LOCAL DEFAULT +10 sl7
+ +25: 0+3c +0 TLS +LOCAL DEFAULT +10 sl8
+ +26: 0+80 +0 TLS +LOCAL DEFAULT +11 bl1
+ +27: 0+84 +0 TLS +LOCAL DEFAULT +11 bl2
+ +28: 0+88 +0 TLS +LOCAL DEFAULT +11 bl3
+ +29: 0+8c +0 TLS +LOCAL DEFAULT +11 bl4
+ +30: 0+90 +0 TLS +LOCAL DEFAULT +11 bl5
+ +31: 0+94 +0 TLS +LOCAL DEFAULT +11 bl6
+ +32: 0+98 +0 TLS +LOCAL DEFAULT +11 bl7
+ +33: 0+9c +0 TLS +LOCAL DEFAULT +11 bl8
+ +34: 0+1c +0 TLS +GLOBAL DEFAULT +10 sg8
+ +35: 0+7c +0 TLS +GLOBAL DEFAULT +11 bg8
+ +36: 0+74 +0 TLS +GLOBAL DEFAULT +11 bg6
+ +37: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
+ +38: 0+68 +0 TLS +GLOBAL DEFAULT +11 bg3
+ +39: 0+502060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +40: 0+8 +0 TLS +GLOBAL DEFAULT +10 sg3
+ +41: 0+48 +0 TLS +GLOBAL HIDDEN +10 sh3
+ +42: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
+ +43: 0+c +0 TLS +GLOBAL DEFAULT +10 sg4
+ +44: 0+10 +0 TLS +GLOBAL DEFAULT +10 sg5
+ +45: 0+70 +0 TLS +GLOBAL DEFAULT +11 bg5
+ +46: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_addr
+ +47: 0+58 +0 TLS +GLOBAL HIDDEN +10 sh7
+ +48: 0+5c +0 TLS +GLOBAL HIDDEN +10 sh8
+ +49: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1
+ +50: 0+40113c +0 FUNC +GLOBAL DEFAULT +8 _start
+ +51: 0+4c +0 TLS +GLOBAL HIDDEN +10 sh4
+ +52: 0+78 +0 TLS +GLOBAL DEFAULT +11 bg7
+ +53: 0+50 +0 TLS +GLOBAL HIDDEN +10 sh5
+ +54: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +55: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
+ +56: 0+401000 +0 FUNC +GLOBAL DEFAULT +8 fn2
+ +57: 0+4 +0 TLS +GLOBAL DEFAULT +10 sg2
+ +58: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
+ +59: 0+40 +0 TLS +GLOBAL HIDDEN +10 sh1
+ +60: 0+14 +0 TLS +GLOBAL DEFAULT +10 sg6
+ +61: 0+18 +0 TLS +GLOBAL DEFAULT +10 sg7
+ +62: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +63: 0+5021a0 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +64: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
+ +65: 0+44 +0 TLS +GLOBAL HIDDEN +10 sh2
+ +66: 0+54 +0 TLS +GLOBAL HIDDEN +10 sh6
+ +67: 0+64 +0 TLS +GLOBAL DEFAULT +11 bg2
+ +68: 0+60 +0 TLS +GLOBAL DEFAULT +11 bg1
+ +69: 0+6c +0 TLS +GLOBAL DEFAULT +11 bg4
diff --git a/ld/testsuite/ld-x86-64/tlsbin.s b/ld/testsuite/ld-x86-64/tlsbin.s
new file mode 100644
index 0000000..eb9bfbc
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbin.s
@@ -0,0 +1,97 @@
+ .section ".tbss", "awT", @nobits
+ .globl bg1, bg2, bg3, bg4, bg5, bg6, bg7, bg8
+bg1: .space 4
+bg2: .space 4
+bg3: .space 4
+bg4: .space 4
+bg5: .space 4
+bg6: .space 4
+bg7: .space 4
+bg8: .space 4
+bl1: .space 4
+bl2: .space 4
+bl3: .space 4
+bl4: .space 4
+bl5: .space 4
+bl6: .space 4
+bl7: .space 4
+bl8: .space 4
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ pushq %rbp
+ movq %rsp, %rbp
+
+ /* IE against global var */
+ movq %fs:0, %r11
+ nop;nop
+ addq sG6@gottpoff(%rip), %r11
+ nop;nop;nop;nop
+
+ /* IE -> LE against global var defined in exec */
+ movq %fs:0, %rdx
+ nop;nop
+ addq bg6@gottpoff(%rip), %rdx
+ nop;nop;nop;nop
+
+ /* IE -> LE against local var */
+ movq %fs:0, %r12
+ nop;nop
+ addq bl6@gottpoff(%rip), %r12
+ nop;nop;nop;nop
+
+ /* direct %fs access IE -> LE against local var */
+ movq bl8@gottpoff(%rip), %rdx
+ nop;nop
+ movq %fs:(%rdx), %rax
+ nop;nop;nop;nop
+
+ /* IE -> LE against hidden but not local var */
+ movq %fs:0, %rdx
+ nop;nop
+ addq sh6@gottpoff(%rip), %rdx
+ nop;nop;nop;nop
+
+ /* direct %fs access IE -> LE against hidden but not local var */
+ movq sh8@gottpoff(%rip), %rdx
+ nop;nop
+ movq %fs:(%rdx), %rax
+ nop;nop;nop;nop
+
+ /* LE, global var defined in exec */
+ movq %fs:0, %rax
+ nop;nop
+ leaq sg2@tpoff(%rax), %rdx
+ nop;nop;nop;nop
+
+ /* LE, local var, non-canonical sequence */
+ movq $2+bl2@tpoff, %r9
+ nop;nop
+ movq %fs:0, %rdx
+ nop;nop
+ addq %r9, %rdx
+ nop;nop;nop;nop
+
+ /* LE, hidden var defined in exec, non-canonical sequence */
+ movq %fs:0, %rdx
+ nop;nop
+ addq $sh2@tpoff+1, %rdx
+ nop;nop;nop;nop
+
+ /* Direct %fs access */
+
+ /* LE, global var defined in exec */
+ movq %fs:sg3@tpoff, %rax
+ nop;nop;nop;nop
+
+ /* LE, local var */
+ movq %fs:bl3@tpoff+3, %r10
+ nop;nop;nop;nop
+
+ /* LE, hidden var defined in exec */
+ movq %fs:1+sh3@tpoff, %rdx
+ nop;nop;nop;nop
+
+ leave
+ ret
diff --git a/ld/testsuite/ld-x86-64/tlsbin.sd b/ld/testsuite/ld-x86-64/tlsbin.sd
new file mode 100644
index 0000000..d378325
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbin.sd
@@ -0,0 +1,14 @@
+#source: tlsbinpic.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:
+ 5021a0 [0-9a-f]+ [0-9a-f]+ 00000000 00000000 .*
+ 5021b0 00000000 00000000 [0-9a-f]+ [0-9a-f]+ .*
+ 5021c0 00000000 00000000 00000000 00000000 .*
+ 5021d0 00000000 00000000 00000000 00000000 .*
diff --git a/ld/testsuite/ld-x86-64/tlsbin.td b/ld/testsuite/ld-x86-64/tlsbin.td
new file mode 100644
index 0000000..f2ba1b4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbin.td
@@ -0,0 +1,16 @@
+#source: tlsbinpic.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:
+ 502000 11000000 12000000 13000000 14000000 .*
+ 502010 15000000 16000000 17000000 18000000 .*
+ 502020 41000000 42000000 43000000 44000000 .*
+ 502030 45000000 46000000 47000000 48000000 .*
+ 502040 01010000 02010000 03010000 04010000 .*
+ 502050 05010000 06010000 07010000 08010000 .*
diff --git a/ld/testsuite/ld-x86-64/tlsbinpic.s b/ld/testsuite/ld-x86-64/tlsbinpic.s
new file mode 100644
index 0000000..da6085f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlsbinpic.s
@@ -0,0 +1,136 @@
+ /* 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 */
+ .long 0x66666666
+ leaq sG1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is not defined in executable where
+ the variable is referenced through IE too */
+ .long 0x66666666
+ leaq sG2@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> LE with global variable defined in executable */
+ .long 0x66666666
+ leaq sg1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> LE with local variable defined in executable */
+ .long 0x66666666
+ leaq sl1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> LE with hidden variable defined in executable */
+ .long 0x66666666
+ leaq sh1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* LD */
+ leaq sl1@tlsld(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop
+ leaq 1+sl1@dtpoff(%rax), %rdx
+ nop;nop
+ leaq sl2@dtpoff+2(%rax), %r9
+ nop;nop;nop;nop
+
+ /* LD against hidden variables */
+ leaq sh1@tlsld(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop
+ 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/tlslib.s b/ld/testsuite/ld-x86-64/tlslib.s
new file mode 100644
index 0000000..9eccc08
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlslib.s
@@ -0,0 +1,18 @@
+ .section ".tdata", "awT", @progbits
+ .globl sG1, sG2, sG3, sG4, sG5, sG6, sG7, sG8
+sG1: .long 513
+sG2: .long 514
+sG3: .long 515
+sG4: .long 516
+sG5: .long 517
+sG6: .long 518
+sG7: .long 519
+sG8: .long 520
+
+ .text
+ /* Dummy. */
+ .globl __tls_get_addr
+ .type __tls_get_addr,@function
+__tls_get_addr:
+ movq %rdi, %rax
+ ret
diff --git a/ld/testsuite/ld-x86-64/tlspic.dd b/ld/testsuite/ld-x86-64/tlspic.dd
new file mode 100644
index 0000000..8c0909a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlspic.dd
@@ -0,0 +1,226 @@
+#source: tlspic1.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+1000 <fn1>:
+ +1000: 55[ ]+push %rbp
+ +1001: 48 89 e5[ ]+mov %rsp,%rbp
+ +1004: 90[ ]+nop *
+ +1005: 90[ ]+nop *
+ +1006: 90[ ]+nop *
+ +1007: 90[ ]+nop *
+# GD
+ +1008: 66 66 66 66 48 8d 3d[ ]+lea 1053165\(%rip\),%rdi +# 102200 <_GLOBAL_OFFSET_TABLE_\+0x70>
+ +100f: ed 11 10 00 *
+# -> R_X86_64_DTPMOD64 sg1
+ +1013: e8 68 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +1018: 90[ ]+nop *
+ +1019: 90[ ]+nop *
+ +101a: 90[ ]+nop *
+ +101b: 90[ ]+nop *
+# GD -> IE because variable is referenced through IE too
+ +101c: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +1023: 00 00 *
+ +1025: 48 03 05 f4 11 10 00[ ]+add 1053172\(%rip\),%rax +# 102220 <_GLOBAL_OFFSET_TABLE_\+0x90>
+# -> R_X86_64_TPOFF64 sg2
+ +102c: 90[ ]+nop *
+ +102d: 90[ ]+nop *
+ +102e: 90[ ]+nop *
+ +102f: 90[ ]+nop *
+# GD against local variable
+ +1030: 66 66 66 66 48 8d 3d[ ]+lea 1053045\(%rip\),%rdi +# 1021b0 <_GLOBAL_OFFSET_TABLE_\+0x20>
+ +1037: 75 11 10 00 *
+# -> R_X86_64_DTPMOD64 [0 0x2000000000000000]
+ +103b: e8 40 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +1040: 90[ ]+nop *
+ +1041: 90[ ]+nop *
+ +1042: 90[ ]+nop *
+ +1043: 90[ ]+nop *
+# GD -> IE against local variable referenced through IE too
+ +1044: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +104b: 00 00 *
+ +104d: 48 03 05 6c 11 10 00[ ]+add 1053036\(%rip\),%rax +# 1021c0 <_GLOBAL_OFFSET_TABLE_\+0x30>
+# -> R_X86_64_TPOFF64 *ABS*+0x24
+ +1054: 90[ ]+nop *
+ +1055: 90[ ]+nop *
+ +1056: 90[ ]+nop *
+ +1057: 90[ ]+nop *
+# GD against hidden and local variable
+ +1058: 66 66 66 66 48 8d 3d[ ]+lea 1053125\(%rip\),%rdi +# 102228 <_GLOBAL_OFFSET_TABLE_\+0x98>
+ +105f: c5 11 10 00 *
+# -> R_X86_64_DTPMOD64 [0 0x4000000000000000]
+ +1063: e8 18 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +1068: 90[ ]+nop *
+ +1069: 90[ ]+nop *
+ +106a: 90[ ]+nop *
+ +106b: 90[ ]+nop *
+# GD -> IE against hidden and local variable referenced through IE too
+ +106c: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +1073: 00 00 *
+ +1075: 48 03 05 bc 11 10 00[ ]+add 1053116\(%rip\),%rax +# 102238 <_GLOBAL_OFFSET_TABLE_\+0xa8>
+# -> R_X86_64_TPOFF64 *ABS*+0x44
+ +107c: 90[ ]+nop *
+ +107d: 90[ ]+nop *
+ +107e: 90[ ]+nop *
+ +107f: 90[ ]+nop *
+# GD against hidden but not local variable
+ +1080: 66 66 66 66 48 8d 3d[ ]+lea 1053013\(%rip\),%rdi +# 1021e0 <_GLOBAL_OFFSET_TABLE_\+0x50>
+ +1087: 55 11 10 00 *
+# -> R_X86_64_DTPMOD64 [0 0x6000000000000000]
+ +108b: e8 f0 f5 ff ff[ ]+callq [0-9a-f]+ <.*>
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +1090: 90[ ]+nop *
+ +1091: 90[ ]+nop *
+ +1092: 90[ ]+nop *
+ +1093: 90[ ]+nop *
+# GD -> IE against hidden but not local variable referenced through IE too
+ +1094: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
+ +109b: 00 00 *
+ +109d: 48 03 05 4c 11 10 00[ ]+add 1053004\(%rip\),%rax +# 1021f0 <_GLOBAL_OFFSET_TABLE_\+0x60>
+# -> R_X86_64_TPOFF64 *ABS*+0x64
+ +10a4: 90[ ]+nop *
+ +10a5: 90[ ]+nop *
+ +10a6: 90[ ]+nop *
+ +10a7: 90[ ]+nop *
+# LD
+ +10a8: 48 8d 3d 21 11 10 00[ ]+lea 1052961\(%rip\),%rdi +# 1021d0 <_GLOBAL_OFFSET_TABLE_\+0x40>
+# -> R_X86_64_DTPMOD64 [0 0x000000000000000]
+ +10af: e8 cc f5 ff ff[ ]+callq [0-9a-f]+ <.*>
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +10b4: 90[ ]+nop *
+ +10b5: 90[ ]+nop *
+ +10b6: 48 8d 90 20 00 00 00[ ]+lea 0x20\(%rax\),%rdx
+ +10bd: 90[ ]+nop *
+ +10be: 90[ ]+nop *
+ +10bf: 4c 8d 88 26 00 00 00[ ]+lea 0x26\(%rax\),%r9
+ +10c6: 90[ ]+nop *
+ +10c7: 90[ ]+nop *
+ +10c8: 90[ ]+nop *
+ +10c9: 90[ ]+nop *
+# LD against hidden and local variables
+ +10ca: 48 8d 3d ff 10 10 00[ ]+lea 1052927\(%rip\),%rdi +# 1021d0 <_GLOBAL_OFFSET_TABLE_\+0x40>
+# -> R_X86_64_DTPMOD64 [0 0x000000000000000]
+ +10d1: e8 aa f5 ff ff[ ]+callq [0-9a-f]+ <.*>
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +10d6: 90[ ]+nop *
+ +10d7: 90[ ]+nop *
+ +10d8: 48 8d 90 40 00 00 00[ ]+lea 0x40\(%rax\),%rdx
+ +10df: 90[ ]+nop *
+ +10e0: 90[ ]+nop *
+ +10e1: 48 8d 88 47 00 00 00[ ]+lea 0x47\(%rax\),%rcx
+ +10e8: 90[ ]+nop *
+ +10e9: 90[ ]+nop *
+ +10ea: 90[ ]+nop *
+ +10eb: 90[ ]+nop *
+# LD against hidden but not local variables
+ +10ec: 48 8d 3d dd 10 10 00[ ]+lea 1052893\(%rip\),%rdi +# 1021d0 <_GLOBAL_OFFSET_TABLE_\+0x40>
+# -> R_X86_64_DTPMOD64 [0 0x000000000000000]
+ +10f3: e8 88 f5 ff ff[ ]+callq [0-9a-f]+ <.*>
+# -> R_X86_64_JUMP_SLOT __tls_get_addr
+ +10f8: 90[ ]+nop *
+ +10f9: 90[ ]+nop *
+ +10fa: 4c 8d a0 60 00 00 00[ ]+lea 0x60\(%rax\),%r12
+ +1101: 90[ ]+nop *
+ +1102: 90[ ]+nop *
+ +1103: 48 8d 88 65 00 00 00[ ]+lea 0x65\(%rax\),%rcx
+ +110a: 90[ ]+nop *
+ +110b: 90[ ]+nop *
+# IE against global var
+ +110c: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +1113: 00 00 *
+ +1115: 90[ ]+nop *
+ +1116: 90[ ]+nop *
+ +1117: 48 03 0d 02 11 10 00[ ]+add 1052930\(%rip\),%rcx +# 102220 <_GLOBAL_OFFSET_TABLE_\+0x90>
+# -> R_X86_64_TPOFF64 sg2
+ +111e: 90[ ]+nop *
+ +111f: 90[ ]+nop *
+ +1120: 90[ ]+nop *
+ +1121: 90[ ]+nop *
+# IE against local var
+ +1122: 64 4c 8b 34 25 00 00[ ]+mov %fs:0x0,%r14
+ +1129: 00 00 *
+ +112b: 90[ ]+nop *
+ +112c: 90[ ]+nop *
+ +112d: 4c 03 35 8c 10 10 00[ ]+add 1052812\(%rip\),%r14 +# 1021c0 <_GLOBAL_OFFSET_TABLE_\+0x30>
+# -> R_X86_64_TPOFF64 *ABS*+0x24
+ +1134: 90[ ]+nop *
+ +1135: 90[ ]+nop *
+ +1136: 90[ ]+nop *
+ +1137: 90[ ]+nop *
+# IE against hidden and local var
+ +1138: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +113f: 00 00 *
+ +1141: 90[ ]+nop *
+ +1142: 90[ ]+nop *
+ +1143: 48 03 0d ee 10 10 00[ ]+add 1052910\(%rip\),%rcx +# 102238 <_GLOBAL_OFFSET_TABLE_\+0xa8>
+# -> R_X86_64_TPOFF64 *ABS*+0x44
+ +114a: 90[ ]+nop *
+ +114b: 90[ ]+nop *
+ +114c: 90[ ]+nop *
+ +114d: 90[ ]+nop *
+# IE against hidden but not local var
+ +114e: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
+ +1155: 00 00 *
+ +1157: 90[ ]+nop *
+ +1158: 90[ ]+nop *
+ +1159: 48 03 0d 90 10 10 00[ ]+add 1052816\(%rip\),%rcx +# 1021f0 <_GLOBAL_OFFSET_TABLE_\+0x60>
+# -> R_X86_64_TPOFF64 *ABS*+0x64
+ +1160: 90[ ]+nop *
+ +1161: 90[ ]+nop *
+ +1162: 90[ ]+nop *
+ +1163: 90[ ]+nop *
+# Direct access through %fs
+# IE against global var
+ +1164: 48 8b 0d 8d 10 10 00[ ]+mov 1052813\(%rip\),%rcx +# 1021f8 <_GLOBAL_OFFSET_TABLE_\+0x68>
+# -> R_X86_64_TPOFF64 sg5
+ +116b: 90[ ]+nop *
+ +116c: 90[ ]+nop *
+ +116d: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
+ +1171: 90[ ]+nop *
+ +1172: 90[ ]+nop *
+ +1173: 90[ ]+nop *
+ +1174: 90[ ]+nop *
+# IE against local var
+ +1175: 4c 8b 15 4c 10 10 00[ ]+mov 1052748\(%rip\),%r10 +# 1021c8 <_GLOBAL_OFFSET_TABLE_\+0x38>
+# -> R_X86_64_TPOFF64 *ABS*+0x30
+ +117c: 90[ ]+nop *
+ +117d: 90[ ]+nop *
+ +117e: 64 4d 8b 22[ ]+mov %fs:\(%r10\),%r12
+ +1182: 90[ ]+nop *
+ +1183: 90[ ]+nop *
+ +1184: 90[ ]+nop *
+ +1185: 90[ ]+nop *
+# IE against hidden and local var
+ +1186: 48 8b 15 83 10 10 00[ ]+mov 1052803\(%rip\),%rdx +# 102210 <_GLOBAL_OFFSET_TABLE_\+0x80>
+# -> R_X86_64_TPOFF64 *ABS*+0x50
+ +118d: 90[ ]+nop *
+ +118e: 90[ ]+nop *
+ +118f: 64 48 8b 12[ ]+mov %fs:\(%rdx\),%rdx
+ +1193: 90[ ]+nop *
+ +1194: 90[ ]+nop *
+ +1195: 90[ ]+nop *
+ +1196: 90[ ]+nop *
+# IE against hidden but not local var
+ +1197: 48 8b 0d 7a 10 10 00[ ]+mov 1052794\(%rip\),%rcx +# 102218 <_GLOBAL_OFFSET_TABLE_\+0x88>
+# -> R_X86_64_TPOFF64 *ABS*+0x70
+ +119e: 90[ ]+nop *
+ +119f: 90[ ]+nop *
+ +11a0: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
+ +11a4: 90[ ]+nop *
+ +11a5: 90[ ]+nop *
+ +11a6: 90[ ]+nop *
+ +11a7: 90[ ]+nop *
+ +11a8: c9[ ]+leaveq *
+ +11a9: c3[ ]+retq *
+ +11aa: 90[ ]+nop *
+ +11ab: 90[ ]+nop *
diff --git a/ld/testsuite/ld-x86-64/tlspic.rd b/ld/testsuite/ld-x86-64/tlspic.rd
new file mode 100644
index 0000000..d8190db
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlspic.rd
@@ -0,0 +1,162 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -WSsrl
+#target: x86_64-*-*
+
+There are 17 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 +.*
+ \[ 7\] .text +PROGBITS +0+1000 0+1000 0+1ac 00 +AX +0 +0 4096
+ \[ 8\] .data +.*
+ \[ 9\] .tdata +PROGBITS +0+102000 0+2000 0+60 00 WAT +0 +0 +1
+ \[10\] .tbss +NOBITS +0+102060 0+2060 0+20 00 WAT +0 +0 +1
+ \[11\] .dynamic +DYNAMIC +0+102060 0+2060 0+130 10 +WA +3 +0 +8
+ \[12\] .got +PROGBITS +0+102190 0+2190 0+b0 08 +WA +0 +0 +8
+ \[13\] .bss +.*
+ \[14\] .shstrtab +.*
+ \[15\] .symtab +.*
+ \[16\] .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+2000 0x0+102000 0x0+102000 0x0+240 0x0+240 RW +0x100000
+ DYNAMIC +0x0+2060 0x0+102060 0x0+102060 0x0+130 0x0+130 RW +0x8
+ TLS +0x0+2000 0x0+102000 0x0+102000 0x0+60 0x0+80 R +0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
+ 01 +.tdata .tbss .dynamic .got *
+ 02 +.tbss .dynamic *
+ 03 +.tdata .tbss *
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 14 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+0+1021b0 0+10 R_X86_64_DTPMOD64 +0+
+0+1021c0 0+12 R_X86_64_TPOFF64 +0+24
+0+1021c8 0+12 R_X86_64_TPOFF64 +0+30
+0+1021d0 0+10 R_X86_64_DTPMOD64 +0+
+0+1021e0 0+10 R_X86_64_DTPMOD64 +0+
+0+1021f0 0+12 R_X86_64_TPOFF64 +0+64
+0+102210 0+12 R_X86_64_TPOFF64 +0+50
+0+102218 0+12 R_X86_64_TPOFF64 +0+70
+0+102228 0+10 R_X86_64_DTPMOD64 +0+
+0+102238 0+12 R_X86_64_TPOFF64 +0+44
+0+1021f8 0+1200000012 R_X86_64_TPOFF64 +0+10 sg5 \+ 0
+0+102200 0+1400000010 R_X86_64_DTPMOD64 +0+ sg1 \+ 0
+0+102208 0+1400000011 R_X86_64_DTPOFF64 +0+ sg1 \+ 0
+0+102220 0+1700000012 R_X86_64_TPOFF64 +0+4 sg2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x658 contains 1 entries:
+ +Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
+0+[0-9a-f]+ 0+1300000007 R_X86_64_JUMP_SLOT +0+ __tls_get_addr \+ 0
+
+Symbol table '.dynsym' contains 29 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 *
+ +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 *
+ +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 *
+ +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 *
+ +14: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +15: 0+102060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +16: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +17: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +18: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +19: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
+ +20: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +21: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +22: 0+102240 +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +23: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +24: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +25: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +26: 0+102240 +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +27: 0+102190 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +28: 0+102240 +0 NOTYPE GLOBAL DEFAULT ABS _end
+
+Symbol table '.symtab' contains 56 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE LOCAL DEFAULT UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 *
+ +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 *
+ +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 *
+ +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 *
+ +14: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14 *
+ +15: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +15 *
+ +16: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +16 *
+ +17: 0+20 +0 TLS +LOCAL DEFAULT +9 sl1
+ +18: 0+24 +0 TLS +LOCAL DEFAULT +9 sl2
+ +19: 0+28 +0 TLS +LOCAL DEFAULT +9 sl3
+ +20: 0+2c +0 TLS +LOCAL DEFAULT +9 sl4
+ +21: 0+30 +0 TLS +LOCAL DEFAULT +9 sl5
+ +22: 0+34 +0 TLS +LOCAL DEFAULT +9 sl6
+ +23: 0+38 +0 TLS +LOCAL DEFAULT +9 sl7
+ +24: 0+3c +0 TLS +LOCAL DEFAULT +9 sl8
+ +25: 0+60 +0 TLS +LOCAL HIDDEN +10 sH1
+ +26: 0+48 +0 TLS +LOCAL HIDDEN +9 sh3
+ +27: 0+64 +0 TLS +LOCAL HIDDEN +10 sH2
+ +28: 0+78 +0 TLS +LOCAL HIDDEN +10 sH7
+ +29: 0+58 +0 TLS +LOCAL HIDDEN +9 sh7
+ +30: 0+5c +0 TLS +LOCAL HIDDEN +9 sh8
+ +31: 0+6c +0 TLS +LOCAL HIDDEN +10 sH4
+ +32: 0+4c +0 TLS +LOCAL HIDDEN +9 sh4
+ +33: 0+68 +0 TLS +LOCAL HIDDEN +10 sH3
+ +34: 0+50 +0 TLS +LOCAL HIDDEN +9 sh5
+ +35: 0+70 +0 TLS +LOCAL HIDDEN +10 sH5
+ +36: 0+74 +0 TLS +LOCAL HIDDEN +10 sH6
+ +37: 0+7c +0 TLS +LOCAL HIDDEN +10 sH8
+ +38: 0+40 +0 TLS +LOCAL HIDDEN +9 sh1
+ +39: 0+44 +0 TLS +LOCAL HIDDEN +9 sh2
+ +40: 0+54 +0 TLS +LOCAL HIDDEN +9 sh6
+ +41: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +42: 0+102060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+ +43: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +44: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +45: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +46: 0+ +0 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
+ +47: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +48: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +49: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
+ +50: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +51: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +52: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +53: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
+ +54: 0+102190 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
+ +55: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
diff --git a/ld/testsuite/ld-x86-64/tlspic.sd b/ld/testsuite/ld-x86-64/tlspic.sd
new file mode 100644
index 0000000..a79ebad
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlspic.sd
@@ -0,0 +1,21 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -sj.got
+#target: x86_64-*-*
+
+.*: +file format elf64-x86-64
+
+Contents of section .got:
+ 102190 [0-9a-f]+ [0-9a-f]+ 00000000 00000000 .*
+ 1021a0 00000000 00000000 [0-9a-f]+ [0-9a-f]+ .*
+ 1021b0 00000000 00000000 20000000 00000000 .*
+ 1021c0 00000000 00000000 00000000 00000000 .*
+ 1021d0 00000000 00000000 00000000 00000000 .*
+ 1021e0 00000000 00000000 60000000 00000000 .*
+ 1021f0 00000000 00000000 00000000 00000000 .*
+ 102200 00000000 00000000 00000000 00000000 .*
+ 102210 00000000 00000000 00000000 00000000 .*
+ 102220 00000000 00000000 00000000 00000000 .*
+ 102230 40000000 00000000 00000000 00000000 .*
diff --git a/ld/testsuite/ld-x86-64/tlspic.td b/ld/testsuite/ld-x86-64/tlspic.td
new file mode 100644
index 0000000..18ec846
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlspic.td
@@ -0,0 +1,16 @@
+#source: tlspic1.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:
+ 102000 11000000 12000000 13000000 14000000 .*
+ 102010 15000000 16000000 17000000 18000000 .*
+ 102020 41000000 42000000 43000000 44000000 .*
+ 102030 45000000 46000000 47000000 48000000 .*
+ 102040 01010000 02010000 03010000 04010000 .*
+ 102050 05010000 06010000 07010000 08010000 .*
diff --git a/ld/testsuite/ld-x86-64/tlspic1.s b/ld/testsuite/ld-x86-64/tlspic1.s
new file mode 100644
index 0000000..64ffc3f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlspic1.s
@@ -0,0 +1,171 @@
+ /* 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 */
+ .long 0x66666666
+ leaq sg1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> IE because variable is referenced through IE too */
+ .long 0x66666666
+ leaq sg2@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD against local variable */
+ .long 0x66666666
+ leaq sl1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> IE against local variable referenced through IE too */
+ .long 0x66666666
+ leaq sl2@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD against hidden and local variable */
+ .long 0x66666666
+ leaq sh1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden and local variable referenced through
+ IE too */
+ .long 0x66666666
+ leaq sh2@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD against hidden but not local variable */
+ .long 0x66666666
+ leaq sH1@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* GD -> IE against hidden but not local variable referenced through
+ IE too */
+ .long 0x66666666
+ leaq sH2@tlsgd(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop;nop;nop
+
+ /* LD */
+ leaq sl1@tlsld(%rip), %rdi
+ call __tls_get_addr@plt
+ 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@tlsld(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop
+ 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@tlsld(%rip), %rdi
+ call __tls_get_addr@plt
+ nop;nop
+ 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/tlspic2.s b/ld/testsuite/ld-x86-64/tlspic2.s
new file mode 100644
index 0000000..5513f9b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tlspic2.s
@@ -0,0 +1,11 @@
+ .section ".tbss", "awT", @nobits
+ .globl sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+ .hidden sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+sH1: .space 4
+sH2: .space 4
+sH3: .space 4
+sH4: .space 4
+sH5: .space 4
+sH6: .space 4
+sH7: .space 4
+sH8: .space 4
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
new file mode 100644
index 0000000..edfae9a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -0,0 +1,51 @@
+# Expect script for ld-x86_64 tests
+# Copyright (C) 2002 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
+# the Free Software Foundation; either version 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+# Test x86_64 linking; all types of relocs. This tests the assembler and
+# tools like objdump as well as the linker.
+
+if { !([istarget "x86_64-*-elf*"]
+ || [istarget "x86_64-*-linux*"]) } {
+ return
+}
+
+# List contains test-items with 3 items followed by 2 lists:
+# 0:name 1:ld options 2:assembler options
+# 3:filenames of assembler files 4: action and options. 5: name of output file
+
+# Actions:
+# objdump: Apply objdump options on result. Compare with regex (last arg).
+# nm: Apply nm options on result. Compare with regex (last arg).
+# readelf: Apply readelf options on result. Compare with regex (last arg).
+
+set x86_64tests {
+ {"TLS -fpic -shared transitions" "-shared -melf_x86_64"
+ "--64" {tlspic1.s tlspic2.s}
+ {{readelf -WSsrl tlspic.rd} {objdump -drj.text tlspic.dd}
+ {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
+ "libtlspic.so"}
+ {"Helper shared library" "-shared -melf_x86_64"
+ "--64" {tlslib.s} {} "libtlslib.so"}
+ {"TLS -fpic and -fno-pic exec transitions"
+ "-melf_x86_64 tmpdir/libtlslib.so" "--64" {tlsbinpic.s tlsbin.s}
+ {{readelf -WSsrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
+ {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
+ "tlsbin"}
+}
+
+run_ld_link_tests $x86_64tests
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 356819f..c70cf5b 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -961,6 +961,136 @@ proc file_contents { filename } {
return $contents
}
+# List contains test-items with 3 items followed by 2 lists:
+# 0:name 1:ld options 2:assembler options
+# 3:filenames of assembler files 4: action and options. 5: name of output file
+
+# Actions:
+# objdump: Apply objdump options on result. Compare with regex (last arg).
+# nm: Apply nm options on result. Compare with regex (last arg).
+# readelf: Apply readelf options on result. Compare with regex (last arg).
+
+proc run_ld_link_tests { ldtests } {
+ global ld
+ global as
+ global nm
+ global objdump
+ global READELF
+ global srcdir
+ global subdir
+ global env
+
+ foreach testitem $ldtests {
+ set testname [lindex $testitem 0]
+ set ld_options [lindex $testitem 1]
+ set as_options [lindex $testitem 2]
+ set as_files [lindex $testitem 3]
+ set actions [lindex $testitem 4]
+ set binfile tmpdir/[lindex $testitem 5]
+ set objfiles {}
+ set is_unresolved 0
+ set failed 0
+
+# verbose -log "Testname is $testname"
+# verbose -log "ld_options is $ld_options"
+# verbose -log "as_options is $as_options"
+# verbose -log "as_files is $as_files"
+# verbose -log "actions is $actions"
+# verbose -log "binfile is $binfile"
+
+ # Assemble each file in the test.
+ foreach as_file $as_files {
+ set objfile "tmpdir/[file rootname $as_file].o"
+ lappend objfiles $objfile
+
+ if ![ld_assemble $as "$as_options $srcdir/$subdir/$as_file" $objfile] {
+ set is_unresolved 1
+ break
+ }
+ }
+
+ # Catch assembler errors.
+ if { $is_unresolved != 0 } {
+ unresolved $testname
+ continue
+ }
+
+ if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
+ fail $testname
+ } else {
+ set failed 0
+ foreach actionlist $actions {
+ set action [lindex $actionlist 0]
+ set progopts [lindex $actionlist 1]
+
+ # There are actions where we run regexp_diff on the
+ # output, and there are other actions (presumably).
+ # Handling of the former look the same.
+ set dump_prog ""
+ switch -- $action {
+ objdump
+ { set dump_prog $objdump }
+ nm
+ { set dump_prog $nm }
+ readelf
+ { set dump_prog $READELF }
+ default
+ {
+ perror "Unrecognized action $action"
+ set is_unresolved 1
+ break
+ }
+ }
+
+ if { $dump_prog != "" } {
+ set dumpfile [lindex $actionlist 2]
+ set binary $dump_prog
+
+ # Ensure consistent sorting of symbols
+ if {[info exists env(LC_ALL)]} {
+ set old_lc_all $env(LC_ALL)
+ }
+ set env(LC_ALL) "C"
+ set cmd "$binary $progopts $binfile > dump.out"
+ send_log "$cmd\n"
+ catch "exec $cmd" comp_output
+ if {[info exists old_lc_all]} {
+ set env(LC_ALL) $old_lc_all
+ } else {
+ unset env(LC_ALL)
+ }
+ set comp_output [prune_warnings $comp_output]
+
+ if ![string match "" $comp_output] then {
+ send_log "$comp_output\n"
+ set failed 1
+ break
+ }
+
+ if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
+ verbose "output is [file_contents "dump.out"]" 2
+ set failed 1
+ break
+ }
+ }
+ }
+
+ if { $failed != 0 } {
+ fail $testname
+ } else { if { $is_unresolved == 0 } {
+ pass $testname
+ } }
+ }
+
+ # Catch action errors.
+ if { $is_unresolved != 0 } {
+ unresolved $testname
+ continue
+ }
+ }
+}
+
+
proc verbose_eval { expr { level 1 } } {
global verbose
if $verbose>$level then { eval verbose "$expr" $level }