aboutsummaryrefslogtreecommitdiff
path: root/gold/layout.cc
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2010-03-01 21:43:50 +0000
committerDoug Kwan <dougkwan@google.com>2010-03-01 21:43:50 +0000
commit2a0ff005c89d674c7e233c7fa612aa2434bcd8df (patch)
treef7cdface7116bfdf3188bd6d8b844deff74b551d /gold/layout.cc
parenta6f5ef51d7c85bd0b950fd182284f6cbff5fecf0 (diff)
downloadgdb-2a0ff005c89d674c7e233c7fa612aa2434bcd8df.zip
gdb-2a0ff005c89d674c7e233c7fa612aa2434bcd8df.tar.gz
gdb-2a0ff005c89d674c7e233c7fa612aa2434bcd8df.tar.bz2
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.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r--gold/layout.cc29
1 files changed, 25 insertions, 4 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index c721ba6..f95813b 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -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)