From 43d12afeb988b9f78691fb861a2027730427da2e Mon Sep 17 00:00:00 2001 From: Doug Kwan Date: Mon, 9 Nov 2009 23:16:55 +0000 Subject: [PATCH] 2009-11-10 Doug Kwan * arm.cc (Arm_relobj::do_relocate_sections): Remove options parameter in method declaration. (Target_arm::relocate_stub): New method declaration. (Target_arm::default_target): Change to return a pointer instead of a const reference. (Reloc_stub::stub_type_for_reloc): Adjust for the change in Target_arm::default_target. (Arm_Relobj::do_relocate_sections): Remove options paramater in method definition. (Target_arm::relocate_section): Adjust view. (Target_arm::relocate_stub): New method definition. --- gold/ChangeLog | 14 +++++++ gold/arm.cc | 107 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 103 insertions(+), 18 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 1432e529fc1..bce6ec55283 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,17 @@ +2009-11-10 Doug Kwan + + * arm.cc (Arm_relobj::do_relocate_sections): Remove options parameter + in method declaration. + (Target_arm::relocate_stub): New method declaration. + (Target_arm::default_target): Change to return a pointer instead of + a const reference. + (Reloc_stub::stub_type_for_reloc): Adjust for the change in + Target_arm::default_target. + (Arm_Relobj::do_relocate_sections): Remove options paramater in + method definition. + (Target_arm::relocate_section): Adjust view. + (Target_arm::relocate_stub): New method definition. + 2009-11-10 Doug Kwan * i386.cc (Target_i386::do_calls_non_split): Add a cast to avoid diff --git a/gold/arm.cc b/gold/arm.cc index 4e6c6a1a3e3..6058637d7b5 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -972,8 +972,7 @@ class Arm_relobj : public Sized_relobj<32, big_endian> Stringpool_template*); void - do_relocate_sections(const General_options& options, - const Symbol_table* symtab, const Layout* layout, + do_relocate_sections(const Symbol_table* symtab, const Layout* layout, const unsigned char* pshdrs, typename Sized_relobj<32, big_endian>::Views* pivews); @@ -1315,13 +1314,20 @@ class Target_arm : public Sized_target<32, big_endian> bool, const unsigned char*, Arm_address, section_size_type); + // Relocate a stub. + void + relocate_stub(Reloc_stub*, const Relocate_info<32, big_endian>*, + Output_section*, unsigned char*, Arm_address, + section_size_type); + // Get the default ARM target. - static const Target_arm& + static Target_arm* default_target() { gold_assert(parameters->target().machine_code() == elfcpp::EM_ARM && parameters->target().is_big_endian() == big_endian); - return static_cast&>(parameters->target()); + return static_cast*>( + parameters->sized_target<32, big_endian>()); } // Whether relocation type uses LSB to distinguish THUMB addresses. @@ -2388,21 +2394,21 @@ Reloc_stub::stub_type_for_reloc( bool thumb_only; if (parameters->target().is_big_endian()) { - const Target_arm& big_endian_target = + const Target_arm* big_endian_target = Target_arm::default_target(); - may_use_blx = big_endian_target.may_use_blx(); - should_force_pic_veneer = big_endian_target.should_force_pic_veneer(); - thumb2 = big_endian_target.using_thumb2(); - thumb_only = big_endian_target.using_thumb_only(); + may_use_blx = big_endian_target->may_use_blx(); + should_force_pic_veneer = big_endian_target->should_force_pic_veneer(); + thumb2 = big_endian_target->using_thumb2(); + thumb_only = big_endian_target->using_thumb_only(); } else { - const Target_arm& little_endian_target = + const Target_arm* little_endian_target = Target_arm::default_target(); - may_use_blx = little_endian_target.may_use_blx(); - should_force_pic_veneer = little_endian_target.should_force_pic_veneer(); - thumb2 = little_endian_target.using_thumb2(); - thumb_only = little_endian_target.using_thumb_only(); + may_use_blx = little_endian_target->may_use_blx(); + should_force_pic_veneer = little_endian_target->should_force_pic_veneer(); + thumb2 = little_endian_target->using_thumb2(); + thumb_only = little_endian_target->using_thumb_only(); } int64_t branch_offset = (int64_t)destination - location; @@ -3380,15 +3386,14 @@ Arm_relobj::do_count_local_symbols( template void Arm_relobj::do_relocate_sections( - const General_options& options, const Symbol_table* symtab, const Layout* layout, const unsigned char* pshdrs, typename Sized_relobj<32, big_endian>::Views* pviews) { // Call parent to relocate sections. - Sized_relobj<32, big_endian>::do_relocate_sections(options, symtab, layout, - pshdrs, pviews); + Sized_relobj<32, big_endian>::do_relocate_sections(symtab, layout, pshdrs, + pviews); // We do not generate stubs if doing a relocatable link. if (parameters->options().relocatable()) @@ -3401,7 +3406,6 @@ Arm_relobj::do_relocate_sections( Target_arm::default_target(); Relocate_info<32, big_endian> relinfo; - relinfo.options = &options; relinfo.symtab = symtab; relinfo.layout = layout; relinfo.object = this; @@ -4775,6 +4779,28 @@ Target_arm::relocate_section( typedef typename Target_arm::Relocate Arm_relocate; gold_assert(sh_type == elfcpp::SHT_REL); + Arm_input_section* arm_input_section = + this->find_arm_input_section(relinfo->object, relinfo->data_shndx); + + // This is an ARM input section and the view covers the whole output + // section. + if (arm_input_section != NULL) + { + gold_assert(needs_special_offset_handling); + Arm_address section_address = arm_input_section->address(); + section_size_type section_size = arm_input_section->data_size(); + + gold_assert((arm_input_section->address() >= address) + && ((arm_input_section->address() + + arm_input_section->data_size()) + <= (address + view_size))); + + off_t offset = section_address - address; + view += offset; + address += offset; + view_size = section_size; + } + gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL, Arm_relocate>( relinfo, @@ -5614,6 +5640,51 @@ Target_arm::do_relax( return any_stub_table_changed; } +// Relocate a stub. + +template +void +Target_arm::relocate_stub( + Reloc_stub* stub, + const Relocate_info<32, big_endian>* relinfo, + Output_section* output_section, + unsigned char* view, + Arm_address address, + section_size_type view_size) +{ + Relocate relocate; + const Stub_template* stub_template = stub->stub_template(); + for (size_t i = 0; i < stub_template->reloc_count(); i++) + { + size_t reloc_insn_index = stub_template->reloc_insn_index(i); + const Insn_template* insn = &stub_template->insns()[reloc_insn_index]; + + unsigned int r_type = insn->r_type(); + section_size_type reloc_offset = stub_template->reloc_offset(i); + section_size_type reloc_size = insn->size(); + gold_assert(reloc_offset + reloc_size <= view_size); + + // This is the address of the stub destination. + Arm_address target = stub->reloc_target(i); + Symbol_value<32> symval; + symval.set_output_value(target); + + // Synthesize a fake reloc just in case. We don't have a symbol so + // we use 0. + unsigned char reloc_buffer[elfcpp::Elf_sizes<32>::rel_size]; + memset(reloc_buffer, 0, sizeof(reloc_buffer)); + elfcpp::Rel_write<32, big_endian> reloc_write(reloc_buffer); + reloc_write.put_r_offset(reloc_offset); + reloc_write.put_r_info(elfcpp::elf_r_info<32>(0, r_type)); + elfcpp::Rel<32, big_endian> rel(reloc_buffer); + + relocate.relocate(relinfo, this, output_section, + this->fake_relnum_for_stubs, rel, r_type, + NULL, &symval, view + reloc_offset, + address + reloc_offset, reloc_size); + } +} + // The selector for arm object files. template -- 2.30.2