summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-02-13 03:17:51 -0800
committerH.J. Lu <hjl.tools@gmail.com>2020-02-13 06:40:27 -0800
commit66539658c0c31b06605e7127c2578c5704cb7326 (patch)
tree12bd96882fc3f3287da06ddda9d57847100661b8
parentb1f73450fecb9f56cd44f29f79c21574cd2f1628 (diff)
downloadbinutils-gdb-users/hjl/pr25355/binutils-2_34-branch.tar.gz
plugin: Search bfd-plugins directories only onceusers/hjl/pr25355/binutils-2_34-branch
try_load_plugin is updated to take either plugin name or plugin entry. load_plugin is updated to search bfd-plugins directories first to build a list of plugins and call try_load_plugin with each plugin on the list. When --plugin is used, the plugin list only has one entry. * plugin.c (try_load_plugin): Make plugin_list_iter an argument and use it if it isn't NULL. Remove has_plugin_p argument. Add a build_list_p argument. Don't search plugin_list. Short circuit when building the plugin list. (has_plugin): Renamed to has_plugin_list. (bfd_plugin_set_plugin): Don't set has_plugin. (bfd_plugin_specified_p): Check plugin_list instead. (build_plugin_list): New function. (load_plugin): Call build_plugin_list and use plugin_list. (cherry picked from commit 99845b3b77ed1248b6fb94707f88868bde358ccc)
-rw-r--r--bfd/plugin.c77
1 files changed, 38 insertions, 39 deletions
diff --git a/bfd/plugin.c b/bfd/plugin.c
index d9416771545..47c3439042c 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -592,16 +592,15 @@ try_claim (bfd *abfd)
}
static int
-try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
+try_load_plugin (const char *pname,
+ struct plugin_list_entry *plugin_list_iter,
+ bfd *abfd, bfd_boolean build_list_p)
{
void *plugin_handle = NULL;
struct ld_plugin_tv tv[12];
int i;
ld_plugin_onload onload;
enum ld_plugin_status status;
- struct plugin_list_entry *plugin_list_iter;
-
- *has_plugin_p = 0;
/* NB: Each object is independent. Reuse the previous plugin from
the last run will lead to wrong result. */
@@ -614,6 +613,9 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
current_plugin = NULL;
}
+ if (plugin_list_iter)
+ pname = plugin_list_iter->plugin_name;
+
plugin_handle = dlopen (pname, RTLD_NOW);
if (!plugin_handle)
{
@@ -621,12 +623,6 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
return 0;
}
- for (plugin_list_iter = plugin_list;
- plugin_list_iter;
- plugin_list_iter = plugin_list_iter->next)
- if (strcmp (plugin_list_iter->plugin_name, pname) == 0)
- break;
-
if (plugin_list_iter == NULL)
{
size_t length_plugin_name = strlen (pname) + 1;
@@ -649,6 +645,8 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
}
plugin_list_iter->handle = plugin_handle;
+ if (build_list_p)
+ return 0;
onload = dlsym (plugin_handle, "onload");
if (!onload)
@@ -717,8 +715,6 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
&& setup_lto_wrapper_env (current_plugin))
return 0;
- *has_plugin_p = 1;
-
abfd->plugin_format = bfd_plugin_no;
if (!current_plugin->claim_file)
@@ -732,8 +728,7 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
}
/* There may be plugin libraries in lib/bfd-plugins. */
-
-static int has_plugin = -1;
+static int has_plugin_list = -1;
static const bfd_target *(*ld_plugin_object_p) (bfd *);
@@ -743,7 +738,6 @@ void
bfd_plugin_set_plugin (const char *p)
{
plugin_name = p;
- has_plugin = p != NULL;
}
/* Return TRUE if a plugin library is used. */
@@ -751,7 +745,7 @@ bfd_plugin_set_plugin (const char *p)
bfd_boolean
bfd_plugin_specified_p (void)
{
- return has_plugin > 0;
+ return plugin_list != NULL;
}
/* Return TRUE if ABFD can be claimed by linker LTO plugin. */
@@ -782,8 +776,8 @@ register_ld_plugin_object_p (const bfd_target *(*object_p) (bfd *))
ld_plugin_object_p = object_p;
}
-static int
-load_plugin (bfd *abfd)
+static void
+build_plugin_list (bfd *abfd)
{
/* The intent was to search ${libdir}/bfd-plugins for plugins, but
unfortunately the original implementation wasn't precisely that
@@ -792,17 +786,10 @@ load_plugin (bfd *abfd)
static const char *path[]
= { LIBDIR "/bfd-plugins", BINDIR "/../lib/bfd-plugins" };
struct stat last_st;
- int found = 0;
unsigned int i;
- if (!has_plugin)
- return found;
-
- if (plugin_name)
- return try_load_plugin (plugin_name, abfd, &has_plugin);
-
- if (plugin_program_name == NULL)
- return found;
+ if (has_plugin_list >= 0)
+ return;
/* Try not to search the same dir twice, by looking at st_dev and
st_ino for the dir. If we are on a file system that always sets
@@ -837,26 +824,38 @@ load_plugin (bfd *abfd)
full_name = concat (plugin_dir, "/", ent->d_name, NULL);
if (stat (full_name, &st) == 0 && S_ISREG (st.st_mode))
- {
- int valid_plugin;
-
- found = try_load_plugin (full_name, abfd, &valid_plugin);
- if (has_plugin <= 0)
- has_plugin = valid_plugin;
- }
+ try_load_plugin (full_name, NULL, abfd, TRUE);
free (full_name);
- if (found)
- break;
}
closedir (d);
}
free (plugin_dir);
}
- if (found)
- break;
}
- return found;
+ has_plugin_list = plugin_list != NULL;
+}
+
+static int
+load_plugin (bfd *abfd)
+{
+ struct plugin_list_entry *plugin_list_iter;
+
+ if (plugin_name)
+ return try_load_plugin (plugin_name, plugin_list, abfd, FALSE);
+
+ if (plugin_program_name == NULL)
+ return 0;
+
+ build_plugin_list (abfd);
+
+ for (plugin_list_iter = plugin_list;
+ plugin_list_iter;
+ plugin_list_iter = plugin_list_iter->next)
+ if (try_load_plugin (NULL, plugin_list_iter, abfd, FALSE))
+ return 1;
+
+ return 0;
}