diff --git a/gold/ehframe.cc b/gold/ehframe.cc index df9448897f..a3a24e5134 100644 --- a/gold/ehframe.cc +++ b/gold/ehframe.cc @@ -487,7 +487,9 @@ Eh_frame::Eh_frame() eh_frame_hdr_(NULL), cie_offsets_(), unmergeable_cie_offsets_(), - merge_map_() + merge_map_(), + mappings_are_done_(false), + final_data_size_(0) { } @@ -1011,6 +1013,15 @@ Eh_frame::fde_count() const void Eh_frame::set_final_data_size() { + // We can be called more than once if Layout::set_segment_offsets + // finds a better mapping. We don't want to add all the mappings + // again. + if (this->mappings_are_done_) + { + this->set_data_size(this->final_data_size_); + return; + } + section_offset_type output_offset = 0; for (Unmergeable_cie_offsets::iterator p = @@ -1028,6 +1039,9 @@ Eh_frame::set_final_data_size() this->addralign(), &this->merge_map_); + this->mappings_are_done_ = true; + this->final_data_size_ = output_offset; + gold_assert((output_offset & (this->addralign() - 1)) == 0); this->set_data_size(output_offset); } diff --git a/gold/ehframe.h b/gold/ehframe.h index cf3b738567..8ff456b908 100644 --- a/gold/ehframe.h +++ b/gold/ehframe.h @@ -427,6 +427,11 @@ class Eh_frame : public Output_section_data Unmergeable_cie_offsets unmergeable_cie_offsets_; // A mapping from input sections to the output section. Merge_map merge_map_; + // Whether we have created the mappings to the output section. + bool mappings_are_done_; + // The final data size. This is only set if mappings_are_done_ is + // true. + section_size_type final_data_size_; }; } // End namespace gold. diff --git a/gold/merge.cc b/gold/merge.cc index 75a3eeea92..192d6a408e 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -528,7 +528,9 @@ Output_merge_string::finalize_merged_data() this->add_mapping(p->object, p->shndx, p->offset, p->length, offset); } - // Save some memory. + // Save some memory. This also ensures that this function will work + // if called twice, as may happen if Layout::set_segment_offsets + // finds a better alignment. this->merged_strings_.clear(); return this->stringpool_.get_strtab_size();