aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-01-29 11:09:55 +1030
committerAlan Modra <amodra@gmail.com>2015-01-29 13:13:02 +1030
commitb86ac8e3a5a3117696b1760003b8e09ed13f1de9 (patch)
tree62ef24abc3d0ef13113729ea6f1ae626e556e4af /ld
parent912ae7dd0fa4658133d4fb77954a57c8548c37d6 (diff)
downloadgdb-b86ac8e3a5a3117696b1760003b8e09ed13f1de9.zip
gdb-b86ac8e3a5a3117696b1760003b8e09ed13f1de9.tar.gz
gdb-b86ac8e3a5a3117696b1760003b8e09ed13f1de9.tar.bz2
Correct PowerPC64 local-dynamic TLS linker optimization
The linker hardcoded r3 into a local-dynamic to local-exec TLS optimization sequence. This is normally the case since r3 is required as a parameter to (the optimized out) __tls_get_addr call. However, it is possible for a compiler, LLVM in this case, to set up the parameter value in another register then copy it to r3 before the call. When fixing this problem, I noticed that ppc32 had another bug when optimizing away one of the TLS insns to a nop. The patch also tidies a mask used by global-dynamic to initial-exec TLS optimization, to just select the fields needed. Leaving the offset in the instruction wasn't a bug since it will be overwritten anyway. bfd/ * elf64-ppc.c (ppc64_elf_relocate_section): Correct GOT_TLSLD optimization. Tidy mask for GOT_TLSGD optimization. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. Correct location of nop zapping high insn too. ld/testsuite/ * ld-powerpc/tlsld.d, * ld-powerpc/tlsld.s: New test. * ld-powerpc/tlsld32.d, * ld-powerpc/tlsld32.s: New test. * ld-powerpc/powerpc.exp: Run them. Move tocvar and tocnovar.
Diffstat (limited to 'ld')
-rw-r--r--ld/testsuite/ChangeLog6
-rw-r--r--ld/testsuite/ld-powerpc/powerpc.exp7
-rw-r--r--ld/testsuite/ld-powerpc/tlsld.d43
-rw-r--r--ld/testsuite/ld-powerpc/tlsld.s48
-rw-r--r--ld/testsuite/ld-powerpc/tlsld32.d44
-rw-r--r--ld/testsuite/ld-powerpc/tlsld32.s43
6 files changed, 189 insertions, 2 deletions
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index c5effcd..d05b762 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-29 Alan Modra <amodra@gmail.com>
+
+ * ld-powerpc/tlsld.d, * ld-powerpc/tlsld.s: New test.
+ * ld-powerpc/tlsld32.d, * ld-powerpc/tlsld32.s: New test.
+ * ld-powerpc/powerpc.exp: Run them. Move tocvar and tocnovar.
+
2015-01-28 H.J. Lu <hongjiu.lu@intel.com>
PR ld/17878
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 81cc310..48aec4a 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -282,8 +282,13 @@ if [ supports_ppc64 ] then {
run_dump_test "ambiguousv2"
run_dump_test "ambiguousv2b"
run_dump_test "defsym"
+ run_dump_test "tocvar"
+ run_dump_test "tocnovar"
+ run_dump_test "tlsld"
}
+run_dump_test "tlsld32"
+
if { [istarget "powerpc*-eabi*"] } {
run_ld_link_tests $ppceabitests
}
@@ -320,5 +325,3 @@ run_dump_test "attr-gnu-12-11"
run_dump_test "attr-gnu-12-21"
run_dump_test "vle-multiseg-6"
-run_dump_test "tocvar"
-run_dump_test "tocnovar"
diff --git a/ld/testsuite/ld-powerpc/tlsld.d b/ld/testsuite/ld-powerpc/tlsld.d
new file mode 100644
index 0000000..d66d1db
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tlsld.d
@@ -0,0 +1,43 @@
+#source: tlsld.s
+#as: -a64
+#ld: -melf64ppc
+#objdump: -dr
+#target: powerpc64*-*-*
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+.*:
+.* nop
+.* addis r29,r13,0
+.* mr r3,r29
+.* nop
+.* addi r3,r3,4096
+.* addis r3,r3,0
+.* ld r3,-32768\(r3\)
+.* nop
+.* addis r29,r13,0
+.* mr r3,r29
+.* nop
+.* addi r3,r3,4096
+.* ld r3,-32768\(r3\)
+.* nop
+.* nop
+.* nop
+.* nop
+.* addis r29,r13,0
+.* mr r3,r29
+.* nop
+.* addi r3,r3,-28672
+.* ld r3,0\(r3\)
+.* nop
+.* nop
+.* addis r29,r13,0
+.* mr r3,r29
+.* nop
+.* addi r3,r3,-28672
+.* ld r3,0\(r3\)
+.* nop
+.* nop
+.* nop
diff --git a/ld/testsuite/ld-powerpc/tlsld.s b/ld/testsuite/ld-powerpc/tlsld.s
new file mode 100644
index 0000000..925d8bf
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tlsld.s
@@ -0,0 +1,48 @@
+ .section ".opd","aw",@progbits
+ .p2align 3
+ .globl _start
+_start:
+ .quad .L_start,.TOC.@tocbase,0
+
+ .text
+.L_start:
+ addis 3,2,PrettyStackTraceHead@got@tlsld@ha
+ addi 29,3,PrettyStackTraceHead@got@tlsld@l
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsld)
+ nop
+ addis 3,3,PrettyStackTraceHead@dtprel@ha
+ ld 3,PrettyStackTraceHead@dtprel@l(3)
+ nop
+
+ addi 29,2,PrettyStackTraceHead@got@tlsld
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsld)
+ nop
+ ld 3,PrettyStackTraceHead@dtprel(3)
+ nop
+ nop
+ nop
+
+ addis 3,2,PrettyStackTraceHead@got@tlsgd@ha
+ addi 29,3,PrettyStackTraceHead@got@tlsgd@l
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsgd)
+ nop
+ ld 3,0(3)
+ nop
+ nop
+
+ addi 29,2,PrettyStackTraceHead@got@tlsgd
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsgd)
+ nop
+ ld 3,0(3)
+ nop
+ nop
+ nop
+
+ .section ".tbss","awT",@nobits
+ .align 3
+PrettyStackTraceHead:
+ .space 8
diff --git a/ld/testsuite/ld-powerpc/tlsld32.d b/ld/testsuite/ld-powerpc/tlsld32.d
new file mode 100644
index 0000000..b0fd657
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tlsld32.d
@@ -0,0 +1,44 @@
+#source: tlsld32.s
+#as: -a32
+#ld: -melf32ppc
+#objdump: -dr
+#target: powerpc*-*-*
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+.*:
+.* nop
+.* addis r29,r2,0
+.* mr r3,r29
+.* addi r3,r3,4096
+.* addis r3,r3,0
+.* lwz r3,-32768\(r3\)
+.* nop
+.* nop
+.* addis r29,r2,0
+.* mr r3,r29
+.* addi r3,r3,4096
+.* lwz r3,-32768\(r3\)
+.* nop
+.* nop
+.* nop
+.* nop
+.* nop
+.* addis r29,r2,0
+.* mr r3,r29
+.* addi r3,r3,-28672
+.* lwz r3,0\(r3\)
+.* nop
+.* nop
+.* nop
+.* addis r29,r2,0
+.* mr r3,r29
+.* addi r3,r3,-28672
+.* lwz r3,0\(r3\)
+.* nop
+.* nop
+.* nop
+.* nop
+#pass
diff --git a/ld/testsuite/ld-powerpc/tlsld32.s b/ld/testsuite/ld-powerpc/tlsld32.s
new file mode 100644
index 0000000..f5561d4
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tlsld32.s
@@ -0,0 +1,43 @@
+ .text
+ .globl _start
+_start:
+ addis 3,31,PrettyStackTraceHead@got@tlsld@ha
+ addi 29,3,PrettyStackTraceHead@got@tlsld@l
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsld)
+ addis 3,3,PrettyStackTraceHead@dtprel@ha
+ lwz 3,PrettyStackTraceHead@dtprel@l(3)
+ nop
+ nop
+
+ addi 29,31,PrettyStackTraceHead@got@tlsld
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsld)
+ lwz 3,PrettyStackTraceHead@dtprel(3)
+ nop
+ nop
+ nop
+ nop
+
+ addis 3,31,PrettyStackTraceHead@got@tlsgd@ha
+ addi 29,3,PrettyStackTraceHead@got@tlsgd@l
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsgd)
+ lwz 3,0(3)
+ nop
+ nop
+ nop
+
+ addi 29,31,PrettyStackTraceHead@got@tlsgd
+ mr 3,29
+ bl __tls_get_addr(PrettyStackTraceHead@tlsgd)
+ lwz 3,0(3)
+ nop
+ nop
+ nop
+ nop
+
+ .section ".tbss","awT",@nobits
+ .align 2
+PrettyStackTraceHead:
+ .space 4