From 9b2fd367561081579a4ee270a6de58d3de910631 Mon Sep 17 00:00:00 2001 From: Doug Kwan Date: Fri, 22 Jan 2010 19:43:00 +0000 Subject: [PATCH] 2010-01-22 Viktor Kutuzov * gold/arm.cc (Target_arm): Updated fix_v4bx method and usage of Fix_v4bx enum values . * gold/options.h (General_options): New option definitions. (General_options::fix_v4bx): New method. (General_options::Fix_v4bx): New enum. * gold/options.cc (General_options::parse_fix_v4bx): New method. (General_options::parse_fix_v4bx_interworking): New method. --- gold/ChangeLog | 10 ++++++++++ gold/arm.cc | 26 +++++++++++++++----------- gold/options.cc | 14 ++++++++++++++ gold/options.h | 25 +++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 69d7c7425b7..0e94f260ab7 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,13 @@ +2010-01-22 Viktor Kutuzov + + * gold/arm.cc (Target_arm): Updated fix_v4bx method and usage of + Fix_v4bx enum values . + * gold/options.h (General_options): New option definitions. + (General_options::fix_v4bx): New method. + (General_options::Fix_v4bx): New enum. + * gold/options.cc (General_options::parse_fix_v4bx): New method. + (General_options::parse_fix_v4bx_interworking): New method. + 2010-01-22 Doug Kwan * arm.cc (Arm_exidx_fixup): New class. diff --git a/gold/arm.cc b/gold/arm.cc index 4075c2e2746..f655d59a128 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -1812,7 +1812,7 @@ class Target_arm : public Sized_target<32, big_endian> stub_factory_(Stub_factory::get_instance()), may_use_blx_(false), should_force_pic_veneer_(false), arm_input_section_map_(), attributes_section_data_(NULL), fix_cortex_a8_(false), - cortex_a8_relocs_info_(), fix_v4bx_(0) + cortex_a8_relocs_info_() { } // Whether we can use BLX. @@ -2049,9 +2049,9 @@ class Target_arm : public Sized_target<32, big_endian> // 0 - do not fix // 1 - replace with MOV instruction (armv4 target) // 2 - make interworking veneer (>= armv4t targets only) - int + General_options::Fix_v4bx fix_v4bx() const - { return this->fix_v4bx_; } + { return parameters->options().fix_v4bx(); } // Scan a span of THUMB code section for Cortex-A8 erratum. void @@ -2415,8 +2415,6 @@ class Target_arm : public Sized_target<32, big_endian> bool fix_cortex_a8_; // Map addresses to relocs for Cortex-A8 erratum. Cortex_a8_relocs_info cortex_a8_relocs_info_; - // Whether we need to fix code for V4BX relocations. - int fix_v4bx_; }; template @@ -6451,7 +6449,8 @@ Target_arm::do_finalize_sections( // Check if we can use V4BX interworking. // The V4BX interworking stub contains BX instruction, // which is not specified for some profiles. - if (this->fix_v4bx() == 2 && !this->may_use_blx()) + if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING + && !this->may_use_blx()) gold_error(_("unable to provide V4BX reloc interworking fix up; " "the target profile does not support BX instruction")); @@ -6943,10 +6942,14 @@ Target_arm::Relocate::relocate( break; case elfcpp::R_ARM_V4BX: - if (target->fix_v4bx() > 0) - reloc_status = - Arm_relocate_functions::v4bx(relinfo, view, object, address, - (target->fix_v4bx() == 2)); + if (target->fix_v4bx() > General_options::FIX_V4BX_NONE) + { + const bool is_v4bx_interworking = + (target->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING); + reloc_status = + Arm_relocate_functions::v4bx(relinfo, view, object, address, + is_v4bx_interworking); + } break; case elfcpp::R_ARM_TARGET1: @@ -8245,7 +8248,8 @@ Target_arm::scan_reloc_for_stub( if (r_type == elfcpp::R_ARM_V4BX) { const uint32_t reg = (addend & 0xf); - if (this->fix_v4bx() == 2 && reg < 0xf) + if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING + && reg < 0xf) { // Try looking up an existing stub from a stub table. Stub_table* stub_table = diff --git a/gold/options.cc b/gold/options.cc index 6c0fa041ec7..f377387ed23 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -586,6 +586,20 @@ General_options::string_to_object_format(const char* arg) } } +void +General_options::parse_fix_v4bx(const char*, const char*, + Command_line*) +{ + this->fix_v4bx_ = FIX_V4BX_REPLACE; +} + +void +General_options::parse_fix_v4bx_interworking(const char*, const char*, + Command_line*) +{ + this->fix_v4bx_ = FIX_V4BX_INTERWORKING; +} + } // End namespace gold. namespace diff --git a/gold/options.h b/gold/options.h index c13601c03ca..22662dbbdf6 100644 --- a/gold/options.h +++ b/gold/options.h @@ -726,6 +726,15 @@ class General_options N_("(ARM only) Fix binaries for Cortex-A8 erratum."), N_("(ARM only) Do not fix binaries for Cortex-A8 erratum.")); + DEFINE_special(fix_v4bx, options::TWO_DASHES, '\0', + N_("(ARM only) Rewrite BX rn as MOV pc, rn for ARMv4"), + NULL); + + DEFINE_special(fix_v4bx_interworking, options::TWO_DASHES, '\0', + N_("(ARM only) Rewrite BX rn branch to ARMv4 interworking " + "veneer"), + NULL); + DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false, N_("Ignored"), NULL); @@ -1218,6 +1227,20 @@ class General_options bool section_start(const char* secname, uint64_t* paddr) const; + enum Fix_v4bx + { + // Leave original instruction. + FIX_V4BX_NONE, + // Replace instruction. + FIX_V4BX_REPLACE, + // Generate an interworking veneer. + FIX_V4BX_INTERWORKING + }; + + Fix_v4bx + fix_v4bx() const + { return (this->fix_v4bx_); } + private: // Don't copy this structure. General_options(const General_options&); @@ -1307,6 +1330,8 @@ class General_options Unordered_set symbols_to_retain_; // Map from section name to address from --section-start. std::map section_starts_; + // Whether to process armv4 bx instruction relocation. + Fix_v4bx fix_v4bx_; }; // The position-dependent options. We use this to store the state of -- 2.30.2