+2015-01-29 Alan Modra <amodra@gmail.com>
+
+ * 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.
+
2015-01-28 Alan Modra <amodra@gmail.com>
* elf64-ppc.h (struct ppc64_elf_params): Add "object_in_toc".
+ R_PPC_GOT_TPREL16);
else
{
- bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
rel->r_offset -= d_offset;
+ bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
r_type = R_PPC_NONE;
}
rel->r_info = ELF32_R_INFO (r_symndx, r_type);
&& branch_reloc_hash_match (input_bfd, rel + 1,
htab->tls_get_addr))
offset = rel[1].r_offset;
+ /* We read the low GOT_TLS insn because we need to keep
+ the destination reg. It may be something other than
+ the usual r3, and moved to r3 before the call by
+ intervening code. */
+ insn1 = bfd_get_32 (output_bfd,
+ contents + rel->r_offset - d_offset);
if ((tls_mask & tls_gd) != 0)
{
/* IE */
- insn1 = bfd_get_32 (output_bfd,
- contents + rel->r_offset - d_offset);
- insn1 &= (1 << 26) - 1;
+ insn1 &= (0x1f << 21) | (0x1f << 16);
insn1 |= 32 << 26; /* lwz */
if (offset != (bfd_vma) -1)
{
else
{
/* LE */
- insn1 = 0x3c620000; /* addis 3,2,0 */
+ insn1 &= 0x1f << 21;
+ insn1 |= 0x3c020000; /* addis r,2,0 */
if (tls_gd == 0)
{
/* Was an LD reloc. */
htab->tls_get_addr,
htab->tls_get_addr_fd))
offset = rel[1].r_offset;
+ /* We read the low GOT_TLS (or TOC16) insn because we
+ need to keep the destination reg. It may be
+ something other than the usual r3, and moved to r3
+ before the call by intervening code. */
+ insn1 = bfd_get_32 (output_bfd,
+ contents + rel->r_offset - d_offset);
if ((tls_mask & tls_gd) != 0)
{
/* IE */
- insn1 = bfd_get_32 (output_bfd,
- contents + rel->r_offset - d_offset);
- insn1 &= (1 << 26) - (1 << 2);
+ insn1 &= (0x1f << 21) | (0x1f << 16);
insn1 |= 58 << 26; /* ld */
insn2 = 0x7c636a14; /* add 3,3,13 */
if (offset != (bfd_vma) -1)
else
{
/* LE */
- insn1 = 0x3c6d0000; /* addis 3,13,0 */
+ insn1 &= 0x1f << 21;
+ insn1 |= 0x3c0d0000; /* addis r,13,0 */
insn2 = 0x38630000; /* addi 3,3,0 */
if (tls_gd == 0)
{
+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
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
}
run_dump_test "attr-gnu-12-21"
run_dump_test "vle-multiseg-6"
-run_dump_test "tocvar"
-run_dump_test "tocnovar"
--- /dev/null
+#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
--- /dev/null
+ .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
--- /dev/null
+#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
--- /dev/null
+ .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