mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
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:
parent
a6f5ef51d7
commit
2a0ff005c8
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user