diff options
author | Cary Coutant <ccoutant@google.com> | 2010-06-10 17:20:27 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2010-06-10 17:20:27 +0000 |
commit | f3a2388fc96c63c0233cdc3449ea61cf36e4975b (patch) | |
tree | d073b85cc10872fe8a3f3a93207f829932255370 /gold/object.cc | |
parent | 7530c4809276954eebc6cfa9a41452d15da31bdb (diff) | |
download | binutils-gdb-f3a2388fc96c63c0233cdc3449ea61cf36e4975b.tar.gz |
* object.cc (Sized_relobj::do_layout): Defer layout for reloc sections.
(Sized_relobj::do_layout_deferred_sections): Do layout for deferred
reloc sections.
* object.h (Sized_relobj::deferred_layout_relocs_): New data member.
PR 11683
* symtab.h (Symbol::is_placeholder): New member function.
* target-reloc.h (relocate_section): Check for placeholder symbols.
* testsuite/Makefile.am (plugin_test_8): New test.
(plugin_test_9): New test.
* testsuite/Makefile.in: Regenerate.
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/gold/object.cc b/gold/object.cc index 24fd5862960..b034ee209ac 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1371,6 +1371,17 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, } Output_section* data_section = out_sections[data_shndx]; + if (data_section == reinterpret_cast<Output_section*>(2)) + { + // The layout for the data section was deferred, so we need + // to defer the relocation section, too. + const char* name = pnames + shdr.get_sh_name(); + this->deferred_layout_relocs_.push_back( + Deferred_layout(i, name, pshdr, 0, elfcpp::SHT_NULL)); + out_sections[i] = reinterpret_cast<Output_section*>(2); + out_section_offsets[i] = invalid_address; + continue; + } if (data_section == NULL) { out_sections[i] = NULL; @@ -1471,6 +1482,36 @@ Sized_relobj<size, big_endian>::do_layout_deferred_sections(Layout* layout) } this->deferred_layout_.clear(); + + // Now handle the deferred relocation sections. + + Output_sections& out_sections(this->output_sections()); + std::vector<Address>& out_section_offsets(this->section_offsets_); + + for (deferred = this->deferred_layout_relocs_.begin(); + deferred != this->deferred_layout_relocs_.end(); + ++deferred) + { + unsigned int shndx = deferred->shndx_; + typename This::Shdr shdr(deferred->shdr_data_); + unsigned int data_shndx = this->adjust_shndx(shdr.get_sh_info()); + + Output_section* data_section = out_sections[data_shndx]; + if (data_section == NULL) + { + out_sections[shndx] = NULL; + out_section_offsets[shndx] = invalid_address; + continue; + } + + Relocatable_relocs* rr = new Relocatable_relocs(); + this->set_relocatable_relocs(shndx, rr); + + Output_section* os = layout->layout_reloc(this, shndx, shdr, + data_section, rr); + out_sections[shndx] = os; + out_section_offsets[shndx] = invalid_address; + } } // Add the symbols to the symbol table. |