[binutils-gdb] Avoid problems with plugins being loaded multiple times.

Nick Clifton nickc@sourceware.org
Thu Aug 23 15:23:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0

commit b0ceb98aec8e1ab610deea9fee9ee75c5911bbc0
Author: Zenith423 <zenith432@users.sourceforge.net>
Date:   Thu Aug 23 16:22:56 2018 +0100

    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.

Diff:
---
 bfd/ChangeLog |  8 ++++++++
 bfd/plugin.c  | 51 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 97c8e08..1cadfc4 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2018-08-23  Zenith423  <zenith432@users.sourceforge.net>
+
+	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.
+
 2018-08-23  Alan Modra  <amodra@gmail.com>
 
 	* elf64-ppc.c (ppc64_elf_relocate_section): Revise "call lacks
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.  */



More information about the Binutils-cvs mailing list