This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] bfd: Add support for more than one plugin in lib/bfd-plugins
- From: Markus Trippelsdorf <markus at trippelsdorf dot de>
- To: binutils at sourceware dot org
- Cc: Nick Clifton <nickc at redhat dot com>, Rafael Avila de Espindola <rafael dot espindola at gmail dot com>
- Date: Tue, 23 Sep 2014 08:25:36 +0200
- Subject: [PATCH] bfd: Add support for more than one plugin in lib/bfd-plugins
- Authentication-results: sourceware.org; auth=none
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