This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] add --ignore-unresolved-symbol from NetBSD (bug#14426)
- From: Jan Beich <jbeich at tormail dot org>
- To: binutils at sourceware dot org
- Date: Wed, 1 Aug 2012 12:43:23 +0000
- Subject: [PATCH] add --ignore-unresolved-symbol from NetBSD (bug#14426)
Allow a specific symbol to be unresolved. This can be useful to let
runtime linker resolve the symbol despite using -Wl,-z,defs.
---
include/bfdlink.h | 4 ++++
ld/ldlex.h | 1 +
ld/ldmain.c | 35 +++++++++++++++++++++++++++--------
ld/ldmain.h | 1 +
ld/lexsup.c | 7 +++++++
5 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/include/bfdlink.h b/include/bfdlink.h
index d900b47..aaac244 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -430,16 +430,20 @@ struct bfd_link_info
this is NULL, and notice_all is FALSE, then no symbols are
reported back. */
struct bfd_hash_table *notice_hash;
/* Hash table of symbols which are being wrapped (the --wrap linker
option). If this is NULL, no symbols are being wrapped. */
struct bfd_hash_table *wrap_hash;
+ /* Hash table of symbols which may be left unresolved during
+ a link. If this is NULL, no symbols can be left unresolved. */
+ struct bfd_hash_table *ignore_hash;
+
/* The output BFD. */
bfd *output_bfd;
/* The list of input BFD's involved in the link. These are chained
together via the link_next field. */
bfd *input_bfds;
bfd **input_bfds_tail;
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 5e3d2fc..441f673 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -130,16 +130,17 @@ enum option_values
OPTION_WARN_ALTERNATE_EM,
OPTION_REDUCE_MEMORY_OVERHEADS,
#ifdef ENABLE_PLUGINS
OPTION_PLUGIN,
OPTION_PLUGIN_OPT,
#endif /* ENABLE_PLUGINS */
OPTION_DEFAULT_SCRIPT,
OPTION_PRINT_OUTPUT_FORMAT,
+ OPTION_IGNORE_UNRESOLVED_SYMBOL,
};
/* The initial parser states. */
typedef enum input_enum {
input_selected, /* We've set the initial state. */
input_script,
input_mri_script,
input_version_script,
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 15f8ebf..4429e1b 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -638,16 +638,33 @@ add_ysym (const char *name)
61))
einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
}
if (bfd_hash_lookup (link_info.notice_hash, name, TRUE, TRUE) == NULL)
einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
}
+void
+add_ignoresym (const char *name)
+{
+ if (link_info.ignore_hash == NULL)
+ {
+ link_info.ignore_hash = xmalloc (sizeof (struct bfd_hash_table));
+ if (! bfd_hash_table_init_n (link_info.ignore_hash,
+ bfd_hash_newfunc,
+ sizeof (struct bfd_hash_entry),
+ 61))
+ einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
+ }
+
+ if (bfd_hash_lookup (link_info.ignore_hash, name, TRUE, TRUE) == NULL)
+ einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
+}
+
/* Record a symbol to be wrapped, from the --wrap option. */
void
add_wrap (const char *name)
{
if (link_info.wrap_hash == NULL)
{
link_info.wrap_hash =
@@ -1223,46 +1240,48 @@ warning_find_reloc (bfd *abfd, asection *sec, void *iarg)
}
free (relpp);
}
/* This is called when an undefined symbol is found. */
static bfd_boolean
-undefined_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+undefined_symbol (struct bfd_link_info *info,
const char *name,
bfd *abfd,
asection *section,
bfd_vma address,
bfd_boolean error)
{
static char *error_name;
static unsigned int error_count;
#define MAX_ERRORS_IN_A_ROW 5
+ if (info->ignore_hash != NULL
+ && bfd_hash_lookup (info->ignore_hash, name, FALSE, FALSE) != NULL)
+ return TRUE;
+
if (config.warn_once)
{
- static struct bfd_hash_table *hash;
-
/* Only warn once about a particular undefined symbol. */
- if (hash == NULL)
+ if (info->ignore_hash == NULL)
{
- hash = (struct bfd_hash_table *)
+ info->ignore_hash = (struct bfd_hash_table *)
xmalloc (sizeof (struct bfd_hash_table));
- if (!bfd_hash_table_init (hash, bfd_hash_newfunc,
+ if (! bfd_hash_table_init (info->ignore_hash, bfd_hash_newfunc,
sizeof (struct bfd_hash_entry)))
einfo (_("%F%P: bfd_hash_table_init failed: %E\n"));
}
- if (bfd_hash_lookup (hash, name, FALSE, FALSE) != NULL)
+ if (bfd_hash_lookup (info->ignore_hash, name, FALSE, FALSE) != NULL)
return TRUE;
- if (bfd_hash_lookup (hash, name, TRUE, TRUE) == NULL)
+ if (bfd_hash_lookup (info->ignore_hash, name, TRUE, TRUE) == NULL)
einfo (_("%F%P: bfd_hash_lookup failed: %E\n"));
}
/* We never print more than a reasonable number of errors in a row
for a single symbol. */
if (error_name != NULL
&& strcmp (name, error_name) == 0)
++error_count;
diff --git a/ld/ldmain.h b/ld/ldmain.h
index 8363833..906c29e 100644
--- a/ld/ldmain.h
+++ b/ld/ldmain.h
@@ -36,11 +36,12 @@ extern bfd_boolean version_printed;
extern bfd_boolean demangling;
extern int g_switch_value;
extern const char *output_filename;
extern struct bfd_link_info link_info;
extern int overflow_cutoff_limit;
extern void add_ysym (const char *);
extern void add_wrap (const char *);
+extern void add_ignoresym (const char *);
extern void add_keepsyms_file (const char *);
#endif
diff --git a/ld/lexsup.c b/ld/lexsup.c
index fc410c9..97f58c2 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -491,16 +491,20 @@ static const struct ld_option ld_options[] =
{ {"error-unresolved-symbols", no_argument, NULL,
OPTION_ERROR_UNRESOLVED_SYMBOLS},
'\0', NULL, N_("Report unresolved symbols as errors"), TWO_DASHES },
{ {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
'\0', NULL, N_("Include all objects from following archives"),
TWO_DASHES },
{ {"wrap", required_argument, NULL, OPTION_WRAP},
'\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
+ { {"ignore-unresolved-symbol", required_argument, NULL,
+ OPTION_IGNORE_UNRESOLVED_SYMBOL},
+ '\0', N_("SYMBOL"),
+ N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES },
};
#define OPTION_COUNT ARRAY_SIZE (ld_options)
void
parse_args (unsigned argc, char **argv)
{
unsigned i;
@@ -1336,16 +1340,19 @@ parse_args (unsigned argc, char **argv)
input_flags.add_DT_NEEDED_for_regular = TRUE;
break;
case OPTION_NO_ADD_DT_NEEDED_FOR_REGULAR:
input_flags.add_DT_NEEDED_for_regular = FALSE;
break;
case OPTION_WRAP:
add_wrap (optarg);
break;
+ case OPTION_IGNORE_UNRESOLVED_SYMBOL:
+ add_ignoresym (optarg);
+ break;
case OPTION_DISCARD_NONE:
link_info.discard = discard_none;
break;
case 'X':
link_info.discard = discard_l;
break;
case 'x':
link_info.discard = discard_all;