public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128])
@ 2023-05-02 17:19 Tobias Burnus
  2023-05-04 10:30 ` Tobias Burnus
  0 siblings, 1 reply; 6+ messages in thread
From: Tobias Burnus @ 2023-05-02 17:19 UTC (permalink / raw)
  To: Binutils, gcc-patches; +Cc: Joseph Myers

[-- Attachment #1: Type: text/plain, Size: 2844 bytes --]

See also https://gcc.gnu.org/PR109128 (+ description in the patch log)

The linker plugin API was designed to handle LTO - such that the compiler (i.e. GCC's lto-plugin)
can claim an input file if it finds LTO code. In that case, the symbols inside that file are ignored
by 'ld'.

However, GCC also uses the LTO for offloading: code designated for running on a non-host device
(GPUs) is saved in a special section in LTO format. This code then ends up being compiled for
offloading but otherwise not the file is not claimed, keeping the symbols for 'ld' to process,
unless that file is also uses real, host-side LTO.

This mostly works okay, but a corner case exists (see PR for an example) where 'ld' calls the
GCC's lto-plugin but does not actually use the symbols of that file. That's fine, in principle,
but if that file contains offloading code, there is a problem: To match host and device functions,
a table is created on both sides, but that table obviously must match. However, when lto-plugin's
offload code processes those while ld does not link them, it fails.

It turned out (kudos to Joseph for debugging + writing the patches) that in that case ld.bfd does
not actually regards that file as being used but just offers it to llto-plugin in case it needs
symbols from it.

To get this working, the current API is insufficient.

Possible solutions:
* Tell lto-plugin whether 'ld' actually needs symbols from a file or it just offers the file
   in case that lto-plugin wants to claim that file
   => That's implemented in the attached patch.
* Make it possible to "claim" a file without discarding the ld-visible symbols
* Asking the linker later whether the file/some symbols are actually used.
* something else ...


What this patch does:
* It adds a new API callback (LDPT_REGISTER_CLAIM_FILE_HOOK_V2) that takes an additional
   boolean argument which states whether ld.bdf intens to use that file/symbols from that
   file or whether it just asks the plugin in case it wants to claim it.
* On the ld.bfd side, it wires this up.
* On the GCC lto-plugin side, it uses that API is available, otherwise it uses the existing API.

The way the linker plugin handling is written, it works fine at runtime if only one side
supports the new hook. (Except, of course, that for fixing the issue both need to support it.)

Regarding those patches: Are they ok for mainline? Any comment, better approach, suggestion?

Tobias

PS: Attached is the Binutils' ld side of the patch and the GCC lto-plugin side of the patch set.
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Attachment #2: gcc-0001-Implement-LDPT_REGISTER_CLAIM_FILE_HOOK_V2-linker-pl.patch --]
[-- Type: text/x-patch, Size: 6549 bytes --]

From cb5bf8fad2e653e44fcae8f4ba0ce6eb5f928cb3 Mon Sep 17 00:00:00 2001
From: Joseph Myers <joseph@codesourcery.com>
Date: Tue, 2 May 2023 17:10:01 +0000
Subject: [PATCH] Implement LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook
 [PR109128]

This is one part of the fix for PR109128, along with a corresponding
binutils's linker change.  Without this patch, what happens in the
linker, when an unused object in a .a file has offload data, is that
elf_link_is_defined_archive_symbol calls bfd_link_plugin_object_p,
which ends up calling the plugin's claim_file_handler, which then
records the object as one with offload data. That is, the linker never
decides to use the object in the first place, but use of this _p
interface (called as part of trying to decide whether to use the
object) results in the plugin deciding to use its offload data (and a
consequent mismatch in the offload data present at runtime).

The new hook allows the linker plugin to distinguish calls to
claim_file_handler that know the object is being used by the linker
(from ldmain.c:add_archive_element), from calls that don't know it's
being used by the linker (from elf_link_is_defined_archive_symbol); in
the latter case, the plugin should avoid recording the object as one
with offload data.

	PR middle-end/109128

	include/
	* plugin-api.h (ld_plugin_claim_file_handler_v2)
	(ld_plugin_register_claim_file_v2)
	(LDPT_REGISTER_CLAIM_FILE_HOOK_V2): New.
       	(struct ld_plugin_tv): Add tv_register_claim_file_v2.

	lto-plugin/
	* lto-plugin.c (register_claim_file_v2): New.
	(claim_file_handler_v2): New.
	(claim_file_handler): Wrap claim_file_handler_v2.
	(onload): Handle LDPT_REGISTER_CLAIM_FILE_HOOK_V2.
---
 include/plugin-api.h    | 16 ++++++++++++++++
 lto-plugin/lto-plugin.c | 31 ++++++++++++++++++++++++++++---
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/include/plugin-api.h b/include/plugin-api.h
index 379828ba854..395d5bcc598 100644
--- a/include/plugin-api.h
+++ b/include/plugin-api.h
@@ -260,6 +260,13 @@ enum ld_plugin_status
 (*ld_plugin_claim_file_handler) (
   const struct ld_plugin_input_file *file, int *claimed);
 
+/* The plugin library's "claim file" handler, version 2.  */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_claim_file_handler_v2) (
+  const struct ld_plugin_input_file *file, int *claimed, int known_used);
+
 /* The plugin library's "all symbols read" handler.  */
 
 typedef
@@ -278,6 +285,13 @@ typedef
 enum ld_plugin_status
 (*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler);
 
+/* The linker's interface for registering the "claim file" handler,
+   version 2.  */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_register_claim_file_v2) (ld_plugin_claim_file_handler_v2 handler);
+
 /* The linker's interface for registering the "all symbols read" handler.  */
 
 typedef
@@ -553,6 +567,7 @@ enum ld_plugin_tag
   LDPT_GET_WRAP_SYMBOLS,
   LDPT_ADD_SYMBOLS_V2,
   LDPT_GET_API_VERSION,
+  LDPT_REGISTER_CLAIM_FILE_HOOK_V2
 };
 
 /* The plugin transfer vector.  */
@@ -565,6 +580,7 @@ struct ld_plugin_tv
     int tv_val;
     const char *tv_string;
     ld_plugin_register_claim_file tv_register_claim_file;
+    ld_plugin_register_claim_file_v2 tv_register_claim_file_v2;
     ld_plugin_register_all_symbols_read tv_register_all_symbols_read;
     ld_plugin_register_cleanup tv_register_cleanup;
     ld_plugin_add_symbols tv_add_symbols;
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index cc512a463f3..ae87089b05d 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -173,6 +173,7 @@ static pthread_mutex_t plugin_lock;
 
 static char *arguments_file_name;
 static ld_plugin_register_claim_file register_claim_file;
+static ld_plugin_register_claim_file_v2 register_claim_file_v2;
 static ld_plugin_register_all_symbols_read register_all_symbols_read;
 static ld_plugin_get_symbols get_symbols, get_symbols_v2, get_symbols_v3;
 static ld_plugin_register_cleanup register_cleanup;
@@ -1191,10 +1192,15 @@ process_offload_section (void *data, const char *name, off_t offset, off_t len)
 }
 
 /* Callback used by a linker to check if the plugin will claim FILE. Writes
-   the result in CLAIMED. */
+   the result in CLAIMED.  If KNOWN_USED, the object is known by the linker
+   to be used, or an older API version is in use that does not provide that
+   information; otherwise, the linker is only determining whether this is
+   a plugin object and it should not be registered as having offload data if
+   not claimed by the plugin.  */
 
 static enum ld_plugin_status
-claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
+claim_file_handler_v2 (const struct ld_plugin_input_file *file, int *claimed,
+		       int known_used)
 {
   enum ld_plugin_status status;
   struct plugin_objfile obj;
@@ -1307,7 +1313,7 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
   if (*claimed && !obj.offload && offload_files_last_lto == NULL)
     offload_files_last_lto = offload_files_last;
 
-  if (obj.offload)
+  if (obj.offload && (known_used || obj.found > 0))
     {
       /* Add file to the list.  The order must be exactly the same as the final
 	 order after recompilation and linking, otherwise host and target tables
@@ -1372,6 +1378,15 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
   return LDPS_OK;
 }
 
+/* Callback used by a linker to check if the plugin will claim FILE. Writes
+   the result in CLAIMED. */
+
+static enum ld_plugin_status
+claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
+{
+  return claim_file_handler_v2 (file, claimed, true);
+}
+
 /* Parse the plugin options. */
 
 static void
@@ -1496,6 +1511,9 @@ onload (struct ld_plugin_tv *tv)
 	case LDPT_REGISTER_CLAIM_FILE_HOOK:
 	  register_claim_file = p->tv_u.tv_register_claim_file;
 	  break;
+	case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
+	  register_claim_file_v2 = p->tv_u.tv_register_claim_file_v2;
+	  break;
 	case LDPT_ADD_SYMBOLS_V2:
 	  add_symbols_v2 = p->tv_u.tv_add_symbols;
 	  break;
@@ -1555,6 +1573,13 @@ onload (struct ld_plugin_tv *tv)
   check (status == LDPS_OK, LDPL_FATAL,
 	 "could not register the claim_file callback");
 
+  if (register_claim_file_v2)
+    {
+      status = register_claim_file_v2 (claim_file_handler_v2);
+      check (status == LDPS_OK, LDPL_FATAL,
+	     "could not register the claim_file_v2 callback");
+    }
+
   if (register_cleanup)
     {
       status = register_cleanup (cleanup_handler);
-- 
2.25.1


[-- Attachment #3: binutils-0001-Add-LDPT_REGISTER_CLAIM_FILE_HOOK_V2-linker-plugin-h.patch --]
[-- Type: text/x-patch, Size: 28902 bytes --]

From 6c9c55a2f72d0a8bf4891560f79a2019ddca404d Mon Sep 17 00:00:00 2001
From: Joseph Myers <joseph@codesourcery.com>
Date: Tue, 2 May 2023 17:02:29 +0000
Subject: [PATCH] Add LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook
 [GCC PR109128]

This is one part of the fix for GCC PR109128, along with a
corresponding GCC change.  Without this patch, what happens in the
linker, when an unused object in a .a file has offload data, is that
elf_link_is_defined_archive_symbol calls bfd_link_plugin_object_p,
which ends up calling the plugin's claim_file_handler, which then
records the object as one with offload data. That is, the linker never
decides to use the object in the first place, but use of this _p
interface (called as part of trying to decide whether to use the
object) results in the plugin deciding to use its offload data (and a
consequent mismatch in the offload data present at runtime).

The new hook allows the linker plugin to distinguish calls to
claim_file_handler that know the object is being used by the linker
(from ldmain.c:add_archive_element), from calls that don't know it's
being used by the linker (from elf_link_is_defined_archive_symbol); in
the latter case, the plugin should avoid recording the object as one
with offload data.

	bfd/
	* plugin.c (struct plugin_list_entry): Add claim_file_v2.
	(register_claim_file_v2): New.
	(try_load_plugin): Use LDPT_REGISTER_CLAIM_FILE_HOOK_V2.
	(ld_plugin_object_p): Take second argument.
	(bfd_link_plugin_object_p): Update call to ld_plugin_object_p.
	(register_ld_plugin_object_p): Update argument prototype.
	(bfd_plugin_object_p): Update call to ld_plugin_object_p.
	* plugin.h (register_ld_plugin_object_p): Update argument
	prototype.

	include/
	* plugin.api;h (ld_plugin_claim_file_handler_v2)
	(ld_plugin_register_claim_file_v2)
	(LDPT_REGISTER_CLAIM_FILE_HOOK_V2): New.
	(struct ld_plugin_tv): Add tv_register_claim_file_v2.

	ld/
	* plugin.c (struct plugin): Add claim_file_handler_v2.
	(LDPT_REGISTER_CLAIM_FILE_HOOK_V2): New.
	(plugin_object_p): Add second argument.  Update call to
	plugin_call_claim_file.
	(register_claim_file_v2): New.
	(set_tv_header): Handle LDPT_REGISTER_CLAIM_FILE_HOOK_V2.
	(plugin_call_claim_file): Add argument known_used.
	(plugin_maybe_claim): Update call to plugin_object_p.
	* testplug.c, testplug2.c, testplug3.c, testplug4.c: Handle
	LDPT_REGISTER_CLAIM_FILE_HOOK_V2.
	* testsuite/ld-plugin/plugin-1.d, testsuite/ld-plugin/plugin-10.d,
	testsuite/ld-plugin/plugin-11.d, testsuite/ld-plugin/plugin-13.d,
	testsuite/ld-plugin/plugin-14.d, testsuite/ld-plugin/plugin-15.d,
	testsuite/ld-plugin/plugin-16.d, testsuite/ld-plugin/plugin-17.d,
	testsuite/ld-plugin/plugin-18.d, testsuite/ld-plugin/plugin-19.d,
	testsuite/ld-plugin/plugin-2.d, testsuite/ld-plugin/plugin-26.d,
	testsuite/ld-plugin/plugin-3.d, testsuite/ld-plugin/plugin-30.d,
	testsuite/ld-plugin/plugin-4.d, testsuite/ld-plugin/plugin-5.d,
	testsuite/ld-plugin/plugin-6.d, testsuite/ld-plugin/plugin-7.d,
	testsuite/ld-plugin/plugin-8.d, testsuite/ld-plugin/plugin-9.d:
	Update test expectations.
---
 bfd/plugin.c                       | 25 ++++++++++++++++++++-----
 bfd/plugin.h                       |  2 +-
 include/plugin-api.h               | 16 ++++++++++++++++
 ld/plugin.c                        | 30 ++++++++++++++++++++++++------
 ld/testplug.c                      |  6 ++++++
 ld/testplug2.c                     |  5 +++++
 ld/testplug3.c                     |  5 +++++
 ld/testplug4.c                     |  5 +++++
 ld/testsuite/ld-plugin/plugin-1.d  |  1 +
 ld/testsuite/ld-plugin/plugin-10.d |  1 +
 ld/testsuite/ld-plugin/plugin-11.d |  1 +
 ld/testsuite/ld-plugin/plugin-13.d |  1 +
 ld/testsuite/ld-plugin/plugin-14.d |  1 +
 ld/testsuite/ld-plugin/plugin-15.d |  1 +
 ld/testsuite/ld-plugin/plugin-16.d |  1 +
 ld/testsuite/ld-plugin/plugin-17.d |  1 +
 ld/testsuite/ld-plugin/plugin-18.d |  1 +
 ld/testsuite/ld-plugin/plugin-19.d |  1 +
 ld/testsuite/ld-plugin/plugin-2.d  |  1 +
 ld/testsuite/ld-plugin/plugin-26.d |  1 +
 ld/testsuite/ld-plugin/plugin-3.d  |  1 +
 ld/testsuite/ld-plugin/plugin-30.d |  1 +
 ld/testsuite/ld-plugin/plugin-4.d  |  1 +
 ld/testsuite/ld-plugin/plugin-5.d  |  1 +
 ld/testsuite/ld-plugin/plugin-6.d  |  1 +
 ld/testsuite/ld-plugin/plugin-7.d  |  1 +
 ld/testsuite/ld-plugin/plugin-8.d  |  1 +
 ld/testsuite/ld-plugin/plugin-9.d  |  1 +
 28 files changed, 102 insertions(+), 12 deletions(-)

diff --git a/bfd/plugin.c b/bfd/plugin.c
index 66d286af6b6..b798d3477ae 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -129,6 +129,7 @@ struct plugin_list_entry
 {
   /* These must be initialized for each IR object with LTO wrapper.  */
   ld_plugin_claim_file_handler claim_file;
+  ld_plugin_claim_file_handler_v2 claim_file_v2;
   ld_plugin_all_symbols_read_handler all_symbols_read;
   ld_plugin_all_symbols_read_handler cleanup_handler;
   bool has_symbol_type;
@@ -159,6 +160,16 @@ register_claim_file (ld_plugin_claim_file_handler handler)
   return LDPS_OK;
 }
 
+
+/* Register a claim-file handler, version 2. */
+
+static enum ld_plugin_status
+register_claim_file_v2 (ld_plugin_claim_file_handler_v2 handler)
+{
+  current_plugin->claim_file_v2 = handler;
+  return LDPS_OK;
+}
+
 static enum ld_plugin_status
 add_symbols (void * handle,
 	     int nsyms,
@@ -337,7 +348,7 @@ try_load_plugin (const char *pname,
 		 bool build_list_p)
 {
   void *plugin_handle;
-  struct ld_plugin_tv tv[5];
+  struct ld_plugin_tv tv[6];
   int i;
   ld_plugin_onload onload;
   enum ld_plugin_status status;
@@ -402,6 +413,10 @@ try_load_plugin (const char *pname,
   tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
   tv[i].tv_u.tv_register_claim_file = register_claim_file;
 
+  ++i;
+  tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK_V2;
+  tv[i].tv_u.tv_register_claim_file_v2 = register_claim_file_v2;
+
   ++i;
   tv[i].tv_tag = LDPT_ADD_SYMBOLS;
   tv[i].tv_u.tv_add_symbols = add_symbols;
@@ -439,7 +454,7 @@ try_load_plugin (const char *pname,
 /* There may be plugin libraries in lib/bfd-plugins.  */
 static int has_plugin_list = -1;
 
-static bfd_cleanup (*ld_plugin_object_p) (bfd *);
+static bfd_cleanup (*ld_plugin_object_p) (bfd *, bool);
 
 static const char *plugin_name;
 
@@ -463,7 +478,7 @@ bool
 bfd_link_plugin_object_p (bfd *abfd)
 {
   if (ld_plugin_object_p)
-    return ld_plugin_object_p (abfd) != NULL;
+    return ld_plugin_object_p (abfd, false) != NULL;
   return false;
 }
 
@@ -480,7 +495,7 @@ bfd_plugin_target_p (const bfd_target *target)
 /* Register OBJECT_P to be used by bfd_plugin_object_p.  */
 
 void
-register_ld_plugin_object_p (bfd_cleanup (*object_p) (bfd *))
+register_ld_plugin_object_p (bfd_cleanup (*object_p) (bfd *, bool))
 {
   ld_plugin_object_p = object_p;
 }
@@ -572,7 +587,7 @@ static bfd_cleanup
 bfd_plugin_object_p (bfd *abfd)
 {
   if (ld_plugin_object_p)
-    return ld_plugin_object_p (abfd);
+    return ld_plugin_object_p (abfd, false);
 
   if (abfd->plugin_format == bfd_plugin_unknown && !load_plugin (abfd))
     return NULL;
diff --git a/bfd/plugin.h b/bfd/plugin.h
index 8da436a86b9..6a6f0f19fc2 100644
--- a/bfd/plugin.h
+++ b/bfd/plugin.h
@@ -27,7 +27,7 @@ void bfd_plugin_set_plugin (const char *);
 bool bfd_plugin_target_p (const bfd_target *);
 bool bfd_plugin_specified_p (void);
 bool bfd_link_plugin_object_p (bfd *);
-void register_ld_plugin_object_p (bfd_cleanup (*object_p) (bfd *));
+void register_ld_plugin_object_p (bfd_cleanup (*object_p) (bfd *, bool));
 void bfd_plugin_close_file_descriptor (bfd *, int);
 
 typedef struct plugin_data_struct
diff --git a/include/plugin-api.h b/include/plugin-api.h
index 379828ba854..395d5bcc598 100644
--- a/include/plugin-api.h
+++ b/include/plugin-api.h
@@ -260,6 +260,13 @@ enum ld_plugin_status
 (*ld_plugin_claim_file_handler) (
   const struct ld_plugin_input_file *file, int *claimed);
 
+/* The plugin library's "claim file" handler, version 2.  */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_claim_file_handler_v2) (
+  const struct ld_plugin_input_file *file, int *claimed, int known_used);
+
 /* The plugin library's "all symbols read" handler.  */
 
 typedef
@@ -278,6 +285,13 @@ typedef
 enum ld_plugin_status
 (*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler);
 
+/* The linker's interface for registering the "claim file" handler,
+   version 2.  */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_register_claim_file_v2) (ld_plugin_claim_file_handler_v2 handler);
+
 /* The linker's interface for registering the "all symbols read" handler.  */
 
 typedef
@@ -553,6 +567,7 @@ enum ld_plugin_tag
   LDPT_GET_WRAP_SYMBOLS,
   LDPT_ADD_SYMBOLS_V2,
   LDPT_GET_API_VERSION,
+  LDPT_REGISTER_CLAIM_FILE_HOOK_V2
 };
 
 /* The plugin transfer vector.  */
@@ -565,6 +580,7 @@ struct ld_plugin_tv
     int tv_val;
     const char *tv_string;
     ld_plugin_register_claim_file tv_register_claim_file;
+    ld_plugin_register_claim_file_v2 tv_register_claim_file_v2;
     ld_plugin_register_all_symbols_read tv_register_all_symbols_read;
     ld_plugin_register_cleanup tv_register_cleanup;
     ld_plugin_add_symbols tv_add_symbols;
diff --git a/ld/plugin.c b/ld/plugin.c
index 34aefc584cc..970cf566ffe 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -87,6 +87,7 @@ typedef struct plugin
   size_t n_args;
   /* The plugin's event handlers.  */
   ld_plugin_claim_file_handler claim_file_handler;
+  ld_plugin_claim_file_handler_v2 claim_file_handler_v2;
   ld_plugin_all_symbols_read_handler all_symbols_read_handler;
   ld_plugin_cleanup_handler cleanup_handler;
   /* TRUE if the cleanup handlers have been called.  */
@@ -159,6 +160,7 @@ static const enum ld_plugin_tag tv_header_tags[] =
   LDPT_LINKER_OUTPUT,
   LDPT_OUTPUT_NAME,
   LDPT_REGISTER_CLAIM_FILE_HOOK,
+  LDPT_REGISTER_CLAIM_FILE_HOOK_V2,
   LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
   LDPT_REGISTER_CLEANUP_HOOK,
   LDPT_ADD_SYMBOLS,
@@ -181,7 +183,7 @@ static bool plugin_notice (struct bfd_link_info *,
 			   struct bfd_link_hash_entry *,
 			   bfd *, asection *, bfd_vma, flagword);
 
-static bfd_cleanup plugin_object_p (bfd *);
+static bfd_cleanup plugin_object_p (bfd *, bool);
 
 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
 
@@ -467,6 +469,15 @@ register_claim_file (ld_plugin_claim_file_handler handler)
   return LDPS_OK;
 }
 
+/* Register a claim-file version 2 handler.  */
+static enum ld_plugin_status
+register_claim_file_v2 (ld_plugin_claim_file_handler_v2 handler)
+{
+  ASSERT (called_plugin);
+  called_plugin->claim_file_handler_v2 = handler;
+  return LDPS_OK;
+}
+
 /* Register an all-symbols-read handler.  */
 static enum ld_plugin_status
 register_all_symbols_read (ld_plugin_all_symbols_read_handler handler)
@@ -1019,6 +1030,9 @@ set_tv_header (struct ld_plugin_tv *tv)
 	case LDPT_REGISTER_CLAIM_FILE_HOOK:
 	  TVU(register_claim_file) = register_claim_file;
 	  break;
+	case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
+	  TVU(register_claim_file_v2) = register_claim_file_v2;
+	  break;
 	case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
 	  TVU(register_all_symbols_read) = register_all_symbols_read;
 	  break;
@@ -1144,7 +1158,8 @@ 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)
+plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed,
+			bool known_used)
 {
   plugin_t *curplug = plugins_list;
   *claimed = false;
@@ -1155,7 +1170,10 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
 	  enum ld_plugin_status rv;
 
 	  called_plugin = curplug;
-	  rv = (*curplug->claim_file_handler) (file, claimed);
+	  if (curplug->claim_file_handler_v2)
+	    rv = (*curplug->claim_file_handler_v2) (file, claimed, known_used);
+	  else
+	    rv = (*curplug->claim_file_handler) (file, claimed);
 	  called_plugin = NULL;
 	  if (rv != LDPS_OK)
 	    set_plugin_error (curplug->name);
@@ -1187,7 +1205,7 @@ plugin_cleanup (bfd *abfd ATTRIBUTE_UNUSED)
 }
 
 static bfd_cleanup
-plugin_object_p (bfd *ibfd)
+plugin_object_p (bfd *ibfd, bool known_used)
 {
   int claimed;
   plugin_input_file_t *input;
@@ -1239,7 +1257,7 @@ plugin_object_p (bfd *ibfd)
 
   claimed = 0;
 
-  if (plugin_call_claim_file (&file, &claimed))
+  if (plugin_call_claim_file (&file, &claimed, known_used))
     einfo (_("%F%P: %s: plugin reported error claiming file\n"),
 	   plugin_error_plugin ());
 
@@ -1294,7 +1312,7 @@ void
 plugin_maybe_claim (lang_input_statement_type *entry)
 {
   ASSERT (entry->header.type == lang_input_statement_enum);
-  if (plugin_object_p (entry->the_bfd))
+  if (plugin_object_p (entry->the_bfd, true))
     {
       bfd *abfd = entry->the_bfd->plugin_dummy_bfd;
 
diff --git a/ld/testplug.c b/ld/testplug.c
index 796d67fe056..4b1bb8ecdbe 100644
--- a/ld/testplug.c
+++ b/ld/testplug.c
@@ -82,6 +82,7 @@ static const tag_name_t tag_names[] =
   ADDENTRY(LDPT_LINKER_OUTPUT),
   ADDENTRY(LDPT_OPTION),
   ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK),
+  ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK_V2),
   ADDENTRY(LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK),
   ADDENTRY(LDPT_REGISTER_CLEANUP_HOOK),
   ADDENTRY(LDPT_ADD_SYMBOLS),
@@ -100,6 +101,7 @@ static const tag_name_t tag_names[] =
 
 /* Function pointers to cache hooks passed at onload time.  */
 static ld_plugin_register_claim_file tv_register_claim_file = 0;
+static ld_plugin_register_claim_file_v2 tv_register_claim_file_v2 = 0;
 static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
 static ld_plugin_register_cleanup tv_register_cleanup = 0;
 static ld_plugin_add_symbols tv_add_symbols = 0;
@@ -389,6 +391,7 @@ dump_tv_tag (size_t n, struct ld_plugin_tv *tv)
 		    tv->tv_u.tv_string);
         break;
       case LDPT_REGISTER_CLAIM_FILE_HOOK:
+      case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
       case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
       case LDPT_REGISTER_CLEANUP_HOOK:
       case LDPT_ADD_SYMBOLS:
@@ -440,6 +443,9 @@ parse_tv_tag (struct ld_plugin_tv *tv)
       case LDPT_REGISTER_CLAIM_FILE_HOOK:
 	SETVAR(tv_register_claim_file);
 	break;
+      case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
+	SETVAR(tv_register_claim_file_v2);
+	break;
       case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
 	SETVAR(tv_register_all_symbols_read);
 	break;
diff --git a/ld/testplug2.c b/ld/testplug2.c
index 0a3339238f0..f1d6f5f9553 100644
--- a/ld/testplug2.c
+++ b/ld/testplug2.c
@@ -82,6 +82,7 @@ static const tag_name_t tag_names[] =
   ADDENTRY(LDPT_LINKER_OUTPUT),
   ADDENTRY(LDPT_OPTION),
   ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK),
+  ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK_V2),
   ADDENTRY(LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK),
   ADDENTRY(LDPT_REGISTER_CLEANUP_HOOK),
   ADDENTRY(LDPT_ADD_SYMBOLS),
@@ -100,6 +101,7 @@ static const tag_name_t tag_names[] =
 
 /* Function pointers to cache hooks passed at onload time.  */
 static ld_plugin_register_claim_file tv_register_claim_file = 0;
+static ld_plugin_register_claim_file_v2 tv_register_claim_file_v2 = 0;
 static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
 static ld_plugin_register_cleanup tv_register_cleanup = 0;
 static ld_plugin_add_symbols tv_add_symbols = 0;
@@ -392,6 +394,9 @@ parse_tv_tag (struct ld_plugin_tv *tv)
       case LDPT_REGISTER_CLAIM_FILE_HOOK:
 	SETVAR(tv_register_claim_file);
 	break;
+      case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
+	SETVAR(tv_register_claim_file_v2);
+	break;
       case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
 	SETVAR(tv_register_all_symbols_read);
 	break;
diff --git a/ld/testplug3.c b/ld/testplug3.c
index 7e009e1ee7a..652d11f4710 100644
--- a/ld/testplug3.c
+++ b/ld/testplug3.c
@@ -82,6 +82,7 @@ static const tag_name_t tag_names[] =
   ADDENTRY(LDPT_LINKER_OUTPUT),
   ADDENTRY(LDPT_OPTION),
   ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK),
+  ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK_V2),
   ADDENTRY(LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK),
   ADDENTRY(LDPT_REGISTER_CLEANUP_HOOK),
   ADDENTRY(LDPT_ADD_SYMBOLS),
@@ -100,6 +101,7 @@ static const tag_name_t tag_names[] =
 
 /* Function pointers to cache hooks passed at onload time.  */
 static ld_plugin_register_claim_file tv_register_claim_file = 0;
+static ld_plugin_register_claim_file_v2 tv_register_claim_file_v2 = 0;
 static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
 static ld_plugin_register_cleanup tv_register_cleanup = 0;
 static ld_plugin_add_symbols tv_add_symbols = 0;
@@ -371,6 +373,9 @@ parse_tv_tag (struct ld_plugin_tv *tv)
       case LDPT_REGISTER_CLAIM_FILE_HOOK:
 	SETVAR(tv_register_claim_file);
 	break;
+      case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
+	SETVAR(tv_register_claim_file_v2);
+	break;
       case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
 	SETVAR(tv_register_all_symbols_read);
 	break;
diff --git a/ld/testplug4.c b/ld/testplug4.c
index 109d500dc0a..9b63e8343c8 100644
--- a/ld/testplug4.c
+++ b/ld/testplug4.c
@@ -82,6 +82,7 @@ static const tag_name_t tag_names[] =
   ADDENTRY(LDPT_LINKER_OUTPUT),
   ADDENTRY(LDPT_OPTION),
   ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK),
+  ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK_V2),
   ADDENTRY(LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK),
   ADDENTRY(LDPT_REGISTER_CLEANUP_HOOK),
   ADDENTRY(LDPT_ADD_SYMBOLS),
@@ -100,6 +101,7 @@ static const tag_name_t tag_names[] =
 
 /* Function pointers to cache hooks passed at onload time.  */
 static ld_plugin_register_claim_file tv_register_claim_file = 0;
+static ld_plugin_register_claim_file_v2 tv_register_claim_file_v2 = 0;
 static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
 static ld_plugin_register_cleanup tv_register_cleanup = 0;
 static ld_plugin_add_symbols tv_add_symbols = 0;
@@ -392,6 +394,9 @@ parse_tv_tag (struct ld_plugin_tv *tv)
       case LDPT_REGISTER_CLAIM_FILE_HOOK:
 	SETVAR(tv_register_claim_file);
 	break;
+      case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
+	SETVAR(tv_register_claim_file_v2);
+	break;
       case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
 	SETVAR(tv_register_all_symbols_read);
 	break;
diff --git a/ld/testsuite/ld-plugin/plugin-1.d b/ld/testsuite/ld-plugin/plugin-1.d
index 6aae4cdc383..381974fcb49 100644
--- a/ld/testsuite/ld-plugin/plugin-1.d
+++ b/ld/testsuite/ld-plugin/plugin-1.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-10.d b/ld/testsuite/ld-plugin/plugin-10.d
index f92ee650c13..f6bb0eb45c6 100644
--- a/ld/testsuite/ld-plugin/plugin-10.d
+++ b/ld/testsuite/ld-plugin/plugin-10.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-11.d b/ld/testsuite/ld-plugin/plugin-11.d
index 6a5abcfc060..63b81603684 100644
--- a/ld/testsuite/ld-plugin/plugin-11.d
+++ b/ld/testsuite/ld-plugin/plugin-11.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-13.d b/ld/testsuite/ld-plugin/plugin-13.d
index 55dea651ec5..4521b34459c 100644
--- a/ld/testsuite/ld-plugin/plugin-13.d
+++ b/ld/testsuite/ld-plugin/plugin-13.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-14.d b/ld/testsuite/ld-plugin/plugin-14.d
index 81365af7524..bd8ef65a204 100644
--- a/ld/testsuite/ld-plugin/plugin-14.d
+++ b/ld/testsuite/ld-plugin/plugin-14.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-15.d b/ld/testsuite/ld-plugin/plugin-15.d
index 02c5e60bf9b..1647500e98f 100644
--- a/ld/testsuite/ld-plugin/plugin-15.d
+++ b/ld/testsuite/ld-plugin/plugin-15.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-16.d b/ld/testsuite/ld-plugin/plugin-16.d
index 504fbdbc0e9..f1ee03a4768 100644
--- a/ld/testsuite/ld-plugin/plugin-16.d
+++ b/ld/testsuite/ld-plugin/plugin-16.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-17.d b/ld/testsuite/ld-plugin/plugin-17.d
index 159d4e47580..5a520b68466 100644
--- a/ld/testsuite/ld-plugin/plugin-17.d
+++ b/ld/testsuite/ld-plugin/plugin-17.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-18.d b/ld/testsuite/ld-plugin/plugin-18.d
index 284fd057686..63d8147ce8e 100644
--- a/ld/testsuite/ld-plugin/plugin-18.d
+++ b/ld/testsuite/ld-plugin/plugin-18.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-19.d b/ld/testsuite/ld-plugin/plugin-19.d
index 621ee7689f0..aa3076372b3 100644
--- a/ld/testsuite/ld-plugin/plugin-19.d
+++ b/ld/testsuite/ld-plugin/plugin-19.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-2.d b/ld/testsuite/ld-plugin/plugin-2.d
index 91822c1f867..f272f53b3c1 100644
--- a/ld/testsuite/ld-plugin/plugin-2.d
+++ b/ld/testsuite/ld-plugin/plugin-2.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-26.d b/ld/testsuite/ld-plugin/plugin-26.d
index c631e387a05..fef25d5c295 100644
--- a/ld/testsuite/ld-plugin/plugin-26.d
+++ b/ld/testsuite/ld-plugin/plugin-26.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-3.d b/ld/testsuite/ld-plugin/plugin-3.d
index f030da467b3..0c23218fef9 100644
--- a/ld/testsuite/ld-plugin/plugin-3.d
+++ b/ld/testsuite/ld-plugin/plugin-3.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-30.d b/ld/testsuite/ld-plugin/plugin-30.d
index eb9d4244786..690ae832990 100644
--- a/ld/testsuite/ld-plugin/plugin-30.d
+++ b/ld/testsuite/ld-plugin/plugin-30.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-4.d b/ld/testsuite/ld-plugin/plugin-4.d
index b240eb221e0..ac4769b99d2 100644
--- a/ld/testsuite/ld-plugin/plugin-4.d
+++ b/ld/testsuite/ld-plugin/plugin-4.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-5.d b/ld/testsuite/ld-plugin/plugin-5.d
index 52abaf2db9d..5c8e8b8393c 100644
--- a/ld/testsuite/ld-plugin/plugin-5.d
+++ b/ld/testsuite/ld-plugin/plugin-5.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-6.d b/ld/testsuite/ld-plugin/plugin-6.d
index b1854ac03f4..41f44fbc37e 100644
--- a/ld/testsuite/ld-plugin/plugin-6.d
+++ b/ld/testsuite/ld-plugin/plugin-6.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-7.d b/ld/testsuite/ld-plugin/plugin-7.d
index c77b66fa9bc..b202edc863e 100644
--- a/ld/testsuite/ld-plugin/plugin-7.d
+++ b/ld/testsuite/ld-plugin/plugin-7.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-8.d b/ld/testsuite/ld-plugin/plugin-8.d
index ca24227a02f..0a38ddb1e4e 100644
--- a/ld/testsuite/ld-plugin/plugin-8.d
+++ b/ld/testsuite/ld-plugin/plugin-8.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
diff --git a/ld/testsuite/ld-plugin/plugin-9.d b/ld/testsuite/ld-plugin/plugin-9.d
index 1155f4f2e33..35fde40c0b1 100644
--- a/ld/testsuite/ld-plugin/plugin-9.d
+++ b/ld/testsuite/ld-plugin/plugin-9.d
@@ -5,6 +5,7 @@ Hello from testplugin.
 .*: LDPT_LINKER_OUTPUT value        0x1 \(1\)
 .*: LDPT_OUTPUT_NAME 'tmpdir/main.x'
 .*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.*
+.*: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 func@0x.*
 .*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.*
 .*: LDPT_REGISTER_CLEANUP_HOOK func@0x.*
 .*: LDPT_ADD_SYMBOLS func@0x.*
-- 
2.25.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128])
  2023-05-02 17:19 [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128]) Tobias Burnus
@ 2023-05-04 10:30 ` Tobias Burnus
  2023-05-04 11:02   ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Tobias Burnus @ 2023-05-04 10:30 UTC (permalink / raw)
  To: Binutils, gcc-patches, Richard Biener; +Cc: Joseph Myers

Based on the the discussion with Richard B. on #gcc, some more details why the linker does
(and might want) to call the plugin for files it does not need:

For LTO with no-fat binaries, a symbol in a static library might still be needed but the linker
does not know as the file might only contain LTO objects. The linker then calls:

   bfd_link_plugin_object_p  -> ld_plugin_object_p
which calls in case of GCC's lto-plugin:
   claim_file_handler

* The latter file checks for LTO symbols and, if found, sets *claimed = true and
   registers the found symbols via add_symbols
→ The linker than ignores all other symbols and only uses the plugin-provided symbols.

* When all files have been processed, the linker calls
   all_symbols_read_handler and the lto-plugin can ask (get_symbols) whether a given
   symbol was used.


For the offload usage, the problem is:

* The code currently assumes that a file is used when 'claim_file_handler' is invoked
   by the linker
→ It cannot claim the file itself as then symbols in the file are ignored by the linker.
→ Thus, if the file contains host-side LTO and is *claimed = true, it is fine.
   Likewise, if symbols in the file cause the linker itself to use the file, it is fine.
   However, if neither the plugin claims the file nor the file is linked via the linker,
   there is a problem (→ mismatch between host and device side).

Inside the all_symbols_read_handler, GCC's lto-plugin.cc could remove a file from the
to-be-used for device-side lto-wrapper list, but there is no way to ask the linker if
a given file is will be linked/is used or not. (Only per-symbol enquiringly for LTO exists.)

The additional flag now permits for the offload use to ignore the file if the linker has
no use for it (and passes it only for non-fat symbols host-side LTO check to the linker);
thus, we can then ignore the file for offloading purpose, unless it is used for LTO - but
that's something the plugin knows itself.


Note: That's really only an issue about whether a file (from a static library) is used
and not whether a certain symbol is used. For the host side, the function-pointer table
is constructed by section merging and the device side also forces the output of the table.
But all output forcing/keep-symbol handling fails if the whole file is dropped on one side
(linker for the host side) but not on the other (linker plugin for the non-host offload side).


I hope this clarifies the problem, background and solution a bit better.

Tobias

On 02.05.23 19:19, Tobias Burnus wrote:
> See also https://gcc.gnu.org/PR109128 (+ description in the patch log)
>
> The linker plugin API was designed to handle LTO - such that the
> compiler (i.e. GCC's lto-plugin)
> can claim an input file if it finds LTO code. In that case, the
> symbols inside that file are ignored
> by 'ld'.
>
> However, GCC also uses the LTO for offloading: code designated for
> running on a non-host device
> (GPUs) is saved in a special section in LTO format. This code then
> ends up being compiled for
> offloading but otherwise not the file is not claimed, keeping the
> symbols for 'ld' to process,
> unless that file is also uses real, host-side LTO.
>
> This mostly works okay, but a corner case exists (see PR for an
> example) where 'ld' calls the
> GCC's lto-plugin but does not actually use the symbols of that file.
> That's fine, in principle,
> but if that file contains offloading code, there is a problem: To
> match host and device functions,
> a table is created on both sides, but that table obviously must match.
> However, when lto-plugin's
> offload code processes those while ld does not link them, it fails.
>
> It turned out (kudos to Joseph for debugging + writing the patches)
> that in that case ld.bfd does
> not actually regards that file as being used but just offers it to
> llto-plugin in case it needs
> symbols from it.
>
> To get this working, the current API is insufficient.
>
> Possible solutions:
> * Tell lto-plugin whether 'ld' actually needs symbols from a file or
> it just offers the file
>   in case that lto-plugin wants to claim that file
>   => That's implemented in the attached patch.
> * Make it possible to "claim" a file without discarding the ld-visible
> symbols
> * Asking the linker later whether the file/some symbols are actually
> used.
> * something else ...
>
>
> What this patch does:
> * It adds a new API callback (LDPT_REGISTER_CLAIM_FILE_HOOK_V2) that
> takes an additional
>   boolean argument which states whether ld.bdf intens to use that
> file/symbols from that
>   file or whether it just asks the plugin in case it wants to claim it.
> * On the ld.bfd side, it wires this up.
> * On the GCC lto-plugin side, it uses that API is available, otherwise
> it uses the existing API.
>
> The way the linker plugin handling is written, it works fine at
> runtime if only one side
> supports the new hook. (Except, of course, that for fixing the issue
> both need to support it.)
>
> Regarding those patches: Are they ok for mainline? Any comment, better
> approach, suggestion?
>
> Tobias
>
> PS: Attached is the Binutils' ld side of the patch and the GCC
> lto-plugin side of the patch set.
> -----------------
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße
> 201, 80634 München; Gesellschaft mit beschränkter Haftung;
> Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft:
> München; Registergericht München, HRB 106955
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128])
  2023-05-04 10:30 ` Tobias Burnus
@ 2023-05-04 11:02   ` Richard Biener
  2023-05-04 13:25     ` Tobias Burnus
  2023-05-11  0:40     ` Alan Modra
  0 siblings, 2 replies; 6+ messages in thread
From: Richard Biener @ 2023-05-04 11:02 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: Binutils, gcc-patches, Joseph Myers

On Thu, 4 May 2023, Tobias Burnus wrote:

> Based on the the discussion with Richard B. on #gcc, some more details why the
> linker does
> (and might want) to call the plugin for files it does not need:
> 
> For LTO with no-fat binaries, a symbol in a static library might still be
> needed but the linker
> does not know as the file might only contain LTO objects. The linker then
> calls:
> 
>   bfd_link_plugin_object_p  -> ld_plugin_object_p
> which calls in case of GCC's lto-plugin:
>   claim_file_handler
> 
> * The latter file checks for LTO symbols and, if found, sets *claimed = true
> and
>   registers the found symbols via add_symbols
> ? The linker than ignores all other symbols and only uses the plugin-provided
> symbols.
> 
> * When all files have been processed, the linker calls
>   all_symbols_read_handler and the lto-plugin can ask (get_symbols) whether a
>   given
>   symbol was used.
> 
> 
> For the offload usage, the problem is:
> 
> * The code currently assumes that a file is used when 'claim_file_handler' is
> invoked
>   by the linker
> ? It cannot claim the file itself as then symbols in the file are ignored by
> the linker.
> ? Thus, if the file contains host-side LTO and is *claimed = true, it is fine.
>   Likewise, if symbols in the file cause the linker itself to use the file, it
>   is fine.
>   However, if neither the plugin claims the file nor the file is linked via
>   the linker,
>   there is a problem (? mismatch between host and device side).
> 
> Inside the all_symbols_read_handler, GCC's lto-plugin.cc could remove a file
> from the
> to-be-used for device-side lto-wrapper list, but there is no way to ask the
> linker if
> a given file is will be linked/is used or not. (Only per-symbol enquiringly
> for LTO exists.)
> 
> The additional flag now permits for the offload use to ignore the file if the
> linker has
> no use for it (and passes it only for non-fat symbols host-side LTO check to
> the linker);
> thus, we can then ignore the file for offloading purpose, unless it is used
> for LTO - but
> that's something the plugin knows itself.
> 
> 
> Note: That's really only an issue about whether a file (from a static library)
> is used
> and not whether a certain symbol is used. For the host side, the
> function-pointer table
> is constructed by section merging and the device side also forces the output
> of the table.
> But all output forcing/keep-symbol handling fails if the whole file is dropped
> on one side
> (linker for the host side) but not on the other (linker plugin for the
> non-host offload side).

So since we expect the linker to use the host side table is there a way
for the plugin to exactly query that (the set of symbols the linker
uses from the object passed to the plugin)?  Because if the linker
uses something from the file but _not_ the host side offload table
(-ffunction-sections -fdata-sections) then things would still go
wrong, right?

Is there a way to connect both in a way that the linker discards
either if the other isn't present?

> 
> I hope this clarifies the problem, background and solution a bit better.
> 
> Tobias
> 
> On 02.05.23 19:19, Tobias Burnus wrote:
> > See also https://gcc.gnu.org/PR109128 (+ description in the patch log)
> >
> > The linker plugin API was designed to handle LTO - such that the
> > compiler (i.e. GCC's lto-plugin)
> > can claim an input file if it finds LTO code. In that case, the
> > symbols inside that file are ignored
> > by 'ld'.
> >
> > However, GCC also uses the LTO for offloading: code designated for
> > running on a non-host device
> > (GPUs) is saved in a special section in LTO format. This code then
> > ends up being compiled for
> > offloading but otherwise not the file is not claimed, keeping the
> > symbols for 'ld' to process,
> > unless that file is also uses real, host-side LTO.
> >
> > This mostly works okay, but a corner case exists (see PR for an
> > example) where 'ld' calls the
> > GCC's lto-plugin but does not actually use the symbols of that file.
> > That's fine, in principle,
> > but if that file contains offloading code, there is a problem: To
> > match host and device functions,
> > a table is created on both sides, but that table obviously must match.
> > However, when lto-plugin's
> > offload code processes those while ld does not link them, it fails.
> >
> > It turned out (kudos to Joseph for debugging + writing the patches)
> > that in that case ld.bfd does
> > not actually regards that file as being used but just offers it to
> > llto-plugin in case it needs
> > symbols from it.
> >
> > To get this working, the current API is insufficient.
> >
> > Possible solutions:
> > * Tell lto-plugin whether 'ld' actually needs symbols from a file or
> > it just offers the file
> >   in case that lto-plugin wants to claim that file
> >   => That's implemented in the attached patch.
> > * Make it possible to "claim" a file without discarding the ld-visible
> > symbols
> > * Asking the linker later whether the file/some symbols are actually
> > used.
> > * something else ...
> >
> >
> > What this patch does:
> > * It adds a new API callback (LDPT_REGISTER_CLAIM_FILE_HOOK_V2) that
> > takes an additional
> >   boolean argument which states whether ld.bdf intens to use that
> > file/symbols from that
> >   file or whether it just asks the plugin in case it wants to claim it.
> > * On the ld.bfd side, it wires this up.
> > * On the GCC lto-plugin side, it uses that API is available, otherwise
> > it uses the existing API.
> >
> > The way the linker plugin handling is written, it works fine at
> > runtime if only one side
> > supports the new hook. (Except, of course, that for fixing the issue
> > both need to support it.)
> >
> > Regarding those patches: Are they ok for mainline? Any comment, better
> > approach, suggestion?
> >
> > Tobias
> >
> > PS: Attached is the Binutils' ld side of the patch and the GCC
> > lto-plugin side of the patch set.
> > -----------------
> > Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstra?e
> > 201, 80634 M?nchen; Gesellschaft mit beschr?nkter Haftung;
> > Gesch?ftsf?hrer: Thomas Heurung, Frank Th?rauf; Sitz der Gesellschaft:
> > M?nchen; Registergericht M?nchen, HRB 106955
> -----------------
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstra?e 201, 80634
> M?nchen; Gesellschaft mit beschr?nkter Haftung; Gesch?ftsf?hrer: Thomas
> Heurung, Frank Th?rauf; Sitz der Gesellschaft: M?nchen; Registergericht
> M?nchen, HRB 106955
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128])
  2023-05-04 11:02   ` Richard Biener
@ 2023-05-04 13:25     ` Tobias Burnus
  2023-05-11  0:40     ` Alan Modra
  1 sibling, 0 replies; 6+ messages in thread
From: Tobias Burnus @ 2023-05-04 13:25 UTC (permalink / raw)
  To: Richard Biener; +Cc: Binutils, gcc-patches, Joseph Myers

On 04.05.23 13:02, Richard Biener wrote:
> So since we expect the linker to use the host side table is there a way
> for the plugin to exactly query that

Background - feel free to skip to the next quote / reply bit.

The following is what we have for the host side:

We have (→ libgcc/offloadstuff.c)
#define OFFLOAD_FUNC_TABLE_SECTION_NAME ".gnu.offload_funcs"

* crtoffloadbegin.a with:
const void *const __offload_func_table[0]
   __attribute__ ((__used__, visibility ("hidden"),
                   section (OFFLOAD_FUNC_TABLE_SECTION_NAME))) = { };

* crtoffloadend.a with:
const void *const __offload_funcs_end[0]
   __attribute__ ((__used__, visibility ("hidden"),
                   section (OFFLOAD_FUNC_TABLE_SECTION_NAME))) = { };

* crtoffloadtable.a with:
const void *const __OFFLOAD_TABLE__[]
   __attribute__ ((__visibility__ ("hidden"))) =
{
   &__offload_func_table, &__offload_funcs_end,


Each TU generates an a static array with constructor in that
section – and the values for the constructor are the function
(or variable) addresses, i.e. omp_finish_file has:

       tree funcs_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
                                     get_identifier (".offload_func_table"),
                                     funcs_decl_type);
       set_decl_section_name (funcs_decl, OFFLOAD_FUNC_TABLE_SECTION_NAME);

> (the set of symbols the linker
> uses from the object passed to the plugin)?  Because if the linker
> uses something from the file but _not_ the host side offload table
> (-ffunction-sections -fdata-sections) then things would still go
> wrong, right?

Shouldn't this only affect where the functions/variables themselves are
placed to - and not the section in which the two offload-funs/-vars arrays
are placed to, given that it was explicitly set?

At least that's how I understand the GCC documentation and after glancing
at the varasm.c code.

That matches also what I see when using those flags. There are differences
related to, e.g. .text.s1.0._omp_fn.0 but .offload_var_table and
.offload_func_table still look fine.


(Side remark, I am wondering whether we should use "retain" for everything
that goes into the special sections, i.e. whether the following should be added:

+#ifndef ACCEL_COMPILER
+      if (SUPPORTS_SHF_GNU_RETAIN)
+       {
+         DECL_ATTRIBUTES (funcs_decl) = tree_cons (get_identifier ("retain"),
+                                                   NULL_TREE, NULL_TREE);

to omp-offload.c (+ "retain" as __attribute__ in libgcc/offloadstuff.c)?

> Is there a way to connect both in a way that the linker discards
> either if the other isn't present?

I think as soon as the file is used, they are present, at least with 'retain',
even though they might be size-zero arrays.

My attempts to check with get_symbols{_v2,_v3} failed. If I recall correctly,
the way everything it setup for the hash, which includes also the file name,
makes it hard to query something which has not been added by get_symbols.
Even if we added a new interface, implementing it in a generic way and being
compatible with the ld.bfd way of storing symbols as hash might be a bit complex.

Tobias

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128])
  2023-05-04 11:02   ` Richard Biener
  2023-05-04 13:25     ` Tobias Burnus
@ 2023-05-11  0:40     ` Alan Modra
  2023-05-11  7:27       ` Richard Biener
  1 sibling, 1 reply; 6+ messages in thread
From: Alan Modra @ 2023-05-11  0:40 UTC (permalink / raw)
  To: Richard Biener; +Cc: Tobias Burnus, Binutils, gcc-patches, Joseph Myers

On Thu, May 04, 2023 at 11:02:25AM +0000, Richard Biener via Binutils wrote:
> So since we expect the linker to use the host side table is there a way
> for the plugin to exactly query that (the set of symbols the linker
> uses from the object passed to the plugin)?

That would be possible and relatively easy to implement, but might be
slow.

>  Because if the linker
> uses something from the file but _not_ the host side offload table
> (-ffunction-sections -fdata-sections) then things would still go
> wrong, right?

> Is there a way to connect both in a way that the linker discards
> either if the other isn't present?

No, or at least I do not want to even think about implementing such a
linker "feature".  The problem is that after you have modified the
global linker symbol table after adding an object's symbols, it is
virtually impossible to restore the state of symbols to what they
would be without that object.  (Yes, we do that sort of thing for
as-needed shared libraries, but the restoration happens immediately
after adding the symbols.  I also regret implementing it the way I
did.)

The patch posted is OK from the linker side of things.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128])
  2023-05-11  0:40     ` Alan Modra
@ 2023-05-11  7:27       ` Richard Biener
  0 siblings, 0 replies; 6+ messages in thread
From: Richard Biener @ 2023-05-11  7:27 UTC (permalink / raw)
  To: Alan Modra; +Cc: Tobias Burnus, Binutils, gcc-patches, Joseph Myers

On Thu, 11 May 2023, Alan Modra wrote:

> On Thu, May 04, 2023 at 11:02:25AM +0000, Richard Biener via Binutils wrote:
> > So since we expect the linker to use the host side table is there a way
> > for the plugin to exactly query that (the set of symbols the linker
> > uses from the object passed to the plugin)?
> 
> That would be possible and relatively easy to implement, but might be
> slow.
> 
> >  Because if the linker
> > uses something from the file but _not_ the host side offload table
> > (-ffunction-sections -fdata-sections) then things would still go
> > wrong, right?
> 
> > Is there a way to connect both in a way that the linker discards
> > either if the other isn't present?
> 
> No, or at least I do not want to even think about implementing such a
> linker "feature".  The problem is that after you have modified the
> global linker symbol table after adding an object's symbols, it is
> virtually impossible to restore the state of symbols to what they
> would be without that object.  (Yes, we do that sort of thing for
> as-needed shared libraries, but the restoration happens immediately
> after adding the symbols.  I also regret implementing it the way I
> did.)

Thanks for explaining.

> The patch posted is OK from the linker side of things.

OK, then lets go with it and hope it fixes the issue for good.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-05-11  7:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-02 17:19 [RFC,patch] Linker plugin - extend API for offloading corner case (aka: LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook [GCC PR109128]) Tobias Burnus
2023-05-04 10:30 ` Tobias Burnus
2023-05-04 11:02   ` Richard Biener
2023-05-04 13:25     ` Tobias Burnus
2023-05-11  0:40     ` Alan Modra
2023-05-11  7:27       ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).