BFD: Add support for more than one plugin in lib/bfd-plugins
authorMarkus Trippelsdorf <markus@trippelsdorf.de>
Wed, 24 Sep 2014 08:34:53 +0000 (18:04 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 24 Sep 2014 08:38:53 +0000 (18:08 +0930)
ar, nm and ranlib currently lack the ability to handle more than one
plugin in lib/bfd-plugins. This patch reshuffles the logic in plugin.c
to add this functionality. One can now place both llvm and gcc plugins
in this directory and have them loaded automatically.
Mixed gcc/llvm archives are also supported (but not very useful until
ld.bfd and ld.gold also would load multiple plugins and use them to
claim different object files).

PR 17422
* plugin.c (try_claim): New function. Moved from
bfd_plugin_object_p.
(try_load_plugin): Pass through bfd. Add test.
(load_plugin): Pass through bfd.
(bfd_plugin_object_p): Move logic to try_claim.

bfd/ChangeLog
bfd/plugin.c

index d8559ea..f70cad6 100644 (file)
@@ -1,3 +1,12 @@
+2014-09-24  Markus Trippelsdorf  <markus@trippelsdorf.de>
+
+       PR 17422
+       * plugin.c (try_claim): New function. Moved from
+       bfd_plugin_object_p.
+       (try_load_plugin): Pass through bfd. Add test.
+       (load_plugin): Pass through bfd.
+       (bfd_plugin_object_p): Move logic to try_claim.
+
 2014-09-23  Sterling Augustine  <augustine.sterling@gmail.com>
 
        * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section
index c9d53c8..d336b67 100644 (file)
@@ -156,9 +156,54 @@ bfd_plugin_set_program_name (const char *program_name)
 }
 
 static int
-try_load_plugin (const char *pname)
+try_claim (bfd *abfd)
 {
-  static void *plugin_handle;
+  int claimed = 0;
+  struct ld_plugin_input_file file;
+  bfd *iobfd;
+
+  file.name = abfd->filename;
+
+  if (abfd->my_archive)
+    {
+      iobfd = abfd->my_archive;
+      file.offset = abfd->origin;
+      file.filesize = arelt_size (abfd);
+    }
+  else
+    {
+      iobfd = abfd;
+      file.offset = 0;
+      file.filesize = 0;
+    }
+
+  if (!iobfd->iostream && !bfd_open_file (iobfd))
+    return 0;
+
+  file.fd = fileno ((FILE *) iobfd->iostream);
+
+  if (!abfd->my_archive)
+    {
+      struct stat stat_buf;
+      if (fstat (file.fd, &stat_buf))
+        return 0;
+      file.filesize = stat_buf.st_size;
+    }
+
+  file.handle = abfd;
+  off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
+  claim_file (&file, &claimed);
+  lseek(file.fd, cur_offset, SEEK_SET);
+  if (!claimed)
+    return 0;
+
+  return 1;
+}
+
+static int
+try_load_plugin (const char *pname, bfd *abfd)
+{
+  void *plugin_handle;
   int tv_size = 4;
   struct ld_plugin_tv tv[tv_size];
   int i;
@@ -200,6 +245,9 @@ try_load_plugin (const char *pname)
   if (!claim_file)
     goto err;
 
+  if (!try_claim (abfd))
+    goto err;
+
   return 1;
 
  err:
@@ -216,7 +264,7 @@ bfd_plugin_set_plugin (const char *p)
 }
 
 static int
-load_plugin (void)
+load_plugin (bfd *abfd)
 {
   char *plugin_dir;
   char *p;
@@ -225,7 +273,7 @@ load_plugin (void)
   int found = 0;
 
   if (plugin_name)
-    return try_load_plugin (plugin_name);
+    return try_load_plugin (plugin_name, abfd);
 
   if (plugin_program_name == NULL)
     return 0;
@@ -248,7 +296,7 @@ load_plugin (void)
 
       full_name = concat (p, "/", ent->d_name, NULL);
       if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode))
-       found = try_load_plugin (full_name);
+       found = try_load_plugin (full_name, abfd);
       free (full_name);
       if (found)
        break;
@@ -266,53 +314,7 @@ load_plugin (void)
 static const bfd_target *
 bfd_plugin_object_p (bfd *abfd)
 {
-  int claimed = 0;
-  struct ld_plugin_input_file file;
-  bfd *iobfd;
-  static int have_loaded = 0;
-  static int have_plugin = 0;
-
-  if (!have_loaded)
-    {
-      have_loaded = 1;
-      have_plugin = load_plugin ();
-    }
-  if (!have_plugin)
-    return NULL;
-
-  file.name = abfd->filename;
-
-  if (abfd->my_archive)
-    {
-      iobfd = abfd->my_archive;
-      file.offset = abfd->origin;
-      file.filesize = arelt_size (abfd);
-    }
-  else
-    {
-      iobfd = abfd;
-      file.offset = 0;
-      file.filesize = 0;
-    }
-
-  if (!iobfd->iostream && !bfd_open_file (iobfd))
-    return NULL;
-
-  file.fd = fileno ((FILE *) iobfd->iostream);
-
-  if (!abfd->my_archive)
-    {
-      struct stat stat_buf;
-      if (fstat (file.fd, &stat_buf))
-        return NULL;
-      file.filesize = stat_buf.st_size;
-    }
-
-  file.handle = abfd;
-  off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
-  claim_file (&file, &claimed);
-  lseek(file.fd, cur_offset, SEEK_SET);
-  if (!claimed)
+  if (!load_plugin (abfd))
     return NULL;
 
   return abfd->xvec;