* arm.cc: Added support for the ARM relocations:
authorIan Lance Taylor <ian@airs.com>
Fri, 29 Jan 2010 15:46:43 +0000 (15:46 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 29 Jan 2010 15:46:43 +0000 (15:46 +0000)
R_ARM_MOVW_BREL_NC, R_ARM_MOVT_BREL, R_ARM_MOVW_BREL,
R_ARM_THM_MOVW_BREL_NC, R_ARM_THM_MOVT_BREL, R_ARM_THM_MOVW_BREL.
(Arm_relocate_functions::movw_rel_nc): Renamed (was
movw_prel_nc).
(Arm_relocate_functions::movw_rel): New method.
(Arm_relocate_functions::movt_rel): Renamed (was movt_prel).
(Arm_relocate_functions::thm_movw_rel_nc): Renamed (was
thm_movw_prel_nc).
(Arm_relocate_functions::thm_movw_rel): New method.
(Arm_relocate_functions::thm_movt_rel): Renamed (was
thm_movt_prel).
(Target_arm::Scan::local): Handle MOVW_BREL/MOVT_BREL
relocations.
(Target_arm::Scan::global): Likewise.
(Target_arm::Relocate::relocate): Likewise.
(Target_arm::Relocatable_size_for_reloc::get_size_for_reloc):
Likewise.

gold/ChangeLog
gold/arm.cc

index 633e9e4a91cb8962292ea15310f0dd5fc1b04e1f..0890040ca9c0905660338100a6794ba468cbe7e6 100644 (file)
@@ -1,3 +1,24 @@
+2010-01-29  Viktor Kutuzov  <vkutuzov@accesssoftek.com>
+
+       * arm.cc: Added support for the ARM relocations:
+       R_ARM_MOVW_BREL_NC, R_ARM_MOVT_BREL, R_ARM_MOVW_BREL,
+       R_ARM_THM_MOVW_BREL_NC, R_ARM_THM_MOVT_BREL, R_ARM_THM_MOVW_BREL.
+       (Arm_relocate_functions::movw_rel_nc): Renamed (was
+       movw_prel_nc).
+       (Arm_relocate_functions::movw_rel): New method.
+       (Arm_relocate_functions::movt_rel): Renamed (was movt_prel).
+       (Arm_relocate_functions::thm_movw_rel_nc): Renamed (was
+       thm_movw_prel_nc).
+       (Arm_relocate_functions::thm_movw_rel): New method.
+       (Arm_relocate_functions::thm_movt_rel): Renamed (was
+       thm_movt_prel).
+       (Target_arm::Scan::local): Handle MOVW_BREL/MOVT_BREL
+       relocations.
+       (Target_arm::Scan::global): Likewise.
+       (Target_arm::Relocate::relocate): Likewise.
+       (Target_arm::Relocatable_size_for_reloc::get_size_for_reloc):
+       Likewise.
+
 2010-01-27  Viktor Kutuzov  <vkutuzov@accesssoftek.com>
 
        * arm.cc: Added support for ARM group relocations.
index 3fe897e0024e1fd51757f62320c28c74fb640195..6c7a011fd2f5448e5315a3fd59253e0eef0b695d 100644 (file)
@@ -109,12 +109,6 @@ const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4);
 //     R_ARM_THM_ALU_PREL_11_0
 //     R_ARM_THM_PC12
 //     R_ARM_REL32_NOI
-//     R_ARM_MOVW_BREL_NC
-//     R_ARM_MOVT_BREL
-//     R_ARM_MOVW_BREL
-//     R_ARM_THM_MOVW_BREL_NC
-//     R_ARM_THM_MOVT_BREL
-//     R_ARM_THM_MOVW_BREL
 //     R_ARM_PLT32_ABS
 //     R_ARM_GOT_ABS
 //     R_ARM_GOT_BREL12
@@ -3155,12 +3149,13 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
   }
 
   // R_ARM_MOVW_PREL_NC: (S + A) | T - P
+  // R_ARM_MOVW_BREL_NC: ((S + A) | T) – B(S)
   static inline typename This::Status
-  movw_prel_nc(unsigned char *view,
-              const Sized_relobj<32, big_endian>* object,
-              const Symbol_value<32>* psymval,
-              Arm_address address,
-              Arm_address thumb_bit)
+  movw_rel_nc(unsigned char* view,
+             const Sized_relobj<32, big_endian>* object,
+             const Symbol_value<32>* psymval,
+             Arm_address address,
+             Arm_address thumb_bit)
   {
     typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
@@ -3172,12 +3167,32 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
     return This::STATUS_OKAY;
   }
 
+  // R_ARM_MOVW_BREL: ((S + A) | T) – B(S)
+  static inline typename This::Status
+  movw_rel(unsigned char* view,
+          const Sized_relobj<32, big_endian>* object,
+          const Symbol_value<32>* psymval,
+          Arm_address address,
+          Arm_address thumb_bit)
+  {
+    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
+    Valtype* wv = reinterpret_cast<Valtype*>(view);
+    Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
+    Valtype addend = This::extract_arm_movw_movt_addend(val);
+    Valtype x = (psymval->value(object, addend) | thumb_bit) - address;
+    val = This::insert_val_arm_movw_movt(val, x);
+    elfcpp::Swap<32, big_endian>::writeval(wv, val);
+    return ((x >= 0x10000) ?
+           This::STATUS_OVERFLOW : This::STATUS_OKAY);
+  }
+
   // R_ARM_MOVT_PREL: S + A - P
+  // R_ARM_MOVT_BREL: S + A – B(S)
   static inline typename This::Status
-  movt_prel(unsigned char *view,
-           const Sized_relobj<32, big_endian>* object,
-           const Symbol_value<32>* psymval,
-            Arm_address address)
+  movt_rel(unsigned char* view,
+          const Sized_relobj<32, big_endian>* object,
+          const Symbol_value<32>* psymval,
+           Arm_address address)
   {
     typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
@@ -3190,12 +3205,13 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
   }
 
   // R_ARM_THM_MOVW_PREL_NC: (S + A) | T - P
+  // R_ARM_THM_MOVW_BREL_NC: ((S + A) | T) – B(S)
   static inline typename This::Status
-  thm_movw_prel_nc(unsigned char *view,
-                  const Sized_relobj<32, big_endian>* object,
-                  const Symbol_value<32>* psymval,
-                  Arm_address address,
-                  Arm_address thumb_bit)
+  thm_movw_rel_nc(unsigned char *view,
+                 const Sized_relobj<32, big_endian>* object,
+                 const Symbol_value<32>* psymval,
+                 Arm_address address,
+                 Arm_address thumb_bit)
   {
     typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
     typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
@@ -3210,12 +3226,35 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
     return This::STATUS_OKAY;
   }
 
+  // R_ARM_THM_MOVW_BREL: ((S + A) | T) – B(S)
+  static inline typename This::Status
+  thm_movw_rel(unsigned char *view,
+              const Sized_relobj<32, big_endian>* object,
+              const Symbol_value<32>* psymval,
+              Arm_address address,
+              Arm_address thumb_bit)
+  {
+    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
+    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
+    Valtype* wv = reinterpret_cast<Valtype*>(view);
+    Reltype val = (elfcpp::Swap<16, big_endian>::readval(wv) << 16)
+                 | elfcpp::Swap<16, big_endian>::readval(wv + 1);
+    Reltype addend = This::extract_thumb_movw_movt_addend(val);
+    Reltype x = (psymval->value(object, addend) | thumb_bit) - address;
+    val = This::insert_val_thumb_movw_movt(val, x);
+    elfcpp::Swap<16, big_endian>::writeval(wv, val >> 16);
+    elfcpp::Swap<16, big_endian>::writeval(wv + 1, val & 0xffff);
+    return ((x >= 0x10000) ?
+           This::STATUS_OVERFLOW : This::STATUS_OKAY);
+  }
+
   // R_ARM_THM_MOVT_PREL: S + A - P
+  // R_ARM_THM_MOVT_BREL: S + A – B(S)
   static inline typename This::Status
-  thm_movt_prel(unsigned char *view,
-               const Sized_relobj<32, big_endian>* object,
-               const Symbol_value<32>* psymval,
-               Arm_address address)
+  thm_movt_rel(unsigned char* view,
+              const Sized_relobj<32, big_endian>* object,
+              const Symbol_value<32>* psymval,
+              Arm_address address)
   {
     typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
     typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
@@ -6514,6 +6553,12 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
     case elfcpp::R_ARM_MOVT_PREL:
     case elfcpp::R_ARM_THM_MOVW_PREL_NC:
     case elfcpp::R_ARM_THM_MOVT_PREL:
+    case elfcpp::R_ARM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_MOVT_BREL:
+    case elfcpp::R_ARM_MOVW_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_THM_MOVT_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL:
     case elfcpp::R_ARM_THM_JUMP6:
     case elfcpp::R_ARM_THM_JUMP8:
     case elfcpp::R_ARM_THM_JUMP11:
@@ -6674,6 +6719,12 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
     case elfcpp::R_ARM_MOVT_PREL:
     case elfcpp::R_ARM_THM_MOVW_PREL_NC:
     case elfcpp::R_ARM_THM_MOVT_PREL:
+    case elfcpp::R_ARM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_MOVT_BREL:
+    case elfcpp::R_ARM_MOVW_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_THM_MOVT_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL:
     case elfcpp::R_ARM_THM_JUMP6:
     case elfcpp::R_ARM_THM_JUMP8:
     case elfcpp::R_ARM_THM_JUMP11:
@@ -7303,27 +7354,62 @@ Target_arm<big_endian>::Relocate::relocate(
       break;
 
     case elfcpp::R_ARM_MOVW_PREL_NC:
-      reloc_status = Arm_relocate_functions::movw_prel_nc(view, object,
-                                                         psymval, address,
-                                                         thumb_bit);
+      reloc_status = Arm_relocate_functions::movw_rel_nc(view, object,
+                                                        psymval, address,
+                                                        thumb_bit);
+      break;
+
+    case elfcpp::R_ARM_MOVW_BREL_NC:
+      reloc_status = Arm_relocate_functions::movw_rel_nc(view, object,
+                                                        psymval, sym_origin,
+                                                        thumb_bit);
+      break;
+
+    case elfcpp::R_ARM_MOVW_BREL:
+      reloc_status = Arm_relocate_functions::movw_rel(view, object,
+                                                     psymval, sym_origin,
+                                                     thumb_bit);
       break;
 
     case elfcpp::R_ARM_MOVT_PREL:
-      reloc_status = Arm_relocate_functions::movt_prel(view, object,
-                                                       psymval, address);
+      reloc_status = Arm_relocate_functions::movt_rel(view, object,
+                                                      psymval, address);
+      break;
+
+    case elfcpp::R_ARM_MOVT_BREL:
+      reloc_status = Arm_relocate_functions::movt_rel(view, object,
+                                                      psymval, sym_origin);
       break;
 
     case elfcpp::R_ARM_THM_MOVW_PREL_NC:
-      reloc_status = Arm_relocate_functions::thm_movw_prel_nc(view, object,
-                                                             psymval, address,
-                                                             thumb_bit);
+      reloc_status = Arm_relocate_functions::thm_movw_rel_nc(view, object,
+                                                            psymval, address,
+                                                            thumb_bit);
+      break;
+
+    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
+      reloc_status = Arm_relocate_functions::thm_movw_rel_nc(view, object,
+                                                            psymval,
+                                                            sym_origin,
+                                                            thumb_bit);
+      break;
+
+    case elfcpp::R_ARM_THM_MOVW_BREL:
+      reloc_status = Arm_relocate_functions::thm_movw_rel(view, object,
+                                                         psymval, sym_origin,
+                                                         thumb_bit);
       break;
 
     case elfcpp::R_ARM_THM_MOVT_PREL:
-      reloc_status = Arm_relocate_functions::thm_movt_prel(view, object,
-                                                          psymval, address);
+      reloc_status = Arm_relocate_functions::thm_movt_rel(view, object,
+                                                         psymval, address);
       break;
        
+    case elfcpp::R_ARM_THM_MOVT_BREL:
+      reloc_status = Arm_relocate_functions::thm_movt_rel(view, object,
+                                                         psymval, sym_origin);
+      break;
+
     case elfcpp::R_ARM_REL32:
       reloc_status = Arm_relocate_functions::rel32(view, object, psymval,
                                                   address, thumb_bit);
@@ -7785,6 +7871,12 @@ Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
     case elfcpp::R_ARM_MOVT_PREL:
     case elfcpp::R_ARM_THM_MOVW_PREL_NC:
     case elfcpp::R_ARM_THM_MOVT_PREL:
+    case elfcpp::R_ARM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_MOVT_BREL:
+    case elfcpp::R_ARM_MOVW_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_THM_MOVT_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL:
     case elfcpp::R_ARM_V4BX:
     case elfcpp::R_ARM_ALU_PC_G0_NC:
     case elfcpp::R_ARM_ALU_PC_G0: