diff options
Diffstat (limited to 'gold/ehframe.cc')
-rw-r--r-- | gold/ehframe.cc | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/gold/ehframe.cc b/gold/ehframe.cc index 699073d..c711bac 100644 --- a/gold/ehframe.cc +++ b/gold/ehframe.cc @@ -326,15 +326,16 @@ Eh_frame_hdr::get_fde_addresses(Output_file* of, // Class Fde. // Write the FDE to OVIEW starting at OFFSET. CIE_OFFSET is the -// offset of the CIE in OVIEW. FDE_ENCODING is the encoding, from the -// CIE. ADDRALIGN is the required alignment. ADDRESS is the virtual -// address of OVIEW. Record the FDE pc for EH_FRAME_HDR. Return the -// new offset. +// offset of the CIE in OVIEW. OUTPUT_OFFSET is the offset of the +// Eh_frame section within the output section. FDE_ENCODING is the +// encoding, from the CIE. ADDRALIGN is the required alignment. +// ADDRESS is the virtual address of OVIEW. Record the FDE pc for +// EH_FRAME_HDR. Return the new offset. template<int size, bool big_endian> section_offset_type -Fde::write(unsigned char* oview, section_offset_type offset, - uint64_t address, unsigned int addralign, +Fde::write(unsigned char* oview, section_offset_type output_offset, + section_offset_type offset, uint64_t address, unsigned int addralign, section_offset_type cie_offset, unsigned char fde_encoding, Eh_frame_hdr* eh_frame_hdr) { @@ -389,7 +390,7 @@ Fde::write(unsigned char* oview, section_offset_type offset, // Tell the exception frame header about this FDE. if (eh_frame_hdr != NULL) - eh_frame_hdr->record_fde(offset, fde_encoding); + eh_frame_hdr->record_fde(output_offset + offset, fde_encoding); return offset + aligned_full_length; } @@ -441,17 +442,19 @@ Cie::set_output_offset(section_offset_type output_offset, return output_offset + length; } -// Write the CIE to OVIEW starting at OFFSET. Round up the bytes to -// ADDRALIGN. ADDRESS is the virtual address of OVIEW. +// Write the CIE to OVIEW starting at OFFSET. OUTPUT_OFFSET is the +// offset of the Eh_frame section within the output section. Round up +// the bytes to ADDRALIGN. ADDRESS is the virtual address of OVIEW. // EH_FRAME_HDR is the exception frame header for FDE recording. // POST_FDES stashes FDEs created after mappings were done, for later // writing. Return the new offset. template<int size, bool big_endian> section_offset_type -Cie::write(unsigned char* oview, section_offset_type offset, - uint64_t address, unsigned int addralign, - Eh_frame_hdr* eh_frame_hdr, Post_fdes* post_fdes) +Cie::write(unsigned char* oview, section_offset_type output_offset, + section_offset_type offset, uint64_t address, + unsigned int addralign, Eh_frame_hdr* eh_frame_hdr, + Post_fdes* post_fdes) { gold_assert((offset & (addralign - 1)) == 0); @@ -488,8 +491,8 @@ Cie::write(unsigned char* oview, section_offset_type offset, if ((*p)->post_map()) post_fdes->push_back(Post_fde(*p, cie_offset, fde_encoding)); else - offset = (*p)->write<size, big_endian>(oview, offset, address, - addralign, cie_offset, + offset = (*p)->write<size, big_endian>(oview, output_offset, offset, + address, addralign, cie_offset, fde_encoding, eh_frame_hdr); } @@ -1093,7 +1096,10 @@ Eh_frame::set_final_data_size() return; } - section_offset_type output_offset = 0; + section_offset_type output_start = 0; + if (this->is_offset_valid()) + output_start = this->offset() - this->output_section()->offset(); + section_offset_type output_offset = output_start; for (Unmergeable_cie_offsets::iterator p = this->unmergeable_cie_offsets_.begin(); @@ -1111,10 +1117,10 @@ Eh_frame::set_final_data_size() &this->merge_map_); this->mappings_are_done_ = true; - this->final_data_size_ = output_offset; + this->final_data_size_ = output_offset - output_start; gold_assert((output_offset & (this->addralign() - 1)) == 0); - this->set_data_size(output_offset); + this->set_data_size(this->final_data_size_); } // Return an output offset for an input offset. @@ -1183,23 +1189,26 @@ Eh_frame::do_sized_write(unsigned char* oview) uint64_t address = this->address(); unsigned int addralign = this->addralign(); section_offset_type o = 0; + const off_t output_offset = this->offset() - this->output_section()->offset(); Post_fdes post_fdes; for (Unmergeable_cie_offsets::iterator p = this->unmergeable_cie_offsets_.begin(); p != this->unmergeable_cie_offsets_.end(); ++p) - o = (*p)->write<size, big_endian>(oview, o, address, addralign, - this->eh_frame_hdr_, &post_fdes); + o = (*p)->write<size, big_endian>(oview, output_offset, o, address, + addralign, this->eh_frame_hdr_, + &post_fdes); for (Cie_offsets::iterator p = this->cie_offsets_.begin(); p != this->cie_offsets_.end(); ++p) - o = (*p)->write<size, big_endian>(oview, o, address, addralign, - this->eh_frame_hdr_, &post_fdes); + o = (*p)->write<size, big_endian>(oview, output_offset, o, address, + addralign, this->eh_frame_hdr_, + &post_fdes); for (Post_fdes::iterator p = post_fdes.begin(); p != post_fdes.end(); ++p) - o = (*p).fde->write<size, big_endian>(oview, o, address, addralign, - (*p).cie_offset, + o = (*p).fde->write<size, big_endian>(oview, output_offset, o, address, + addralign, (*p).cie_offset, (*p).fde_encoding, this->eh_frame_hdr_); } |