aboutsummaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2010-03-01 21:43:50 +0000
committerDoug Kwan <dougkwan@google.com>2010-03-01 21:43:50 +0000
commit2a0ff005c89d674c7e233c7fa612aa2434bcd8df (patch)
treef7cdface7116bfdf3188bd6d8b844deff74b551d /gold/output.cc
parenta6f5ef51d7c85bd0b950fd182284f6cbff5fecf0 (diff)
downloadfsf-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.cc49
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();