mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
plugin: Search bfd-plugins directories only once
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.
This commit is contained in:
@ -1,3 +1,15 @@
|
|||||||
|
2020-02-13 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2020-02-11 H.J. Lu <hongjiu.lu@intel.com>
|
2020-02-11 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR binutils/25355
|
PR binutils/25355
|
||||||
|
77
bfd/plugin.c
77
bfd/plugin.c
@ -592,16 +592,15 @@ try_claim (bfd *abfd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
void *plugin_handle = NULL;
|
||||||
struct ld_plugin_tv tv[12];
|
struct ld_plugin_tv tv[12];
|
||||||
int i;
|
int i;
|
||||||
ld_plugin_onload onload;
|
ld_plugin_onload onload;
|
||||||
enum ld_plugin_status status;
|
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
|
/* NB: Each object is independent. Reuse the previous plugin from
|
||||||
the last run will lead to wrong result. */
|
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;
|
current_plugin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (plugin_list_iter)
|
||||||
|
pname = plugin_list_iter->plugin_name;
|
||||||
|
|
||||||
plugin_handle = dlopen (pname, RTLD_NOW);
|
plugin_handle = dlopen (pname, RTLD_NOW);
|
||||||
if (!plugin_handle)
|
if (!plugin_handle)
|
||||||
{
|
{
|
||||||
@ -621,12 +623,6 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
|
|||||||
return 0;
|
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)
|
if (plugin_list_iter == NULL)
|
||||||
{
|
{
|
||||||
size_t length_plugin_name = strlen (pname) + 1;
|
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;
|
plugin_list_iter->handle = plugin_handle;
|
||||||
|
if (build_list_p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
onload = dlsym (plugin_handle, "onload");
|
onload = dlsym (plugin_handle, "onload");
|
||||||
if (!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))
|
&& setup_lto_wrapper_env (current_plugin))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*has_plugin_p = 1;
|
|
||||||
|
|
||||||
abfd->plugin_format = bfd_plugin_no;
|
abfd->plugin_format = bfd_plugin_no;
|
||||||
|
|
||||||
if (!current_plugin->claim_file)
|
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. */
|
/* There may be plugin libraries in lib/bfd-plugins. */
|
||||||
|
static int has_plugin_list = -1;
|
||||||
static int has_plugin = -1;
|
|
||||||
|
|
||||||
static const bfd_target *(*ld_plugin_object_p) (bfd *);
|
static const bfd_target *(*ld_plugin_object_p) (bfd *);
|
||||||
|
|
||||||
@ -743,7 +738,6 @@ void
|
|||||||
bfd_plugin_set_plugin (const char *p)
|
bfd_plugin_set_plugin (const char *p)
|
||||||
{
|
{
|
||||||
plugin_name = p;
|
plugin_name = p;
|
||||||
has_plugin = p != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return TRUE if a plugin library is used. */
|
/* Return TRUE if a plugin library is used. */
|
||||||
@ -751,7 +745,7 @@ bfd_plugin_set_plugin (const char *p)
|
|||||||
bfd_boolean
|
bfd_boolean
|
||||||
bfd_plugin_specified_p (void)
|
bfd_plugin_specified_p (void)
|
||||||
{
|
{
|
||||||
return has_plugin > 0;
|
return plugin_list != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return TRUE if ABFD can be claimed by linker LTO plugin. */
|
/* 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;
|
ld_plugin_object_p = object_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
load_plugin (bfd *abfd)
|
build_plugin_list (bfd *abfd)
|
||||||
{
|
{
|
||||||
/* The intent was to search ${libdir}/bfd-plugins for plugins, but
|
/* The intent was to search ${libdir}/bfd-plugins for plugins, but
|
||||||
unfortunately the original implementation wasn't precisely that
|
unfortunately the original implementation wasn't precisely that
|
||||||
@ -792,17 +786,10 @@ load_plugin (bfd *abfd)
|
|||||||
static const char *path[]
|
static const char *path[]
|
||||||
= { LIBDIR "/bfd-plugins", BINDIR "/../lib/bfd-plugins" };
|
= { LIBDIR "/bfd-plugins", BINDIR "/../lib/bfd-plugins" };
|
||||||
struct stat last_st;
|
struct stat last_st;
|
||||||
int found = 0;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!has_plugin)
|
if (has_plugin_list >= 0)
|
||||||
return found;
|
return;
|
||||||
|
|
||||||
if (plugin_name)
|
|
||||||
return try_load_plugin (plugin_name, abfd, &has_plugin);
|
|
||||||
|
|
||||||
if (plugin_program_name == NULL)
|
|
||||||
return found;
|
|
||||||
|
|
||||||
/* Try not to search the same dir twice, by looking at st_dev and
|
/* 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
|
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);
|
full_name = concat (plugin_dir, "/", ent->d_name, NULL);
|
||||||
if (stat (full_name, &st) == 0 && S_ISREG (st.st_mode))
|
if (stat (full_name, &st) == 0 && S_ISREG (st.st_mode))
|
||||||
{
|
try_load_plugin (full_name, NULL, abfd, TRUE);
|
||||||
int valid_plugin;
|
|
||||||
|
|
||||||
found = try_load_plugin (full_name, abfd, &valid_plugin);
|
|
||||||
if (has_plugin <= 0)
|
|
||||||
has_plugin = valid_plugin;
|
|
||||||
}
|
|
||||||
free (full_name);
|
free (full_name);
|
||||||
if (found)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
closedir (d);
|
closedir (d);
|
||||||
}
|
}
|
||||||
free (plugin_dir);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user