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 v2] [GOLD] Add plugin API for processing plugin-added input files


On Wed, Sep 20, 2017 at 2:50 PM, Cary Coutant <ccoutant@gmail.com> wrote:
> 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:

Thanks for your help! I just emailed the GCC patches list with the
plugin API change.

In the process of preparing the GCC header patch I realized there was
an extra function that I accidentally left in the original patch. Here
is an updated version without the unnecessary and unused
ld_plugin_get_input_handle typedef. I also neglected to write proper
Changelog entries, so here are those as well.


include/Changelog:
2017-09-21  Stephen Crane <sjc@immunant.com>

        * plugin-api.h: Add new hook to the plugin transfer vector to
        support assigning plugin-generated sections to unique output
        segments.
        (ld_plugin_register_new_input): New hook.
        (ld_plugin_tag): Add LDPT_REGISTER_NEW_INPUT_HOOK.
        (ld_plugin_tv): Add tv_register_new_input.

gold/Changelog:
2017-09-21  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.
---
 gold/plugin.cc       | 63 +++++++++++++++++++++++++++++++++++++++-------------
 gold/plugin.h        | 19 ++++++++++++++++
 include/plugin-api.h | 18 ++++++++++++++-
 3 files changed, 84 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..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;
 };

-- 
2.14.1


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