aboutsummaryrefslogtreecommitdiff
path: root/gold/arm.cc
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2010-01-23 01:07:59 +0000
committerDoug Kwan <dougkwan@google.com>2010-01-23 01:07:59 +0000
commit8923b24c4bde41e6a15026aa1d20493fd383066c (patch)
treedfe04658736dd194c41401949bafb2afdf47dafb /gold/arm.cc
parent767acc28c194ace624485f0a907e07d1e95d4ce1 (diff)
downloadgdb-8923b24c4bde41e6a15026aa1d20493fd383066c.zip
gdb-8923b24c4bde41e6a15026aa1d20493fd383066c.tar.gz
gdb-8923b24c4bde41e6a15026aa1d20493fd383066c.tar.bz2
2010-01-22 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::do_relax): Record an output section for section offset adjustment it contains any stub table that has changed. * layout.cc (Layout::clean_up_after_relaxation): Adjust section offsets in an output section if necessary. * output.cc (Output_section::Output_section): Initialize section_offsets_need_adjustments_. (Output_section::add_input_section_for_script): Renamed to Output_section::add_simple_input_section. (Output_section::save_states): Add a comment. (Output_section::discard_states): New method defintion. (Output_section::adjust_section_offsets): Same. * output.h (Output_section::add_input_section_for_script): Renamed to Output_section::add_simple_input_section. (Output_section::discard_states): New method declaration. (Output_section::adjust_section_offsets): Same. (Output_section::section_offsets_need_adjustment, Output_section::set_section_offsets_need_adjustment): New method definitions. (Output_section::section_offsets_need_adjustment_): New data member. * script-sections.cc (Output_section_element_input::set_section_address): Adjust code for renaming of Output_section::add_input_section_for_script. (Orphan_output_section::set_section_address): Same.
Diffstat (limited to 'gold/arm.cc')
-rw-r--r--gold/arm.cc26
1 files changed, 25 insertions, 1 deletions
diff --git a/gold/arm.cc b/gold/arm.cc
index f655d59..03f59f6 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -8716,12 +8716,36 @@ Target_arm<big_endian>::do_relax(
// or addresses alignments changed. These are the only things that
// matter.
bool any_stub_table_changed = false;
+ Unordered_set<const Output_section*> sections_needing_adjustment;
for (Stub_table_iterator sp = this->stub_tables_.begin();
(sp != this->stub_tables_.end()) && !any_stub_table_changed;
++sp)
{
if ((*sp)->update_data_size_and_addralign())
- any_stub_table_changed = true;
+ {
+ // Update data size of stub table owner.
+ Arm_input_section<big_endian>* owner = (*sp)->owner();
+ uint64_t address = owner->address();
+ off_t offset = owner->offset();
+ owner->reset_address_and_file_offset();
+ owner->set_address_and_file_offset(address, offset);
+
+ sections_needing_adjustment.insert(owner->output_section());
+ any_stub_table_changed = true;
+ }
+ }
+
+ // Output_section_data::output_section() returns a const pointer but we
+ // need to update output sections, so we record all output sections needing
+ // update above and scan the sections here to find out what sections need
+ // to be updated.
+ for(Layout::Section_list::const_iterator p = layout->section_list().begin();
+ p != layout->section_list().end();
+ ++p)
+ {
+ if (sections_needing_adjustment.find(*p)
+ != sections_needing_adjustment.end())
+ (*p)->set_section_offsets_need_adjustment();
}
// Finalize the stubs in the last relaxation pass.