Ignore broken plugins
authorYury Usishchev <y.usishchev@samsung.com>
Wed, 15 Jul 2015 17:06:43 +0000 (20:06 +0300)
committerDongkyun Son <dongkyun.s@samsung.com>
Wed, 3 May 2023 09:42:13 +0000 (18:42 +0900)
Allow cross-configured ld to ignore plugins that cannot be dlopened

Change-Id: I0bbca32123aeba869d843fdfb9179815af888f5c
Signed-off-by: Yury Usishchev <y.usishchev@samsung.com>
gold/plugin.cc
gold/plugin.h
ld/plugin.c

index 2cc13a7..270c597 100644 (file)
@@ -199,9 +199,16 @@ Plugin::load()
   this->handle_ = dlopen(this->filename_.c_str(), RTLD_NOW);
   if (this->handle_ == NULL)
     {
+#ifdef IGNORE_BROKEN_PLUGINS
+      gold_warning(_("%s: could not load plugin library: %s"),
+                   this->filename_.c_str(), dlerror());
+      this->broken_=true;
+      return;
+#else
       gold_error(_("%s: could not load plugin library: %s"),
                  this->filename_.c_str(), dlerror());
       return;
+#endif
     }
 
   // Find the plugin's onload entry point.
@@ -715,6 +722,17 @@ Plugin_manager::~Plugin_manager()
 }
 
 // Load all plugin libraries.
+#ifdef IGNORE_BROKEN_PLUGINS
+bool delete_broken(const Plugin* a){
+  if(a->broken()){
+    // remove broken plugin as it will be deleted from list
+    delete a;
+    return true;
+  } else {
+    return false;
+  }
+}
+#endif
 
 void
 Plugin_manager::load_plugins(Layout* layout)
@@ -731,6 +749,9 @@ Plugin_manager::load_plugins(Layout* layout)
        this->current_ != this->plugins_.end();
        ++this->current_)
     (*this->current_)->load();
+#ifdef IGNORE_BROKEN_PLUGINS
+  this->plugins_.remove_if(delete_broken);
+#endif
 }
 
 // Call the plugin claim-file handlers in turn to see if any claim the file.
index 0520a84..826997e 100644 (file)
@@ -62,6 +62,9 @@ class Plugin
       all_symbols_read_handler_(NULL),
       cleanup_handler_(NULL),
       new_input_handler_(NULL),
+#ifdef IGNORE_BROKEN_PLUGINS
+      broken_(false),
+#endif
       cleanup_done_(false)
   { }
 
@@ -114,6 +117,11 @@ class Plugin
   {
     this->args_.push_back(arg);
   }
+#ifdef IGNORE_BROKEN_PLUGINS
+  bool
+  broken() const
+  { return this->broken_; }
+#endif
 
   const std::string&
   filename() const
@@ -134,6 +142,10 @@ class Plugin
   ld_plugin_all_symbols_read_handler all_symbols_read_handler_;
   ld_plugin_cleanup_handler cleanup_handler_;
   ld_plugin_new_input_handler new_input_handler_;
+#ifdef IGNORE_BROKEN_PLUGINS
+  // TRUE if we cannot open this plugin
+  bool broken_;
+#endif
   // TRUE if the cleanup handlers have been called.
   bool cleanup_done_;
 };
index 34aefc5..a81d829 100644 (file)
@@ -125,6 +125,9 @@ static plugin_t **plugins_tail_chain_ptr = &plugins_list;
 /* The last plugin added to the list, for receiving args.  */
 static plugin_t *last_plugin = NULL;
 
+/* This is set when we ignored last plugin */
+static bfd_boolean last_plugin_ignored;
+
 /* The tail of the arg chain of the last plugin added to the list.  */
 static plugin_arg_t **last_plugin_args_tail_chain_ptr = NULL;
 
@@ -249,8 +252,16 @@ plugin_opt_plugin (const char *plugin)
   memset (newplug, 0, sizeof *newplug);
   newplug->name = plugin;
   newplug->dlhandle = dlopen (plugin, RTLD_NOW);
-  if (!newplug->dlhandle)
-    einfo (_("%F%P: %s: error loading plugin: %s\n"), plugin, dlerror ());
+  if (!newplug->dlhandle) {
+#ifdef IGNORE_BROKEN_PLUGINS
+    einfo (_("%P: %s: error loading plugin: %s\n"), plugin, dlerror ());
+    last_plugin_ignored=TRUE;
+    free(newplug);
+    return;
+#else
+    einfo (_("%P%F: %s: error loading plugin: %s\n"), plugin, dlerror ());
+#endif
+  }
 
   /* Check if plugin has been loaded already.  */
   while (curplug)
@@ -271,6 +282,9 @@ plugin_opt_plugin (const char *plugin)
   /* Record it as current plugin for receiving args.  */
   last_plugin = newplug;
   last_plugin_args_tail_chain_ptr = &newplug->args;
+#ifdef IGNORE_BROKEN_PLUGINS
+  last_plugin_ignored=FALSE;
+#endif
 }
 
 /* Accumulate option arguments for last-loaded plugin, or return
@@ -278,6 +292,11 @@ plugin_opt_plugin (const char *plugin)
 int
 plugin_opt_plugin_arg (const char *arg)
 {
+#ifdef IGNORE_BROKEN_PLUGINS
+  /* Ignore options for ignored plugin */
+  if (last_plugin_ignored)
+    return 0;
+#endif
   plugin_arg_t *newarg;
 
   if (!last_plugin)