2010-03-01 Doug Kwan <dougkwan@google.com>

* layout.cc (Layout::Layout): Force section types of .init_array*,
	.preinit_array* and .fini_array* sections.
	* output.cc (Output_section::Input_section_sort_entry::has_priority):
	Fix check of return value of std::string::find.().
	(Output_section::Input_section_sort_compare::operator()): Remove
	comment about .init_array.
	(Output_section::Input_section_sort_init_fini_compare::operator()):
	New method.
	(Output_section::sort_attached_input_sections): Handle .init_array
	and .fini_array specially.
	* output.h (Output_section::Inut_section_sort_compare): Update
	comment.
	(Output_section::Input_section_sort_init_fini_compare): New struct.
This commit is contained in:
Doug Kwan 2010-03-01 21:43:50 +00:00
parent a6f5ef51d7
commit 2a0ff005c8
4 changed files with 95 additions and 9 deletions

View File

@ -1,3 +1,19 @@
2010-03-01 Doug Kwan <dougkwan@google.com>
* layout.cc (Layout::Layout): Force section types of .init_array*,
.preinit_array* and .fini_array* sections.
* output.cc (Output_section::Input_section_sort_entry::has_priority):
Fix check of return value of std::string::find.().
(Output_section::Input_section_sort_compare::operator()): Remove
comment about .init_array.
(Output_section::Input_section_sort_init_fini_compare::operator()):
New method.
(Output_section::sort_attached_input_sections): Handle .init_array
and .fini_array specially.
* output.h (Output_section::Inut_section_sort_compare): Update
comment.
(Output_section::Input_section_sort_init_fini_compare): New struct.
2010-02-26 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::Relocate::reloc_is_non_pic): Treat

View File

@ -582,19 +582,40 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
Output_section* os;
// Sometimes .init_array*, .preinit_array* and .fini_array* do not have
// correct section types. Force them here.
elfcpp::Elf_Word sh_type = shdr.get_sh_type();
if (sh_type == elfcpp::SHT_PROGBITS)
{
static const char init_array_prefix[] = ".init_array";
static const char preinit_array_prefix[] = ".preinit_array";
static const char fini_array_prefix[] = ".fini_array";
static size_t init_array_prefix_size = sizeof(init_array_prefix) - 1;
static size_t preinit_array_prefix_size =
sizeof(preinit_array_prefix) - 1;
static size_t fini_array_prefix_size = sizeof(fini_array_prefix) - 1;
if (strncmp(name, init_array_prefix, init_array_prefix_size) == 0)
sh_type = elfcpp::SHT_INIT_ARRAY;
else if (strncmp(name, preinit_array_prefix, preinit_array_prefix_size)
== 0)
sh_type = elfcpp::SHT_PREINIT_ARRAY;
else if (strncmp(name, fini_array_prefix, fini_array_prefix_size) == 0)
sh_type = elfcpp::SHT_FINI_ARRAY;
}
// In a relocatable link a grouped section must not be combined with
// any other sections.
if (parameters->options().relocatable()
&& (shdr.get_sh_flags() & elfcpp::SHF_GROUP) != 0)
{
name = this->namepool_.add(name, true, NULL);
os = this->make_output_section(name, shdr.get_sh_type(),
shdr.get_sh_flags(), false, false,
false, false, false);
os = this->make_output_section(name, sh_type, shdr.get_sh_flags(), false,
false, false, false, false);
}
else
{
os = this->choose_output_section(object, name, shdr.get_sh_type(),
os = this->choose_output_section(object, name, sh_type,
shdr.get_sh_flags(), true, false,
false, false, false, false);
if (os == NULL)

View File

@ -2695,7 +2695,7 @@ class Output_section::Input_section_sort_entry
has_priority() const
{
gold_assert(this->section_has_name_);
return this->section_name_.find('.', 1);
return this->section_name_.find('.', 1) != std::string::npos;
}
// Return true if this an input file whose base name matches
@ -2773,8 +2773,6 @@ Output_section::Input_section_sort_compare::operator()(
}
// 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)
@ -2791,6 +2789,42 @@ Output_section::Input_section_sort_compare::operator()(
return s1.index() < s2.index();
}
// Return true if S1 should come before S2 in an .init_array or .fini_array
// output section.
bool
Output_section::Input_section_sort_init_fini_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 section without a priority follows a section with a priority.
// This is the reverse of .ctors and .dtors sections.
bool s1_has_priority = s1.has_priority();
bool s2_has_priority = s2.has_priority();
if (s1_has_priority && !s2_has_priority)
return true;
if (!s1_has_priority && s2_has_priority)
return false;
// Otherwise we sort by name.
int compare = s1.section_name().compare(s2.section_name());
if (compare != 0)
return compare < 0;
// Otherwise we keep the input order.
return s1.index() < s2.index();
}
// Sort the input sections attached to an output section.
void
@ -2819,7 +2853,14 @@ Output_section::sort_attached_input_sections()
sort_list.push_back(Input_section_sort_entry(*p, i));
// Sort the input sections.
std::sort(sort_list.begin(), sort_list.end(), Input_section_sort_compare());
if (this->type() == elfcpp::SHT_PREINIT_ARRAY
|| this->type() == elfcpp::SHT_INIT_ARRAY
|| this->type() == elfcpp::SHT_FINI_ARRAY)
std::sort(sort_list.begin(), sort_list.end(),
Input_section_sort_init_fini_compare());
else
std::sort(sort_list.begin(), sort_list.end(),
Input_section_sort_compare());
// Copy the sorted input sections back to our list.
this->input_sections_.clear();

View File

@ -3378,7 +3378,7 @@ class Output_section : public Output_data
// This class is used to sort the input sections.
class Input_section_sort_entry;
// This is the sort comparison function.
// This is the sort comparison function for ctors and dtors.
struct Input_section_sort_compare
{
bool
@ -3386,6 +3386,14 @@ class Output_section : public Output_data
const Input_section_sort_entry&) const;
};
// This is the sort comparison function for .init_array and .fini_array.
struct Input_section_sort_init_fini_compare
{
bool
operator()(const Input_section_sort_entry&,
const Input_section_sort_entry&) const;
};
// Fill data. This is used to fill in data between input sections.
// It is also used for data statements (BYTE, WORD, etc.) in linker
// scripts. When we have to keep track of the input sections, we