gcc-toolset-14-binutils/SOURCES/binutils-LTO-plugin-common-symbols.patch
2025-04-22 07:44:15 +00:00

294 lines
10 KiB
Diff

From a6f8fe0a9e9cbe871652e46ba7c22d5e9fb86208 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 14 Aug 2024 20:50:02 -0700
Subject: [PATCH] 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.
commit c839a44c39161c9932d58c28c2949ab3bb94ea6f
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sun Sep 8 17:27:00 2024 -0700
bfd: Pass true to ld_plugin_object_p
Since linker calls bfd_plugin_object_p, which calls ld_plugin_object_p,
only for command-line input objects, pass true to ld_plugin_object_p so
that the same input IR file won't be included twice if the new LTO hook,
LDPT_REGISTER_CLAIM_FILE_HOOK_V2 isn't used.
PR ld/32153
* plugin.c (bfd_plugin_object_p): Pass true to ld_plugin_object_p.
diff -rup binutils.orig/bfd/archures.c binutils-2.41/bfd/archures.c
--- binutils.orig/bfd/archures.c 2025-02-20 16:28:36.178833667 +0000
+++ binutils-2.41/bfd/archures.c 2025-02-20 20:20:34.505422221 +0000
@@ -931,6 +931,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;
diff -rup binutils.orig/bfd/bfd-in2.h binutils-2.41/bfd/bfd-in2.h
--- binutils.orig/bfd/bfd-in2.h 2025-02-20 16:28:36.284833929 +0000
+++ binutils-2.41/bfd/bfd-in2.h 2025-02-20 20:21:33.281519583 +0000
@@ -1912,7 +1912,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
diff -rup binutils.orig/bfd/bfd.c binutils-2.41/bfd/bfd.c
--- binutils.orig/bfd/bfd.c 2025-02-20 16:28:36.178833667 +0000
+++ binutils-2.41/bfd/bfd.c 2025-02-20 20:20:12.473385721 +0000
@@ -57,7 +57,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
diff -rup binutils.orig/bfd/elflink.c binutils-2.41/bfd/elflink.c
--- binutils.orig/bfd/elflink.c 2025-02-20 16:28:36.284833929 +0000
+++ binutils-2.41/bfd/elflink.c 2025-02-20 20:21:00.217464813 +0000
@@ -3581,6 +3581,7 @@ elf_link_is_defined_archive_symbol (bfd
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))
diff -rup binutils.orig/bfd/plugin.c binutils-2.41/bfd/plugin.c
--- binutils.orig/bfd/plugin.c 2025-02-20 16:28:36.241833823 +0000
+++ binutils-2.41/bfd/plugin.c 2025-02-20 20:14:43.601840910 +0000
@@ -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;
@@ -586,8 +596,12 @@ load_plugin (bfd *abfd)
static bfd_cleanup
bfd_plugin_object_p (bfd *abfd)
{
+ /* Since ld_plugin_object_p is called only for linker command-line input
+ objects, pass true to ld_plugin_object_p so that the same input IR
+ file won't be included twice if the LDPT_REGISTER_CLAIM_FILE_HOOK_V2
+ isn't used. */
if (ld_plugin_object_p)
- return ld_plugin_object_p (abfd, false);
+ return ld_plugin_object_p (abfd, true);
if (abfd->plugin_format == bfd_plugin_unknown && !load_plugin (abfd))
return NULL;
diff -rup binutils.orig/ld/plugin.c binutils-2.41/ld/plugin.c
--- binutils.orig/ld/plugin.c 2025-02-20 16:28:37.210836204 +0000
+++ binutils-2.41/ld/plugin.c 2025-02-20 20:23:41.314731681 +0000
@@ -773,14 +773,17 @@ get_symbols (const void *handle, int nsy
if (syms[n].def != LDPK_UNDEF && syms[n].def != LDPK_WEAKUNDEF)
{
blhe = h;
- if (blhe && link_info.wrap_hash != NULL)
+ /* Check if a symbol is a wrapper symbol. */
+ if (blhe)
{
- /* Check if a symbol is a wrapper symbol. */
- struct bfd_link_hash_entry *unwrap
- = unwrap_hash_lookup (&link_info, (bfd *) abfd, blhe);
- if (unwrap && unwrap != h)
- wrap_status = wrapper;
- }
+ if (link_info.wrap_hash != NULL)
+ {
+ struct bfd_link_hash_entry *unwrap
+ = unwrap_hash_lookup (&link_info, (bfd *) abfd, blhe);
+ if (unwrap != NULL && unwrap != h)
+ wrap_status = wrapper;
+ }
+ }
}
else
{
@@ -1159,10 +1162,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)
@@ -1171,7 +1175,11 @@ plugin_call_claim_file (const struct ld_
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;
@@ -1180,6 +1188,7 @@ plugin_call_claim_file (const struct ld_
}
curplug = curplug->next;
}
+
return plugin_error_p () ? -1 : 0;
}
@@ -1207,7 +1216,7 @@ plugin_cleanup (bfd *abfd ATTRIBUTE_UNUS
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;
@@ -1216,12 +1225,17 @@ plugin_object_p (bfd *ibfd, bool known_u
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
@@ -1257,7 +1271,8 @@ plugin_object_p (bfd *ibfd, bool known_u
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 ());
@@ -1277,7 +1292,13 @@ plugin_object_p (bfd *ibfd, bool known_u
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;
@@ -1363,14 +1384,17 @@ plugin_call_cleanup (void)
{
if (curplug->cleanup_handler && !curplug->cleanup_done)
{
- enum ld_plugin_status rv;
- curplug->cleanup_done = true;
- called_plugin = curplug;
- rv = (*curplug->cleanup_handler) ();
- called_plugin = NULL;
- if (rv != LDPS_OK)
- info_msg (_("%P: %s: error in plugin cleanup: %d (ignored)\n"),
- curplug->name, rv);
+ if (1)
+ {
+ enum ld_plugin_status rv;
+ curplug->cleanup_done = true;
+ called_plugin = curplug;
+ rv = (*curplug->cleanup_handler) ();
+ called_plugin = NULL;
+ if (rv != LDPS_OK)
+ info_msg (_("%P: %s: error in plugin cleanup: %d (ignored)\n"),
+ curplug->name, rv);
+ }
dlclose (curplug->dlhandle);
}
curplug = curplug->next;