diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2024-08-14 20:50:02 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2024-08-15 16:24:02 -0700 |
commit | 92b6ecd5589fb7db9f28dba41978f87974312aa5 (patch) | |
tree | 6b4ecba6bb73b695fcdc2d16b65ccdc56924944f | |
parent | 0831d9e199b1520482ca430cbf0cf85745736e82 (diff) | |
download | binutils-92b6ecd5589fb7db9f28dba41978f87974312aa5.zip binutils-92b6ecd5589fb7db9f28dba41978f87974312aa5.tar.gz binutils-92b6ecd5589fb7db9f28dba41978f87974312aa5.tar.bz2 |
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>
(cherry picked from commit a6f8fe0a9e9cbe871652e46ba7c22d5e9fb86208)
-rw-r--r-- | bfd/archures.c | 1 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 3 | ||||
-rw-r--r-- | bfd/bfd.c | 3 | ||||
-rw-r--r-- | bfd/elflink.c | 1 | ||||
-rw-r--r-- | bfd/plugin.c | 22 | ||||
-rw-r--r-- | ld/plugin.c | 35 |
6 files changed, 48 insertions, 17 deletions
diff --git a/bfd/archures.c b/bfd/archures.c index 94118b8..c4decc5 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -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; diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index e3b5a8b..40ec416 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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 @@ -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 diff --git a/bfd/elflink.c b/bfd/elflink.c index 2430d60..336bcbf 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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)) diff --git a/bfd/plugin.c b/bfd/plugin.c index 026654f..f6c6fdb 100644 --- a/bfd/plugin.c +++ b/bfd/plugin.c @@ -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; diff --git a/ld/plugin.c b/ld/plugin.c index 51c4765..34ae3a0 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -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; |