From 5a3528e2fcdacd4215291aa6462168d637106475 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 | 21 ++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/gold/plugin.cc b/gold/plugin.cc index 026748f..34639b8 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -187,9 +187,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. @@ -455,6 +462,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) @@ -464,6 +482,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 652ec58..8122839 100644 --- a/gold/plugin.h +++ b/gold/plugin.h @@ -60,6 +60,9 @@ class Plugin claim_file_handler_(NULL), all_symbols_read_handler_(NULL), cleanup_handler_(NULL), +#ifdef IGNORE_BROKEN_PLUGINS + broken_(false), +#endif cleanup_done_(false) { } @@ -103,6 +106,11 @@ class Plugin { this->args_.push_back(arg); } +#ifdef IGNORE_BROKEN_PLUGINS + bool + broken() const + { return this->broken_; } +#endif private: Plugin(const Plugin&); @@ -118,6 +126,10 @@ 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_; +#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 4c161d1..180b77d 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -119,6 +119,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; @@ -242,8 +245,16 @@ plugin_opt_plugin (const char *plugin) memset (newplug, 0, sizeof *newplug); newplug->name = plugin; newplug->dlhandle = dlopen (plugin, RTLD_NOW); - if (!newplug->dlhandle) + 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 + } /* Chain on end, so when we run list it is in command-line order. */ *plugins_tail_chain_ptr = newplug; @@ -252,6 +263,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 @@ -259,6 +273,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