diff options
author | Doug Kwan <dougkwan@google.com> | 2010-02-09 06:46:00 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2010-02-09 06:46:00 +0000 |
commit | cb1be87e23111486165d9351b787ad73605176eb (patch) | |
tree | ba2f54e382473d72eea152f370515de39fd1e560 /gold/arm.cc | |
parent | 024c4466738f9e18a8a3e15592e1250a61f288b9 (diff) | |
download | gdb-cb1be87e23111486165d9351b787ad73605176eb.zip gdb-cb1be87e23111486165d9351b787ad73605176eb.tar.gz gdb-cb1be87e23111486165d9351b787ad73605176eb.tar.bz2 |
2010-02-08 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_relobj::simple_input_section_output_address): New
method.
(Arm_relobj::section_needs_cortex_a8_stub_scanning,
Arm_relobj::scan_section_for_cortex_a8_stubs,
Arm_relobj::do_relocation_section): Instead of calling
Output_section::output_address, use faster
Arm_relobj::simple_input_section_output_address.
Diffstat (limited to 'gold/arm.cc')
-rw-r--r-- | gold/arm.cc | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/gold/arm.cc b/gold/arm.cc index bec70db..f121f93 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -1603,6 +1603,11 @@ class Arm_relobj : public Sized_relobj<32, big_endian> make_exidx_input_section(unsigned int shndx, const elfcpp::Shdr<32, big_endian>& shdr); + // Return the output address of either a plain input section or a + // relaxed input section. SHNDX is the section index. + Arm_address + simple_input_section_output_address(unsigned int, Output_section*); + typedef std::vector<Stub_table<big_endian>*> Stub_table_list; typedef Unordered_map<unsigned int, const Arm_exidx_input_section*> Exidx_section_map; @@ -5538,6 +5543,29 @@ Arm_relobj<big_endian>::section_needs_reloc_stub_scanning( out_sections[index], symtab); } +// Return the output address of either a plain input section or a relaxed +// input section. SHNDX is the section index. We define and use this +// instead of calling Output_section::output_address because that is slow +// for large output. + +template<bool big_endian> +Arm_address +Arm_relobj<big_endian>::simple_input_section_output_address( + unsigned int shndx, + Output_section* os) +{ + if (this->is_output_section_offset_invalid(shndx)) + { + const Output_relaxed_input_section* poris = + os->find_relaxed_input_section(this, shndx); + // We do not handle merged sections here. + gold_assert(poris != NULL); + return poris->address(); + } + else + return os->address() + this->get_output_section_offset(shndx); +} + // Determine if we want to scan the SHNDX-th section for non-relocation stubs. // This is a helper for Arm_relobj::scan_sections_for_stubs() below. @@ -5552,11 +5580,9 @@ Arm_relobj<big_endian>::section_needs_cortex_a8_stub_scanning( if (!this->section_is_scannable(shdr, shndx, os, symtab)) return false; - // Find output address of section. - Arm_address address = os->output_address(this, shndx, 0); - // If the section does not cross any 4K-boundaries, it does not need to // be scanned. + Arm_address address = this->simple_input_section_output_address(shndx, os); if ((address & ~0xfffU) == ((address + shdr.get_sh_size() - 1) & ~0xfffU)) return false; @@ -5573,7 +5599,8 @@ Arm_relobj<big_endian>::scan_section_for_cortex_a8_erratum( Output_section* os, Target_arm<big_endian>* arm_target) { - Arm_address output_address = os->output_address(this, shndx, 0); + Arm_address output_address = + this->simple_input_section_output_address(shndx, os); // Get the section contents. section_size_type input_view_size = 0; @@ -5912,7 +5939,8 @@ Arm_relobj<big_endian>::do_relocate_sections( // Adjust view to cover section. Output_section* os = this->output_section(i); gold_assert(os != NULL); - Arm_address section_address = os->output_address(this, i, 0); + Arm_address section_address = + this->simple_input_section_output_address(i, os); uint64_t section_size = this->section_size(i); gold_assert(section_address >= view_address |