aboutsummaryrefslogtreecommitdiff
path: root/gold/arm.cc
diff options
context:
space:
mode:
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.