Aligned vs. unaligned ppc32 relocs
authorAlan Modra <amodra@gmail.com>
Wed, 14 Aug 2019 07:01:05 +0000 (16:31 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 16 Aug 2019 04:07:54 +0000 (13:37 +0930)
Given R_PPC_ADDR32 or R_PPC_UADDR32 relocs, this patch generates
R_PPC_ADDR32 or R_PPC_UADDR32 dynamic relocs from either type
depending on whether r_offset is 4-byte aligned, and similarly for
R_PPC_ADDR16/R_PPC_UADDR16.

* elf32-ppc.c (ppc_elf_relocate_section): Optimize unaligned relocs.

bfd/ChangeLog
bfd/elf32-ppc.c

index 8e63c9b8f9d077aae4ac8ea2c84ea7e6780d92d6..5c3efb94c887f2f6be208a13912338035471c41e 100644 (file)
@@ -1,3 +1,7 @@
+2019-08-16  Alan Modra  <amodra@gmail.com>
+
+       * elf32-ppc.c (ppc_elf_relocate_section): Optimize unaligned relocs.
+
 2019-08-15  Jim Wilson  <jimw@sifive.com>
 
        * elfnn-riscv.c (perform_relocation) <R_RISCV_RVC_LUI>: If
index e683590f417801cb6ea6d60aca4beb07e41e7b0e..78d39efe48c2304574458a8fc04ea6fc511f7de4 100644 (file)
@@ -8157,6 +8157,14 @@ ppc_elf_relocate_section (bfd *output_bfd,
              outrel.r_offset += (input_section->output_section->vma
                                  + input_section->output_offset);
 
+             /* Optimize unaligned reloc use.  */
+             if ((r_type == R_PPC_ADDR32 && (outrel.r_offset & 3) != 0)
+                 || (r_type == R_PPC_UADDR32 && (outrel.r_offset & 3) == 0))
+               r_type ^= R_PPC_ADDR32 ^ R_PPC_UADDR32;
+             if ((r_type == R_PPC_ADDR16 && (outrel.r_offset & 1) != 0)
+                 || (r_type == R_PPC_UADDR16 && (outrel.r_offset & 1) == 0))
+               r_type ^= R_PPC_ADDR16 ^ R_PPC_UADDR16;
+
              if (skip)
                memset (&outrel, 0, sizeof outrel);
              else if (!SYMBOL_REFERENCES_LOCAL (info, h))