diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-03-29 08:09:55 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-03-29 08:09:55 +0000 |
commit | 0a4e7c6f2e3795efd7f055ba3efa3c2e77cd2c4f (patch) | |
tree | 4c46305cdbdb035ddad987d6c76abc3c3b6f9ca3 /gold | |
parent | 7b2620a9d274c224e9b16ba346a6d444030ac01a (diff) | |
download | binutils-redhat-0a4e7c6f2e3795efd7f055ba3efa3c2e77cd2c4f.tar.gz |
* output.cc
(Output_section::Input_section_sort_entry::has_priority): New
function.
(Output_section::Input_section_sort_entry::match_file_name): New
function.
(Output_section::Input_section_sort_entry::match_section_name):
Remove.
(Output_section::Input_section_sort_entry::match_section_name_prefix):
Remove.
(Output_section::Input_section_sort_entry::match_section_file):
Remove.
(Output_section::Input_section_sort_compare::operator()): Rewrite
using new Input_section_sort_entry functions. Sort crtbegin and
crtend first. Sort sections with no priority before sections with
a priority.
* testsuite/initpri1.c (d3): Check j != 4.
(cd5): New constructor/destructor function.
(main): Check j != 2.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 19 | ||||
-rw-r--r-- | gold/output.cc | 95 | ||||
-rw-r--r-- | gold/testsuite/initpri1.c | 12 |
3 files changed, 63 insertions, 63 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index bdbac5d938..9a213c21fb 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,24 @@ 2008-03-29 Ian Lance Taylor <iant@google.com> + * output.cc + (Output_section::Input_section_sort_entry::has_priority): New + function. + (Output_section::Input_section_sort_entry::match_file_name): New + function. + (Output_section::Input_section_sort_entry::match_section_name): + Remove. + (Output_section::Input_section_sort_entry::match_section_name_prefix): + Remove. + (Output_section::Input_section_sort_entry::match_section_file): + Remove. + (Output_section::Input_section_sort_compare::operator()): Rewrite + using new Input_section_sort_entry functions. Sort crtbegin and + crtend first. Sort sections with no priority before sections with + a priority. + * testsuite/initpri1.c (d3): Check j != 4. + (cd5): New constructor/destructor function. + (main): Check j != 2. + * symtab.cc (Symbol_table::add_from_object): If we don't use the new symbol when resolving, don't call set_is_default. * testsuite/ver_test_7.cc: New file. diff --git a/gold/output.cc b/gold/output.cc index ad822d1a22..f3ae678407 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -2055,42 +2055,25 @@ class Output_section::Input_section_sort_entry return this->section_name_; } - // Return true if the section name is either SECTION_NAME1 or - // SECTION_NAME2. + // Return true if the section name has a priority. This is assumed + // to be true if it has a dot after the initial dot. bool - match_section_name(const char* section_name1, const char* section_name2) const + has_priority() const { gold_assert(this->section_has_name_); - return (this->section_name_ == section_name1 - || this->section_name_ == section_name2); + return this->section_name_.find('.', 1); } - // Return true if PREFIX1 or PREFIX2 is a prefix of the section - // name. + // 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". + // This is to match crtbegin.o as well as crtbeginS.o without + // getting confused by other possibilities. Overall matching the + // 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_section_name_prefix(const char* prefix1, const char* prefix2) const + match_file_name(const char* match_file_name) const { - gold_assert(this->section_has_name_); - return (this->section_name_.compare(0, strlen(prefix1), prefix1) == 0 - || this->section_name_.compare(0, strlen(prefix2), prefix2) == 0); - } - - // Return true if this is for a section named SECTION_NAME1 or - // SECTION_NAME2 in 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". This is to match - // crtbegin.o as well as crtbeginS.o without getting confused by - // other possibilities. Overall matching the 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_section_file(const char* section_name1, const char* section_name2, - const char* match_file_name) const - { - gold_assert(this->section_has_name_); - if (this->section_name_ != section_name1 - && this->section_name_ != section_name2) - return false; 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); @@ -2121,20 +2104,9 @@ Output_section::Input_section_sort_compare::operator()( const Output_section::Input_section_sort_entry& s1, const Output_section::Input_section_sort_entry& s2) const { - // We sort all the sections with no names to the end. - if (!s1.section_has_name() || !s2.section_has_name()) - { - if (s1.section_has_name()) - return true; - if (s2.section_has_name()) - return false; - return s1.index() < s2.index(); - } - - // A .ctors or .dtors section from crtbegin.o must come before any - // other .ctors* or .dtors* section. - bool s1_begin = s1.match_section_file(".ctors", ".dtors", "crtbegin"); - bool s2_begin = s2.match_section_file(".ctors", ".dtors", "crtbegin"); + // crtbegin.o must come first. + bool s1_begin = s1.match_file_name("crtbegin"); + bool s2_begin = s2.match_file_name("crtbegin"); if (s1_begin || s2_begin) { if (!s1_begin) @@ -2144,10 +2116,9 @@ Output_section::Input_section_sort_compare::operator()( return s1.index() < s2.index(); } - // A .ctors or .dtors section from crtend.o must come after any - // other .ctors* or .dtors* section. - bool s1_end = s1.match_section_file(".ctors", ".dtors", "crtend"); - bool s2_end = s2.match_section_file(".ctors", ".dtors", "crtend"); + // crtend.o must come last. + bool s1_end = s1.match_file_name("crtend"); + bool s2_end = s2.match_file_name("crtend"); if (s1_end || s2_end) { if (!s1_end) @@ -2157,22 +2128,24 @@ Output_section::Input_section_sort_compare::operator()( return s1.index() < s2.index(); } - // A .ctors or .init_array section with a priority precedes a .ctors - // or .init_array section without a priority. - if (s1.match_section_name_prefix(".ctors.", ".init_array.") - && s2.match_section_name(".ctors", ".init_array")) - return true; - if (s2.match_section_name_prefix(".ctors.", ".init_array.") - && s1.match_section_name(".ctors", ".init_array")) - return false; + // We sort all the sections with no names to the end. + if (!s1.section_has_name() || !s2.section_has_name()) + { + if (s1.section_has_name()) + return true; + if (s2.section_has_name()) + return false; + return s1.index() < s2.index(); + } - // A .dtors or .fini_array section with a priority follows a .dtors - // or .fini_array section without a priority. - if (s1.match_section_name_prefix(".dtors.", ".fini_array.") - && s2.match_section_name(".dtors", ".fini_array")) + // A section with a priority follows a section without a priority. + // The GNU linker does this for all but .init_array sections; until + // further notice we'll assume that that is an mistake. + bool s1_has_priority = s1.has_priority(); + bool s2_has_priority = s2.has_priority(); + if (s1_has_priority && !s2_has_priority) return false; - if (s2.match_section_name_prefix(".dtors.", ".fini_array.") - && s1.match_section_name(".dtors", ".fini_array")) + if (!s1_has_priority && s2_has_priority) return true; // Otherwise we sort by name. diff --git a/gold/testsuite/initpri1.c b/gold/testsuite/initpri1.c index 4826389b68..890df03ec4 100644 --- a/gold/testsuite/initpri1.c +++ b/gold/testsuite/initpri1.c @@ -64,7 +64,7 @@ void d2() { } void d3() { - if (j != 2) + if (j != 4) abort (); if (--i != 1) abort (); @@ -78,10 +78,18 @@ void cd4() { ++j; } +void cd5() __attribute__((constructor, destructor)); + +void cd5() { + if (i != 3) + abort(); + ++j; +} + int main () { if (i != 3) return 1; - if (j != 1) + if (j != 2) abort (); return 0; } |