Aligned vs. unaligned ppc32 relocs
[external/binutils.git] / bfd / elf32-ppc.c
index b1ae0de..78d39ef 100644 (file)
@@ -1705,7 +1705,7 @@ ppc_elf_write_section (bfd *abfd ATTRIBUTE_UNUSED,
 /* Finally we can generate the output section.  */
 
 static void
-ppc_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
+ppc_final_write_processing (bfd *abfd)
 {
   bfd_byte *buffer;
   asection *asec;
@@ -1757,11 +1757,11 @@ ppc_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
   apuinfo_list_finish ();
 }
 
-static void
-ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker)
+static bfd_boolean
+ppc_elf_final_write_processing (bfd *abfd)
 {
-  ppc_final_write_processing (abfd, linker);
-  _bfd_elf_final_write_processing (abfd, linker);
+  ppc_final_write_processing (abfd);
+  return _bfd_elf_final_write_processing (abfd);
 }
 \f
 static bfd_boolean
@@ -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))
@@ -10494,11 +10502,11 @@ ppc_elf_vxworks_add_symbol_hook (bfd *abfd,
   return ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp);
 }
 
-static void
-ppc_elf_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+static bfd_boolean
+ppc_elf_vxworks_final_write_processing (bfd *abfd)
 {
-  ppc_final_write_processing (abfd, linker);
-  elf_vxworks_final_write_processing (abfd, linker);
+  ppc_final_write_processing (abfd);
+  return elf_vxworks_final_write_processing (abfd);
 }
 
 /* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so