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>
* 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
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;