diff options
-rw-r--r-- | gold/ChangeLog | 17 | ||||
-rw-r--r-- | gold/arm.cc | 5 | ||||
-rw-r--r-- | gold/reloc.h | 23 | ||||
-rw-r--r-- | gold/target-reloc.h | 7 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 10 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 8 | ||||
-rwxr-xr-x | gold/testsuite/arm_unaligned_reloc.sh | 7 |
7 files changed, 73 insertions, 4 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index aac3aa0..f3707ae 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,20 @@ +2011-11-09 Doug Kwan <dougkwan@google.com> + + PR gold/13362 + * arm.cc (Arm_scan_relocatable_relocs::Default_scan_relocatable_relocs): + Use unaligned 4-byte relocs for static 32-bit data as required by EABI. + * reloc.h (Relocatable_relocs::Reloc_strategy): New enum + RELOC_ADJUST_FOR_SECTION_4_UNALIGNED. + (Relocate_functions::rel_unaligned): New. + (Relocate_functions::rel32_unaligned): New. + * target-reloc.h (relocate_for_relocatable): Add code to handle + RELOC_ADJUST_FOR_SECTION_4_UNALIGNED. + * testsuite/Makefile.am (arm_unaligned_reloc_r.stdout, + arm_unaligned_reloc_r): New targets. + * testsuite/Makefile.in: Regenerate. + * arm_unaligned_reloc.sh: Check unaligned relocs in relocatable + linking. + 2011-11-02 Ian Lance Taylor <iant@google.com> * configure.ac: Add --with-lib-path option. Define LIB_PATH and diff --git a/gold/arm.cc b/gold/arm.cc index 200c371..a17469b 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -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; diff --git a/gold/reloc.h b/gold/reloc.h index 3a33c9b..fefcb3f 100644 --- a/gold/reloc.h +++ b/gold/reloc.h @@ -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<valsize, big_endian>::writeval(wv, x); } + // Like the above but for relocs at unaligned addresses. + template<int valsize> + static inline void + rel_unaligned(unsigned char* view, + const Sized_relobj_file<size, big_endian>* object, + const Symbol_value<size>* psymval) + { + typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype + Valtype; + Valtype x = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view); + x = psymval->value(object, x); + elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, x); + } + // Do a simple relocation with the addend in the relocation. // VALSIZE is the size of the value. template<int valsize> @@ -558,6 +574,13 @@ public: const Symbol_value<size>* 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<size, big_endian>* object, + const Symbol_value<size>* 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) diff --git a/gold/target-reloc.h b/gold/target-reloc.h index 832c5d6..464a3fa 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -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<size, big_endian>::rel32_unaligned(padd, + object, + psymval); + break; + default: gold_unreachable(); } diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 47058e9..794dac8 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -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 diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index f66fb8a..af62c8d 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -568,6 +568,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_exidx_test.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr12826.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_unaligned_reloc.stdout \ +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_unaligned_reloc_r.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_arm.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_thumb.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_thumb_5t.stdout \ @@ -610,6 +611,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_local \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_local_reloc \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_unaligned_reloc \ +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_unaligned_reloc_r \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_arm \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_thumb \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_thumb_5t \ @@ -5474,9 +5476,15 @@ uninstall-am: @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc.stdout: arm_unaligned_reloc @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -D $< > $@ +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc_r.stdout: arm_unaligned_reloc_r +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -Dr $< > $@ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc: arm_unaligned_reloc.o ../ld-new @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -o $@ $< +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc_r: arm_unaligned_reloc.o ../ld-new +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -r -o $@ $< + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc.o: arm_unaligned_reloc.s @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< diff --git a/gold/testsuite/arm_unaligned_reloc.sh b/gold/testsuite/arm_unaligned_reloc.sh index 496ee28..39a5a11 100755 --- a/gold/testsuite/arm_unaligned_reloc.sh +++ b/gold/testsuite/arm_unaligned_reloc.sh @@ -47,4 +47,11 @@ check arm_unaligned_reloc.stdout "^ a005: ffffeffb .*$" check arm_unaligned_reloc.stdout "^0000a009 <abs16>:" 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 |