Kyle McMartin d7c318
From 4613510308cea27713e8c7424b2afee9b99f6226 Mon Sep 17 00:00:00 2001
Kyle McMartin d7c318
From: Alan Modra <amodra@gmail.com>
Kyle McMartin d7c318
Date: Tue, 12 Aug 2014 10:43:33 +0930
Kyle McMartin d7c318
Subject: [PATCH] Change ld "notice" interface for better handling of
Kyle McMartin d7c318
 indirect symbols
Kyle McMartin d7c318
Kyle McMartin d7c318
The main aim of this change was to have non_ir_ref set correctly on
Kyle McMartin d7c318
new indirect symbols.  I could have added a "copy" param to the "notice"
Kyle McMartin d7c318
function, so that indirect symbols could be created in plugin_notice,
Kyle McMartin d7c318
but it seemed cleaner to create indirect syms earlier and pass them
Kyle McMartin d7c318
rather than "string" to "notice".
Kyle McMartin d7c318
Kyle McMartin d7c318
include/
Kyle McMartin d7c318
	* bfdlink.h (struct bfd_link_callbacks <notice>): Remove "string"
Kyle McMartin d7c318
	param, add "inh".
Kyle McMartin d7c318
bfd/
Kyle McMartin d7c318
	* coff-aux.c (coff_m68k_aux_link_add_one_symbol): Only call "notice"
Kyle McMartin d7c318
	here when not calling the generic add_symbol function.  Formatting.
Kyle McMartin d7c318
	Correct handling of indirect symbols.  Update notice call.
Kyle McMartin d7c318
	* elflink.c (_bfd_elf_notice_as_needed): Update notice call.
Kyle McMartin d7c318
	* linker.c (_bfd_generic_link_add_one_symbol): Create indirect
Kyle McMartin d7c318
	symbols early.  Update notice call.  Add comments regarding weak
Kyle McMartin d7c318
	symbols vs. indirect.
Kyle McMartin d7c318
ld/
Kyle McMartin d7c318
	* ldmain.c (notice): Update args.
Kyle McMartin d7c318
	* plugin.c (plugin_notice): Likewise.  Follow warning sym link.
Kyle McMartin d7c318
	Handle new indirect symbol.
Kyle McMartin d7c318
---
Kyle McMartin d7c318
 bfd/coff-aux.c    | 62 ++++++++++++++++++++++-------------------
Kyle McMartin d7c318
 bfd/elflink.c     |  2 +-
Kyle McMartin d7c318
 bfd/linker.c      | 82 +++++++++++++++++++++++++++++--------------------------
Kyle McMartin d7c318
 include/bfdlink.h | 13 ++++-----
Kyle McMartin d7c318
 ld/ldmain.c       |  6 ++--
Kyle McMartin d7c318
 ld/plugin.c       | 33 ++++++++++++----------
Kyle McMartin d7c318
 9 files changed, 128 insertions(+), 91 deletions(-)
Kyle McMartin d7c318
Kyle McMartin d7c318
diff --git a/bfd/coff-aux.c b/bfd/coff-aux.c
Kyle McMartin d7c318
index e79c77a..d95b98b 100644
Kyle McMartin d7c318
--- a/bfd/coff-aux.c
Kyle McMartin d7c318
+++ b/bfd/coff-aux.c
Kyle McMartin d7c318
@@ -73,20 +73,17 @@ coff_m68k_aux_link_add_one_symbol (struct bfd_link_info *info,
Kyle McMartin d7c318
 				   bfd_boolean collect,
Kyle McMartin d7c318
 				   struct bfd_link_hash_entry **hashp)
Kyle McMartin d7c318
 {
Kyle McMartin d7c318
-  struct bfd_link_hash_entry *h;
Kyle McMartin d7c318
+  struct bfd_link_hash_entry *h, *inh, *t;
Kyle McMartin d7c318
 
Kyle McMartin d7c318
-  if ((flags & (BSF_WARNING | BSF_CONSTRUCTOR | BSF_WEAK)) == 0 &&
Kyle McMartin d7c318
-      !bfd_is_und_section (section) &&
Kyle McMartin d7c318
-      !bfd_is_com_section (section))
Kyle McMartin d7c318
+  if ((flags & (BSF_WARNING | BSF_CONSTRUCTOR | BSF_WEAK)) == 0
Kyle McMartin d7c318
+      && !bfd_is_und_section (section)
Kyle McMartin d7c318
+      && !bfd_is_com_section (section))
Kyle McMartin d7c318
     {
Kyle McMartin d7c318
       /* The new symbol is a definition or an indirect definition */
Kyle McMartin d7c318
 
Kyle McMartin d7c318
       /* This bit copied from linker.c */
Kyle McMartin d7c318
       if (hashp != NULL && *hashp != NULL)
Kyle McMartin d7c318
-	{
Kyle McMartin d7c318
-	  h = *hashp;
Kyle McMartin d7c318
-	  BFD_ASSERT (strcmp (h->root.string, name) == 0);
Kyle McMartin d7c318
-	}
Kyle McMartin d7c318
+	h = *hashp;
Kyle McMartin d7c318
       else
Kyle McMartin d7c318
 	{
Kyle McMartin d7c318
 	  h = bfd_link_hash_lookup (info->hash, name, TRUE, copy, FALSE);
Kyle McMartin d7c318
@@ -98,37 +95,46 @@ coff_m68k_aux_link_add_one_symbol (struct bfd_link_info *info,
Kyle McMartin d7c318
 	    }
Kyle McMartin d7c318
 	}
Kyle McMartin d7c318
 
Kyle McMartin d7c318
-      if (info->notice_hash != (struct bfd_hash_table *) NULL
Kyle McMartin d7c318
-	  && (bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE)
Kyle McMartin d7c318
-	      != (struct bfd_hash_entry *) NULL))
Kyle McMartin d7c318
-	{
Kyle McMartin d7c318
-	  if (! (*info->callbacks->notice) (info, h, abfd, section, value,
Kyle McMartin d7c318
-					    flags, string))
Kyle McMartin d7c318
-	    return FALSE;
Kyle McMartin d7c318
-	}
Kyle McMartin d7c318
-
Kyle McMartin d7c318
       if (hashp != (struct bfd_link_hash_entry **) NULL)
Kyle McMartin d7c318
 	*hashp = h;
Kyle McMartin d7c318
       /* end duplication from linker.c */
Kyle McMartin d7c318
 
Kyle McMartin d7c318
-      if (h->type == bfd_link_hash_defined
Kyle McMartin d7c318
-	  || h->type == bfd_link_hash_indirect)
Kyle McMartin d7c318
+      t = h;
Kyle McMartin d7c318
+      inh = NULL;
Kyle McMartin d7c318
+      if (h->type == bfd_link_hash_indirect)
Kyle McMartin d7c318
 	{
Kyle McMartin d7c318
-	  asection *msec;
Kyle McMartin d7c318
+	  inh = h->u.i.link;
Kyle McMartin d7c318
+	  t = inh;
Kyle McMartin d7c318
+	}
Kyle McMartin d7c318
 
Kyle McMartin d7c318
-	  if (h->type == bfd_link_hash_defined)
Kyle McMartin d7c318
-	    msec = h->u.def.section;
Kyle McMartin d7c318
-	  else
Kyle McMartin d7c318
-	    msec = bfd_ind_section_ptr;
Kyle McMartin d7c318
+      if (t->type == bfd_link_hash_defined)
Kyle McMartin d7c318
+	{
Kyle McMartin d7c318
+	  asection *msec = t->u.def.section;
Kyle McMartin d7c318
+	  bfd_boolean special = FALSE;
Kyle McMartin d7c318
 
Kyle McMartin d7c318
 	  if (bfd_is_abs_section (msec) && !bfd_is_abs_section (section))
Kyle McMartin d7c318
 	    {
Kyle McMartin d7c318
-	      h->u.def.section = section;
Kyle McMartin d7c318
-	      h->u.def.value = value;
Kyle McMartin d7c318
-	      return TRUE;
Kyle McMartin d7c318
+	      t->u.def.section = section;
Kyle McMartin d7c318
+	      t->u.def.value = value;
Kyle McMartin d7c318
+	      special = TRUE;
Kyle McMartin d7c318
 	    }
Kyle McMartin d7c318
 	  else if (bfd_is_abs_section (section) && !bfd_is_abs_section (msec))
Kyle McMartin d7c318
-	    return TRUE;
Kyle McMartin d7c318
+	    special = TRUE;
Kyle McMartin d7c318
+
Kyle McMartin d7c318
+	  if (special)
Kyle McMartin d7c318
+	    {
Kyle McMartin d7c318
+	      if (info->notice_all
Kyle McMartin d7c318
+		  || (info->notice_hash != NULL
Kyle McMartin d7c318
+		      && bfd_hash_lookup (info->notice_hash, name,
Kyle McMartin d7c318
+					  FALSE, FALSE) != NULL))
Kyle McMartin d7c318
+		{
Kyle McMartin d7c318
+		  if (!(*info->callbacks->notice) (info, h, inh,
Kyle McMartin d7c318
+						   abfd, section, value, flags))
Kyle McMartin d7c318
+		    return FALSE;
Kyle McMartin d7c318
+		}
Kyle McMartin d7c318
+
Kyle McMartin d7c318
+	      return TRUE;
Kyle McMartin d7c318
+	    }
Kyle McMartin d7c318
 	}
Kyle McMartin d7c318
     }
Kyle McMartin d7c318
 
Kyle McMartin d7c318
diff --git a/bfd/elflink.c b/bfd/elflink.c
Kyle McMartin d7c318
index 69a87a6..de0a734 100644
Kyle McMartin d7c318
--- a/bfd/elflink.c
Kyle McMartin d7c318
+++ b/bfd/elflink.c
Kyle McMartin d7c318
@@ -3299,7 +3299,7 @@ _bfd_elf_notice_as_needed (bfd *ibfd,
Kyle McMartin d7c318
 			   struct bfd_link_info *info,
Kyle McMartin d7c318
 			   enum notice_asneeded_action act)
Kyle McMartin d7c318
 {
Kyle McMartin d7c318
-  return (*info->callbacks->notice) (info, NULL, ibfd, NULL, act, 0, NULL);
Kyle McMartin d7c318
+  return (*info->callbacks->notice) (info, NULL, NULL, ibfd, NULL, act, 0);
Kyle McMartin d7c318
 }
Kyle McMartin d7c318
 
Kyle McMartin d7c318
 /* Add symbols from an ELF object file to the linker hash table.  */
Kyle McMartin d7c318
diff --git a/bfd/linker.c b/bfd/linker.c
Kyle McMartin d7c318
index 1a5ecef..abdf5b0 100644
Kyle McMartin d7c318
--- a/bfd/linker.c
Kyle McMartin d7c318
+++ b/bfd/linker.c
Kyle McMartin d7c318
@@ -1442,13 +1442,23 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
Kyle McMartin d7c318
 {
Kyle McMartin d7c318
   enum link_row row;
Kyle McMartin d7c318
   struct bfd_link_hash_entry *h;
Kyle McMartin d7c318
+  struct bfd_link_hash_entry *inh = NULL;
Kyle McMartin d7c318
   bfd_boolean cycle;
Kyle McMartin d7c318
 
Kyle McMartin d7c318
   BFD_ASSERT (section != NULL);
Kyle McMartin d7c318
 
Kyle McMartin d7c318
   if (bfd_is_ind_section (section)
Kyle McMartin d7c318
       || (flags & BSF_INDIRECT) != 0)
Kyle McMartin d7c318
-    row = INDR_ROW;
Kyle McMartin d7c318
+    {
Kyle McMartin d7c318
+      row = INDR_ROW;
Kyle McMartin d7c318
+      /* Create the indirect symbol here.  This is for the benefit of
Kyle McMartin d7c318
+	 the plugin "notice" function.
Kyle McMartin d7c318
+	 STRING is the name of the symbol we want to indirect to.  */
Kyle McMartin d7c318
+      inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE,
Kyle McMartin d7c318
+					  copy, FALSE);
Kyle McMartin d7c318
+      if (inh == NULL)
Kyle McMartin d7c318
+	return FALSE;
Kyle McMartin d7c318
+    }
Kyle McMartin d7c318
   else if ((flags & BSF_WARNING) != 0)
Kyle McMartin d7c318
     row = WARN_ROW;
Kyle McMartin d7c318
   else if ((flags & BSF_CONSTRUCTOR) != 0)
Kyle McMartin d7c318
@@ -1493,8 +1503,8 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
Kyle McMartin d7c318
       || (info->notice_hash != NULL
Kyle McMartin d7c318
 	  && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
Kyle McMartin d7c318
     {
Kyle McMartin d7c318
-      if (! (*info->callbacks->notice) (info, h,
Kyle McMartin d7c318
-					abfd, section, value, flags, string))
Kyle McMartin d7c318
+      if (! (*info->callbacks->notice) (info, h, inh,
Kyle McMartin d7c318
+					abfd, section, value, flags))
Kyle McMartin d7c318
 	return FALSE;
Kyle McMartin d7c318
     }
Kyle McMartin d7c318
 
Kyle McMartin d7c318
@@ -1728,44 +1738,40 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
Kyle McMartin d7c318
 	    return FALSE;
Kyle McMartin d7c318
 	  /* Fall through.  */
Kyle McMartin d7c318
 	case IND:
Kyle McMartin d7c318
-	  /* Create an indirect symbol.  */
Kyle McMartin d7c318
-	  {
Kyle McMartin d7c318
-	    struct bfd_link_hash_entry *inh;
Kyle McMartin d7c318
-
Kyle McMartin d7c318
-	    /* STRING is the name of the symbol we want to indirect
Kyle McMartin d7c318
-	       to.  */
Kyle McMartin d7c318
-	    inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE,
Kyle McMartin d7c318
-						copy, FALSE);
Kyle McMartin d7c318
-	    if (inh == NULL)
Kyle McMartin d7c318
+	  if (inh->type == bfd_link_hash_indirect
Kyle McMartin d7c318
+	      && inh->u.i.link == h)
Kyle McMartin d7c318
+	    {
Kyle McMartin d7c318
+	      (*_bfd_error_handler)
Kyle McMartin d7c318
+		(_("%B: indirect symbol `%s' to `%s' is a loop"),
Kyle McMartin d7c318
+		 abfd, name, string);
Kyle McMartin d7c318
+	      bfd_set_error (bfd_error_invalid_operation);
Kyle McMartin d7c318
 	      return FALSE;
Kyle McMartin d7c318
-	    if (inh->type == bfd_link_hash_indirect
Kyle McMartin d7c318
-		&& inh->u.i.link == h)
Kyle McMartin d7c318
-	      {
Kyle McMartin d7c318
-		(*_bfd_error_handler)
Kyle McMartin d7c318
-		  (_("%B: indirect symbol `%s' to `%s' is a loop"),
Kyle McMartin d7c318
-		   abfd, name, string);
Kyle McMartin d7c318
-		bfd_set_error (bfd_error_invalid_operation);
Kyle McMartin d7c318
-		return FALSE;
Kyle McMartin d7c318
-	      }
Kyle McMartin d7c318
-	    if (inh->type == bfd_link_hash_new)
Kyle McMartin d7c318
-	      {
Kyle McMartin d7c318
-		inh->type = bfd_link_hash_undefined;
Kyle McMartin d7c318
-		inh->u.undef.abfd = abfd;
Kyle McMartin d7c318
-		bfd_link_add_undef (info->hash, inh);
Kyle McMartin d7c318
-	      }
Kyle McMartin d7c318
+	    }
Kyle McMartin d7c318
+	  if (inh->type == bfd_link_hash_new)
Kyle McMartin d7c318
+	    {
Kyle McMartin d7c318
+	      inh->type = bfd_link_hash_undefined;
Kyle McMartin d7c318
+	      inh->u.undef.abfd = abfd;
Kyle McMartin d7c318
+	      bfd_link_add_undef (info->hash, inh);
Kyle McMartin d7c318
+	    }
Kyle McMartin d7c318
 
Kyle McMartin d7c318
-	    /* If the indirect symbol has been referenced, we need to
Kyle McMartin d7c318
-	       push the reference down to the symbol we are
Kyle McMartin d7c318
-	       referencing.  */
Kyle McMartin d7c318
-	    if (h->type != bfd_link_hash_new)
Kyle McMartin d7c318
-	      {
Kyle McMartin d7c318
-		row = UNDEF_ROW;
Kyle McMartin d7c318
-		cycle = TRUE;
Kyle McMartin d7c318
-	      }
Kyle McMartin d7c318
+	  /* If the indirect symbol has been referenced, we need to
Kyle McMartin d7c318
+	     push the reference down to the symbol we are referencing.  */
Kyle McMartin d7c318
+	  if (h->type != bfd_link_hash_new)
Kyle McMartin d7c318
+	    {
Kyle McMartin d7c318
+	      /* ??? If inh->type == bfd_link_hash_undefweak this
Kyle McMartin d7c318
+		 converts inh to bfd_link_hash_undefined.  */
Kyle McMartin d7c318
+	      row = UNDEF_ROW;
Kyle McMartin d7c318
+	      cycle = TRUE;
Kyle McMartin d7c318
+	    }
Kyle McMartin d7c318
 
Kyle McMartin d7c318
-	    h->type = bfd_link_hash_indirect;
Kyle McMartin d7c318
-	    h->u.i.link = inh;
Kyle McMartin d7c318
-	  }
Kyle McMartin d7c318
+	  h->type = bfd_link_hash_indirect;
Kyle McMartin d7c318
+	  h->u.i.link = inh;
Kyle McMartin d7c318
+	  /* Not setting h = h->u.i.link here means that when cycle is
Kyle McMartin d7c318
+	     set above we'll always go to REFC, and then cycle again
Kyle McMartin d7c318
+	     to the indirected symbol.  This means that any successful
Kyle McMartin d7c318
+	     change of an existing symbol to indirect counts as a
Kyle McMartin d7c318
+	     reference.  ??? That may not be correct when the existing
Kyle McMartin d7c318
+	     symbol was defweak.  */
Kyle McMartin d7c318
 	  break;
Kyle McMartin d7c318
 
Kyle McMartin d7c318
 	case SET:
Kyle McMartin d7c318
diff --git a/include/bfdlink.h b/include/bfdlink.h
Kyle McMartin d7c318
index 58dba2a..125683d 100644
Kyle McMartin d7c318
--- a/include/bfdlink.h
Kyle McMartin d7c318
+++ b/include/bfdlink.h
Kyle McMartin d7c318
@@ -640,15 +640,14 @@ struct bfd_link_callbacks
Kyle McMartin d7c318
     (struct bfd_link_info *, const char *name,
Kyle McMartin d7c318
      bfd *abfd, asection *section, bfd_vma address);
Kyle McMartin d7c318
   /* A function which is called when a symbol in notice_hash is
Kyle McMartin d7c318
-     defined or referenced.  H is the symbol.  ABFD, SECTION and
Kyle McMartin d7c318
-     ADDRESS are the (new) value of the symbol.  If SECTION is
Kyle McMartin d7c318
-     bfd_und_section, this is a reference.  FLAGS are the symbol
Kyle McMartin d7c318
-     BSF_* flags.  STRING is the name of the symbol to indirect to if
Kyle McMartin d7c318
-     the sym is indirect, or the warning string if a warning sym.  */
Kyle McMartin d7c318
+     defined or referenced.  H is the symbol, INH the indirect symbol
Kyle McMartin d7c318
+     if applicable.  ABFD, SECTION and ADDRESS are the (new) value of
Kyle McMartin d7c318
+     the symbol.  If SECTION is bfd_und_section, this is a reference.
Kyle McMartin d7c318
+     FLAGS are the symbol BSF_* flags.  */
Kyle McMartin d7c318
   bfd_boolean (*notice)
Kyle McMartin d7c318
     (struct bfd_link_info *, struct bfd_link_hash_entry *h,
Kyle McMartin d7c318
-     bfd *abfd, asection *section, bfd_vma address, flagword flags,
Kyle McMartin d7c318
-     const char *string);
Kyle McMartin d7c318
+     struct bfd_link_hash_entry *inh,
Kyle McMartin d7c318
+     bfd *abfd, asection *section, bfd_vma address, flagword flags);
Kyle McMartin d7c318
   /* Error or warning link info message.  */
Kyle McMartin d7c318
   void (*einfo)
Kyle McMartin d7c318
     (const char *fmt, ...);
Kyle McMartin d7c318
diff --git a/ld/ldmain.c b/ld/ldmain.c
Kyle McMartin d7c318
index ea25afe..77235d5 100644
Kyle McMartin d7c318
--- a/ld/ldmain.c
Kyle McMartin d7c318
+++ b/ld/ldmain.c
Kyle McMartin d7c318
@@ -137,7 +137,7 @@ static bfd_boolean unattached_reloc
Kyle McMartin d7c318
   (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
Kyle McMartin d7c318
 static bfd_boolean notice
Kyle McMartin d7c318
   (struct bfd_link_info *, struct bfd_link_hash_entry *,
Kyle McMartin d7c318
-   bfd *, asection *, bfd_vma, flagword, const char *);
Kyle McMartin d7c318
+   struct bfd_link_hash_entry *, bfd *, asection *, bfd_vma, flagword);
Kyle McMartin d7c318
 
Kyle McMartin d7c318
 static struct bfd_link_callbacks link_callbacks =
Kyle McMartin d7c318
 {
Kyle McMartin d7c318
@@ -1461,11 +1461,11 @@ unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED,
Kyle McMartin d7c318
 static bfd_boolean
Kyle McMartin d7c318
 notice (struct bfd_link_info *info,
Kyle McMartin d7c318
 	struct bfd_link_hash_entry *h,
Kyle McMartin d7c318
+	struct bfd_link_hash_entry *inh ATTRIBUTE_UNUSED,
Kyle McMartin d7c318
 	bfd *abfd,
Kyle McMartin d7c318
 	asection *section,
Kyle McMartin d7c318
 	bfd_vma value,
Kyle McMartin d7c318
-	flagword flags ATTRIBUTE_UNUSED,
Kyle McMartin d7c318
-	const char *string ATTRIBUTE_UNUSED)
Kyle McMartin d7c318
+	flagword flags ATTRIBUTE_UNUSED)
Kyle McMartin d7c318
 {
Kyle McMartin d7c318
   const char *name;
Kyle McMartin d7c318
 
Kyle McMartin d7c318
diff --git a/ld/plugin.c b/ld/plugin.c
Kyle McMartin d7c318
index 8d6ae05..8cca7d0 100644
Kyle McMartin d7c318
--- a/ld/plugin.c
Kyle McMartin d7c318
+++ b/ld/plugin.c
Kyle McMartin d7c318
@@ -127,8 +127,9 @@ static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
Kyle McMartin d7c318
 
Kyle McMartin d7c318
 /* Forward references.  */
Kyle McMartin d7c318
 static bfd_boolean plugin_notice (struct bfd_link_info *,
Kyle McMartin d7c318
-				  struct bfd_link_hash_entry *, bfd *,
Kyle McMartin d7c318
-				  asection *, bfd_vma, flagword, const char *);
Kyle McMartin d7c318
+				  struct bfd_link_hash_entry *,
Kyle McMartin d7c318
+				  struct bfd_link_hash_entry *,
Kyle McMartin d7c318
+				  bfd *, asection *, bfd_vma, flagword);
Kyle McMartin d7c318
 
Kyle McMartin d7c318
 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
Kyle McMartin d7c318
 
Kyle McMartin d7c318
@@ -962,16 +963,21 @@ plugin_call_cleanup (void)
Kyle McMartin d7c318
 static bfd_boolean
Kyle McMartin d7c318
 plugin_notice (struct bfd_link_info *info,
Kyle McMartin d7c318
 	       struct bfd_link_hash_entry *h,
Kyle McMartin d7c318
+	       struct bfd_link_hash_entry *inh,
Kyle McMartin d7c318
 	       bfd *abfd,
Kyle McMartin d7c318
 	       asection *section,
Kyle McMartin d7c318
 	       bfd_vma value,
Kyle McMartin d7c318
-	       flagword flags,
Kyle McMartin d7c318
-	       const char *string)
Kyle McMartin d7c318
+	       flagword flags)
Kyle McMartin d7c318
 {
Kyle McMartin d7c318
+  struct bfd_link_hash_entry *orig_h = h;
Kyle McMartin d7c318
+
Kyle McMartin d7c318
   if (h != NULL)
Kyle McMartin d7c318
     {
Kyle McMartin d7c318
       bfd *sym_bfd;
Kyle McMartin d7c318
 
Kyle McMartin d7c318
+      if (h->type == bfd_link_hash_warning)
Kyle McMartin d7c318
+	h = h->u.i.link;
Kyle McMartin d7c318
+
Kyle McMartin d7c318
       /* Nothing to do here if this def/ref is from an IR dummy BFD.  */
Kyle McMartin d7c318
       if (is_ir_dummy_bfd (abfd))
Kyle McMartin d7c318
 	;
Kyle McMartin d7c318
@@ -981,16 +987,15 @@ plugin_notice (struct bfd_link_info *info,
Kyle McMartin d7c318
       else if (bfd_is_ind_section (section)
Kyle McMartin d7c318
 	       || (flags & BSF_INDIRECT) != 0)
Kyle McMartin d7c318
 	{
Kyle McMartin d7c318
+	  /* ??? Some of this is questionable.  See comments in
Kyle McMartin d7c318
+	     _bfd_generic_link_add_one_symbol for case IND.  */
Kyle McMartin d7c318
 	  if (h->type != bfd_link_hash_new)
Kyle McMartin d7c318
 	    {
Kyle McMartin d7c318
-	      struct bfd_link_hash_entry *inh;
Kyle McMartin d7c318
-
Kyle McMartin d7c318
 	      h->non_ir_ref = TRUE;
Kyle McMartin d7c318
-	      inh = bfd_wrapped_link_hash_lookup (abfd, info, string, FALSE,
Kyle McMartin d7c318
-						  FALSE, FALSE);
Kyle McMartin d7c318
-	      if (inh != NULL)
Kyle McMartin d7c318
-		inh->non_ir_ref = TRUE;
Kyle McMartin d7c318
+	      inh->non_ir_ref = TRUE;
Kyle McMartin d7c318
 	    }
Kyle McMartin d7c318
+	  else if (inh->type == bfd_link_hash_new)
Kyle McMartin d7c318
+	    inh->non_ir_ref = TRUE;
Kyle McMartin d7c318
 	}
Kyle McMartin d7c318
 
Kyle McMartin d7c318
       /* Nothing to do here for warning symbols.  */
Kyle McMartin d7c318
@@ -1031,13 +1036,13 @@ plugin_notice (struct bfd_link_info *info,
Kyle McMartin d7c318
     }
Kyle McMartin d7c318
 
Kyle McMartin d7c318
   /* Continue with cref/nocrossref/trace-sym processing.  */
Kyle McMartin d7c318
-  if (h == NULL
Kyle McMartin d7c318
+  if (orig_h == NULL
Kyle McMartin d7c318
       || orig_notice_all
Kyle McMartin d7c318
       || (info->notice_hash != NULL
Kyle McMartin d7c318
-	  && bfd_hash_lookup (info->notice_hash, h->root.string,
Kyle McMartin d7c318
+	  && bfd_hash_lookup (info->notice_hash, orig_h->root.string,
Kyle McMartin d7c318
 			      FALSE, FALSE) != NULL))
Kyle McMartin d7c318
-    return (*orig_callbacks->notice) (info, h,
Kyle McMartin d7c318
-				      abfd, section, value, flags, string);
Kyle McMartin d7c318
+    return (*orig_callbacks->notice) (info, orig_h, inh,
Kyle McMartin d7c318
+				      abfd, section, value, flags);
Kyle McMartin d7c318
   return TRUE;
Kyle McMartin d7c318
 }
Kyle McMartin d7c318
 
Kyle McMartin d7c318
-- 
Kyle McMartin d7c318
1.9.3
Kyle McMartin d7c318