2010-01-22 Viktor Kutuzov <vkutuzov@accesssoftek.com>

* 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.
This commit is contained in:
Doug Kwan 2010-01-22 19:43:00 +00:00
parent 80d0d023f5
commit 9b2fd36756
4 changed files with 64 additions and 11 deletions

View File

@ -1,3 +1,13 @@
2010-01-22 Viktor Kutuzov <vkutuzov@accesssoftek.com>
* 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 <dougkwan@google.com>
* arm.cc (Arm_exidx_fixup): New class.

View File

@ -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<bool big_endian>
@ -6451,7 +6449,8 @@ Target_arm<big_endian>::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<big_endian>::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<big_endian>::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<big_endian>* stub_table =

View File

@ -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

View File

@ -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<std::string> symbols_to_retain_;
// Map from section name to address from --section-start.
std::map<std::string, uint64_t> 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