This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files


Hi all,

I just wanted to ping this patch and see if this change (or something
else that allows unique segments in plugin-created objects) can be
added to the plugin API.

Thanks,
Stephen

On Thu, Aug 24, 2017 at 10:48 PM, Stephen Crane <sjc@immunant.com> wrote:
> I have a gold plugin that needs to call the
> unique_segment_for_sections interface for sections in an input file
> created by a plugin. Specifically, I want to assign a section created
> during LTO to a unique output segment with special flags. Here is a
> patch that allows this use case by adding a callback that gives the
> plugin the opportunity to get an input handle for plugin-created input
> files. Could this be added to the gold plugin API? Is there a better
> way to do this?
>
> Thanks,
> Stephen Crane
>
>
>
> 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 is called
> when reading symbols from a new input file added after the all_symbols_read
> event (i.e. an input file added by a plugin).
> ---
>  gold/plugin.cc       | 63 +++++++++++++++++++++++++++++++++++++++-------------
>  gold/plugin.h        | 19 ++++++++++++++++
>  include/plugin-api.h | 26 +++++++++++++++++++++-
>  3 files changed, 92 insertions(+), 16 deletions(-)
>
> diff --git a/gold/plugin.cc b/gold/plugin.cc
> index c051805cec..fcd913b34e 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];
> @@ -345,6 +348,10 @@ Plugin::load()
>    tv[i].tv_tag = LDPT_GET_INPUT_SECTION_SIZE;
>    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_);
>          }
>      }
>
> @@ -1903,6 +1926,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.
> diff --git a/gold/plugin.h b/gold/plugin.h
> index 7658668502..d591d26821 100644
> --- a/gold/plugin.h
> +++ b/gold/plugin.h
> @@ -60,6 +60,7 @@ class Plugin
>        claim_file_handler_(NULL),
>        all_symbols_read_handler_(NULL),
>        cleanup_handler_(NULL),
> +      new_input_handler_(NULL),
>        cleanup_done_(false)
>    { }
>
> @@ -78,6 +79,10 @@ class Plugin
>    void
>    all_symbols_read();
>
> +  // Call the new_input handler.
> +  void
> +  new_input(struct ld_plugin_input_file* plugin_input_file);
> +
>    // Call the cleanup handler.
>    void
>    cleanup();
> @@ -97,6 +102,11 @@ class Plugin
>    set_cleanup_handler(ld_plugin_cleanup_handler handler)
>    { this->cleanup_handler_ = handler; }
>
> +  // Register a new_input handler.
> +  void
> +  set_new_input_handler(ld_plugin_new_input_handler handler)
> +  { this->new_input_handler_ = handler; }
> +
>    // Add an argument
>    void
>    add_option(const char* arg)
> @@ -118,6 +128,7 @@ class Plugin
>    ld_plugin_claim_file_handler claim_file_handler_;
>    ld_plugin_all_symbols_read_handler all_symbols_read_handler_;
>    ld_plugin_cleanup_handler cleanup_handler_;
> +  ld_plugin_new_input_handler new_input_handler_;
>    // TRUE if the cleanup handlers have been called.
>    bool cleanup_done_;
>  };
> @@ -218,6 +229,14 @@ class Plugin_manager
>      (*this->current_)->set_all_symbols_read_handler(handler);
>    }
>
> +  // Register a new_input handler.
> +  void
> +  set_new_input_handler(ld_plugin_new_input_handler handler)
> +  {
> +    gold_assert(this->current_ != plugins_.end());
> +    (*this->current_)->set_new_input_handler(handler);
> +  }
> +
>    // Register a claim-file handler.
>    void
>    set_cleanup_handler(ld_plugin_cleanup_handler handler)
> diff --git a/include/plugin-api.h b/include/plugin-api.h
> index 3a3e8b456d..0fbd6fed9e 100644
> --- a/include/plugin-api.h
> +++ b/include/plugin-api.h
> @@ -365,6 +365,28 @@ enum ld_plugin_status
>  (*ld_plugin_get_input_section_size) (const struct ld_plugin_section section,
>                                       uint64_t *secsize);
>
> +typedef
> +enum ld_plugin_status
> +(*ld_plugin_new_input_handler) (const struct ld_plugin_input_file *file);
> +
> +/* The linker's interface for registering the "new_input" handler. This handler
> +   will be notified when a new input file has been added after the
> +   all_symbols_read event, allowing the plugin to, for example, set a unique
> +   segment for sections in plugin-generated input files. */
> +
> +typedef
> +enum ld_plugin_status
> +(*ld_plugin_register_new_input) (ld_plugin_new_input_handler handler);
> +
> +/* The linker's interface for getting an input file handle for a new input file
> +   added by a plugin.  */
> +
> +typedef
> +enum ld_plugin_status
> +(*ld_plugin_get_input_handle) (const char *pathname,
> +                               void **handle);
> +
> +
>  enum ld_plugin_level
>  {
>    LDPL_INFO,
> @@ -407,7 +429,8 @@ enum ld_plugin_tag
>    LDPT_UNIQUE_SEGMENT_FOR_SECTIONS = 27,
>    LDPT_GET_SYMBOLS_V3 = 28,
>    LDPT_GET_INPUT_SECTION_ALIGNMENT = 29,
> -  LDPT_GET_INPUT_SECTION_SIZE = 30
> +  LDPT_GET_INPUT_SECTION_SIZE = 30,
> +  LDPT_REGISTER_NEW_INPUT_HOOK = 31
>  };
>
>  /* The plugin transfer vector.  */
> @@ -441,6 +464,7 @@ struct ld_plugin_tv
>      ld_plugin_unique_segment_for_sections tv_unique_segment_for_sections;
>      ld_plugin_get_input_section_alignment tv_get_input_section_alignment;
>      ld_plugin_get_input_section_size tv_get_input_section_size;
> +    ld_plugin_register_new_input tv_register_new_input;
>    } tv_u;
>  };
>
> --
> 2.14.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]