* 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.
This commit is contained in:
parent
479f65031f
commit
ab794b6bda
|
@ -1,5 +1,24 @@
|
||||||
2008-03-29 Ian Lance Taylor <iant@google.com>
|
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
|
* symtab.cc (Symbol_table::add_from_object): If we don't use the
|
||||||
new symbol when resolving, don't call set_is_default.
|
new symbol when resolving, don't call set_is_default.
|
||||||
* testsuite/ver_test_7.cc: New file.
|
* testsuite/ver_test_7.cc: New file.
|
||||||
|
|
113
gold/output.cc
113
gold/output.cc
|
@ -2055,42 +2055,25 @@ class Output_section::Input_section_sort_entry
|
||||||
return this->section_name_;
|
return this->section_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the section name is either SECTION_NAME1 or
|
// Return true if the section name has a priority. This is assumed
|
||||||
// SECTION_NAME2.
|
// to be true if it has a dot after the initial dot.
|
||||||
bool
|
bool
|
||||||
match_section_name(const char* section_name1, const char* section_name2) const
|
has_priority() const
|
||||||
{
|
{
|
||||||
gold_assert(this->section_has_name_);
|
gold_assert(this->section_has_name_);
|
||||||
return (this->section_name_ == section_name1
|
return this->section_name_.find('.', 1);
|
||||||
|| this->section_name_ == section_name2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if PREFIX1 or PREFIX2 is a prefix of the section
|
// Return true if this an input file whose base name matches
|
||||||
// name.
|
// 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
|
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 std::string& file_name(this->input_section_.relobj()->name());
|
||||||
const char* base_name = lbasename(file_name.c_str());
|
const char* base_name = lbasename(file_name.c_str());
|
||||||
size_t match_len = strlen(match_file_name);
|
size_t match_len = strlen(match_file_name);
|
||||||
|
@ -2121,6 +2104,30 @@ Output_section::Input_section_sort_compare::operator()(
|
||||||
const Output_section::Input_section_sort_entry& s1,
|
const Output_section::Input_section_sort_entry& s1,
|
||||||
const Output_section::Input_section_sort_entry& s2) const
|
const Output_section::Input_section_sort_entry& s2) const
|
||||||
{
|
{
|
||||||
|
// 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)
|
||||||
|
return false;
|
||||||
|
if (!s2_begin)
|
||||||
|
return true;
|
||||||
|
return s1.index() < s2.index();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
return true;
|
||||||
|
if (!s2_end)
|
||||||
|
return false;
|
||||||
|
return s1.index() < s2.index();
|
||||||
|
}
|
||||||
|
|
||||||
// We sort all the sections with no names to the end.
|
// 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() || !s2.section_has_name())
|
||||||
{
|
{
|
||||||
|
@ -2131,48 +2138,14 @@ Output_section::Input_section_sort_compare::operator()(
|
||||||
return s1.index() < s2.index();
|
return s1.index() < s2.index();
|
||||||
}
|
}
|
||||||
|
|
||||||
// A .ctors or .dtors section from crtbegin.o must come before any
|
// A section with a priority follows a section without a priority.
|
||||||
// other .ctors* or .dtors* section.
|
// The GNU linker does this for all but .init_array sections; until
|
||||||
bool s1_begin = s1.match_section_file(".ctors", ".dtors", "crtbegin");
|
// further notice we'll assume that that is an mistake.
|
||||||
bool s2_begin = s2.match_section_file(".ctors", ".dtors", "crtbegin");
|
bool s1_has_priority = s1.has_priority();
|
||||||
if (s1_begin || s2_begin)
|
bool s2_has_priority = s2.has_priority();
|
||||||
{
|
if (s1_has_priority && !s2_has_priority)
|
||||||
if (!s1_begin)
|
|
||||||
return false;
|
|
||||||
if (!s2_begin)
|
|
||||||
return true;
|
|
||||||
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");
|
|
||||||
if (s1_end || s2_end)
|
|
||||||
{
|
|
||||||
if (!s1_end)
|
|
||||||
return true;
|
|
||||||
if (!s2_end)
|
|
||||||
return false;
|
|
||||||
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;
|
return false;
|
||||||
|
if (!s1_has_priority && s2_has_priority)
|
||||||
// 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"))
|
|
||||||
return false;
|
|
||||||
if (s2.match_section_name_prefix(".dtors.", ".fini_array.")
|
|
||||||
&& s1.match_section_name(".dtors", ".fini_array"))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise we sort by name.
|
// Otherwise we sort by name.
|
||||||
|
|
|
@ -64,7 +64,7 @@ void d2() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void d3() {
|
void d3() {
|
||||||
if (j != 2)
|
if (j != 4)
|
||||||
abort ();
|
abort ();
|
||||||
if (--i != 1)
|
if (--i != 1)
|
||||||
abort ();
|
abort ();
|
||||||
|
@ -78,10 +78,18 @@ void cd4() {
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cd5() __attribute__((constructor, destructor));
|
||||||
|
|
||||||
|
void cd5() {
|
||||||
|
if (i != 3)
|
||||||
|
abort();
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
|
||||||
int main () {
|
int main () {
|
||||||
if (i != 3)
|
if (i != 3)
|
||||||
return 1;
|
return 1;
|
||||||
if (j != 1)
|
if (j != 2)
|
||||||
abort ();
|
abort ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue