BFD: Add support for more than one plugin in lib/bfd-plugins

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.
This commit is contained in:
Markus Trippelsdorf 2014-09-24 18:04:53 +09:30 committed by Alan Modra
parent 71b9b91bce
commit e44f5bef12
2 changed files with 63 additions and 52 deletions

View 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> 2014-09-23 Sterling Augustine <augustine.sterling@gmail.com>
* elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section

View file

@ -156,9 +156,54 @@ bfd_plugin_set_program_name (const char *program_name)
} }
static int 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; int tv_size = 4;
struct ld_plugin_tv tv[tv_size]; struct ld_plugin_tv tv[tv_size];
int i; int i;
@ -200,6 +245,9 @@ try_load_plugin (const char *pname)
if (!claim_file) if (!claim_file)
goto err; goto err;
if (!try_claim (abfd))
goto err;
return 1; return 1;
err: err:
@ -216,7 +264,7 @@ bfd_plugin_set_plugin (const char *p)
} }
static int static int
load_plugin (void) load_plugin (bfd *abfd)
{ {
char *plugin_dir; char *plugin_dir;
char *p; char *p;
@ -225,7 +273,7 @@ load_plugin (void)
int found = 0; int found = 0;
if (plugin_name) if (plugin_name)
return try_load_plugin (plugin_name); return try_load_plugin (plugin_name, abfd);
if (plugin_program_name == NULL) if (plugin_program_name == NULL)
return 0; return 0;
@ -248,7 +296,7 @@ load_plugin (void)
full_name = concat (p, "/", ent->d_name, NULL); full_name = concat (p, "/", ent->d_name, NULL);
if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode)) 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); free (full_name);
if (found) if (found)
break; break;
@ -266,53 +314,7 @@ load_plugin (void)
static const bfd_target * static const bfd_target *
bfd_plugin_object_p (bfd *abfd) bfd_plugin_object_p (bfd *abfd)
{ {
int claimed = 0; if (!load_plugin (abfd))
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)
return NULL; return NULL;
return abfd->xvec; return abfd->xvec;