diff options
author | Alexander Ivchenko <alexander.ivchenko@intel.com> | 2013-01-25 14:35:38 +0400 |
---|---|---|
committer | Alexander Ivchenko <alexander.ivchenko@intel.com> | 2013-01-25 15:38:32 +0400 |
commit | 43cc3f59831134ed0b2447bb21767371417ac54a (patch) | |
tree | c10353fa1c13ac509d4d2269f8d15ac71d78eee4 | |
parent | 8415ff0aaeb157307bb01a45373dba81919882fc (diff) | |
download | toolchain_binutils-43cc3f59831134ed0b2447bb21767371417ac54a.zip toolchain_binutils-43cc3f59831134ed0b2447bb21767371417ac54a.tar.gz toolchain_binutils-43cc3f59831134ed0b2447bb21767371417ac54a.tar.bz2 |
[2.22.90] Backport of two patches from mainline that enable
sorting of text sections
Author: Sriraman Tallam <tmsriram@google.com>
Date: Thu Jan 10 00:18:14 2013 +0000
Make linker scripts and section ordering via --section-ordering-file or
linker plugins work. This patch lets linker scripts take precedence.
2013-01-09 Sriraman Tallam <tmsriram@google.com>
* output.h (sort_attached_input_sections): Change to be public.
* script-sections.cc
(Output_section_definition::set_section_addresses): Sort
attached input sections according to section order before linker
script assigns section addresses.
(Orphan_output_section::set_section_addresses): Sort
attached input sections according to section order before linker
script assigns section addresses.
* Makefile.am (final_layout.sh): Use a simple linker script to
check if section ordering still works.
* Makefile.in: Regenerate.
Author: Ian Lance Taylor <ian@airs.com>
Date: Fri Dec 21 06:24:31 2012 +0000
* layout.cc (Layout::special_ordering_of_input_section): New
function.
(Layout::layout): If input section requires special ordering, must
sort input sections.
(Layout::make_output_section): May sort .text input sections.
(Layout::is_section_name_prefix_grouped): Remove.
* layout.h (class Layout): Declare
special_ordering_of_input_section. Don't declare
is_section_name_prefix_grouped.
* output.cc (Output_section::add_input_section): Revert last
change.
(Output_section::Input_section_sort::match_file_name): Don't crash
if called on output section data.
(Output_section::Input_section_sort_compare): Sort based on
special ordering.
(Output_section::Input_section_sort_section_order_index_compare):
Revert last patch.
(Output_section::sort_attached_input_sections): Likewise.
Change-Id: I385c609300f697abcdeb82324c9af903259fe2b6
-rw-r--r-- | binutils-2.22/gold/layout.cc | 43 | ||||
-rw-r--r-- | binutils-2.22/gold/layout.h | 8 | ||||
-rw-r--r-- | binutils-2.22/gold/output.cc | 19 |
3 files changed, 69 insertions, 1 deletions
diff --git a/binutils-2.22/gold/layout.cc b/binutils-2.22/gold/layout.cc index ad667ab..cc800cd 100644 --- a/binutils-2.22/gold/layout.cc +++ b/binutils-2.22/gold/layout.cc @@ -993,6 +993,33 @@ Layout::init_fixed_output_section(const char* name, return os; } +// Return the index by which an input section should be ordered. This +// is used to sort some .text sections, for compatibility with GNU ld. + +int +Layout::special_ordering_of_input_section(const char* name) +{ + // The GNU linker has some special handling for some sections that + // wind up in the .text section. Sections that start with these + // prefixes must appear first, and must appear in the order listed + // here. + static const char* const text_section_sort[] = + { + ".text.unlikely", + ".text.exit", + ".text.startup", + ".text.hot" + }; + + for (size_t i = 0; + i < sizeof(text_section_sort) / sizeof(text_section_sort[0]); + i++) + if (is_prefix_of(text_section_sort[i], name)) + return i; + + return -1; +} + // Return the output section to use for input section SHNDX, with name // NAME, with header HEADER, from object OBJECT. RELOC_SHNDX is the // index of a relocation section which applies to this section, or 0 @@ -1052,6 +1079,13 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx, || strcmp(name, ".dtors") == 0)))) os->set_must_sort_attached_input_sections(); + // By default the GNU linker sorts some special text sections ahead + // of others. We are compatible. + if (!this->script_options_->saw_sections_clause() + && !parameters->options().relocatable() + && Layout::special_ordering_of_input_section(name) >= 0) + os->set_must_sort_attached_input_sections(); + // If this is a .ctors or .ctors.* section being mapped to a // .init_array section, or a .dtors or .dtors.* section being mapped // to a .fini_array section, we will need to reverse the words if @@ -1530,6 +1564,15 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type, || strcmp(name, ".dtors") == 0)))) os->set_may_sort_attached_input_sections(); + // The GNU linker by default sorts .text.{unlikely,exit,startup,hot} + // sections before other .text sections. We are compatible. We + // need to know that this might happen before we attach any input + // sections. + if (!this->script_options_->saw_sections_clause() + && !parameters->options().relocatable() + && strcmp(name, ".text") == 0) + os->set_may_sort_attached_input_sections(); + // Check for .stab*str sections, as .stab* sections need to link to // them. if (type == elfcpp::SHT_STRTAB diff --git a/binutils-2.22/gold/layout.h b/binutils-2.22/gold/layout.h index 4643e32..fc8675f 100644 --- a/binutils-2.22/gold/layout.h +++ b/binutils-2.22/gold/layout.h @@ -528,6 +528,14 @@ class Layout get_section_order_map() { return &this->section_order_map_; } + // Some input sections require special ordering, for compatibility + // with GNU ld. Given the name of an input section, return -1 if it + // does not require special ordering. Otherwise, return the index + // by which it should be ordered compared to other input sections + // that require special ordering. + static int + special_ordering_of_input_section(const char* name); + bool is_section_ordering_specified() { return this->section_ordering_specified_; } diff --git a/binutils-2.22/gold/output.cc b/binutils-2.22/gold/output.cc index aceee1b..82e2ea7 100644 --- a/binutils-2.22/gold/output.cc +++ b/binutils-2.22/gold/output.cc @@ -3259,7 +3259,11 @@ class Output_section::Input_section_sort_entry // in order to better support gcc, and we need to be compatible. bool match_file_name(const char* file_name) const - { return Layout::match_file_name(this->input_section_.relobj(), file_name); } + { + if (this->input_section_.is_output_section_data()) + return false; + return Layout::match_file_name(this->input_section_.relobj(), file_name); + } // Returns 1 if THIS should appear before S in section order, -1 if S // appears before THIS and 0 if they are not comparable. @@ -3331,6 +3335,19 @@ Output_section::Input_section_sort_compare::operator()( 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()); + if (o1 != o2) + { + if (o1 < 0) + return false; + else if (o2 < 0) + return true; + else + return o1 < o2; + } + // 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(); |