diff options
author | Zenith423 <zenith432@users.sourceforge.net> | 2018-08-23 16:22:56 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2018-08-23 16:22:56 +0100 |
commit | b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0 (patch) | |
tree | 7dd7e1f16df9fb59ef5796dbe0606e1521323d67 /bfd/plugin.c | |
parent | 12a0d0f66172b9504e29000fa4f4e5c34109d6db (diff) | |
download | binutils-b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0.zip binutils-b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0.tar.gz binutils-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.c | 51 |
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. */ |