]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
lto: Don't include unused LTO archive members in output
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 15 Aug 2024 03:50:02 +0000 (20:50 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 15 Aug 2024 10:54:11 +0000 (03:54 -0700)
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>
bfd/archures.c
bfd/bfd-in2.h
bfd/bfd.c
bfd/elflink.c
bfd/plugin.c
ld/plugin.c

index 94118b8d2cfc667333ba19c2b95b019c7e91379d..c4decc59e4aebe293f6fd86e63cef13e2f151c02 100644 (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;
index e3b5a8b8522f3103343ff77a08a73218b0aab6f4..40ec416ddeda7e22e56c30daac18d64086210583 100644 (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
index ae79c6490b5f1909c6b9e62f0f131f91b3ef0d65..a93be109f11135d44637e81fb92a7e57a2930cd3 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -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
index ed0bd71859b1d967cd444fa9b9194783692fc354..9eb1122d5133259254c0d8899e1452558bd4e128 100644 (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))
index 026654fd9d375cc336bdcbb388cc29bbde04bd87..f6c6fdbee69a9b33ee85f0b3077a8b4cc2386d5b 100644 (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;
index 51c4765cc5b5ca5ea8679bf2af3e2d19678b37b5..34ae3a0e0d8d03a7329bef0cd496c3404a74d72b 100644 (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;