diff options
author | Doug Kwan <dougkwan@google.com> | 2010-03-01 21:43:50 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2010-03-01 21:43:50 +0000 |
commit | 2a0ff005c89d674c7e233c7fa612aa2434bcd8df (patch) | |
tree | f7cdface7116bfdf3188bd6d8b844deff74b551d /gold/layout.cc | |
parent | a6f5ef51d7c85bd0b950fd182284f6cbff5fecf0 (diff) | |
download | gdb-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.cc | 29 |
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) |