2011-11-09 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Thu, 10 Nov 2011 00:41:53 +0000 (00:41 +0000)
committerDoug Kwan <dougkwan@google.com>
Thu, 10 Nov 2011 00:41:53 +0000 (00:41 +0000)
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.

gold/ChangeLog
gold/arm.cc
gold/reloc.h
gold/target-reloc.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/arm_unaligned_reloc.sh

index aac3aa0f49542b6caf7d295f951c976569952d76..f3707ae910749d27faa2ead73260fde392bc367a 100644 (file)
@@ -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
index 200c371310118b79a26c008e6d8f4ba1c19371a2..a17469b2c9f255bd3a55e4eb41956b128eb7289e 100644 (file)
@@ -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 3a33c9b01ba40bd60a8e1cfdfa61056debc2ef64..fefcb3f1e2841a0f38ca54e149d9de38ee163d54 100644 (file)
@@ -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)
index 832c5d6db7dafeec8be16b57ded273cb785e2256..464a3fa896c643eccc994ef40c928d606ff07cf0 100644 (file)
@@ -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();
            }
index 47058e92a2143dd7b0e41f9ae7fa7f4db1e0829e..794dac8fc28a9789199fe5b68befdb87c7b23c48 100644 (file)
@@ -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 f66fb8a77df3274142dd05e88e19e364da55726c..af62c8d1dd8e8715531d15652d6f92e006124565 100644 (file)
@@ -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 $@ $<
 
index 496ee280ffc628d4fbd83c626f969dbd27671f16..39a5a110c6ba5b1e187c30e6daf8912a6a374690 100755 (executable)
@@ -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