forked from Imagelibrary/binutils-gdb
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:
63
bfd/plugin.c
63
bfd/plugin.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user