diff options
author | Cary Coutant <ccoutant@google.com> | 2008-12-23 02:02:20 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2008-12-23 02:02:20 +0000 |
commit | 5995b57073ad5990e2f63c7f65c0a6c27cad55a9 (patch) | |
tree | 9748f0e3d8e6651b0446acc2556b3083887d7606 /gold/object.cc | |
parent | bce3bbcb768f893debb22320380b25e34547c8c6 (diff) | |
download | gdb-5995b57073ad5990e2f63c7f65c0a6c27cad55a9.zip gdb-5995b57073ad5990e2f63c7f65c0a6c27cad55a9.tar.gz gdb-5995b57073ad5990e2f63c7f65c0a6c27cad55a9.tar.bz2 |
* object.cc (Sized_relobj::layout_section): New function.
(Sized_relobj::do_layout): Defer layout of input sections until after
plugin has provided replacement files.
(Sized_relobj::do_layout_deferred_sections): New function.
* object.h (Relobj::set_section_offset): Remove virtual keyword.
(Relobj::layout_deferred_sections): New function.
(Relobj::do_layout_deferred_sections): New function.
(Sized_relobj::do_layout_deferred_sections): New function.
(Sized_relobj::layout_section): New function.
(Sized_relobj::Deferred_layout): New structure.
(Sized_relobj::deferred_layout_): New field.
* plugin.cc (Plugin_manager::finish): Renamed, was cleanup.
Change all callers. Layout deferred sections.
(class Plugin_finish): Renamed, was Plugin_cleanup. Change all
references.
(Plugin_hook::run): Move code from do_plugin_hook inline.
(Plugin_hook::do_plugin_hook): Remove.
* plugin.h (Plugin_manager::Plugin_manager): Add missing initializers.
(Plugin_manager::finish): Renamed, was cleanup.
(Plugin_manager::should_defer_layout): New function.
(Plugin_manager::add_deferred_layout_object): New function.
(Plugin_manager::Deferred_layout_list): New type.
(Plugin_manager::deferred_layout_objects_): New field.
(Plugin_hook::do_plugin_hook): Remove.
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 95 |
1 files changed, 81 insertions, 14 deletions
diff --git a/gold/object.cc b/gold/object.cc index f7dcda8..b1f83e7 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -37,6 +37,7 @@ #include "reloc.h" #include "object.h" #include "dynobj.h" +#include "plugin.h" namespace gold { @@ -784,6 +785,34 @@ Sized_relobj<size, big_endian>::include_linkonce_section( return include1 && include2; } +// Layout an input section. + +template<int size, bool big_endian> +inline void +Sized_relobj<size, big_endian>::layout_section(Layout* layout, + unsigned int shndx, + const char* name, + typename This::Shdr& shdr, + unsigned int reloc_shndx, + unsigned int reloc_type) +{ + off_t offset; + Output_section* os = layout->layout(this, shndx, name, shdr, + reloc_shndx, reloc_type, &offset); + + this->output_sections()[shndx] = os; + if (offset == -1) + this->section_offsets_[shndx] = invalid_address; + else + this->section_offsets_[shndx] = convert_types<Address, off_t>(offset); + + // If this section requires special handling, and if there are + // relocs that apply to it, then we must do the special handling + // before we apply the relocs. + if (offset == -1 && reloc_shndx != 0) + this->set_relocs_must_follow_section_writes(); +} + // Lay out the input sections. We walk through the sections and check // whether they should be included in the link. If they should, we // pass them to the Layout object, which will return an output section @@ -807,6 +836,13 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, const unsigned char* pnamesu = sd->section_names->data(); const char* pnames = reinterpret_cast<const char*>(pnamesu); + // If any input files have been claimed by plugins, we need to defer + // actual layout until the replacement files have arrived. + const bool should_defer_layout = + (parameters->options().has_plugins() + && parameters->options().plugins()->should_defer_layout()); + unsigned int num_sections_to_defer = 0; + // For each section, record the index of the reloc section if any. // Use 0 to mean that there is no reloc section, -1U to mean that // there is more than one. @@ -818,6 +854,10 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, { typename This::Shdr shdr(pshdrs); + // Count the number of sections whose layout will be deferred. + if (should_defer_layout && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC)) + ++num_sections_to_defer; + unsigned int sh_type = shdr.get_sh_type(); if (sh_type == elfcpp::SHT_REL || sh_type == elfcpp::SHT_RELA) { @@ -856,6 +896,12 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, return; } + if (num_sections_to_defer > 0) + { + parameters->options().plugins()->add_deferred_layout_object(this); + this->deferred_layout_.reserve(num_sections_to_defer); + } + // Whether we've seen a .note.GNU-stack section. bool seen_gnu_stack = false; // The flags of a .note.GNU-stack section. @@ -960,22 +1006,22 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, continue; } - off_t offset; - Output_section* os = layout->layout(this, i, name, shdr, - reloc_shndx[i], reloc_type[i], - &offset); + if (should_defer_layout && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC)) + { + this->deferred_layout_.push_back(Deferred_layout(i, name, pshdrs, + reloc_shndx[i], + reloc_type[i])); - out_sections[i] = os; - if (offset == -1) - out_section_offsets[i] = invalid_address; + // Put dummy values here; real values will be supplied by + // do_layout_deferred_sections. + out_sections[i] = reinterpret_cast<Output_section*>(1); + out_section_offsets[i] = invalid_address; + } else - out_section_offsets[i] = convert_types<Address, off_t>(offset); - - // If this section requires special handling, and if there are - // relocs that apply to it, then we must do the special handling - // before we apply the relocs. - if (offset == -1 && reloc_shndx[i] != 0) - this->set_relocs_must_follow_section_writes(); + { + this->layout_section(layout, i, name, shdr, reloc_shndx[i], + reloc_type[i]); + } } layout->layout_gnu_stack(seen_gnu_stack, gnu_stack_flags); @@ -1059,6 +1105,27 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, sd->section_names = NULL; } +// Layout sections whose layout was deferred while waiting for +// input files from a plugin. + +template<int size, bool big_endian> +void +Sized_relobj<size, big_endian>::do_layout_deferred_sections(Layout* layout) +{ + typename std::vector<Deferred_layout>::iterator deferred; + + for (deferred = this->deferred_layout_.begin(); + deferred != this->deferred_layout_.end(); + ++deferred) + { + typename This::Shdr shdr(deferred->shdr_data_); + this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(), + shdr, deferred->reloc_shndx_, deferred->reloc_type_); + } + + this->deferred_layout_.clear(); +} + // Add the symbols to the symbol table. template<int size, bool big_endian> |