Index: script-sections.cc =================================================================== RCS file: /cvs/src/src/gold/script-sections.cc,v retrieving revision 1.44 diff -p -u -r1.44 script-sections.cc --- script-sections.cc 6 Oct 2010 08:58:57 -0000 1.44 +++ script-sections.cc 12 Oct 2010 19:21:23 -0000 @@ -3552,8 +3552,19 @@ Script_sections::set_section_addresses(S 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 O 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->get_allocated_sections(§ions); // 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, §ions); Index: testsuite/Makefile.am =================================================================== RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v retrieving revision 1.148 diff -p -u -r1.148 Makefile.am --- testsuite/Makefile.am 18 Sep 2010 00:34:58 -0000 1.148 +++ testsuite/Makefile.am 12 Oct 2010 19:21:23 -0000 @@ -70,12 +70,14 @@ LDADD = libgoldtest.a ../libgold.a ../.. # The unittests themselves +if NATIVE_OR_CROSS_LINKER check_PROGRAMS += object_unittest object_unittest_SOURCES = object_unittest.cc check_PROGRAMS += binary_unittest binary_unittest_SOURCES = binary_unittest.cc +endif NATIVE_OR_CROSS_LINKER # --------------------------------------------------------------------- # These tests test the output of gold (end-to-end tests). In @@ -1798,7 +1800,21 @@ memory_test.stdout: memory_test endif GCC endif NATIVE_LINKER -# These tests work with cross linkers. +# These tests work with native and cross linkers. + +if NATIVE_OR_CROSS_LINKER + +# Test script section order. +check_SCRIPTS += script_test_10.sh +check_DATA += script_test_10.stdout +script_test_10.o: script_test_10.s + $(TEST_AS) -o $@ $< +script_test_10: $(srcdir)/script_test_10.t script_test_10.o gcctestdir/ld + gcctestdir/ld -o $@ script_test_10.o -T $(srcdir)/script_test_10.t +script_test_10.stdout: script_test_10 + $(TEST_READELF) -SW script_test_10 > $@ + +# These tests work with cross linkers only. if DEFAULT_TARGET_I386 @@ -2131,3 +2147,6 @@ MOSTLYCLEANFILES += arm_cortex_a8_b_cond arm_cortex_a8_blx arm_cortex_a8_local arm_cortex_a8_local_reloc endif DEFAULT_TARGET_ARM + +endif NATIVE_OR_CROSS_LINKER +