aboutsummaryrefslogtreecommitdiff
path: root/gold/script-sections.cc
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin@accesssoftek.com>2016-06-28 13:56:05 -0700
committerCary Coutant <ccoutant@gmail.com>2016-06-28 13:56:05 -0700
commitf224a3c59068fc8060c261d329f54bdc7374d63a (patch)
treeb7426a9f3f684eeaab4ed25c8545e670faf191fa /gold/script-sections.cc
parent9abdce70ac7a3ee8f92285c314fa7728d3c1aa43 (diff)
downloadfsf-binutils-gdb-f224a3c59068fc8060c261d329f54bdc7374d63a.zip
fsf-binutils-gdb-f224a3c59068fc8060c261d329f54bdc7374d63a.tar.gz
fsf-binutils-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.cc57
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();
}