lto: Don't include unused LTO archive members in output

When plugin_object_p is called by elf_link_is_defined_archive_symbol to
check if a symbol in archive is a real definition, set archive member
plugin_format to bfd_plugin_yes_unused to avoid including the unused LTO
archive members in linker output.  When plugin_object_p is called as
known used, call plugin claim_file if plugin_format is bfd_plugin_unknown
or bfd_plugin_yes_unused.

To get the proper support for archives with LTO common symbols with GCC,
the GCC fix for

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116361

is needed.

bfd/

	PR ld/32083
	* archures.c (bfd_arch_get_compatible): Treat bfd_plugin_yes_unused
	the same as bfd_plugin_yes.
	* elflink.c (elf_link_is_defined_archive_symbol): Likewise.
	* bfd.c (bfd_plugin_format): Add bfd_plugin_yes_unused.
	* plugin.c (try_claim): Try claim_file_v2 first.
	* bfd-in2.h: Regenerated.

ld/

	PR ld/32083
	* plugin.c (plugin_call_claim_file): Add an argument to return
	if LDPT_REGISTER_CLAIM_FILE_HOOK_V2 is used.
	(plugin_object_p): When KNOWN_USED is false, we call plugin
	claim_file if plugin_format is bfd_plugin_unknown and set
	plugin_format to bfd_plugin_yes_unused on LTO object.  When
	KNOWN_USED is true, we call plugin claim_file if plugin_format
	is bfd_plugin_unknown or bfd_plugin_yes_unused.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
H.J. Lu 2024-08-14 20:50:02 -07:00
parent 72e96189d8
commit a6f8fe0a9e
6 changed files with 48 additions and 17 deletions

View File

@ -947,6 +947,7 @@ bfd_arch_get_compatible (const bfd *abfd,
to assume that they know what they are doing. */
if (accept_unknowns
|| ubfd->plugin_format == bfd_plugin_yes
|| ubfd->plugin_format == bfd_plugin_yes_unused
|| strcmp (bfd_get_target (ubfd), "binary") == 0)
return kbfd->arch_info;
return NULL;

View File

@ -1947,7 +1947,8 @@ enum bfd_plugin_format
{
bfd_plugin_unknown = 0,
bfd_plugin_yes = 1,
bfd_plugin_no = 2
bfd_plugin_yes_unused = 2,
bfd_plugin_no = 3
};
struct bfd_build_id

View File

@ -65,7 +65,8 @@ EXTERNAL
. {
. bfd_plugin_unknown = 0,
. bfd_plugin_yes = 1,
. bfd_plugin_no = 2
. bfd_plugin_yes_unused = 2,
. bfd_plugin_no = 3
. };
.
.struct bfd_build_id

View File

@ -3653,6 +3653,7 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
object file is an IR object, give linker LTO plugin a chance to
get the correct symbol table. */
if (abfd->plugin_format == bfd_plugin_yes
|| abfd->plugin_format == bfd_plugin_yes_unused
#if BFD_SUPPORTS_PLUGINS
|| (abfd->plugin_format == bfd_plugin_unknown
&& bfd_link_plugin_object_p (abfd))

View File

@ -329,13 +329,23 @@ try_claim (bfd *abfd)
struct ld_plugin_input_file file;
file.handle = abfd;
if (bfd_plugin_open_input (abfd, &file)
&& current_plugin->claim_file)
if (bfd_plugin_open_input (abfd, &file))
{
current_plugin->claim_file (&file, &claimed);
bfd_plugin_close_file_descriptor ((abfd->my_archive != NULL
? abfd : NULL),
file.fd);
bool claim_file_called = false;
if (current_plugin->claim_file_v2)
{
current_plugin->claim_file_v2 (&file, &claimed, false);
claim_file_called = true;
}
else if (current_plugin->claim_file)
{
current_plugin->claim_file (&file, &claimed);
claim_file_called = true;
}
if (claim_file_called)
bfd_plugin_close_file_descriptor ((abfd->my_archive != NULL
? abfd : NULL),
file.fd);
}
return claimed;

View File

@ -1174,10 +1174,11 @@ plugin_load_plugins (void)
/* Call 'claim file' hook for all plugins. */
static int
plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed,
bool known_used)
int *claim_file_handler_v2, bool known_used)
{
plugin_t *curplug = plugins_list;
*claimed = false;
*claim_file_handler_v2 = false;
while (curplug && !*claimed)
{
if (curplug->claim_file_handler)
@ -1186,7 +1187,11 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed,
called_plugin = curplug;
if (curplug->claim_file_handler_v2)
rv = (*curplug->claim_file_handler_v2) (file, claimed, known_used);
{
rv = (*curplug->claim_file_handler_v2) (file, claimed,
known_used);
*claim_file_handler_v2 = true;
}
else
rv = (*curplug->claim_file_handler) (file, claimed);
called_plugin = NULL;
@ -1222,7 +1227,7 @@ plugin_cleanup (bfd *abfd ATTRIBUTE_UNUSED)
static bfd_cleanup
plugin_object_p (bfd *ibfd, bool known_used)
{
int claimed;
int claimed, claim_file_handler_v2;
plugin_input_file_t *input;
struct ld_plugin_input_file file;
bfd *abfd;
@ -1231,12 +1236,17 @@ plugin_object_p (bfd *ibfd, bool known_used)
if ((ibfd->flags & BFD_PLUGIN) != 0)
return NULL;
if (ibfd->plugin_format != bfd_plugin_unknown)
/* When KNOWN_USED is false, we call plugin claim_file if plugin_format
is bfd_plugin_unknown and set plugin_format to bfd_plugin_yes_unused
on LTO object. When KNOWN_USED is true, we call plugin claim_file
if plugin_format is bfd_plugin_unknown or bfd_plugin_yes_unused. */
if (ibfd->plugin_format != bfd_plugin_unknown
&& (!known_used || ibfd->plugin_format != bfd_plugin_yes_unused))
{
if (ibfd->plugin_format == bfd_plugin_yes)
return plugin_cleanup;
else
if (ibfd->plugin_format == bfd_plugin_no)
return NULL;
else
return plugin_cleanup;
}
/* We create a dummy BFD, initially empty, to house whatever symbols
@ -1272,7 +1282,8 @@ plugin_object_p (bfd *ibfd, bool known_used)
claimed = 0;
if (plugin_call_claim_file (&file, &claimed, known_used))
if (plugin_call_claim_file (&file, &claimed, &claim_file_handler_v2,
known_used))
einfo (_("%F%P: %s: plugin reported error claiming file\n"),
plugin_error_plugin ());
@ -1292,7 +1303,13 @@ plugin_object_p (bfd *ibfd, bool known_used)
if (claimed)
{
ibfd->plugin_format = bfd_plugin_yes;
/* Set plugin_format to bfd_plugin_yes_unused if KNOWN_USED is
false for plugin claim_file_v2 to avoid including the unused
LTO archive members in linker output. */
if (known_used || !claim_file_handler_v2)
ibfd->plugin_format = bfd_plugin_yes;
else
ibfd->plugin_format = bfd_plugin_yes_unused;
ibfd->plugin_dummy_bfd = abfd;
bfd_make_readable (abfd);
abfd->no_export = ibfd->no_export;