aboutsummaryrefslogtreecommitdiff
path: root/bfd/plugin.c
diff options
context:
space:
mode:
authorZenith423 <zenith432@users.sourceforge.net>2018-08-23 16:22:56 +0100
committerNick Clifton <nickc@redhat.com>2018-08-23 16:22:56 +0100
commitb0ceb98aec8e1ab610deea9fee9ee75c5911bbc0 (patch)
tree7dd7e1f16df9fb59ef5796dbe0606e1521323d67 /bfd/plugin.c
parent12a0d0f66172b9504e29000fa4f4e5c34109d6db (diff)
downloadgdb-b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0.zip
gdb-b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0.tar.gz
gdb-b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0.tar.bz2
Avoid problems with plugins being loaded multiple times.
PR 23460 * plugin.c (struct plugin_list_entry): New structure. (plugin_list): New variable. (try_load_plugin): Place opened plugins on a list. Ensure that the refcount in the dynamic loader is kept at 1.
Diffstat (limited to 'bfd/plugin.c')
-rw-r--r--bfd/plugin.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/bfd/plugin.c b/bfd/plugin.c
index d9b9e2f..fe34115 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -219,6 +219,15 @@ try_claim (bfd *abfd)
return claimed;
}
+struct plugin_list_entry
+{
+ void * handle;
+ ld_plugin_claim_file_handler claim_file;
+ struct plugin_list_entry * next;
+};
+
+static struct plugin_list_entry * plugin_list = NULL;
+
static int
try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
{
@@ -227,9 +236,7 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
int i;
ld_plugin_onload onload;
enum ld_plugin_status status;
-
- if (claim_file)
- goto have_claim_file;
+ struct plugin_list_entry *plugin_list_iter;
*has_plugin_p = 0;
@@ -240,9 +247,30 @@ 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 (plugin_handle == plugin_list_iter->handle)
+ {
+ dlclose (plugin_handle);
+ if (!plugin_list_iter->claim_file)
+ return 0;
+
+ register_claim_file (plugin_list_iter->claim_file);
+ goto have_claim_file;
+ }
+ }
+
+ plugin_list_iter = (struct plugin_list_entry *) xmalloc (sizeof *plugin_list_iter);
+ plugin_list_iter->handle = plugin_handle;
+ plugin_list_iter->claim_file = NULL;
+ plugin_list_iter->next = plugin_list;
+ plugin_list = plugin_list_iter;
+
onload = dlsym (plugin_handle, "onload");
if (!onload)
- goto err;
+ return 0;
i = 0;
tv[i].tv_tag = LDPT_MESSAGE;
@@ -263,7 +291,9 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
status = (*onload)(tv);
if (status != LDPS_OK)
- goto err;
+ return 0;
+
+ plugin_list_iter->claim_file = claim_file;
have_claim_file:
*has_plugin_p = 1;
@@ -271,20 +301,13 @@ have_claim_file:
abfd->plugin_format = bfd_plugin_no;
if (!claim_file)
- goto err;
+ return 0;
if (!try_claim (abfd))
- goto err;
+ return 0;
abfd->plugin_format = bfd_plugin_yes;
-
return 1;
-
- err:
- if (plugin_handle)
- dlclose (plugin_handle);
- register_claim_file (NULL);
- return 0;
}
/* There may be plugin libraries in lib/bfd-plugins. */