diff options
author | Sriraman Tallam <tmsriram@google.com> | 2010-06-01 23:37:58 +0000 |
---|---|---|
committer | Sriraman Tallam <tmsriram@google.com> | 2010-06-01 23:37:58 +0000 |
commit | 6e9ba2ca9c85e1d04123b87af1d57d57a5e6e82a (patch) | |
tree | 8b4563c393ebbff8629de584992234b3c6ff6e67 /gold/output.cc | |
parent | ae4d0c03d93ab5c671f7cb68c736ae2f28f3ec0b (diff) | |
download | gdb-6e9ba2ca9c85e1d04123b87af1d57d57a5e6e82a.zip gdb-6e9ba2ca9c85e1d04123b87af1d57d57a5e6e82a.tar.gz gdb-6e9ba2ca9c85e1d04123b87af1d57d57a5e6e82a.tar.bz2 |
* gold.h (is_wildcard_string): New function.
* layout.cc (Layout::layout): Pass this pointer to add_input_section.
(Layout::layout_eh_frame): Ditto.
(Layout::find_section_order_index): New method.
(Layout::read_layout_from_file): New method.
* layout.h (Layout::find_section_order_index): New method.
(Layout::read_layout_from_file): New method.
(Layout::input_section_position_): New private member.
(Layout::input_section_glob_): New private member.
* main.cc (main): Call read_layout_from_file here.
* options.h (--section-ordering-file): New option.
* output.cc (Output_section::input_section_order_specified_): New
member.
(Output_section::Output_section): Initialize new member.
(Output_section::add_input_section): Add new parameter.
Keep input sections when --section-ordering-file is used.
(Output_section::set_final_data_size): Sort input sections when
section ordering file is specified.
(Output_section::Input_section_sort_entry): Add new parameter.
Check sorting type.
(Output_section::Input_section_sort_entry::compare_section_ordering):
New method.
(Output_section::Input_section_sort_compare::operator()): Change to
consider section_order_index.
(Output_section::Input_section_sort_init_fini_compare::operator()):
Change to consider section_order_index.
(Output_section::Input_section_sort_section_order_index_compare
::operator()): New method.
(Output_section::sort_attached_input_sections): Change to sort
according to section order when specified.
(Output_section::add_input_section<32, true>): Add new parameter.
(Output_section::add_input_section<64, true>): Add new parameter.
(Output_section::add_input_section<32, false>): Add new parameter.
(Output_section::add_input_section<64, false>): Add new parameter.
* output.h (Output_section::add_input_section): Add new parameter.
(Output_section::input_section_order_specified): New
method.
(Output_section::set_input_section_order_specified): New method.
(Input_section::Input_section): Initialize section_order_index_.
(Input_section::section_order_index): New method.
(Input_section::set_section_order_index): New method.
(Input_section::section_order_index_): New member.
(Input_section::Input_section_sort_section_order_index_compare): New
struct.
(Output_section::input_section_order_specified_): New member.
* script-sections.cc (is_wildcard_string): Delete and move modified
method to gold.h.
(Output_section_element_input::Output_section_element_input): Modify
call to is_wildcard_string.
(Output_section_element_input::Input_section_pattern
::Input_section_pattern): Ditto.
(Output_section_element_input::Output_section_element_input): Ditto.
* testsuite/Makefile.am (final_layout): New test case.
* testsuite/Makefile.in: Regenerate.
* testsuite/final_layout.cc: New file.
* testsuite/final_layout.sh: New file.
Diffstat (limited to 'gold/output.cc')
-rw-r--r-- | gold/output.cc | 112 |
1 files changed, 95 insertions, 17 deletions
diff --git a/gold/output.cc b/gold/output.cc index 752a1d3..3cfcf1e 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1933,6 +1933,7 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type, found_in_sections_clause_(false), has_load_address_(false), info_uses_section_index_(false), + input_section_order_specified_(false), may_sort_attached_input_sections_(false), must_sort_attached_input_sections_(false), attached_input_sections_are_sorted_(false), @@ -1994,7 +1995,8 @@ Output_section::set_entsize(uint64_t v) template<int size, bool big_endian> off_t -Output_section::add_input_section(Sized_relobj<size, big_endian>* object, +Output_section::add_input_section(Layout* layout, + Sized_relobj<size, big_endian>* object, unsigned int shndx, const char* secname, const elfcpp::Shdr<size, big_endian>& shdr, @@ -2090,16 +2092,30 @@ Output_section::add_input_section(Sized_relobj<size, big_endian>* object, // We need to keep track of this section if we are already keeping // track of sections, or if we are relaxing. Also, if this is a // section which requires sorting, or which may require sorting in - // the future, we keep track of the sections. + // the future, we keep track of the sections. If the + // --section-ordering-file option is used to specify the order of + // sections, we need to keep track of sections. if (have_sections_script || !this->input_sections_.empty() || this->may_sort_attached_input_sections() || this->must_sort_attached_input_sections() || parameters->options().user_set_Map() - || parameters->target().may_relax()) - this->input_sections_.push_back(Input_section(object, shndx, - shdr.get_sh_size(), - addralign)); + || parameters->target().may_relax() + || parameters->options().section_ordering_file()) + { + Input_section isecn(object, shndx, shdr.get_sh_size(), addralign); + if (parameters->options().section_ordering_file()) + { + unsigned int section_order_index = + layout->find_section_order_index(std::string(secname)); + if (section_order_index != 0) + { + isecn.set_section_order_index(section_order_index); + this->set_input_section_order_specified(); + } + } + this->input_sections_.push_back(isecn); + } return aligned_offset_in_section; } @@ -2623,7 +2639,8 @@ Output_section::set_final_data_size() return; } - if (this->must_sort_attached_input_sections()) + if (this->must_sort_attached_input_sections() + || this->input_section_order_specified()) this->sort_attached_input_sections(); uint64_t address = this->address(); @@ -2700,12 +2717,14 @@ class Output_section::Input_section_sort_entry { } Input_section_sort_entry(const Input_section& input_section, - unsigned int index) + unsigned int index, + bool must_sort_attached_input_sections) : input_section_(input_section), index_(index), section_has_name_(input_section.is_input_section() || input_section.is_relaxed_input_section()) { - if (this->section_has_name_) + if (this->section_has_name_ + && must_sort_attached_input_sections) { // This is only called single-threaded from Layout::finalize, // so it is OK to lock. Unfortunately we have no way to pass @@ -2782,6 +2801,22 @@ class Output_section::Input_section_sort_entry return memcmp(base_name + base_len - 2, ".o", 2) == 0; } + // Returns 0 if sections are not comparable. Returns 1 if THIS is the + // first section in order, returns -1 for S. + int + compare_section_ordering(const Input_section_sort_entry& s) const + { + gold_assert(this->index_ != -1U); + if (this->input_section_.section_order_index() == 0 + || s.input_section().section_order_index() == 0) + return 0; + if (this->input_section_.section_order_index() + < s.input_section().section_order_index()) + return 1; + else + return -1; + } + private: // The Input_section we are sorting. Input_section input_section_; @@ -2843,6 +2878,12 @@ Output_section::Input_section_sort_compare::operator()( if (!s1_has_priority && s2_has_priority) return true; + // Check if a section order exists for these sections through a section + // ordering file. If sequence_num is 0, an order does not exist. + int sequence_num = s1.compare_section_ordering(s2); + if (sequence_num != 0) + return sequence_num == 1; + // Otherwise we sort by name. int compare = s1.section_name().compare(s2.section_name()); if (compare != 0) @@ -2879,6 +2920,12 @@ Output_section::Input_section_sort_init_fini_compare::operator()( if (!s1_has_priority && s2_has_priority) return false; + // Check if a section order exists for these sections through a section + // ordering file. If sequence_num is 0, an order does not exist. + int sequence_num = s1.compare_section_ordering(s2); + if (sequence_num != 0) + return sequence_num == 1; + // Otherwise we sort by name. int compare = s1.section_name().compare(s2.section_name()); if (compare != 0) @@ -2888,6 +2935,22 @@ Output_section::Input_section_sort_init_fini_compare::operator()( return s1.index() < s2.index(); } +// Return true if S1 should come before S2. +bool +Output_section::Input_section_sort_section_order_index_compare::operator()( + const Output_section::Input_section_sort_entry& s1, + const Output_section::Input_section_sort_entry& s2) const +{ + // Check if a section order exists for these sections through a section + // ordering file. If sequence_num is 0, an order does not exist. + int sequence_num = s1.compare_section_ordering(s2); + if (sequence_num != 0) + return sequence_num == 1; + + // Otherwise we keep the input order. + return s1.index() < s2.index(); +} + // Sort the input sections attached to an output section. void @@ -2913,17 +2976,27 @@ Output_section::sort_attached_input_sections() for (Input_section_list::iterator p = this->input_sections_.begin(); p != this->input_sections_.end(); ++p, ++i) - sort_list.push_back(Input_section_sort_entry(*p, i)); + sort_list.push_back(Input_section_sort_entry(*p, i, + this->must_sort_attached_input_sections())); // Sort the input sections. - 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()); + if (this->must_sort_attached_input_sections()) + { + 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()); + } else - std::sort(sort_list.begin(), sort_list.end(), - Input_section_sort_compare()); + { + gold_assert(parameters->options().section_ordering_file()); + std::sort(sort_list.begin(), sort_list.end(), + Input_section_sort_section_order_index_compare()); + } // Copy the sorted input sections back to our list. this->input_sections_.clear(); @@ -2931,6 +3004,7 @@ Output_section::sort_attached_input_sections() p != sort_list.end(); ++p) this->input_sections_.push_back(p->input_section()); + sort_list.clear(); // Remember that we sorted the input sections, since we might get // called again. @@ -4466,6 +4540,7 @@ Output_file::close() template off_t Output_section::add_input_section<32, false>( + Layout* layout, Sized_relobj<32, false>* object, unsigned int shndx, const char* secname, @@ -4478,6 +4553,7 @@ Output_section::add_input_section<32, false>( template off_t Output_section::add_input_section<32, true>( + Layout* layout, Sized_relobj<32, true>* object, unsigned int shndx, const char* secname, @@ -4490,6 +4566,7 @@ Output_section::add_input_section<32, true>( template off_t Output_section::add_input_section<64, false>( + Layout* layout, Sized_relobj<64, false>* object, unsigned int shndx, const char* secname, @@ -4502,6 +4579,7 @@ Output_section::add_input_section<64, false>( template off_t Output_section::add_input_section<64, true>( + Layout* layout, Sized_relobj<64, true>* object, unsigned int shndx, const char* secname, |