summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2013-11-01 19:25:56 +1030
committerAlan Modra <amodra@gmail.com>2013-11-04 10:21:32 +1030
commit52a82034ac9a288d2d8e60efa880623288b5d228 (patch)
treea1563eb868c979d4a8885798d64a36a9f7bb187a
parenta345bc8d317a159e3e887632d80c5a8282d34f07 (diff)
downloadbinutils-gdb-52a82034ac9a288d2d8e60efa880623288b5d228.tar.gz
Edit ELFv2 global entry prologue to non-PIC
Changing addis r2,r12,..; addi r2,r2,.. to lis r2,..; addi r2,r2.. in non-PIC executables has the benefit of removing a dependency on r12. bfd/ * elf64-ppc.c (ppc64_elf_relocate_section): Edit global entry prologue to non-PIC in non-PIC executables. ld/testsuite/ * ld-powerpc/elfv2exe.d: Adjust for non-PIC global entry.
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf64-ppc.c33
-rw-r--r--ld/testsuite/ChangeLog4
-rw-r--r--ld/testsuite/ld-powerpc/elfv2exe.d4
4 files changed, 44 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bbba087a187..99d8d0923f4 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,10 @@
2013-11-04 Alan Modra <amodra@gmail.com>
+ * elf64-ppc.c (ppc64_elf_relocate_section): Edit global entry
+ prologue to non-PIC in non-PIC executables.
+
+2013-11-04 Alan Modra <amodra@gmail.com>
+
* elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Copy
pointer_equality_needed flag.
(ppc64_elf_check_relocs): For ELFv2 arrange to emit plt
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index f9177a7f122..249b6f3e399 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -13486,6 +13486,39 @@ ppc64_elf_relocate_section (bfd *output_bfd,
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
}
break;
+
+ case R_PPC64_REL16_HA:
+ /* If we are generating a non-PIC executable, edit
+ . 0: addis 2,12,.TOC.-0b@ha
+ . addi 2,2,.TOC.-0b@l
+ used by ELFv2 global entry points to set up r2, to
+ . lis 2,.TOC.@ha
+ . addi 2,2,.TOC.@l
+ if .TOC. is in range. */
+ if (!info->shared
+ && h != NULL && &h->elf == htab->elf.hgot
+ && rel + 1 < relend
+ && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)
+ && rel[1].r_offset == rel->r_offset + 4
+ && rel[1].r_addend == rel->r_addend + 4
+ && relocation + 0x80008000 <= 0xffffffff)
+ {
+ unsigned int insn1, insn2;
+ bfd_vma offset = rel->r_offset - d_offset;
+ insn1 = bfd_get_32 (output_bfd, contents + offset);
+ insn2 = bfd_get_32 (output_bfd, contents + offset + 4);
+ if ((insn1 & 0xffff0000) == 0x3c4c0000 /* addis 2,12 */
+ && (insn2 & 0xffff0000) == 0x38420000 /* addi 2,2 */)
+ {
+ r_type = R_PPC64_ADDR16_HA;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ rel->r_addend -= d_offset;
+ rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_ADDR16_LO);
+ rel[1].r_addend -= d_offset + 4;
+ bfd_put_32 (output_bfd, 0x3c400000, contents + offset);
+ }
+ }
+ break;
}
/* Handle other relocations that tweak non-addend part of insn. */
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 01175a53921..38192f2169a 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2013-11-04 Alan Modra <amodra@gmail.com>
+ * ld-powerpc/elfv2exe.d: Adjust for non-PIC global entry.
+
+2013-11-04 Alan Modra <amodra@gmail.com>
+
* ld-elfvers/vers24.rd: Allow extra readelf output after
symbol visibility.
* ld-ifunc/ifunc.exp: Likewise.
diff --git a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d
index 50d46851312..7ff9d389113 100644
--- a/ld/testsuite/ld-powerpc/elfv2exe.d
+++ b/ld/testsuite/ld-powerpc/elfv2exe.d
@@ -20,8 +20,8 @@ Disassembly of section \.text:
.*: (20 04 80 4e|4e 80 04 20) bctr
0+100000e0 <_start>:
-.*: (02 00 4c 3c|3c 4c 00 02) addis r2,r12,2
-.*: (60 80 42 38|38 42 80 60) addi r2,r2,-32672
+.*: (02 10 40 3c|3c 40 10 02) lis r2,4098
+.*: (40 81 42 38|38 42 81 40) addi r2,r2,-32448
.*: (a6 02 08 7c|7c 08 02 a6) mflr r0
.*: (e1 ff 21 f8|f8 21 ff e1) stdu r1,-32\(r1\)
.*: (30 00 01 f8|f8 01 00 30) std r0,48\(r1\)