From 392c5a61c579abdfa07c36a756ca264137f0ef9d Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 29 Jan 2010 15:46:43 +0000 Subject: [PATCH] * 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. --- gold/ChangeLog | 21 ++++++++ gold/arm.cc | 160 +++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 147 insertions(+), 34 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 633e9e4a9..0890040ca 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,24 @@ +2010-01-29 Viktor Kutuzov + + * 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 * arm.cc: Added support for ARM group relocations. diff --git a/gold/arm.cc b/gold/arm.cc index 3fe897e00..6c7a011fd 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -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(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(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(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(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::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::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::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::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: -- 2.11.4.GIT