diff options
author | Doug Kwan <dougkwan@google.com> | 2010-03-01 21:43:50 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2010-03-01 21:43:50 +0000 |
commit | 2a0ff005c89d674c7e233c7fa612aa2434bcd8df (patch) | |
tree | f7cdface7116bfdf3188bd6d8b844deff74b551d /gold/output.cc | |
parent | a6f5ef51d7c85bd0b950fd182284f6cbff5fecf0 (diff) | |
download | fsf-binutils-gdb-2a0ff005c89d674c7e233c7fa612aa2434bcd8df.zip fsf-binutils-gdb-2a0ff005c89d674c7e233c7fa612aa2434bcd8df.tar.gz fsf-binutils-gdb-2a0ff005c89d674c7e233c7fa612aa2434bcd8df.tar.bz2 |
2010-03-01 Doug Kwan <dougkwan@google.com>
* layout.cc (Layout::Layout): Force section types of .init_array*,
.preinit_array* and .fini_array* sections.
* output.cc (Output_section::Input_section_sort_entry::has_priority):
Fix check of return value of std::string::find.().
(Output_section::Input_section_sort_compare::operator()): Remove
comment about .init_array.
(Output_section::Input_section_sort_init_fini_compare::operator()):
New method.
(Output_section::sort_attached_input_sections): Handle .init_array
and .fini_array specially.
* output.h (Output_section::Inut_section_sort_compare): Update
comment.
(Output_section::Input_section_sort_init_fini_compare): New struct.
Diffstat (limited to 'gold/output.cc')
-rw-r--r-- | gold/output.cc | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/gold/output.cc b/gold/output.cc index 1c2533c..d49f08b 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -2695,7 +2695,7 @@ class Output_section::Input_section_sort_entry has_priority() const { gold_assert(this->section_has_name_); - return this->section_name_.find('.', 1); + return this->section_name_.find('.', 1) != std::string::npos; } // Return true if this an input file whose base name matches @@ -2773,8 +2773,6 @@ Output_section::Input_section_sort_compare::operator()( } // A section with a priority follows a section without a priority. - // The GNU linker does this for all but .init_array sections; until - // further notice we'll assume that that is an mistake. bool s1_has_priority = s1.has_priority(); bool s2_has_priority = s2.has_priority(); if (s1_has_priority && !s2_has_priority) @@ -2791,6 +2789,42 @@ Output_section::Input_section_sort_compare::operator()( return s1.index() < s2.index(); } +// Return true if S1 should come before S2 in an .init_array or .fini_array +// output section. + +bool +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(); + bool s2_has_priority = s2.has_priority(); + if (s1_has_priority && !s2_has_priority) + return true; + if (!s1_has_priority && s2_has_priority) + return false; + + // Otherwise we sort by name. + int compare = s1.section_name().compare(s2.section_name()); + if (compare != 0) + return compare < 0; + + // Otherwise we keep the input order. + return s1.index() < s2.index(); +} + // Sort the input sections attached to an output section. void @@ -2819,7 +2853,14 @@ Output_section::sort_attached_input_sections() sort_list.push_back(Input_section_sort_entry(*p, i)); // Sort the input sections. - std::sort(sort_list.begin(), sort_list.end(), Input_section_sort_compare()); + if (this->type() == elfcpp::SHT_PREINIT_ARRAY + || this->type() == elfcpp::SHT_INIT_ARRAY + || this->type() == elfcpp::SHT_FINI_ARRAY) + std::sort(sort_list.begin(), sort_list.end(), + Input_section_sort_init_fini_compare()); + else + std::sort(sort_list.begin(), sort_list.end(), + Input_section_sort_compare()); // Copy the sorted input sections back to our list. this->input_sections_.clear(); |