diff options
author | Doug Kwan <dougkwan@google.com> | 2009-11-25 04:32:36 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2009-11-25 04:32:36 +0000 |
commit | 50aeb7d4316c838b8d3d41c2191a7ec2a0874f49 (patch) | |
tree | 19addef07371e4a76beedb50f46c2a96ba941688 /gold/arm.cc | |
parent | 51938283769ef9915b3106f48193ed42a3cea44e (diff) | |
download | gdb-50aeb7d4316c838b8d3d41c2191a7ec2a0874f49.zip gdb-50aeb7d4316c838b8d3d41c2191a7ec2a0874f49.tar.gz gdb-50aeb7d4316c838b8d3d41c2191a7ec2a0874f49.tar.bz2 |
2009-11-25 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::Target_arm): Move method definition outside of
class definition. Add code to handle --target1-rel, --target1-abs
and --target2= options.
(Target_arm::get_reloc_reloc_type): Change method to be non-static
and const.
(Target_arm::target1_is_rel_, Target_arm::target2_reloc_): New data
member declaration.
(Target_arm::Scan::local, Target_arm::Scan::global,
Target_arm::Relocate::relocate,
Target_arm::Relocatable_size_for_reloc::get_size_for_reloc): Adjust
call to Target_arm::get_real_reloc_type.
(Target_arm::get_real_reloc_type): Use command line options to
determine real types of R_ARM_TARGET1 and R_ARM_TARGET2.
* options.h (--target1-rel, --target1-abs, --target2): New ARM-only
options.
Diffstat (limited to 'gold/arm.cc')
-rw-r--r-- | gold/arm.cc | 81 |
1 files changed, 62 insertions, 19 deletions
diff --git a/gold/arm.cc b/gold/arm.cc index 3ea98de..d8e274e 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -1142,14 +1142,7 @@ class Target_arm : public Sized_target<32, big_endian> // When were are relocating a stub, we pass this as the relocation number. static const size_t fake_relnum_for_stubs = static_cast<size_t>(-1); - Target_arm() - : Sized_target<32, big_endian>(&arm_info), - got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL), - copy_relocs_(elfcpp::R_ARM_COPY), dynbss_(NULL), stub_tables_(), - stub_factory_(Stub_factory::get_instance()), - may_use_blx_(true), should_force_pic_veneer_(false), - arm_input_section_map_() - { } + Target_arm(); // Whether we can use BLX. bool @@ -1298,8 +1291,8 @@ class Target_arm : public Sized_target<32, big_endian> } // Map platform-specific reloc types - static unsigned int - get_real_reloc_type (unsigned int r_type); + unsigned int + get_real_reloc_type (unsigned int r_type) const; // // Methods to support stub-generations. @@ -1631,6 +1624,11 @@ class Target_arm : public Sized_target<32, big_endian> Stub_table_list stub_tables_; // Stub factory. const Stub_factory &stub_factory_; + // Whether R_ARM_TARGET1 maps to R_ARM_REL32 or R_ARM_ABS32. + bool target1_is_rel_; + // What R_ARM_TARGET2 maps to. It should be one of R_ARM_REL32, R_ARM_ABS32 + // and R_ARM_GOT_PREL. + unsigned int target2_reloc_; // Whether we can use BLX. bool may_use_blx_; // Whether we force PIC branch veneers. @@ -2310,6 +2308,51 @@ Arm_relocate_functions<big_endian>::arm_branch_common( ? This::STATUS_OVERFLOW : This::STATUS_OKAY); } +template<bool big_endian> +Target_arm<big_endian>::Target_arm() + : Sized_target<32, big_endian>(&arm_info), + got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL), + copy_relocs_(elfcpp::R_ARM_COPY), dynbss_(NULL), stub_tables_(), + stub_factory_(Stub_factory::get_instance()), target1_is_rel_(false), + may_use_blx_(true), should_force_pic_veneer_(false), + arm_input_section_map_() +{ + // FIXME: This is not strictly compatible with ld, which allows both + // --target1-abs and --target-rel to be given. + if (parameters->options().user_set_target1_abs() + && parameters->options().user_set_target1_rel()) + { + gold_error(_("Cannot use both --target1-abs and --target1-rel.")); + } + else if (parameters->options().user_set_target1_rel()) + this->target1_is_rel_ = true; + else if (parameters->options().user_set_target1_abs()) + this->target1_is_rel_ = false; + + if (parameters->options().user_set_target2()) + { + if (strcmp(parameters->options().target2(), "rel") == 0) + this->target2_reloc_ = elfcpp::R_ARM_REL32; + else if (strcmp(parameters->options().target2(), "abs") == 0) + this->target2_reloc_ = elfcpp::R_ARM_ABS32; + else if (strcmp(parameters->options().target2(), "got-rel") == 0) + this->target2_reloc_ = elfcpp::R_ARM_GOT_PREL; + else + gold_unreachable(); + } + else + { + // Default values for R_ARM_TARGET2: + // + // R_ARM_REL32 (arm*-*-elf, arm*-*-eabi) + // R_ARM_ABS32 (arm*-*-symbianelf) + // R_ARM_GOT_PREL (arm*-*-linux, arm*-*-*bsd) + + // This is the default value for EABI. + this->target2_reloc_ = elfcpp::R_ARM_REL32; + } +} + // Relocate THUMB long branches. This handles relocation types // R_ARM_THM_CALL, R_ARM_THM_JUMP24 and R_ARM_THM_XPC22. // If IS_WEAK_UNDEFINED_WITH_PLT is true. The target symbol is weakly @@ -4166,7 +4209,7 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab, unsigned int r_type, const elfcpp::Sym<32, big_endian>&) { - r_type = get_real_reloc_type(r_type); + r_type = target->get_real_reloc_type(r_type); switch (r_type) { case elfcpp::R_ARM_NONE: @@ -4293,7 +4336,7 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab, unsigned int r_type, Symbol* gsym) { - r_type = get_real_reloc_type(r_type); + r_type = target->get_real_reloc_type(r_type); switch (r_type) { case elfcpp::R_ARM_NONE: @@ -4705,7 +4748,7 @@ Target_arm<big_endian>::Relocate::relocate( { typedef Arm_relocate_functions<big_endian> Arm_relocate_functions; - r_type = get_real_reloc_type(r_type); + r_type = target->get_real_reloc_type(r_type); const Arm_relobj<big_endian>* object = Arm_relobj<big_endian>::as_arm_relobj(relinfo->object); @@ -5170,7 +5213,9 @@ Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc( unsigned int r_type, Relobj* object) { - r_type = get_real_reloc_type(r_type); + const Target_arm<big_endian>* arm_target = + Target_arm<big_endian>::default_target(); + r_type = arm_target->get_real_reloc_type(r_type); switch (r_type) { case elfcpp::R_ARM_NONE: @@ -5315,17 +5360,15 @@ Target_arm<big_endian>::do_dynsym_value(const Symbol* gsym) const // template<bool big_endian> unsigned int -Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type) +Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type) const { switch (r_type) { case elfcpp::R_ARM_TARGET1: - // This is either R_ARM_ABS32 or R_ARM_REL32; - return elfcpp::R_ARM_ABS32; + return this->target1_is_rel_? elfcpp::R_ARM_REL32 : elfcpp::R_ARM_ABS32; case elfcpp::R_ARM_TARGET2: - // This can be any reloc type but ususally is R_ARM_GOT_PREL - return elfcpp::R_ARM_GOT_PREL; + return this->target2_reloc_; default: return r_type; |