From ed6f9d09f2b955996ad5f014f3c265aae4549b0a Mon Sep 17 00:00:00 2001 From: Yury Usishchev Date: Wed, 15 Jul 2015 20:06:43 +0300 Subject: [PATCH] Ignore broken plugins Allow cross-configured ld to ignore plugins that cannot be dlopened Change-Id: I0bbca32123aeba869d843fdfb9179815af888f5c Signed-off-by: Yury Usishchev --- gold/plugin.cc | 21 +++++++++++++++++++++ gold/plugin.h | 12 ++++++++++++ ld/plugin.c | 23 +++++++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/gold/plugin.cc b/gold/plugin.cc index 2cc13a7..270c597 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -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. diff --git a/gold/plugin.h b/gold/plugin.h index 0520a84..826997e 100644 --- a/gold/plugin.h +++ b/gold/plugin.h @@ -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_; }; diff --git a/ld/plugin.c b/ld/plugin.c index 34aefc5..a81d829 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -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) -- 2.7.4