Edit ELFv2 global entry prologue to non-PIC
authorAlan Modra <amodra@gmail.com>
Fri, 1 Nov 2013 08:55:56 +0000 (19:25 +1030)
committerAlan Modra <amodra@gmail.com>
Sun, 3 Nov 2013 23:51:32 +0000 (10:21 +1030)
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.

bfd/ChangeLog
bfd/elf64-ppc.c
ld/testsuite/ChangeLog
ld/testsuite/ld-powerpc/elfv2exe.d

index bbba087a1870c79d4fbca239d694bbea82c4f153..99d8d0923f4770ce40cc89b48de7f6a8c1f99079 100644 (file)
@@ -1,3 +1,8 @@
+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
index f9177a7f1222de5f38e3d07b5620541864733e70..249b6f3e3993234f22c7a2e43faf051c531fbcc2 100644 (file)
@@ -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.  */
index 01175a5392153119375bd8e6659ee4942599e33d..38192f2169a19cbd78cb2a647fb7c89a0c699eca 100644 (file)
@@ -1,3 +1,7 @@
+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
index 50d46851312a69203014f34e2954b68c5370a8f1..7ff9d3891139bbbb95499cc938402856dd4386ba 100644 (file)
@@ -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\)