/* Plugin control for the GNU linker.
- Copyright (C) 2010-2021 Free Software Foundation, Inc.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
#if !(defined(errno) || defined(_MSC_VER) && defined(_INC_ERRNO))
extern int errno;
#endif
-#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
+#if defined (HAVE_DLFCN_H)
+#include <dlfcn.h>
+#elif defined (HAVE_WINDOWS_H)
#include <windows.h>
#endif
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. */
pointer. */
typedef struct plugin_input_file
{
+ /* The dummy BFD. */
bfd *abfd;
+ /* The original input BFD. Non-NULL if it is an archive member. */
bfd *ibfd;
view_buffer_t view_buffer;
char *name;
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,
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)
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)
/* We need to know if the sym is referenced from non-IR files. Or
even potentially-referenced, perhaps in a future final link if
this is a partial one, perhaps dynamically at load-time if the
- symbol is externally visible. Also check for wrapper symbol. */
- if (blhe->non_ir_ref_regular || wrap_status == wrapper)
+ symbol is externally visible. Also check for __real_SYM
+ reference and wrapper symbol. */
+ if (blhe->non_ir_ref_regular
+ || blhe->ref_real
+ || wrap_status == wrapper)
res = LDPR_PREVAILING_DEF;
else if (wrap_status == wrapped)
res = LDPR_RESOLVED_IR;
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;
/* 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;
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);
}
static bfd_cleanup
-plugin_object_p (bfd *ibfd)
+plugin_object_p (bfd *ibfd, bool known_used)
{
int claimed;
plugin_input_file_t *input;
file.handle = input;
input->abfd = abfd;
- input->ibfd = ibfd;
+ input->ibfd = ibfd->my_archive != NULL ? ibfd : NULL;
input->view_buffer.addr = NULL;
input->view_buffer.filesize = 0;
input->view_buffer.offset = 0;
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 ());
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;