diff options
author | Ian Lance Taylor <iant@google.com> | 2008-03-13 20:58:11 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2008-03-13 20:58:11 +0000 |
commit | 1d6531cfad3c386b17a44432c8d915f0147cb716 (patch) | |
tree | aa06d3c971f940021205489831c611ed26d4db71 | |
parent | 018f1beaa07e1ea906fde814c0f3b45b2a6f21f4 (diff) | |
download | gdb-1d6531cfad3c386b17a44432c8d915f0147cb716.zip gdb-1d6531cfad3c386b17a44432c8d915f0147cb716.tar.gz gdb-1d6531cfad3c386b17a44432c8d915f0147cb716.tar.bz2 |
Don't crash if we change the address of the .eh_frame section after we
find its size.
-rw-r--r-- | gold/ehframe.cc | 16 | ||||
-rw-r--r-- | gold/ehframe.h | 5 | ||||
-rw-r--r-- | gold/merge.cc | 4 |
3 files changed, 23 insertions, 2 deletions
diff --git a/gold/ehframe.cc b/gold/ehframe.cc index df94488..a3a24e5 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 cf3b738..8ff456b 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 75a3eee..192d6a4 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -528,7 +528,9 @@ Output_merge_string<Char_type>::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(); |