diff options
author | Ian Lance Taylor <ian@airs.com> | 2011-06-23 00:46:14 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2011-06-23 00:46:14 +0000 |
commit | 5393d7415a71a6f2cf3752e02ef078d7ff6e5f0a (patch) | |
tree | a0c89965b041ce2f337110a23e6f7e552984c545 /gold/output.cc | |
parent | 1c23ac006028a1d2b12bdfec2fe73751fb7481ec (diff) | |
download | gdb-5393d7415a71a6f2cf3752e02ef078d7ff6e5f0a.zip gdb-5393d7415a71a6f2cf3752e02ef078d7ff6e5f0a.tar.gz gdb-5393d7415a71a6f2cf3752e02ef078d7ff6e5f0a.tar.bz2 |
PR gold/12910
* options.h (class General_options): Add --ctors-in-init-array.
* layout.cc (Layout::get_output_section): Treat SHT_INIT_ARRAY and
friends as SHT_PROGBITS for merging sections.
(Layout::layout): Remove special handling of .init_array and
friends. Don't sort if doing relocatable link. Sort for .ctors
and .dtors if ctors_in_init_array.
(Layout::make_output_section): Force correct section types for
.init_array and friends. Don't sort if doing relocatable link,
Don't sort .ctors and .dtors if ctors_in_init_array.
(Layout::section_name_mapping): Remove .ctors. and .dtorso.
(Layout::output_section_name): Add relobj parameter. Change all
callers. Handle .ctors. and .dtors. in code rather than table.
Handle .ctors and .dtors if ctors_in_init_array.
(Layout::match_file_name): New function, moved from output.cc.
* layout.h (class Layout): Update declarations.
* output.cc: Include "layout.h".
(Input_section_sort_entry::get_priority): New function.
(Input_section_sort_entry::match_file_name): Just call
Layout::match_file_name.
(Output_section::Input_section_sort_init_fini_compare::operator()):
Handle .ctors and .dtors. Sort by explicit priority rather than
by name.
* configure.ac: Remove CONSTRUCTOR_PRIORITY test and conditional.
* testsuite/initpri2.c: New test.
* testsuite/Makefile.am: Don't test CONSTRUCTOR_PRIORITY.
(check_PROGRAMS): Add initpri2.
(initpri2_SOURCES, initpri2_DEPENDENCIES): New variables.
(initpri2_LDFLAGS, initpri2_LDADD): New variables.
* configure, testsuite/Makefile.in: Rebuild.
Diffstat (limited to 'gold/output.cc')
-rw-r--r-- | gold/output.cc | 67 |
1 files changed, 54 insertions, 13 deletions
diff --git a/gold/output.cc b/gold/output.cc index c7d3e9f..8912c4e 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -42,6 +42,7 @@ #include "reloc.h" #include "merge.h" #include "descriptors.h" +#include "layout.h" #include "output.h" // For systems without mmap support. @@ -3017,7 +3018,7 @@ Output_section::do_set_tls_offset(uint64_t tls_base) // priority ordering implemented by the GNU linker, in which the // priority becomes part of the section name and the sections are // sorted by name. We only do this for an output section if we see an -// attached input section matching ".ctor.*", ".dtor.*", +// attached input section matching ".ctors.*", ".dtors.*", // ".init_array.*" or ".fini_array.*". class Output_section::Input_section_sort_entry @@ -3092,6 +3093,34 @@ class Output_section::Input_section_sort_entry return this->section_name_.find('.', 1) != std::string::npos; } + // Return the priority. Believe it or not, gcc encodes the priority + // differently for .ctors/.dtors and .init_array/.fini_array + // sections. + unsigned int + get_priority() const + { + gold_assert(this->section_has_name_); + bool is_ctors; + if (is_prefix_of(".ctors.", this->section_name_.c_str()) + || is_prefix_of(".dtors.", this->section_name_.c_str())) + is_ctors = true; + else if (is_prefix_of(".init_array.", this->section_name_.c_str()) + || is_prefix_of(".fini_array.", this->section_name_.c_str())) + is_ctors = false; + else + return 0; + char* end; + unsigned long prio = strtoul((this->section_name_.c_str() + + (is_ctors ? 7 : 12)), + &end, 10); + if (*end != '\0') + return 0; + else if (is_ctors) + return 65535 - prio; + else + return prio; + } + // Return true if this an input file whose base name matches // FILE_NAME. The base name must have an extension of ".o", and // must be exactly FILE_NAME.o or FILE_NAME, one character, ".o". @@ -3100,18 +3129,8 @@ class Output_section::Input_section_sort_entry // file name this way is a dreadful hack, but the GNU linker does it // in order to better support gcc, and we need to be compatible. bool - match_file_name(const char* match_file_name) const - { - const std::string& file_name(this->input_section_.relobj()->name()); - const char* base_name = lbasename(file_name.c_str()); - size_t match_len = strlen(match_file_name); - if (strncmp(base_name, match_file_name, match_len) != 0) - return false; - size_t base_len = strlen(base_name); - if (base_len != match_len + 2 && base_len != match_len + 3) - return false; - return memcmp(base_name + base_len - 2, ".o", 2) == 0; - } + match_file_name(const char* file_name) const + { 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. @@ -3233,6 +3252,28 @@ Output_section::Input_section_sort_init_fini_compare::operator()( if (!s1_has_priority && s2_has_priority) return false; + // .ctors and .dtors sections without priority come after + // .init_array and .fini_array sections without priority. + if (!s1_has_priority + && (s1.section_name() == ".ctors" || s1.section_name() == ".dtors") + && s1.section_name() != s2.section_name()) + return false; + if (!s2_has_priority + && (s2.section_name() == ".ctors" || s2.section_name() == ".dtors") + && s2.section_name() != s1.section_name()) + return true; + + // Sort by priority if we can. + if (s1_has_priority) + { + unsigned int s1_prio = s1.get_priority(); + unsigned int s2_prio = s2.get_priority(); + if (s1_prio < s2_prio) + return true; + else if (s1_prio > s2_prio) + 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); |