summaryrefslogtreecommitdiff
path: root/gold/script-sections.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2010-10-12 19:21:41 +0000
committerIan Lance Taylor <ian@airs.com>2010-10-12 19:21:41 +0000
commiteb3730490ec71b6e8a9d63a0348b40d484041db5 (patch)
tree35f77a081e9d01a073baecec2ae2e8677d9f0589 /gold/script-sections.cc
parent3cef71791839860d05c8c4246c4e1ce2520b44ca (diff)
* script-sections.h (class Script_sections): Make
Sections_elements typedef public. * script-sections.cc (class Sort_output_sections): Add elements_ field. Add constructor which sets it; change all callers. (Sort_output_sections::is_before): New function. (Sort_output_sections::operator()): Call is_before. * configure.ac (NATIVE_OR_CROSS_LINKER): New automake conditional. * testsuite/script_test_10.sh: New test. Test script section order. * testsuite/script_test_10.t: Likewise. * testsuite/script_test_10.s: Likewise. * testsuite/Makefile.am: Wrap the cross linker tests and the common tests into NATIVE_OR_CROSS_LINKER. (check_SCRIPTS): Add script_test_10.sh. (check_DATA): Add script_test_10.stdout. (script_test_10.o, script_test_10): New targets. (script_test_10.stdout): New target. * configure, testsuite/Makefile.in: Regenerate.
Diffstat (limited to 'gold/script-sections.cc')
-rw-r--r--gold/script-sections.cc45
1 files changed, 43 insertions, 2 deletions
diff --git a/gold/script-sections.cc b/gold/script-sections.cc
index 550a6a39be..57e5279dd2 100644
--- a/gold/script-sections.cc
+++ b/gold/script-sections.cc
@@ -3552,8 +3552,19 @@ Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout)
class Sort_output_sections
{
public:
+ Sort_output_sections(const Script_sections::Sections_elements* elements)
+ : elements_(elements)
+ { }
+
bool
operator()(const Output_section* os1, const Output_section* os2) const;
+
+ private:
+ bool
+ is_before(const Output_section* os1, const Output_section* os2) const;
+
+ private:
+ const Script_sections::Sections_elements* elements_;
};
bool
@@ -3592,7 +3603,36 @@ Sort_output_sections::operator()(const Output_section* os1,
if (!os1->is_noload() && os2->is_noload())
return true;
- // Otherwise we don't care.
+ // The sections have the same address. Check the section positions
+ // in accordance with the linker script.
+ return this->is_before(os1, os2);
+}
+
+// Return true if OS1 comes before OS2 in ELEMENTS_. This ensures
+// that we keep empty sections in the order in which they appear in a
+// linker script.
+
+bool
+Sort_output_sections::is_before(const Output_section* os1,
+ const Output_section* os2) const
+{
+ if (this->elements_ == NULL)
+ return false;
+
+ for (Script_sections::Sections_elements::const_iterator
+ p = this->elements_->begin();
+ p != this->elements_->end();
+ ++p)
+ {
+ if (os1 == (*p)->get_output_section())
+ {
+ for (++p; p != this->elements_->end(); ++p)
+ if (os2 == (*p)->get_output_section())
+ return true;
+ break;
+ }
+ }
+
return false;
}
@@ -3666,7 +3706,8 @@ Script_sections::create_segments(Layout* layout, uint64_t dot_alignment)
layout->get_allocated_sections(&sections);
// Sort the sections by address.
- std::stable_sort(sections.begin(), sections.end(), Sort_output_sections());
+ std::stable_sort(sections.begin(), sections.end(),
+ Sort_output_sections(this->sections_elements_));
this->create_note_and_tls_segments(layout, &sections);