Index: gold/arm.cc =================================================================== RCS file: /cvs/src/src/gold/arm.cc,v retrieving revision 1.140 diff -u -u -p -r1.140 arm.cc --- gold/arm.cc 3 Nov 2011 03:38:34 -0000 1.140 +++ gold/arm.cc 9 Nov 2011 23:19:09 -0000 @@ -2075,7 +2075,8 @@ class Arm_scan_relocatable_relocs : case elfcpp::R_ARM_TARGET1: case elfcpp::R_ARM_TARGET2: gold_unreachable(); - // Relocations that write full 32 bits. + // Relocations that write full 32 bits and + // have alignment of 1. case elfcpp::R_ARM_ABS32: case elfcpp::R_ARM_REL32: case elfcpp::R_ARM_SBREL32: @@ -2093,7 +2094,7 @@ class Arm_scan_relocatable_relocs : case elfcpp::R_ARM_TLS_LDO32: case elfcpp::R_ARM_TLS_IE32: case elfcpp::R_ARM_TLS_LE32: - return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4; + return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED; default: // For all other static relocations, return RELOC_SPECIAL. return Relocatable_relocs::RELOC_SPECIAL; Index: gold/reloc.h =================================================================== RCS file: /cvs/src/src/gold/reloc.h,v retrieving revision 1.31 diff -u -u -p -r1.31 reloc.h --- gold/reloc.h 24 May 2011 21:41:10 -0000 1.31 +++ gold/reloc.h 9 Nov 2011 23:19:09 -0000 @@ -247,6 +247,8 @@ class Relocatable_relocs RELOC_ADJUST_FOR_SECTION_2, RELOC_ADJUST_FOR_SECTION_4, RELOC_ADJUST_FOR_SECTION_8, + // Like RELOC_ADJUST_FOR_SECTION_4 but for unaligned relocs. + RELOC_ADJUST_FOR_SECTION_4_UNALIGNED, // Discard the input reloc--process it completely when relocating // the data section contents. RELOC_DISCARD, @@ -347,6 +349,20 @@ private: elfcpp::Swap::writeval(wv, x); } + // Like the above but for relocs at unaligned addresses. + template + static inline void + rel_unaligned(unsigned char* view, + const Sized_relobj_file* object, + const Symbol_value* psymval) + { + typedef typename elfcpp::Swap_unaligned::Valtype + Valtype; + Valtype x = elfcpp::Swap_unaligned::readval(view); + x = psymval->value(object, x); + elfcpp::Swap_unaligned::writeval(view, x); + } + // Do a simple relocation with the addend in the relocation. // VALSIZE is the size of the value. template @@ -558,6 +574,13 @@ public: const Symbol_value* psymval) { This::template rel<32>(view, object, psymval); } + // Like above but for relocs at unaligned addresses. + static inline void + rel32_unaligned(unsigned char* view, + const Sized_relobj_file* object, + const Symbol_value* psymval) + { This::template rel_unaligned<32>(view, object, psymval); } + // Do an 32-bit RELA relocation with the addend in the relocation. static inline void rela32(unsigned char* view, elfcpp::Elf_Word value, elfcpp::Elf_Word addend) Index: gold/target-reloc.h =================================================================== RCS file: /cvs/src/src/gold/target-reloc.h,v retrieving revision 1.50 diff -u -u -p -r1.50 target-reloc.h --- gold/target-reloc.h 11 Jul 2011 16:19:51 -0000 1.50 +++ gold/target-reloc.h 9 Nov 2011 23:19:09 -0000 @@ -669,6 +669,7 @@ relocate_for_relocatable( case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2: case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4: case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8: + case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED: { // We are adjusting a section symbol. We need to find // the symbol table index of the section symbol for @@ -790,6 +791,12 @@ relocate_for_relocatable( psymval); break; + case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED: + Relocate_functions::rel32_unaligned(padd, + object, + psymval); + break; + default: gold_unreachable(); } Index: gold/testsuite/Makefile.am =================================================================== RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v retrieving revision 1.185 diff -u -u -p -r1.185 Makefile.am --- gold/testsuite/Makefile.am 3 Nov 2011 03:38:34 -0000 1.185 +++ gold/testsuite/Makefile.am 9 Nov 2011 23:19:09 -0000 @@ -2521,18 +2521,24 @@ pr12826_2.o: pr12826_2.s $(TEST_AS) -o $@ $< check_SCRIPTS += arm_unaligned_reloc.sh -check_DATA += arm_unaligned_reloc.stdout +check_DATA += arm_unaligned_reloc.stdout arm_unaligned_reloc_r.stdout arm_unaligned_reloc.stdout: arm_unaligned_reloc $(TEST_OBJDUMP) -D $< > $@ +arm_unaligned_reloc_r.stdout: arm_unaligned_reloc_r + $(TEST_OBJDUMP) -Dr $< > $@ + arm_unaligned_reloc: arm_unaligned_reloc.o ../ld-new ../ld-new -o $@ $< +arm_unaligned_reloc_r: arm_unaligned_reloc.o ../ld-new + ../ld-new -r -o $@ $< + arm_unaligned_reloc.o: arm_unaligned_reloc.s $(TEST_AS) -o $@ $< -MOSTLYCLEANFILES += arm_unaligned_reloc +MOSTLYCLEANFILES += arm_unaligned_reloc arm_unaligned_reloc_r # Check ARM to ARM farcall veneers Index: gold/testsuite/arm_unaligned_reloc.sh =================================================================== RCS file: /cvs/src/src/gold/testsuite/arm_unaligned_reloc.sh,v retrieving revision 1.1 diff -u -u -p -r1.1 arm_unaligned_reloc.sh --- gold/testsuite/arm_unaligned_reloc.sh 6 Jul 2011 17:58:42 -0000 1.1 +++ gold/testsuite/arm_unaligned_reloc.sh 9 Nov 2011 23:19:09 -0000 @@ -47,4 +47,11 @@ check arm_unaligned_reloc.stdout "^ a check arm_unaligned_reloc.stdout "^0000a009 :" check arm_unaligned_reloc.stdout "^ a009: 00009000 .*$" +check arm_unaligned_reloc_r.stdout "^ 1: 00000000 .*$" +check arm_unaligned_reloc_r.stdout "^[ ]*1: R_ARM_ABS32 .data.0$" +check arm_unaligned_reloc_r.stdout "^ 5: 00000000 .*$" +check arm_unaligned_reloc_r.stdout "^[ ]*5: R_ARM_REL32 .data.0$" +check arm_unaligned_reloc_r.stdout "^ 9: 00000000 .*$" +check arm_unaligned_reloc_r.stdout "^[ ]*9: R_ARM_ABS16 .data.0$" + exit 0