This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] bfd: Add support for more than one plugin in lib/bfd-plugins


Hi,

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).

For example:

markus@x4 tmp % ll /usr/x86_64-pc-linux-gnu/binutils-bin/lib/bfd-plugins
total 12K
drwxr-xr-x 2 root root 4.0K Sep 22 21:38 .
drwxr-xr-x 3 root root 4.0K Oct  7  2012 ..
lrwxrwxrwx 1 root root   65 Sep 22 21:36 liblto_plugin.so.0.0.0 -> /usr/libexec/gcc/x86_64-pc-linux-gnu/4.9.2/liblto_plugin.so.0.0.0
lrwxrwxrwx 1 root root   26 Sep 22 21:38 LLVMgold.so -> /usr/local/lib/LLVMgold.so

markus@x4 tmp % cat a.c
extern void foo1 (void);
void foo2 (void) { foo1 (); }
void foo3 (void) {}

markus@x4 tmp % cat b.c
extern void foo2 (void);
extern void foo3 (void);
void foo1 (void) { foo3 (); }
int main (void) { foo2 (); }

markus@x4 tmp % gcc -c -flto a.c
markus@x4 tmp % ar cr a.a a.o
markus@x4 tmp % gcc -flto b.c a.a

markus@x4 tmp % clang -c -flto a.c
markus@x4 tmp % ar cr a.a a.o
markus@x4 tmp % clang -flto b.c a.a

(mixed gcc/llvm archives are fine:)
markus@x4 tmp % gcc -c -flto a.c
markus@x4 tmp % clang -c -flto b.c
markus@x4 tmp % ar cr a.a a.o b.o
markus@x4 tmp % ranlib a.a
markus@x4 tmp % nm a.a

a.o:
         U foo1
00000000 T foo2
00000000 T foo3

b.o:
00000000 T foo1
         U foo2
         U foo3
00000000 T main

Does this patch look OK?
Thanks.

2014-09-23  Markus Trippelsdorf  <markus@trippelsdorf.de>

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

diff --git a/bfd/plugin.c b/bfd/plugin.c
index c9d53c89a61f..bae86ccd9623 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -156,7 +156,52 @@ bfd_plugin_set_program_name (const char *program_name)
 }
 
 static int
-try_load_plugin (const char *pname)
+try_claim (bfd *abfd)
+{
+  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)
 {
   static void *plugin_handle;
   int tv_size = 4;
@@ -164,7 +209,6 @@ try_load_plugin (const char *pname)
   int i;
   ld_plugin_onload onload;
   enum ld_plugin_status status;
-
   plugin_handle = dlopen (pname, RTLD_NOW);
   if (!plugin_handle)
     {
@@ -200,6 +244,9 @@ try_load_plugin (const char *pname)
   if (!claim_file)
     goto err;
 
+  if (!try_claim (abfd))
+    goto err;
+
   return 1;
 
  err:
@@ -216,7 +263,7 @@ bfd_plugin_set_plugin (const char *p)
 }
 
 static int
-load_plugin (void)
+load_plugin (bfd *abfd)
 {
   char *plugin_dir;
   char *p;
@@ -225,7 +272,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 +295,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 +313,10 @@ 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))
+  if (!load_plugin (abfd))
     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 (!try_claim (abfd))
     return NULL;
 
   return abfd->xvec;
-- 
Markus


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]