Merge linker plugin handling into BFD plugin support

Linker plugin_maybe_claim is the interface of linker plugin support.
This patch extracts linker plugin_maybe_claim into plugin_object_p and
makes it available to BFD via a new function:

void register_ld_plugin_object_p (const bfd_target *(*) (bfd *));

bfd_plugin_object_p calls plugin_object_p registered by linker first.  It
adds an enum bfd_plugin_format field and a pointer to plugin dummy BFD so
that plugin_object_p stores plugin dummy BFD to allow plugin_maybe_claim
to retrieve it later.

bfd/

	PR ld/17878
	* bfd.c (bfd_plugin_format): New.
	(bfd): Add plugin_format and plugin_dummy_bfd.
	* plugin.c (try_load_plugin): Take a pointer to bfd_boolean
	argument to return TRUE if any plugin is found.  Set plugin_format.
	(has_plugin): New.
	(bfd_plugin_target_p): New.
	(bfd_plugin_specified_p): Likewise.
	(bfd_plugin_target_p): Likewise.
	(register_ld_plugin_object_p): Likewise.
	(bfd_plugin_set_plugin): Set has_plugin.
	(load_plugin): Cache try_load_plugin result.
	(bfd_plugin_object_p): Try ld_plugin_object_p first.  Check
	plugin_format.
	* plugin.h (bfd_plugin_target_p): New.
	(bfd_plugin_specified_p): Likewise.
	(register_ld_plugin_object_p): Likewise.
	* bfd-in2.h: Regenerated.

ld/

	PR ld/17878
	* plugin.c: Include ../bfd/plugin.h.
	(plugin_get_ir_dummy_bfd): Call bfd_create with
	link_info.output_bfd instead of srctemplate.  Copy BFD info
	from srctemplate only if it doesn't use BFD plugin target
	vector.
	(plugin_load_plugins): Call register_ld_plugin_object_p with
	(plugin_object_p)
	(plugin_maybe_claim): Renamed to ...
	(plugin_object_p): This.  Return dummy BFD target vector if
	input is calimed by plugin library, otherwise return NULL.
	Update plugin_format and plugin_dummy_bfd.
	(plugin_maybe_claim): New.  Use plugin_object_p.

xx
This commit is contained in:
H.J. Lu
2015-02-11 05:01:03 -08:00
parent 18ad82c163
commit 5ae0078cd2
5 changed files with 160 additions and 39 deletions

View File

@@ -203,7 +203,7 @@ try_claim (bfd *abfd)
}
static int
try_load_plugin (const char *pname, bfd *abfd)
try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
{
void *plugin_handle;
int tv_size = 4;
@@ -212,6 +212,8 @@ try_load_plugin (const char *pname, bfd *abfd)
ld_plugin_onload onload;
enum ld_plugin_status status;
*has_plugin_p = 0;
plugin_handle = dlopen (pname, RTLD_NOW);
if (!plugin_handle)
{
@@ -244,25 +246,63 @@ try_load_plugin (const char *pname, bfd *abfd)
if (status != LDPS_OK)
goto err;
*has_plugin_p = 1;
abfd->plugin_format = bfd_plugin_no;
if (!claim_file)
goto err;
if (!try_claim (abfd))
goto err;
abfd->plugin_format = bfd_plugin_yes;
return 1;
err:
plugin_handle = NULL;
return 0;
}
/* There may be plugin libraries in lib/bfd-plugins. */
static int has_plugin = -1;
static const bfd_target *(*ld_plugin_object_p) (bfd *);
static const char *plugin_name;
void
bfd_plugin_set_plugin (const char *p)
{
plugin_name = p;
has_plugin = p != NULL;
}
/* Return TRUE if a plugin library is used. */
bfd_boolean
bfd_plugin_specified_p (void)
{
return has_plugin > 0;
}
extern const bfd_target plugin_vec;
/* Return TRUE if TARGET is a pointer to plugin_vec. */
bfd_boolean
bfd_plugin_target_p (const bfd_target *target)
{
return target == &plugin_vec;
}
/* Register OBJECT_P to be used by bfd_plugin_object_p. */
void
register_ld_plugin_object_p (const bfd_target *(*object_p) (bfd *))
{
ld_plugin_object_p = object_p;
}
static int
@@ -274,11 +314,14 @@ load_plugin (bfd *abfd)
struct dirent *ent;
int found = 0;
if (!has_plugin)
return found;
if (plugin_name)
return try_load_plugin (plugin_name, abfd);
return try_load_plugin (plugin_name, abfd, &has_plugin);
if (plugin_program_name == NULL)
return 0;
return found;
plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL);
p = make_relative_prefix (plugin_program_name,
@@ -295,10 +338,13 @@ load_plugin (bfd *abfd)
{
char *full_name;
struct stat s;
int valid_plugin;
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, abfd);
found = try_load_plugin (full_name, abfd, &valid_plugin);
if (has_plugin <= 0)
has_plugin = valid_plugin;
free (full_name);
if (found)
break;
@@ -316,10 +362,13 @@ load_plugin (bfd *abfd)
static const bfd_target *
bfd_plugin_object_p (bfd *abfd)
{
if (!load_plugin (abfd))
if (ld_plugin_object_p)
return ld_plugin_object_p (abfd);
if (abfd->plugin_format == bfd_plugin_uknown && !load_plugin (abfd))
return NULL;
return abfd->xvec;
return abfd->plugin_format == bfd_plugin_yes ? abfd->xvec : NULL;
}
/* Copy any private info we understand from the input bfd