You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
2.1 KiB
60 lines
2.1 KiB
6 years ago
|
commit 52a82034ac9a288d2d8e60efa880623288b5d228
|
||
|
Author: Alan Modra <amodra@gmail.com>
|
||
|
Date: Fri Nov 1 19:25:56 2013 +1030
|
||
|
|
||
|
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.
|
||
|
|
||
|
Index: gdb-7.6.1/bfd/elf64-ppc.c
|
||
|
===================================================================
|
||
|
--- gdb-7.6.1.orig/bfd/elf64-ppc.c
|
||
|
+++ gdb-7.6.1/bfd/elf64-ppc.c
|
||
|
@@ -13280,6 +13280,39 @@ ppc64_elf_relocate_section (bfd *output_
|
||
|
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. */
|