This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]