aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/ChangeLog17
-rw-r--r--gold/arm.cc5
-rw-r--r--gold/reloc.h23
-rw-r--r--gold/target-reloc.h7
-rw-r--r--gold/testsuite/Makefile.am10
-rw-r--r--gold/testsuite/Makefile.in8
-rwxr-xr-xgold/testsuite/arm_unaligned_reloc.sh7
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