From: Ian Lance Taylor Date: Mon, 5 May 2008 19:16:43 +0000 (+0000) Subject: * object.cc (Sized_relobj::include_section_group): Adjust section X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8825ac63ef01c08e4668e652d461f94e6761a312;p=binutils-gdb.git * object.cc (Sized_relobj::include_section_group): Adjust section indexes read from group data. Build vector to pass to layout_group. * layout.cc (Layout::layout_group): Add flags and shndxes parameters. Remove contents parameter. Change caller. Update explicit instantiations. * layout.h (class Layout): Update layout_group declaration. * output.cc (Output_data_group::Output_data_group): Add flags and input_shndxes parameters. Remove contents parameter. Change caller. (Output_data_group::do_write): Change input_sections_ to input_shndxes_. * output.h (class Output_data_group): Update constructor declaration. Rename input_sections_ to input_shndxes_. * testsuite/many_sections_test.cc: Add template. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index 246cf08ada5..47f824ee65b 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,21 @@ +2008-05-05 Ian Lance Taylor + + * object.cc (Sized_relobj::include_section_group): Adjust section + indexes read from group data. Build vector to pass to + layout_group. + * layout.cc (Layout::layout_group): Add flags and shndxes + parameters. Remove contents parameter. Change caller. Update + explicit instantiations. + * layout.h (class Layout): Update layout_group declaration. + * output.cc (Output_data_group::Output_data_group): Add flags and + input_shndxes parameters. Remove contents parameter. Change + caller. + (Output_data_group::do_write): Change input_sections_ to + input_shndxes_. + * output.h (class Output_data_group): Update constructor + declaration. Rename input_sections_ to input_shndxes_. + * testsuite/many_sections_test.cc: Add template. + 2008-04-30 Cary Coutant * target-reloc.h (relocate_section): Fix dead-pointer bug. diff --git a/gold/layout.cc b/gold/layout.cc index 8d0d5f79e01..85648d31a3e 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -503,7 +503,8 @@ Layout::layout_group(Symbol_table* symtab, const char* group_section_name, const char* signature, const elfcpp::Shdr& shdr, - const elfcpp::Elf_Word* contents) + elfcpp::Elf_Word flags, + std::vector* shndxes) { gold_assert(parameters->options().relocatable()); gold_assert(shdr.get_sh_type() == elfcpp::SHT_GROUP); @@ -531,7 +532,8 @@ Layout::layout_group(Symbol_table* symtab, section_size_type entry_count = convert_to_section_size_type(shdr.get_sh_size() / 4); Output_section_data* posd = - new Output_data_group(object, entry_count, contents); + new Output_data_group(object, entry_count, flags, + shndxes); os->add_output_section_data(posd); } @@ -3258,7 +3260,8 @@ Layout::layout_group<32, false>(Symbol_table* symtab, const char* group_section_name, const char* signature, const elfcpp::Shdr<32, false>& shdr, - const elfcpp::Elf_Word* contents); + elfcpp::Elf_Word flags, + std::vector* shndxes); #endif #ifdef HAVE_TARGET_32_BIG @@ -3270,7 +3273,8 @@ Layout::layout_group<32, true>(Symbol_table* symtab, const char* group_section_name, const char* signature, const elfcpp::Shdr<32, true>& shdr, - const elfcpp::Elf_Word* contents); + elfcpp::Elf_Word flags, + std::vector* shndxes); #endif #ifdef HAVE_TARGET_64_LITTLE @@ -3282,7 +3286,8 @@ Layout::layout_group<64, false>(Symbol_table* symtab, const char* group_section_name, const char* signature, const elfcpp::Shdr<64, false>& shdr, - const elfcpp::Elf_Word* contents); + elfcpp::Elf_Word flags, + std::vector* shndxes); #endif #ifdef HAVE_TARGET_64_BIG @@ -3294,7 +3299,8 @@ Layout::layout_group<64, true>(Symbol_table* symtab, const char* group_section_name, const char* signature, const elfcpp::Shdr<64, true>& shdr, - const elfcpp::Elf_Word* contents); + elfcpp::Elf_Word flags, + std::vector* shndxes); #endif #ifdef HAVE_TARGET_32_LITTLE diff --git a/gold/layout.h b/gold/layout.h index 8584a0cabf5..2a173d700f5 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -125,7 +125,8 @@ class Layout const char* group_section_name, const char* signature, const elfcpp::Shdr& shdr, - const elfcpp::Elf_Word* contents); + elfcpp::Elf_Word flags, + std::vector* shndxes); // Like layout, only for exception frame sections. OBJECT is an // object file. SYMBOLS is the contents of the symbol table diff --git a/gold/object.cc b/gold/object.cc index 8f444113ee8..b49bee17502 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -604,10 +604,6 @@ Sized_relobj::include_section_group( bool include_group = ((flags & elfcpp::GRP_COMDAT) == 0 || layout->add_comdat(this, index, signature, true)); - if (include_group && parameters->options().relocatable()) - layout->layout_group(symtab, this, index, name, signature.c_str(), - shdr, pword); - Relobj* kept_object = NULL; Comdat_group* kept_group = NULL; @@ -629,10 +625,20 @@ Sized_relobj::include_section_group( } size_t count = shdr.get_sh_size() / sizeof(elfcpp::Elf_Word); + + std::vector shndxes; + bool relocate_group = include_group && parameters->options().relocatable(); + if (relocate_group) + shndxes.reserve(count - 1); + for (size_t i = 1; i < count; ++i) { elfcpp::Elf_Word secnum = - elfcpp::Swap<32, big_endian>::readval(pword + i); + this->adjust_shndx(elfcpp::Swap<32, big_endian>::readval(pword + i)); + + if (relocate_group) + shndxes.push_back(secnum); + if (secnum >= this->shnum()) { this->error(_("section %u in section group %u out of range"), @@ -681,6 +687,10 @@ Sized_relobj::include_section_group( } } + if (relocate_group) + layout->layout_group(symtab, this, index, name, signature.c_str(), + shdr, flags, &shndxes); + return include_group; } diff --git a/gold/output.cc b/gold/output.cc index ded6d42bb9d..a3c1f856902 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -997,16 +997,13 @@ template Output_data_group::Output_data_group( Sized_relobj* relobj, section_size_type entry_count, - const elfcpp::Elf_Word* contents) + elfcpp::Elf_Word flags, + std::vector* input_shndxes) : Output_section_data(entry_count * 4, 4), - relobj_(relobj) + relobj_(relobj), + flags_(flags) { - this->flags_ = elfcpp::Swap<32, big_endian>::readval(contents); - for (section_size_type i = 1; i < entry_count; ++i) - { - unsigned int shndx = elfcpp::Swap<32, big_endian>::readval(contents + i); - this->input_sections_.push_back(shndx); - } + this->input_shndxes_.swap(*input_shndxes); } // Write out the section group, which means translating the section @@ -1026,8 +1023,8 @@ Output_data_group::do_write(Output_file* of) ++contents; for (std::vector::const_iterator p = - this->input_sections_.begin(); - p != this->input_sections_.end(); + this->input_shndxes_.begin(); + p != this->input_shndxes_.end(); ++p, ++contents) { section_offset_type dummy; @@ -1052,7 +1049,7 @@ Output_data_group::do_write(Output_file* of) of->write_output_view(off, oview_size, oview); // We no longer need this information. - this->input_sections_.clear(); + this->input_shndxes_.clear(); } // Output_data_got::Got_entry methods. diff --git a/gold/output.h b/gold/output.h index b6527a34f72..9d6577e376e 100644 --- a/gold/output.h +++ b/gold/output.h @@ -1346,9 +1346,11 @@ template class Output_data_group : public Output_section_data { public: + // The constructor clears *INPUT_SHNDXES. Output_data_group(Sized_relobj* relobj, section_size_type entry_count, - const elfcpp::Elf_Word* contents); + elfcpp::Elf_Word flags, + std::vector* input_shndxes); void do_write(Output_file*); @@ -1359,7 +1361,7 @@ class Output_data_group : public Output_section_data // The group flag word. elfcpp::Elf_Word flags_; // The section indexes of the input sections in this group. - std::vector input_sections_; + std::vector input_shndxes_; }; // Output_data_got is used to manage a GOT. Each entry in the GOT is diff --git a/gold/testsuite/many_sections_test.cc b/gold/testsuite/many_sections_test.cc index dcb1cd2a408..e4b74c3484f 100644 --- a/gold/testsuite/many_sections_test.cc +++ b/gold/testsuite/many_sections_test.cc @@ -29,9 +29,23 @@ #include "many_sections_define.h" +// This tests a section group. +template +class C +{ + public: + static T val() { return C::val_; } + private: + static T val_; +}; + +template +T C::val_; + int main(int, char**) { #include "many_sections_check.h" + assert(C::val() == 0); return 0; }