OSDN Git Service

* arm.cc (Arm_relocate_functions::got_prel) New function.
authorian <ian>
Wed, 7 Oct 2009 15:30:40 +0000 (15:30 +0000)
committerian <ian>
Wed, 7 Oct 2009 15:30:40 +0000 (15:30 +0000)
(Scan::local, Scan::global): Handle R_ARM_GOT_PREL.
(Relocate::relocate): Likewise.
(Relocatable_size_for_reloc::get_size_for_reloc): Likewise.

gold/ChangeLog
gold/arm.cc

index 796344c..28f76fb 100644 (file)
@@ -1,3 +1,10 @@
+2009-10-07  Viktor Kutuzov  <vkutuzov@accesssoftek.com>
+
+       * arm.cc (Arm_relocate_functions::got_prel) New function.
+       (Scan::local, Scan::global): Handle R_ARM_GOT_PREL.
+       (Relocate::relocate): Likewise.
+       (Relocatable_size_for_reloc::get_size_for_reloc): Likewise.
+
 2009-10-06  Ian Lance Taylor  <iant@google.com>
 
        * options.h (class General_options): Define
index 96bbdef..f70964c 100644 (file)
@@ -68,11 +68,13 @@ class Output_data_plt_arm;
 // R_ARM_RELATIVE
 // R_ARM_GOTOFF32
 // R_ARM_GOT_BREL
+// R_ARM_GOT_PREL
 // R_ARM_PLT32
 // R_ARM_CALL
 // R_ARM_JUMP24
 // R_ARM_TARGET1
 // R_ARM_PREL31
+// R_ARM_ABS8
 // 
 // TODOs:
 // - Generate various branch stubs.
@@ -679,6 +681,16 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
     return This::STATUS_OKAY;
   }
 
+  // R_ARM_GOT_PREL: GOT(S) + A – P
+  static inline typename This::Status
+  got_prel(unsigned char* view,
+          typename elfcpp::Swap<32, big_endian>::Valtype got_offset,
+          elfcpp::Elf_types<32>::Elf_Addr address)
+  {
+    Base::rel32(view, got_offset - address);
+    return This::STATUS_OKAY;
+  }
+
   // R_ARM_PLT32: (S + A) | T - P
   static inline typename This::Status
   plt32(unsigned char *view,
@@ -1156,6 +1168,7 @@ Target_arm<big_endian>::Scan::local(const General_options&,
       break;
 
     case elfcpp::R_ARM_GOT_BREL:
+    case elfcpp::R_ARM_GOT_PREL:
       {
        // The symbol requires a GOT entry.
        Output_data_got<32, big_endian>* got =
@@ -1351,6 +1364,7 @@ Target_arm<big_endian>::Scan::global(const General_options&,
       break;
       
     case elfcpp::R_ARM_GOT_BREL:
+    case elfcpp::R_ARM_GOT_PREL:
       {
        // The symbol requires a GOT entry.
        Output_data_got<32, big_endian>* got =
@@ -1623,6 +1637,7 @@ Target_arm<big_endian>::Relocate::relocate(
   switch (r_type)
     {
     case elfcpp::R_ARM_GOT_BREL:
+    case elfcpp::R_ARM_GOT_PREL:
       if (gsym != NULL)
        {
          gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
@@ -1708,6 +1723,18 @@ Target_arm<big_endian>::Relocate::relocate(
       reloc_status = Arm_relocate_functions::got_brel(view, got_offset);
       break;
 
+    case elfcpp::R_ARM_GOT_PREL:
+      gold_assert(have_got_offset);
+      // Get the address origin for GOT PLT, which is allocated right
+      // after the GOT section, to calculate an absolute address of
+      // the symbol GOT entry (got_origin + got_offset).
+      elfcpp::Elf_types<32>::Elf_Addr got_origin;
+      got_origin = target->got_plt_section()->address();
+      reloc_status = Arm_relocate_functions::got_prel(view,
+                                                     got_origin + got_offset,
+                                                     address);
+      break;
+
     case elfcpp::R_ARM_PLT32:
       gold_assert(gsym == NULL
                  || gsym->has_plt_offset()
@@ -1837,6 +1864,7 @@ Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
     case elfcpp::R_ARM_GOTOFF32:
     case elfcpp::R_ARM_BASE_PREL:
     case elfcpp::R_ARM_GOT_BREL:
+    case elfcpp::R_ARM_GOT_PREL:
     case elfcpp::R_ARM_PLT32:
     case elfcpp::R_ARM_CALL:
     case elfcpp::R_ARM_JUMP24: