diff options
-rw-r--r-- | gold/ChangeLog | 22 | ||||
-rw-r--r-- | gold/ehframe.cc | 55 | ||||
-rw-r--r-- | gold/ehframe.h | 7 | ||||
-rw-r--r-- | gold/output.cc | 73 |
4 files changed, 72 insertions, 85 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 4fce2cb..0fa1561 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,25 @@ +2014-09-02 Cary Coutant <ccoutant@google.com> + + PR gold/17005 + * ehframe.cc (Fde::write): Add output_offset parameter. + (Cie::write): Likewise. + (Eh_frame::set_final_data_size): Account for offset within output + section. + (Eh_frame::do_sized_write): Likewise. + * ehframe.h (Fde::write): Add output_offset parameter. + (Cie::write): Likewise. + * output.cc (Output_section::Input_section_sort_entry): Remove + section_has_name_; add output_section_name parameter. Use + output section name for non-input sections. + (Output_section::Input_section_sort_entry::section_has_name): Remove. + (Output_section::Input_section_sort_entry::section_has_name_): Remove. + (Output_section::Input_section_sort_compare): Remove logic for + sections without names. + (Output_section::Input_section_sort_init_fini_compare): Likewise. + (Output_section::Input_section_sort_section_prefix_special_ordering_compare): + Likewise. + (Output_section::Input_section_sort_section_name_compare): Likewise. + 2014-08-29 Han Shen <shenhan@google.com> Jing Yu <jingyu@google.com> 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_); } diff --git a/gold/ehframe.h b/gold/ehframe.h index 42ed7f6..2ae12e0 100644 --- a/gold/ehframe.h +++ b/gold/ehframe.h @@ -211,8 +211,8 @@ class Fde // FDE in EH_FRAME_HDR. Return the new offset. template<int size, bool big_endian> section_offset_type - write(unsigned char* oview, section_offset_type offset, - uint64_t address, unsigned int addralign, + write(unsigned char* oview, section_offset_type output_section_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); @@ -317,7 +317,8 @@ class Cie // writing. Return the new offset. template<int size, bool big_endian> section_offset_type - write(unsigned char* oview, section_offset_type offset, uint64_t address, + write(unsigned char* oview, section_offset_type output_section_offset, + section_offset_type offset, uint64_t address, unsigned int addralign, Eh_frame_hdr* eh_frame_hdr, Post_fdes* post_fdes); diff --git a/gold/output.cc b/gold/output.cc index c078fbb..3361991a 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -3206,18 +3206,17 @@ class Output_section::Input_section_sort_entry { public: Input_section_sort_entry() - : input_section_(), index_(-1U), section_has_name_(false), - section_name_() + : input_section_(), index_(-1U), section_name_() { } Input_section_sort_entry(const Input_section& input_section, unsigned int index, - bool must_sort_attached_input_sections) - : input_section_(input_section), index_(index), - section_has_name_(input_section.is_input_section() - || input_section.is_relaxed_input_section()) + bool must_sort_attached_input_sections, + const char* output_section_name) + : input_section_(input_section), index_(index), section_name_() { - if (this->section_has_name_ + if ((input_section.is_input_section() + || input_section.is_relaxed_input_section()) && must_sort_attached_input_sections) { // This is only called single-threaded from Layout::finalize, @@ -3233,6 +3232,12 @@ class Output_section::Input_section_sort_entry // Layout::layout if this becomes a speed problem. this->section_name_ = obj->section_name(input_section.shndx()); } + else if (input_section.is_output_section_data() + && must_sort_attached_input_sections) + { + // For linker-generated sections, use the output section name. + this->section_name_.assign(output_section_name); + } } // Return the Input_section. @@ -3252,16 +3257,10 @@ class Output_section::Input_section_sort_entry return this->index_; } - // Whether there is a section name. - bool - section_has_name() const - { return this->section_has_name_; } - // The section name. const std::string& section_name() const { - gold_assert(this->section_has_name_); return this->section_name_; } @@ -3270,7 +3269,6 @@ class Output_section::Input_section_sort_entry bool has_priority() const { - gold_assert(this->section_has_name_); return this->section_name_.find('.', 1) != std::string::npos; } @@ -3280,7 +3278,6 @@ class Output_section::Input_section_sort_entry unsigned int get_priority() const { - gold_assert(this->section_has_name_); bool is_ctors; if (is_prefix_of(".ctors.", this->section_name_.c_str()) || is_prefix_of(".dtors.", this->section_name_.c_str())) @@ -3339,9 +3336,6 @@ class Output_section::Input_section_sort_entry Input_section input_section_; // The index of this Input_section in the original list. unsigned int index_; - // Whether this Input_section has a section name--it won't if this - // is some random Output_section_data. - bool section_has_name_; // The section name if there is one. std::string section_name_; }; @@ -3377,16 +3371,6 @@ Output_section::Input_section_sort_compare::operator()( return s1.index() < s2.index(); } - // We sort all the sections with no names to the end. - if (!s1.section_has_name() || !s2.section_has_name()) - { - if (s1.section_has_name()) - return true; - if (s2.section_has_name()) - return false; - return s1.index() < s2.index(); - } - // A section with a priority follows a section without a priority. bool s1_has_priority = s1.has_priority(); bool s2_has_priority = s2.has_priority(); @@ -3418,16 +3402,6 @@ Output_section::Input_section_sort_init_fini_compare::operator()( const Output_section::Input_section_sort_entry& s1, const Output_section::Input_section_sort_entry& s2) const { - // We sort all the sections with no names to the end. - if (!s1.section_has_name() || !s2.section_has_name()) - { - if (s1.section_has_name()) - return true; - if (s2.section_has_name()) - return false; - return s1.index() < s2.index(); - } - // A section without a priority follows a section with a priority. // This is the reverse of .ctors and .dtors sections. bool s1_has_priority = s1.has_priority(); @@ -3503,16 +3477,6 @@ Output_section::Input_section_sort_section_prefix_special_ordering_compare const Output_section::Input_section_sort_entry& s1, const Output_section::Input_section_sort_entry& s2) const { - // We sort all the sections with no names to the end. - if (!s1.section_has_name() || !s2.section_has_name()) - { - if (s1.section_has_name()) - return true; - if (s2.section_has_name()) - return false; - return s1.index() < s2.index(); - } - // Some input section names have special ordering requirements. int o1 = Layout::special_ordering_of_input_section(s1.section_name().c_str()); int o2 = Layout::special_ordering_of_input_section(s2.section_name().c_str()); @@ -3539,16 +3503,6 @@ Output_section::Input_section_sort_section_name_compare const Output_section::Input_section_sort_entry& s1, const Output_section::Input_section_sort_entry& s2) const { - // We sort all the sections with no names to the end. - if (!s1.section_has_name() || !s2.section_has_name()) - { - if (s1.section_has_name()) - return true; - if (s2.section_has_name()) - return false; - return s1.index() < s2.index(); - } - // We sort by name. int compare = s1.section_name().compare(s2.section_name()); if (compare != 0) @@ -3616,7 +3570,8 @@ Output_section::sort_attached_input_sections() p != this->input_sections_.end(); ++p, ++i) sort_list.push_back(Input_section_sort_entry(*p, i, - this->must_sort_attached_input_sections())); + this->must_sort_attached_input_sections(), + this->name())); // Sort the input sections. if (this->must_sort_attached_input_sections()) |