diff options
author | Igor Kudrin <ikudrin@accesssoftek.com> | 2016-06-28 13:56:05 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2016-06-28 13:56:05 -0700 |
commit | f224a3c59068fc8060c261d329f54bdc7374d63a (patch) | |
tree | b7426a9f3f684eeaab4ed25c8545e670faf191fa /gold/script-sections.cc | |
parent | 9abdce70ac7a3ee8f92285c314fa7728d3c1aa43 (diff) | |
download | gdb-f224a3c59068fc8060c261d329f54bdc7374d63a.zip gdb-f224a3c59068fc8060c261d329f54bdc7374d63a.tar.gz gdb-f224a3c59068fc8060c261d329f54bdc7374d63a.tar.bz2 |
Implement SORT_BY_INIT_PRIORITY.
2016-06-28 Igor Kudrin <ikudrin@accesssoftek.com>
gold/
PR gold/18098
* script-c.h (Sort_wildcard): Add SORT_WILDCARD_BY_INIT_PRIORITY.
* script-sections.cc (Input_section_sorter::get_init_priority): New method.
(Input_section_sorter::operator()): Handle SORT_WILDCARD_BY_INIT_PRIORITY.
(Output_section_element_input::print): Likewise.
* script.cc (script_keyword_parsecodes): Add entry SORT_BY_INIT_PRIORITY.
* yyscript.y (SORT_BY_INIT_PRIORITY): New token.
(wildcard_section): Handle SORT_BY_INIT_PRIORITY.
* testsuite/Makefile.am (script_test_14): New test.
* testsuite/Makefile.in: Regenerate.
* testsuite/script_test_14.s: New test source file.
* testsuite/script_test_14.sh: New test script.
* testsuite/script_test_14.t: New test linker script.
Diffstat (limited to 'gold/script-sections.cc')
-rw-r--r-- | gold/script-sections.cc | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/gold/script-sections.cc b/gold/script-sections.cc index ef82953..96c68de 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -1524,18 +1524,69 @@ class Input_section_sorter operator()(const Input_section_info&, const Input_section_info&) const; private: + static unsigned long + get_init_priority(const char*); + Sort_wildcard filename_sort_; Sort_wildcard section_sort_; }; +// Return a relative priority of the section with the specified NAME +// (a lower value meand a higher priority), or 0 if it should be compared +// with others as strings. +// The implementation of this function is copied from ld/ldlang.c. + +unsigned long +Input_section_sorter::get_init_priority(const char* name) +{ + char* end; + unsigned long init_priority; + + // GCC uses the following section names for the init_priority + // attribute with numerical values 101 and 65535 inclusive. A + // lower value means a higher priority. + // + // 1: .init_array.NNNN/.fini_array.NNNN: Where NNNN is the + // decimal numerical value of the init_priority attribute. + // The order of execution in .init_array is forward and + // .fini_array is backward. + // 2: .ctors.NNNN/.dtors.NNNN: Where NNNN is 65535 minus the + // decimal numerical value of the init_priority attribute. + // The order of execution in .ctors is backward and .dtors + // is forward. + + if (strncmp(name, ".init_array.", 12) == 0 + || strncmp(name, ".fini_array.", 12) == 0) + { + init_priority = strtoul(name + 12, &end, 10); + return *end ? 0 : init_priority; + } + else if (strncmp(name, ".ctors.", 7) == 0 + || strncmp(name, ".dtors.", 7) == 0) + { + init_priority = strtoul(name + 7, &end, 10); + return *end ? 0 : 65535 - init_priority; + } + + return 0; +} + bool Input_section_sorter::operator()(const Input_section_info& isi1, const Input_section_info& isi2) const { + if (this->section_sort_ == SORT_WILDCARD_BY_INIT_PRIORITY) + { + unsigned long ip1 = get_init_priority(isi1.section_name().c_str()); + unsigned long ip2 = get_init_priority(isi2.section_name().c_str()); + if (ip1 != 0 && ip2 != 0 && ip1 != ip2) + return ip1 < ip2; + } if (this->section_sort_ == SORT_WILDCARD_BY_NAME || this->section_sort_ == SORT_WILDCARD_BY_NAME_BY_ALIGNMENT || (this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT_BY_NAME - && isi1.addralign() == isi2.addralign())) + && isi1.addralign() == isi2.addralign()) + || this->section_sort_ == SORT_WILDCARD_BY_INIT_PRIORITY) { if (isi1.section_name() != isi2.section_name()) return isi1.section_name() < isi2.section_name(); @@ -1827,6 +1878,10 @@ Output_section_element_input::print(FILE* f) const fprintf(f, "SORT_BY_ALIGNMENT(SORT_BY_NAME("); close_parens = 2; break; + case SORT_WILDCARD_BY_INIT_PRIORITY: + fprintf(f, "SORT_BY_INIT_PRIORITY("); + close_parens = 1; + break; default: gold_unreachable(); } |