public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] [GOLD] Add plugin API for processing plugin-added input files
@ 2017-08-25  5:49 Stephen Crane
  2017-09-14 22:16 ` Stephen Crane
  0 siblings, 1 reply; 15+ messages in thread
From: Stephen Crane @ 2017-08-25  5:49 UTC (permalink / raw)
  To: binutils

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-08-25  5:49 [PATCH] [GOLD] Add plugin API for processing plugin-added input files Stephen Crane
@ 2017-09-14 22:16 ` Stephen Crane
  2017-09-20 21:51   ` Cary Coutant
  0 siblings, 1 reply; 15+ messages in thread
From: Stephen Crane @ 2017-09-14 22:16 UTC (permalink / raw)
  To: binutils

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-09-14 22:16 ` Stephen Crane
@ 2017-09-20 21:51   ` Cary Coutant
  0 siblings, 0 replies; 15+ messages in thread
From: Cary Coutant @ 2017-09-20 21:51 UTC (permalink / raw)
  To: Stephen Crane; +Cc: Binutils, Sriraman Tallam

> 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.
>
> 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?

This seems reasonable, although I haven't given your patch a good look
yet. Before we put this in gold, though, you should post your proposed
change to the plugin interface (i.e., plugin-api.h) to the gcc-patches
mailing list for review there (please cc me), then be prepared to
update the whopr/driver wiki page on the GCC wiki:

https://gcc.gnu.org/wiki/whopr/driver

The patch to plugin-api.h will need to be applied first on the GCC
tree, then synced back to the binutils tree.

I'd suggest you also cc Sriraman Tallam (cc'ed here). The API
extensions for assigning sections to unique segments are his, so he
may have some useful feedback for you.

-cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-12-11 23:03                       ` Sriraman Tallam via binutils
@ 2017-12-12 18:51                         ` Stephen Crane
  0 siblings, 0 replies; 15+ messages in thread
From: Stephen Crane @ 2017-12-12 18:51 UTC (permalink / raw)
  To: Sriraman Tallam; +Cc: Cary Coutant, Binutils, GCC Patches

Thank you so much. I just added documentation for the new hook to
https://gcc.gnu.org/wiki/whopr/driver so that should finish off this
feature.

I'm happy to fix any bugs that might crop up related to this hook, of
course. I don't follow the binutils list closely, so I apologize in
advance if I miss any issues related to this feature. Just CC me
explicitly and I'll jump on it.

Thanks,
- stephen

On Mon, Dec 11, 2017 at 3:03 PM, Sriraman Tallam <tmsriram@google.com> wrote:
> On Mon, Dec 11, 2017 at 2:16 PM, Stephen Crane <sjc@immunant.com> wrote:
>> Thanks for committing the GCC portion and following up on this. I had
>> been meaning to write and ask. I don't have commit privs for binutils,
>> so either you or Cary will have to commit the binutils patch as well,
>> if it's not too much trouble. I think much has changed to need a
>> rebase?
>
> I just committed your patch.  I had to make one very minor change to
> plugin_new_section_layout.c to compile, move the loop initialization
> declaration outside as that is not allowed on C.  I tested the patch.
>
> Thanks
> Sri
>
>>
>> Thanks,
>> Stephen
>>
>> On Mon, Dec 11, 2017 at 2:10 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>>> On Thu, Nov 9, 2017 at 9:04 PM, Cary Coutant <ccoutant@gmail.com> wrote:
>>>>> include/ChangeLog:
>>>>> 2017-11-09  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 funcion hook type.
>>>>>         (ld_plugin_register_new_input): New interface.
>>>>>         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
>>>>>         (tv_register_new_input): New member.
>>>>>
>>>>>
>>>>> gold/ChangeLog:
>>>>> 2017-11-09  Stephen Crane  <sjc@immunant.com>
>>>>>
>>>>>         * 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.
>>>>
>>>> These are OK. Thanks!
>>>>
>>>> Sri, I'm out of town through 11/18, and won't be able to commit the
>>>> include/ patch to GCC before Stage 1 ends. Can you take care of it?
>>>> (If not, I'll take care of it when I get back -- it was approved
>>>> during Stage 1, so I think it's OK to commit early in Stage 3,
>>>> especially since it's nothing but new declarations.)
>>>
>>> Stephen, I was looking at binutils and realized this patch has not
>>> been committed yet.  I only committed the GCC portion, plugin-api.h.
>>>
>>> Thanks
>>> Sri
>>>
>>>>
>>>> -cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-12-11 22:16                     ` Stephen Crane
  2017-12-11 22:33                       ` Sriraman Tallam via binutils
@ 2017-12-11 23:03                       ` Sriraman Tallam via binutils
  2017-12-12 18:51                         ` Stephen Crane
  1 sibling, 1 reply; 15+ messages in thread
From: Sriraman Tallam via binutils @ 2017-12-11 23:03 UTC (permalink / raw)
  To: Stephen Crane; +Cc: Cary Coutant, Binutils, GCC Patches

On Mon, Dec 11, 2017 at 2:16 PM, Stephen Crane <sjc@immunant.com> wrote:
> Thanks for committing the GCC portion and following up on this. I had
> been meaning to write and ask. I don't have commit privs for binutils,
> so either you or Cary will have to commit the binutils patch as well,
> if it's not too much trouble. I think much has changed to need a
> rebase?

I just committed your patch.  I had to make one very minor change to
plugin_new_section_layout.c to compile, move the loop initialization
declaration outside as that is not allowed on C.  I tested the patch.

Thanks
Sri

>
> Thanks,
> Stephen
>
> On Mon, Dec 11, 2017 at 2:10 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>> On Thu, Nov 9, 2017 at 9:04 PM, Cary Coutant <ccoutant@gmail.com> wrote:
>>>> include/ChangeLog:
>>>> 2017-11-09  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 funcion hook type.
>>>>         (ld_plugin_register_new_input): New interface.
>>>>         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
>>>>         (tv_register_new_input): New member.
>>>>
>>>>
>>>> gold/ChangeLog:
>>>> 2017-11-09  Stephen Crane  <sjc@immunant.com>
>>>>
>>>>         * 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.
>>>
>>> These are OK. Thanks!
>>>
>>> Sri, I'm out of town through 11/18, and won't be able to commit the
>>> include/ patch to GCC before Stage 1 ends. Can you take care of it?
>>> (If not, I'll take care of it when I get back -- it was approved
>>> during Stage 1, so I think it's OK to commit early in Stage 3,
>>> especially since it's nothing but new declarations.)
>>
>> Stephen, I was looking at binutils and realized this patch has not
>> been committed yet.  I only committed the GCC portion, plugin-api.h.
>>
>> Thanks
>> Sri
>>
>>>
>>> -cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-12-11 22:16                     ` Stephen Crane
@ 2017-12-11 22:33                       ` Sriraman Tallam via binutils
  2017-12-11 23:03                       ` Sriraman Tallam via binutils
  1 sibling, 0 replies; 15+ messages in thread
From: Sriraman Tallam via binutils @ 2017-12-11 22:33 UTC (permalink / raw)
  To: Stephen Crane; +Cc: Cary Coutant, Binutils, GCC Patches

On Mon, Dec 11, 2017 at 2:16 PM, Stephen Crane <sjc@immunant.com> wrote:
> Thanks for committing the GCC portion and following up on this. I had
> been meaning to write and ask. I don't have commit privs for binutils,
> so either you or Cary will have to commit the binutils patch as well,
> if it's not too much trouble. I think much has changed to need a
> rebase?

Ok, let me apply your patch.  I will get back if there are inconsistencies.

Thanks
Sri

>
> Thanks,
> Stephen
>
> On Mon, Dec 11, 2017 at 2:10 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>> On Thu, Nov 9, 2017 at 9:04 PM, Cary Coutant <ccoutant@gmail.com> wrote:
>>>> include/ChangeLog:
>>>> 2017-11-09  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 funcion hook type.
>>>>         (ld_plugin_register_new_input): New interface.
>>>>         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
>>>>         (tv_register_new_input): New member.
>>>>
>>>>
>>>> gold/ChangeLog:
>>>> 2017-11-09  Stephen Crane  <sjc@immunant.com>
>>>>
>>>>         * 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.
>>>
>>> These are OK. Thanks!
>>>
>>> Sri, I'm out of town through 11/18, and won't be able to commit the
>>> include/ patch to GCC before Stage 1 ends. Can you take care of it?
>>> (If not, I'll take care of it when I get back -- it was approved
>>> during Stage 1, so I think it's OK to commit early in Stage 3,
>>> especially since it's nothing but new declarations.)
>>
>> Stephen, I was looking at binutils and realized this patch has not
>> been committed yet.  I only committed the GCC portion, plugin-api.h.
>>
>> Thanks
>> Sri
>>
>>>
>>> -cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-12-11 22:10                   ` Sriraman Tallam via binutils
@ 2017-12-11 22:16                     ` Stephen Crane
  2017-12-11 22:33                       ` Sriraman Tallam via binutils
  2017-12-11 23:03                       ` Sriraman Tallam via binutils
  0 siblings, 2 replies; 15+ messages in thread
From: Stephen Crane @ 2017-12-11 22:16 UTC (permalink / raw)
  To: Sriraman Tallam; +Cc: Cary Coutant, Binutils, GCC Patches

Thanks for committing the GCC portion and following up on this. I had
been meaning to write and ask. I don't have commit privs for binutils,
so either you or Cary will have to commit the binutils patch as well,
if it's not too much trouble. I think much has changed to need a
rebase?

Thanks,
Stephen

On Mon, Dec 11, 2017 at 2:10 PM, Sriraman Tallam <tmsriram@google.com> wrote:
> On Thu, Nov 9, 2017 at 9:04 PM, Cary Coutant <ccoutant@gmail.com> wrote:
>>> include/ChangeLog:
>>> 2017-11-09  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 funcion hook type.
>>>         (ld_plugin_register_new_input): New interface.
>>>         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
>>>         (tv_register_new_input): New member.
>>>
>>>
>>> gold/ChangeLog:
>>> 2017-11-09  Stephen Crane  <sjc@immunant.com>
>>>
>>>         * 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.
>>
>> These are OK. Thanks!
>>
>> Sri, I'm out of town through 11/18, and won't be able to commit the
>> include/ patch to GCC before Stage 1 ends. Can you take care of it?
>> (If not, I'll take care of it when I get back -- it was approved
>> during Stage 1, so I think it's OK to commit early in Stage 3,
>> especially since it's nothing but new declarations.)
>
> Stephen, I was looking at binutils and realized this patch has not
> been committed yet.  I only committed the GCC portion, plugin-api.h.
>
> Thanks
> Sri
>
>>
>> -cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-11-10  5:06                 ` Cary Coutant
  2017-11-10 16:29                   ` Sriraman Tallam via binutils
  2017-11-10 22:11                   ` Sriraman Tallam via binutils
@ 2017-12-11 22:10                   ` Sriraman Tallam via binutils
  2017-12-11 22:16                     ` Stephen Crane
  2 siblings, 1 reply; 15+ messages in thread
From: Sriraman Tallam via binutils @ 2017-12-11 22:10 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Stephen Crane, Binutils, GCC Patches

On Thu, Nov 9, 2017 at 9:04 PM, Cary Coutant <ccoutant@gmail.com> wrote:
>> include/ChangeLog:
>> 2017-11-09  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 funcion hook type.
>>         (ld_plugin_register_new_input): New interface.
>>         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
>>         (tv_register_new_input): New member.
>>
>>
>> gold/ChangeLog:
>> 2017-11-09  Stephen Crane  <sjc@immunant.com>
>>
>>         * 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.
>
> These are OK. Thanks!
>
> Sri, I'm out of town through 11/18, and won't be able to commit the
> include/ patch to GCC before Stage 1 ends. Can you take care of it?
> (If not, I'll take care of it when I get back -- it was approved
> during Stage 1, so I think it's OK to commit early in Stage 3,
> especially since it's nothing but new declarations.)

Stephen, I was looking at binutils and realized this patch has not
been committed yet.  I only committed the GCC portion, plugin-api.h.

Thanks
Sri

>
> -cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-11-10  5:06                 ` Cary Coutant
  2017-11-10 16:29                   ` Sriraman Tallam via binutils
@ 2017-11-10 22:11                   ` Sriraman Tallam via binutils
  2017-12-11 22:10                   ` Sriraman Tallam via binutils
  2 siblings, 0 replies; 15+ messages in thread
From: Sriraman Tallam via binutils @ 2017-11-10 22:11 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Stephen Crane, Binutils, GCC Patches

On Thu, Nov 9, 2017 at 9:04 PM, Cary Coutant <ccoutant@gmail.com> wrote:

> > include/ChangeLog:
> > 2017-11-09  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 funcion hook type.
> >         (ld_plugin_register_new_input): New interface.
> >         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
> >         (tv_register_new_input): New member.
> >
> >
> > gold/ChangeLog:
> > 2017-11-09  Stephen Crane  <sjc@immunant.com>
> >
> >         * 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.
>
> These are OK. Thanks!
>
> Sri, I'm out of town through 11/18, and won't be able to commit the
> include/ patch to GCC before Stage 1 ends. Can you take care of it?
> (If not, I'll take care of it when I get back -- it was approved
> during Stage 1, so I think it's OK to commit early in Stage 3,
> especially since it's nothing but new declarations.)
>

Committed plugin-api.h patch to GCC trunk.

Thanks
Sri


>
> -cary
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-11-10  5:06                 ` Cary Coutant
@ 2017-11-10 16:29                   ` Sriraman Tallam via binutils
  2017-11-10 22:11                   ` Sriraman Tallam via binutils
  2017-12-11 22:10                   ` Sriraman Tallam via binutils
  2 siblings, 0 replies; 15+ messages in thread
From: Sriraman Tallam via binutils @ 2017-11-10 16:29 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Stephen Crane, Binutils, GCC Patches

On Thu, Nov 9, 2017 at 9:04 PM, Cary Coutant <ccoutant@gmail.com> wrote:

> > include/ChangeLog:
> > 2017-11-09  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 funcion hook type.
> >         (ld_plugin_register_new_input): New interface.
> >         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
> >         (tv_register_new_input): New member.
> >
> >
> > gold/ChangeLog:
> > 2017-11-09  Stephen Crane  <sjc@immunant.com>
> >
> >         * 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.
>
> These are OK. Thanks!
>
> Sri, I'm out of town through 11/18, and won't be able to commit the
> include/ patch to GCC before Stage 1 ends. Can you take care of it?
> (If not, I'll take care of it when I get back -- it was approved
> during Stage 1, so I think it's OK to commit early in Stage 3,
> especially since it's nothing but new declarations.)
>

Sure, I will do this today.

Thanks
Sri


>
> -cary
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-11-10  1:24               ` Stephen Crane
@ 2017-11-10  5:06                 ` Cary Coutant
  2017-11-10 16:29                   ` Sriraman Tallam via binutils
                                     ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Cary Coutant @ 2017-11-10  5:06 UTC (permalink / raw)
  To: Stephen Crane; +Cc: Sriraman Tallam, Binutils, GCC Patches

> include/ChangeLog:
> 2017-11-09  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 funcion hook type.
>         (ld_plugin_register_new_input): New interface.
>         (LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
>         (tv_register_new_input): New member.
>
>
> gold/ChangeLog:
> 2017-11-09  Stephen Crane  <sjc@immunant.com>
>
>         * 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.

These are OK. Thanks!

Sri, I'm out of town through 11/18, and won't be able to commit the
include/ patch to GCC before Stage 1 ends. Can you take care of it?
(If not, I'll take care of it when I get back -- it was approved
during Stage 1, so I think it's OK to commit early in Stage 3,
especially since it's nothing but new declarations.)

-cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-11-08 22:37             ` Cary Coutant
@ 2017-11-10  1:24               ` Stephen Crane
  2017-11-10  5:06                 ` Cary Coutant
  0 siblings, 1 reply; 15+ messages in thread
From: Stephen Crane @ 2017-11-10  1:24 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Sriraman Tallam, Binutils, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1708 bytes --]

Cary Coutant <ccoutant@gmail.com> writes:

> The patch for include/plugin-api.h needs to be separated out (with a
> ChangeLog entry of its own), and applied first to the GCC tree, then
> synced to binutils. After that, the rest of this patch is OK to apply.

Thanks. Attached is the patch for plugin-api.h which needs to be applied
to GCC and binutils (plugin_api_new_input.patch). Also attached is the
gold patch to implement the new functionality
(gold_new_input_handler.patch). ChangeLogs for both patches are below. I
don't have write access to either repo, so would you be willing to
commit on my behalf?

> Can you also update the GCC wiki whopr/driver page?

I'd be happy to if I can be added to the EditorGroup (my username is
StephenCrane).


include/ChangeLog:
2017-11-09  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 funcion hook type.
	(ld_plugin_register_new_input): New interface.
	(LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
	(tv_register_new_input): New member.


gold/ChangeLog:
2017-11-09  Stephen Crane  <sjc@immunant.com>

	* 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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: plugin_api_new_input.patch --]
[-- Type: text/x-patch, Size: 2086 bytes --]

commit f45d97f0ee4c202602c9951ade622caf2e27ffe2
Author: Stephen Crane <sjc@immunant.com>
Date:   Thu Sep 21 14:22:37 2017 -0700

    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).

diff --git a/include/plugin-api.h b/include/plugin-api.h
index 3a3e8b456db..f081f85dfaf 100644
--- a/include/plugin-api.h
+++ b/include/plugin-api.h
@@ -365,6 +365,20 @@ 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);
+
+
 enum ld_plugin_level
 {
   LDPL_INFO,
@@ -407,7 +421,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 +456,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;
 };
 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: gold_new_input_handler.patch --]
[-- Type: text/x-patch, Size: 18711 bytes --]

diff --git a/gold/plugin.cc b/gold/plugin.cc
index 5ea23b5bdd..49212b4309 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_);
         }
     }
 
@@ -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.
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/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index d8426db62f..050da8bef9 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -2397,6 +2397,23 @@ plugin_section_order.so: plugin_section_order.o gcctestdir/ld
 plugin_section_order.o: plugin_section_order.c
 	$(COMPILE) -O0 -c -fpic -o $@ $<
 
+# Uses the plugin_final_layout.sh script above to avoid duplication
+check_DATA += plugin_layout_new_file.stdout plugin_layout_new_file_readelf.stdout
+MOSTLYCLEANFILES += plugin_layout_new_file
+plugin_final_layout.o.syms: plugin_final_layout.o
+	$(TEST_READELF) -sW $< >$@ 2>/dev/null
+plugin_layout_new_file: plugin_final_layout.o.syms plugin_test.so plugin_new_section_layout.so gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ -Wl,--plugin,"./plugin_test.so"  -Wl,--plugin,"./plugin_new_section_layout.so" plugin_final_layout.o.syms
+plugin_layout_new_file.stdout: plugin_layout_new_file
+	$(TEST_NM) -n --synthetic plugin_layout_new_file > plugin_layout_new_file.stdout
+plugin_layout_new_file_readelf.stdout: plugin_layout_new_file
+	$(TEST_READELF) -Wl plugin_layout_new_file > plugin_layout_new_file_readelf.stdout
+
+plugin_new_section_layout.so: plugin_new_section_layout.o gcctestdir/ld
+	$(LINK) -Bgcctestdir/ -shared plugin_new_section_layout.o
+plugin_new_section_layout.o: plugin_new_section_layout.c
+	$(COMPILE) -O0 -c -fpic -o $@ $<
+
 check_SCRIPTS += plugin_layout_with_alignment.sh
 check_DATA += plugin_layout_with_alignment.stdout
 MOSTLYCLEANFILES += plugin_layout_with_alignment
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index c42c472795..da6a3c41e8 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -577,11 +577,16 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@@TLS_TRUE@am__append_51 = plugin_test_tls.err
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_52 = unused.c \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_final_layout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_new_file \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_with_alignment
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_53 = plugin_final_layout.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_with_alignment.sh
+
+# Uses the plugin_final_layout.sh script above to avoid duplication
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_54 = plugin_final_layout.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_final_layout_readelf.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_new_file.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_new_file_readelf.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_with_alignment.stdout
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_55 = exclude_libs_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	local_labels_test \
@@ -7050,6 +7055,19 @@ uninstall-am:
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(LINK) -Bgcctestdir/ -shared plugin_section_order.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_section_order.o: plugin_section_order.c
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(COMPILE) -O0 -c -fpic -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_final_layout.o.syms: plugin_final_layout.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(TEST_READELF) -sW $< >$@ 2>/dev/null
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_new_file: plugin_final_layout.o.syms plugin_test.so plugin_new_section_layout.so gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(CXXLINK) -Bgcctestdir/ -Wl,--plugin,"./plugin_test.so"  -Wl,--plugin,"./plugin_new_section_layout.so" plugin_final_layout.o.syms
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_new_file.stdout: plugin_layout_new_file
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(TEST_NM) -n --synthetic plugin_layout_new_file > plugin_layout_new_file.stdout
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_new_file_readelf.stdout: plugin_layout_new_file
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(TEST_READELF) -Wl plugin_layout_new_file > plugin_layout_new_file_readelf.stdout
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_new_section_layout.so: plugin_new_section_layout.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(LINK) -Bgcctestdir/ -shared plugin_new_section_layout.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_new_section_layout.o: plugin_new_section_layout.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(COMPILE) -O0 -c -fpic -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_with_alignment.o: plugin_layout_with_alignment.c
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(COMPILE) -O0 -c -ffunction-sections  -fdata-sections -g -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_with_alignment: plugin_layout_with_alignment.o plugin_section_alignment.so gcctestdir/ld
diff --git a/gold/testsuite/plugin_final_layout.sh b/gold/testsuite/plugin_final_layout.sh
index 54985916a7..3157beacf4 100755
--- a/gold/testsuite/plugin_final_layout.sh
+++ b/gold/testsuite/plugin_final_layout.sh
@@ -23,7 +23,7 @@
 # MA 02110-1301, USA.
 
 # The goal of this program is to verify if --section-ordering-file works as
-# intended.  File final_layout.cc is in this test.
+# intended.  File plugin_final_layout.cc is in this test.
 
 
 set -e
@@ -37,7 +37,7 @@ BEGIN { saw1 = 0; saw2 = 0; err = 0; }
      saw2 = 1;
      if (!saw1)
        {
-	  printf \"layout of $2 and $3 is not right\\n\";
+	  printf \"layout of $2 and $3 is not right in file $1\\n\";
 	  err = 1;
 	  exit 1;
        }
@@ -45,12 +45,12 @@ BEGIN { saw1 = 0; saw2 = 0; err = 0; }
 END {
       if (!saw1 && !err)
         {
-	  printf \"did not see $2\\n\";
+	  printf \"did not see $2 in file $1\\n\";
 	  exit 1;
 	}
       if (!saw2 && !err)
 	{
-	  printf \"did not see $3\\n\";
+	  printf \"did not see $3 in file $1\\n\";
 	  exit 1;
 	}
     }" $1
@@ -74,12 +74,12 @@ BEGIN { saw_section = 0; saw_unique = 0; }
 END {
       if (!saw_section)
 	{
-	  printf \"Section $2 not seen in output\\n\";
+	  printf \"Section $2 not seen in output file $1\\n\";
 	  exit 1;
 	}
       else if (!saw_unique)
 	{
-	  printf \"Unique segment not seen for: $2\\n\";
+	  printf \"Unique segment not seen for: $2 in file $1\\n\";
 	  exit 1;
 	}
     }" $1
@@ -88,3 +88,7 @@ END {
 check plugin_final_layout.stdout "_Z3foov" "_Z3barv"
 check plugin_final_layout.stdout "_Z3barv" "_Z3bazv"
 check_unique_segment plugin_final_layout_readelf.stdout ".text.plugin_created_unique"
+
+check plugin_layout_new_file.stdout "_Z3foov" "_Z3barv"
+check plugin_layout_new_file.stdout "_Z3barv" "_Z3bazv"
+check_unique_segment plugin_layout_new_file_readelf.stdout ".text.plugin_created_unique"
diff --git a/gold/testsuite/plugin_new_section_layout.c b/gold/testsuite/plugin_new_section_layout.c
new file mode 100644
index 0000000000..f27ad4c530
--- /dev/null
+++ b/gold/testsuite/plugin_new_section_layout.c
@@ -0,0 +1,181 @@
+/* plugin_new_section_layout.c -- Simple plugin to reorder function sections in
+   plugin-generated objects
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   Written by Stephen Crane <sjc@immunant.com>.
+
+   This file is part of gold.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* This plugin tests the new_input API of the linker plugin interface that
+ * allows plugins to modify section layout and assign sections to segments for
+ * sections in plugin-generated object files. It assumes that another plugin is
+ * also in use which will add new files. In practice a plugin is likely to
+ * generate new input files itself in all_symbols_read and want to
+ * reorder/assign sections for these files in the new_input_hook callback. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "plugin-api.h"
+#include "elf/common.h"
+
+static ld_plugin_get_input_section_count get_input_section_count = NULL;
+static ld_plugin_get_input_section_type get_input_section_type = NULL;
+static ld_plugin_get_input_section_name get_input_section_name = NULL;
+static ld_plugin_update_section_order update_section_order = NULL;
+static ld_plugin_allow_section_ordering allow_section_ordering = NULL;
+static ld_plugin_allow_unique_segment_for_sections 
+    allow_unique_segment_for_sections = NULL;
+static ld_plugin_unique_segment_for_sections unique_segment_for_sections = NULL;
+
+enum ld_plugin_status onload(struct ld_plugin_tv *tv);
+enum ld_plugin_status new_input_hook(const struct ld_plugin_input_file *file);
+
+/* Plugin entry point.  */
+enum ld_plugin_status
+onload(struct ld_plugin_tv *tv)
+{
+  struct ld_plugin_tv *entry;
+  for (entry = tv; entry->tv_tag != LDPT_NULL; ++entry)
+    {
+      switch (entry->tv_tag)
+        {
+        case LDPT_GET_INPUT_SECTION_COUNT:
+          get_input_section_count = *entry->tv_u.tv_get_input_section_count;
+          break;
+        case LDPT_GET_INPUT_SECTION_TYPE:
+          get_input_section_type = *entry->tv_u.tv_get_input_section_type;
+          break;
+        case LDPT_GET_INPUT_SECTION_NAME:
+          get_input_section_name = *entry->tv_u.tv_get_input_section_name;
+          break;
+	case LDPT_UPDATE_SECTION_ORDER:
+	  update_section_order = *entry->tv_u.tv_update_section_order;
+	  break;
+	case LDPT_ALLOW_SECTION_ORDERING:
+	  allow_section_ordering = *entry->tv_u.tv_allow_section_ordering;
+	  break;
+	case LDPT_ALLOW_UNIQUE_SEGMENT_FOR_SECTIONS:
+	  allow_unique_segment_for_sections
+	      = *entry->tv_u.tv_allow_unique_segment_for_sections;
+	  break;
+	case LDPT_UNIQUE_SEGMENT_FOR_SECTIONS:
+	  unique_segment_for_sections
+	      = *entry->tv_u.tv_unique_segment_for_sections;
+	  break;
+        case LDPT_REGISTER_NEW_INPUT_HOOK:
+          assert((*entry->tv_u.tv_register_new_input) (new_input_hook)
+		 == LDPS_OK);
+          break;
+        default:
+          break;
+        }
+    }
+
+  if (get_input_section_count == NULL
+      || get_input_section_type == NULL
+      || get_input_section_name == NULL
+      || update_section_order == NULL
+      || allow_section_ordering == NULL
+      || allow_unique_segment_for_sections == NULL
+      || unique_segment_for_sections == NULL)
+    {
+      fprintf(stderr, "Some interfaces are missing\n");
+      return LDPS_ERR;
+    }
+
+  /* Inform the linker to prepare for section reordering.  */
+  (*allow_section_ordering)();
+  /* Inform the linker to prepare to map some sections to unique
+     segments.  */
+  (*allow_unique_segment_for_sections)(); 
+
+  return LDPS_OK;
+}
+
+inline static int is_prefix_of(const char *prefix, const char *str)
+{
+  return strncmp(prefix, str, strlen (prefix)) == 0;
+}
+
+/* This function is called by the linker when new files are added by a plugin.
+   We can now tell the linker the desired function order since we have a file
+   handle for the newly added file.  */
+
+enum ld_plugin_status
+new_input_hook(const struct ld_plugin_input_file *file)
+{
+  struct ld_plugin_section section_list[3];
+  int num_entries = 0;
+  unsigned int count;
+
+  if (get_input_section_count(file->handle, &count) != LDPS_OK)
+    return LDPS_ERR;
+
+  for (unsigned i = 0; i < count; ++i)
+  {
+    struct ld_plugin_section section;
+    unsigned int type = 0;
+    char *name = NULL;
+    int position = 3;
+
+    section.handle = file->handle;
+    section.shndx = i;
+
+    if (get_input_section_type(section, &type) != LDPS_OK)
+      return LDPL_FATAL;
+    if (type != SHT_PROGBITS)
+      continue;
+
+    if (get_input_section_name(section, &name))
+      return LDPL_FATAL;
+
+    /* As in plugin_section_order.c, order is foo() followed by bar()
+       followed by baz() */
+    if (is_prefix_of(".text.", name))
+    {
+      if (strstr(name, "_Z3foov") != NULL)
+        position = 0;
+      else if (strstr(name, "_Z3barv") != NULL)
+        position = 1;
+      else if (strstr(name, "_Z3bazv") != NULL)
+        position = 2;
+      else
+        position = 3;
+    }
+    if (position < 3)
+    {
+      section_list[position] = section;
+      num_entries++;
+    }
+  }
+
+  if (num_entries != 3)
+    return LDPL_FATAL;
+
+  update_section_order(section_list, num_entries);
+  unique_segment_for_sections (".text.plugin_created_unique", 0, 0x1000,
+                               section_list, num_entries);
+
+  return LDPS_OK;
+}
-- 
2.15.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-11-08  0:39           ` Stephen Crane
@ 2017-11-08 22:37             ` Cary Coutant
  2017-11-10  1:24               ` Stephen Crane
  0 siblings, 1 reply; 15+ messages in thread
From: Cary Coutant @ 2017-11-08 22:37 UTC (permalink / raw)
  To: Stephen Crane; +Cc: Sriraman Tallam, Binutils

>> gold/Changelog:
>>
>>         * 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.

The patch for include/plugin-api.h needs to be separated out (with a
ChangeLog entry of its own), and applied first to the GCC tree, then
synced to binutils. After that, the rest of this patch is OK to apply.

(GCC is in Stage 1 through Nov. 17. It would be best to get that
change in by then.)

Can you also update the GCC wiki whopr/driver page?

-cary

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-10-20 21:49         ` [PATCH] " Stephen Crane
@ 2017-11-08  0:39           ` Stephen Crane
  2017-11-08 22:37             ` Cary Coutant
  0 siblings, 1 reply; 15+ messages in thread
From: Stephen Crane @ 2017-11-08  0:39 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Sriraman Tallam, Binutils

Just wanted to ping this patch and see who would be the appropriate
person to approve if it's good to go.

Thanks,
Stephen

On Fri, Oct 20, 2017 at 2:49 PM, Stephen Crane <sjc@immunant.com> wrote:
>
> A single test script sounds good to me. Attached is an updated and
> rebased patch using a unified test script. I added the failing input
> file to the test output to make it clear in the log which test failed.
>
> gold/Changelog:
>
>         * 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.
>
> - stephen
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] [GOLD] Add plugin API for processing plugin-added input files
  2017-10-20  0:51       ` Cary Coutant
@ 2017-10-20 21:49         ` Stephen Crane
  2017-11-08  0:39           ` Stephen Crane
  0 siblings, 1 reply; 15+ messages in thread
From: Stephen Crane @ 2017-10-20 21:49 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Sriraman Tallam, Binutils

[-- Attachment #1: Type: text/plain, Size: 789 bytes --]


A single test script sounds good to me. Attached is an updated and
rebased patch using a unified test script. I added the failing input
file to the test output to make it clear in the log which test failed.

gold/Changelog:

        * 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.

- stephen


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gold_plugin_api_new_input-v3.patch --]
[-- Type: text/x-patch, Size: 20982 bytes --]

commit 4b5e6a058b8f4069d989752485eaa5003bcec94d
Author: Stephen Crane <sjc@immunant.com>
Date:   Fri Oct 20 14:26:30 2017 -0700

    [GOLD] 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 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).
    
    New test exercises the new input hook by generating a new file using the basic
    test plugin and then reordering its sections and assigning sections to unique
    segments in a second plugin.

diff --git a/gold/plugin.cc b/gold/plugin.cc
index 5ea23b5bdd..49212b4309 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_);
         }
     }
 
@@ -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.
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/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index d9a0669fb4..ced831a935 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -2397,6 +2397,23 @@ plugin_section_order.so: plugin_section_order.o gcctestdir/ld
 plugin_section_order.o: plugin_section_order.c
 	$(COMPILE) -O0 -c -fpic -o $@ $<
 
+# Uses the plugin_final_layout.sh script above to avoid duplication
+check_DATA += plugin_layout_new_file.stdout plugin_layout_new_file_readelf.stdout
+MOSTLYCLEANFILES += plugin_layout_new_file
+plugin_final_layout.o.syms: plugin_final_layout.o
+	$(TEST_READELF) -sW $< >$@ 2>/dev/null
+plugin_layout_new_file: plugin_final_layout.o.syms plugin_test.so plugin_new_section_layout.so gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ -Wl,--plugin,"./plugin_test.so"  -Wl,--plugin,"./plugin_new_section_layout.so" plugin_final_layout.o.syms
+plugin_layout_new_file.stdout: plugin_layout_new_file
+	$(TEST_NM) -n --synthetic plugin_layout_new_file > plugin_layout_new_file.stdout
+plugin_layout_new_file_readelf.stdout: plugin_layout_new_file
+	$(TEST_READELF) -Wl plugin_layout_new_file > plugin_layout_new_file_readelf.stdout
+
+plugin_new_section_layout.so: plugin_new_section_layout.o gcctestdir/ld
+	$(LINK) -Bgcctestdir/ -shared plugin_new_section_layout.o
+plugin_new_section_layout.o: plugin_new_section_layout.c
+	$(COMPILE) -O0 -c -fpic -o $@ $<
+
 check_SCRIPTS += plugin_layout_with_alignment.sh
 check_DATA += plugin_layout_with_alignment.stdout
 MOSTLYCLEANFILES += plugin_layout_with_alignment
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index b8db70d75d..6bc1bbb360 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -577,11 +577,16 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@@TLS_TRUE@am__append_51 = plugin_test_tls.err
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_52 = unused.c \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_final_layout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_new_file \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_with_alignment
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_53 = plugin_final_layout.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_with_alignment.sh
+
+# Uses the plugin_final_layout.sh script above to avoid duplication
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_54 = plugin_final_layout.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_final_layout_readelf.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_new_file.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_new_file_readelf.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	plugin_layout_with_alignment.stdout
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_55 = exclude_libs_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	local_labels_test \
@@ -7032,6 +7037,19 @@ uninstall-am:
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(LINK) -Bgcctestdir/ -shared plugin_section_order.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_section_order.o: plugin_section_order.c
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(COMPILE) -O0 -c -fpic -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_final_layout.o.syms: plugin_final_layout.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(TEST_READELF) -sW $< >$@ 2>/dev/null
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_new_file: plugin_final_layout.o.syms plugin_test.so plugin_new_section_layout.so gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(CXXLINK) -Bgcctestdir/ -Wl,--plugin,"./plugin_test.so"  -Wl,--plugin,"./plugin_new_section_layout.so" plugin_final_layout.o.syms
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_new_file.stdout: plugin_layout_new_file
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(TEST_NM) -n --synthetic plugin_layout_new_file > plugin_layout_new_file.stdout
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_new_file_readelf.stdout: plugin_layout_new_file
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(TEST_READELF) -Wl plugin_layout_new_file > plugin_layout_new_file_readelf.stdout
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_new_section_layout.so: plugin_new_section_layout.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(LINK) -Bgcctestdir/ -shared plugin_new_section_layout.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_new_section_layout.o: plugin_new_section_layout.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(COMPILE) -O0 -c -fpic -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_with_alignment.o: plugin_layout_with_alignment.c
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@	$(COMPILE) -O0 -c -ffunction-sections  -fdata-sections -g -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_layout_with_alignment: plugin_layout_with_alignment.o plugin_section_alignment.so gcctestdir/ld
diff --git a/gold/testsuite/plugin_final_layout.sh b/gold/testsuite/plugin_final_layout.sh
index 54985916a7..3157beacf4 100755
--- a/gold/testsuite/plugin_final_layout.sh
+++ b/gold/testsuite/plugin_final_layout.sh
@@ -23,7 +23,7 @@
 # MA 02110-1301, USA.
 
 # The goal of this program is to verify if --section-ordering-file works as
-# intended.  File final_layout.cc is in this test.
+# intended.  File plugin_final_layout.cc is in this test.
 
 
 set -e
@@ -37,7 +37,7 @@ BEGIN { saw1 = 0; saw2 = 0; err = 0; }
      saw2 = 1;
      if (!saw1)
        {
-	  printf \"layout of $2 and $3 is not right\\n\";
+	  printf \"layout of $2 and $3 is not right in file $1\\n\";
 	  err = 1;
 	  exit 1;
        }
@@ -45,12 +45,12 @@ BEGIN { saw1 = 0; saw2 = 0; err = 0; }
 END {
       if (!saw1 && !err)
         {
-	  printf \"did not see $2\\n\";
+	  printf \"did not see $2 in file $1\\n\";
 	  exit 1;
 	}
       if (!saw2 && !err)
 	{
-	  printf \"did not see $3\\n\";
+	  printf \"did not see $3 in file $1\\n\";
 	  exit 1;
 	}
     }" $1
@@ -74,12 +74,12 @@ BEGIN { saw_section = 0; saw_unique = 0; }
 END {
       if (!saw_section)
 	{
-	  printf \"Section $2 not seen in output\\n\";
+	  printf \"Section $2 not seen in output file $1\\n\";
 	  exit 1;
 	}
       else if (!saw_unique)
 	{
-	  printf \"Unique segment not seen for: $2\\n\";
+	  printf \"Unique segment not seen for: $2 in file $1\\n\";
 	  exit 1;
 	}
     }" $1
@@ -88,3 +88,7 @@ END {
 check plugin_final_layout.stdout "_Z3foov" "_Z3barv"
 check plugin_final_layout.stdout "_Z3barv" "_Z3bazv"
 check_unique_segment plugin_final_layout_readelf.stdout ".text.plugin_created_unique"
+
+check plugin_layout_new_file.stdout "_Z3foov" "_Z3barv"
+check plugin_layout_new_file.stdout "_Z3barv" "_Z3bazv"
+check_unique_segment plugin_layout_new_file_readelf.stdout ".text.plugin_created_unique"
diff --git a/gold/testsuite/plugin_new_section_layout.c b/gold/testsuite/plugin_new_section_layout.c
new file mode 100644
index 0000000000..f27ad4c530
--- /dev/null
+++ b/gold/testsuite/plugin_new_section_layout.c
@@ -0,0 +1,181 @@
+/* plugin_new_section_layout.c -- Simple plugin to reorder function sections in
+   plugin-generated objects
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   Written by Stephen Crane <sjc@immunant.com>.
+
+   This file is part of gold.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* This plugin tests the new_input API of the linker plugin interface that
+ * allows plugins to modify section layout and assign sections to segments for
+ * sections in plugin-generated object files. It assumes that another plugin is
+ * also in use which will add new files. In practice a plugin is likely to
+ * generate new input files itself in all_symbols_read and want to
+ * reorder/assign sections for these files in the new_input_hook callback. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "plugin-api.h"
+#include "elf/common.h"
+
+static ld_plugin_get_input_section_count get_input_section_count = NULL;
+static ld_plugin_get_input_section_type get_input_section_type = NULL;
+static ld_plugin_get_input_section_name get_input_section_name = NULL;
+static ld_plugin_update_section_order update_section_order = NULL;
+static ld_plugin_allow_section_ordering allow_section_ordering = NULL;
+static ld_plugin_allow_unique_segment_for_sections 
+    allow_unique_segment_for_sections = NULL;
+static ld_plugin_unique_segment_for_sections unique_segment_for_sections = NULL;
+
+enum ld_plugin_status onload(struct ld_plugin_tv *tv);
+enum ld_plugin_status new_input_hook(const struct ld_plugin_input_file *file);
+
+/* Plugin entry point.  */
+enum ld_plugin_status
+onload(struct ld_plugin_tv *tv)
+{
+  struct ld_plugin_tv *entry;
+  for (entry = tv; entry->tv_tag != LDPT_NULL; ++entry)
+    {
+      switch (entry->tv_tag)
+        {
+        case LDPT_GET_INPUT_SECTION_COUNT:
+          get_input_section_count = *entry->tv_u.tv_get_input_section_count;
+          break;
+        case LDPT_GET_INPUT_SECTION_TYPE:
+          get_input_section_type = *entry->tv_u.tv_get_input_section_type;
+          break;
+        case LDPT_GET_INPUT_SECTION_NAME:
+          get_input_section_name = *entry->tv_u.tv_get_input_section_name;
+          break;
+	case LDPT_UPDATE_SECTION_ORDER:
+	  update_section_order = *entry->tv_u.tv_update_section_order;
+	  break;
+	case LDPT_ALLOW_SECTION_ORDERING:
+	  allow_section_ordering = *entry->tv_u.tv_allow_section_ordering;
+	  break;
+	case LDPT_ALLOW_UNIQUE_SEGMENT_FOR_SECTIONS:
+	  allow_unique_segment_for_sections
+	      = *entry->tv_u.tv_allow_unique_segment_for_sections;
+	  break;
+	case LDPT_UNIQUE_SEGMENT_FOR_SECTIONS:
+	  unique_segment_for_sections
+	      = *entry->tv_u.tv_unique_segment_for_sections;
+	  break;
+        case LDPT_REGISTER_NEW_INPUT_HOOK:
+          assert((*entry->tv_u.tv_register_new_input) (new_input_hook)
+		 == LDPS_OK);
+          break;
+        default:
+          break;
+        }
+    }
+
+  if (get_input_section_count == NULL
+      || get_input_section_type == NULL
+      || get_input_section_name == NULL
+      || update_section_order == NULL
+      || allow_section_ordering == NULL
+      || allow_unique_segment_for_sections == NULL
+      || unique_segment_for_sections == NULL)
+    {
+      fprintf(stderr, "Some interfaces are missing\n");
+      return LDPS_ERR;
+    }
+
+  /* Inform the linker to prepare for section reordering.  */
+  (*allow_section_ordering)();
+  /* Inform the linker to prepare to map some sections to unique
+     segments.  */
+  (*allow_unique_segment_for_sections)(); 
+
+  return LDPS_OK;
+}
+
+inline static int is_prefix_of(const char *prefix, const char *str)
+{
+  return strncmp(prefix, str, strlen (prefix)) == 0;
+}
+
+/* This function is called by the linker when new files are added by a plugin.
+   We can now tell the linker the desired function order since we have a file
+   handle for the newly added file.  */
+
+enum ld_plugin_status
+new_input_hook(const struct ld_plugin_input_file *file)
+{
+  struct ld_plugin_section section_list[3];
+  int num_entries = 0;
+  unsigned int count;
+
+  if (get_input_section_count(file->handle, &count) != LDPS_OK)
+    return LDPS_ERR;
+
+  for (unsigned i = 0; i < count; ++i)
+  {
+    struct ld_plugin_section section;
+    unsigned int type = 0;
+    char *name = NULL;
+    int position = 3;
+
+    section.handle = file->handle;
+    section.shndx = i;
+
+    if (get_input_section_type(section, &type) != LDPS_OK)
+      return LDPL_FATAL;
+    if (type != SHT_PROGBITS)
+      continue;
+
+    if (get_input_section_name(section, &name))
+      return LDPL_FATAL;
+
+    /* As in plugin_section_order.c, order is foo() followed by bar()
+       followed by baz() */
+    if (is_prefix_of(".text.", name))
+    {
+      if (strstr(name, "_Z3foov") != NULL)
+        position = 0;
+      else if (strstr(name, "_Z3barv") != NULL)
+        position = 1;
+      else if (strstr(name, "_Z3bazv") != NULL)
+        position = 2;
+      else
+        position = 3;
+    }
+    if (position < 3)
+    {
+      section_list[position] = section;
+      num_entries++;
+    }
+  }
+
+  if (num_entries != 3)
+    return LDPL_FATAL;
+
+  update_section_order(section_list, num_entries);
+  unique_segment_for_sections (".text.plugin_created_unique", 0, 0x1000,
+                               section_list, num_entries);
+
+  return LDPS_OK;
+}
diff --git a/include/plugin-api.h b/include/plugin-api.h
index 3a3e8b456d..f081f85dfa 100644
--- a/include/plugin-api.h
+++ b/include/plugin-api.h
@@ -365,6 +365,20 @@ 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);
+
+
 enum ld_plugin_level
 {
   LDPL_INFO,
@@ -407,7 +421,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 +456,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;
 };
 

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-12-12 18:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-25  5:49 [PATCH] [GOLD] Add plugin API for processing plugin-added input files Stephen Crane
2017-09-14 22:16 ` Stephen Crane
2017-09-20 21:51   ` Cary Coutant
2017-09-26  1:46 [PATCH 2/2] " Stephen Crane
2017-10-11  7:09 ` Sriraman Tallam via binutils
2017-10-14  1:00   ` Stephen Crane
2017-10-14  5:47     ` Sriraman Tallam via binutils
2017-10-20  0:51       ` Cary Coutant
2017-10-20 21:49         ` [PATCH] " Stephen Crane
2017-11-08  0:39           ` Stephen Crane
2017-11-08 22:37             ` Cary Coutant
2017-11-10  1:24               ` Stephen Crane
2017-11-10  5:06                 ` Cary Coutant
2017-11-10 16:29                   ` Sriraman Tallam via binutils
2017-11-10 22:11                   ` Sriraman Tallam via binutils
2017-12-11 22:10                   ` Sriraman Tallam via binutils
2017-12-11 22:16                     ` Stephen Crane
2017-12-11 22:33                       ` Sriraman Tallam via binutils
2017-12-11 23:03                       ` Sriraman Tallam via binutils
2017-12-12 18:51                         ` Stephen Crane

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).