diff options
author | Stephen Crane <sjc@immunant.com> | 2017-12-11 14:58:38 -0800 |
---|---|---|
committer | Sriraman Tallam <tmsriram@google.com> | 2017-12-11 14:58:38 -0800 |
commit | c4e648430f3c5c135310f87280d45dba581aaa7b (patch) | |
tree | 026ea986bfbb2b5856062f4507404f4f00d2d27c /gold/plugin.cc | |
parent | 4c5ae11b42433dbffc33fbde75c9e415594504d8 (diff) | |
download | gdb-c4e648430f3c5c135310f87280d45dba581aaa7b.zip gdb-c4e648430f3c5c135310f87280d45dba581aaa7b.tar.gz gdb-c4e648430f3c5c135310f87280d45dba581aaa7b.tar.bz2 |
Add plugin API for processing plugin-added input files
Gold plugins may wish to further process an input file added by a plugin. For
example, the plugin may need to assign a unique segment for sections in a
plugin-generated input file. This patch adds a plugin callback that the linker
will call when reading symbols from a new input file added after the
all_symbols_read event (i.e. an input file added by a plugin).
2017-12-11 Stephen Crane <sjc@immunant.com>
* plugin-api.h: Add new plugin hook to allow processing of input
files added by a plugin.
(ld_plugin_new_input_handler): New function hook type.
(ld_plugin_register_new_input): New interface.
(LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
(tv_register_new_input): New member.
* plugin.cc (Plugin::load): Include hooks for register_new_input
in transfer vector.
(Plugin::new_input): New function.
(register_new_input): New function.
(Plugin_manager::claim_file): Call Plugin::new_input if in
replacement phase.
* plugin.h (Plugin::set_new_input_handler): New function.
* testsuite/plugin_new_section_layout.c: New plugin to test
new_input plugin API.
* testsuite/plugin_final_layout.sh: Add new input test.
* testsuite/Makefile.am (plugin_layout_new_file): New test case.
* testsuite/Makefile.in: Regenerate.
Diffstat (limited to 'gold/plugin.cc')
-rw-r--r-- | gold/plugin.cc | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/gold/plugin.cc b/gold/plugin.cc index 5ea23b5..49212b4 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -167,6 +167,9 @@ static enum ld_plugin_status get_input_section_size(const struct ld_plugin_section section, uint64_t* secsize); +static enum ld_plugin_status +register_new_input(ld_plugin_new_input_handler handler); + }; #endif // ENABLE_PLUGINS @@ -211,7 +214,7 @@ Plugin::load() sscanf(ver, "%d.%d", &major, &minor); // Allocate and populate a transfer vector. - const int tv_fixed_size = 29; + const int tv_fixed_size = 30; int tv_size = this->args_.size() + tv_fixed_size; ld_plugin_tv* tv = new ld_plugin_tv[tv_size]; @@ -346,6 +349,10 @@ Plugin::load() tv[i].tv_u.tv_get_input_section_size = get_input_section_size; ++i; + tv[i].tv_tag = LDPT_REGISTER_NEW_INPUT_HOOK; + tv[i].tv_u.tv_register_new_input = register_new_input; + + ++i; tv[i].tv_tag = LDPT_NULL; tv[i].tv_u.tv_val = 0; @@ -383,6 +390,15 @@ Plugin::all_symbols_read() (*this->all_symbols_read_handler_)(); } +// Call the new_input handler. + +inline void +Plugin::new_input(struct ld_plugin_input_file* plugin_input_file) +{ + if (this->new_input_handler_ != NULL) + (*this->new_input_handler_)(plugin_input_file); +} + // Call the cleanup handler. inline void @@ -476,8 +492,6 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset, gold_assert(lock_initialized); Hold_lock hl(*this->lock_); - if (this->in_replacement_phase_) - return NULL; unsigned int handle = this->objects_.size(); this->input_file_ = input_file; @@ -494,19 +508,28 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset, this->current_ != this->plugins_.end(); ++this->current_) { - if ((*this->current_)->claim_file(&this->plugin_input_file_)) + // If we aren't yet in replacement phase, allow plugins to claim input + // files, otherwise notify the plugin of the new input file, if needed. + if (!this->in_replacement_phase_) { - this->any_claimed_ = true; - this->in_claim_file_handler_ = false; - - if (this->objects_.size() > handle - && this->objects_[handle]->pluginobj() != NULL) - return this->objects_[handle]->pluginobj(); - - // If the plugin claimed the file but did not call the - // add_symbols callback, we need to create the Pluginobj now. - Pluginobj* obj = this->make_plugin_object(handle); - return obj; + if ((*this->current_)->claim_file(&this->plugin_input_file_)) + { + this->any_claimed_ = true; + this->in_claim_file_handler_ = false; + + if (this->objects_.size() > handle + && this->objects_[handle]->pluginobj() != NULL) + return this->objects_[handle]->pluginobj(); + + // If the plugin claimed the file but did not call the + // add_symbols callback, we need to create the Pluginobj now. + Pluginobj* obj = this->make_plugin_object(handle); + return obj; + } + } + else + { + (*this->current_)->new_input(&this->plugin_input_file_); } } @@ -1905,6 +1928,16 @@ unique_segment_for_sections(const char* segment_name, return LDPS_OK; } +// Register a new_input handler. + +static enum ld_plugin_status +register_new_input(ld_plugin_new_input_handler handler) +{ + gold_assert(parameters->options().has_plugins()); + parameters->options().plugins()->set_new_input_handler(handler); + return LDPS_OK; +} + #endif // ENABLE_PLUGINS // Allocate a Pluginobj object of the appropriate size and endianness. |