Automatic date update in version.in
[external/binutils.git] / bfd / plugin.c
index d9b9e2f..5f760e9 100644 (file)
@@ -1,5 +1,5 @@
 /* Plugin support for BFD.
-   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+   Copyright (C) 2009-2019 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -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,32 @@ 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 = bfd_malloc (sizeof *plugin_list_iter);
+  if (plugin_list_iter == NULL)
+    return 0;
+  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 +293,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 +303,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.  */
@@ -507,13 +532,13 @@ bfd_plugin_canonicalize_symtab (bfd *abfd,
   struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
   long nsyms = plugin_data->nsyms;
   const struct ld_plugin_symbol *syms = plugin_data->syms;
-  static asection fake_section;
-  static asection fake_common_section;
+  static asection fake_section
+    = BFD_FAKE_SECTION (fake_section, NULL, "plug", 0,
+                       SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS);
+  static asection fake_common_section
+    = BFD_FAKE_SECTION (fake_common_section, NULL, "plug", 0, SEC_IS_COMMON);
   int i;
 
-  fake_section.name = ".text";
-  fake_common_section.flags = SEC_IS_COMMON;
-
   for (i = 0; i < nsyms; i++)
     {
       asymbol *s = bfd_alloc (abfd, sizeof (asymbol));