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]

Change multiple_definition and multiple_common interface


This prepares the way for fixing PR12365 wrt common symbols.

include/
	PR ld/12365
	* bfdlink.h (struct bfd_link_callbacks): Modify multiple_definition
	and multiple_common parameters to pass in a bfd_link_hash_entry
	pointer rather than name,bfd etc. found in the hash entry.
bfd/
	PR ld/12365
	* elflink.c (_bfd_elf_merge_symbol): Update multiple_common calls.
	* linker.c (_bfd_generic_link_add_one_symbol): Likewise.  Call
	multiple_definition regardless of allow_multiple_definition.
	* simple.c (simple_dummy_multiple_definition): Update.
	* xcofflink.c (xcoff_link_add_symbols): Update multiple_definition
	calls.
ld/
	PR ld/12365
	* ldmain.c (multiple_definition): Take a bfd_link_hash_entry
	pointer arg rather than "name", "obfd", "osec", "oval".  Add code
	removed from linker.c.  Hack around xcofflink.c oddity in
	passing NULL nbfd.
	(multiple_common): Similarly.
	* plugin.c (orig_allow_multiple_defs): Delete.
	(plugin_call_all_symbols_read): Don't twiddle allow_multiple_definition.
	(plugin_multiple_definition): Update.

Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.82
diff -u -p -r1.82 bfdlink.h
--- include/bfdlink.h	14 Oct 2010 01:31:28 -0000	1.82
+++ include/bfdlink.h	19 Apr 2011 14:45:52 -0000
@@ -487,30 +487,21 @@ struct bfd_link_callbacks
   bfd_boolean (*add_archive_element)
     (struct bfd_link_info *, bfd *abfd, const char *name, bfd **subsbfd);
   /* A function which is called when a symbol is found with multiple
-     definitions.  NAME is the symbol which is defined multiple times.
-     OBFD is the old BFD, OSEC is the old section, OVAL is the old
-     value, NBFD is the new BFD, NSEC is the new section, and NVAL is
-     the new value.  OBFD may be NULL.  OSEC and NSEC may be
-     bfd_com_section or bfd_ind_section.  */
+     definitions.  H is the symbol which is defined multiple times.
+     NBFD is the new BFD, NSEC is the new section, and NVAL is the new
+     value.  NSEC may be bfd_com_section or bfd_ind_section.  */
   bfd_boolean (*multiple_definition)
-    (struct bfd_link_info *, const char *name,
-     bfd *obfd, asection *osec, bfd_vma oval,
+    (struct bfd_link_info *, struct bfd_link_hash_entry *h,
      bfd *nbfd, asection *nsec, bfd_vma nval);
   /* A function which is called when a common symbol is defined
-     multiple times.  NAME is the symbol appearing multiple times.
-     OBFD is the BFD of the existing symbol; it may be NULL if this is
-     not known.  OTYPE is the type of the existing symbol, which may
-     be bfd_link_hash_defined, bfd_link_hash_defweak,
-     bfd_link_hash_common, or bfd_link_hash_indirect.  If OTYPE is
-     bfd_link_hash_common, OSIZE is the size of the existing symbol.
+     multiple times.  H is the symbol appearing multiple times.
      NBFD is the BFD of the new symbol.  NTYPE is the type of the new
      symbol, one of bfd_link_hash_defined, bfd_link_hash_common, or
      bfd_link_hash_indirect.  If NTYPE is bfd_link_hash_common, NSIZE
      is the size of the new symbol.  */
   bfd_boolean (*multiple_common)
-    (struct bfd_link_info *, const char *name,
-     bfd *obfd, enum bfd_link_hash_type otype, bfd_vma osize,
-     bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize);
+    (struct bfd_link_info *, struct bfd_link_hash_entry *h,
+     bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize);
   /* A function which is called to add a symbol to a set.  ENTRY is
      the link hash table entry for the set itself (e.g.,
      __CTOR_LIST__).  RELOC is the relocation to use for an entry in
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.397
diff -u -p -r1.397 elflink.c
--- bfd/elflink.c	17 Apr 2011 23:15:12 -0000	1.397
+++ bfd/elflink.c	19 Apr 2011 14:45:57 -0000
@@ -1361,8 +1361,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	 symbols defined in dynamic objects.  */
 
       if (! ((*info->callbacks->multiple_common)
-	     (info, h->root.root.string, oldbfd, bfd_link_hash_common,
-	      h->size, abfd, bfd_link_hash_common, sym->st_size)))
+	     (info, &h->root, abfd, bfd_link_hash_common, sym->st_size)))
 	return FALSE;
 
       if (sym->st_size > h->size)
@@ -1513,8 +1512,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	 common symbol, but we don't know what to use for the section
 	 or the alignment.  */
       if (! ((*info->callbacks->multiple_common)
-	     (info, h->root.root.string, oldbfd, bfd_link_hash_common,
-	      h->size, abfd, bfd_link_hash_common, sym->st_size)))
+	     (info, &h->root, abfd, bfd_link_hash_common, sym->st_size)))
 	return FALSE;
 
       /* If the presumed common symbol in the dynamic object is
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.78
diff -u -p -r1.78 linker.c
--- bfd/linker.c	13 Dec 2010 01:06:16 -0000	1.78
+++ bfd/linker.c	19 Apr 2011 14:45:58 -0000
@@ -1651,9 +1651,7 @@ _bfd_generic_link_add_one_symbol (struct
 	     previously common.  */
 	  BFD_ASSERT (h->type == bfd_link_hash_common);
 	  if (! ((*info->callbacks->multiple_common)
-		 (info, h->root.string,
-		  h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
-		  abfd, bfd_link_hash_defined, 0)))
+		 (info, h, abfd, bfd_link_hash_defined, 0)))
 	    return FALSE;
 	  /* Fall through.  */
 	case DEF:
@@ -1782,9 +1780,7 @@ _bfd_generic_link_add_one_symbol (struct
 	     two sizes, and use the section required by the larger symbol.  */
 	  BFD_ASSERT (h->type == bfd_link_hash_common);
 	  if (! ((*info->callbacks->multiple_common)
-		 (info, h->root.string,
-		  h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
-		  abfd, bfd_link_hash_common, value)))
+		 (info, h, abfd, bfd_link_hash_common, value)))
 	    return FALSE;
 	  if (value > h->u.c.size)
 	    {
@@ -1821,23 +1817,11 @@ _bfd_generic_link_add_one_symbol (struct
 	  break;
 
 	case CREF:
-	  {
-	    bfd *obfd;
-
-	    /* We have found a common definition for a symbol which
-	       was already defined.  FIXME: It would nice if we could
-	       report the BFD which defined an indirect symbol, but we
-	       don't have anywhere to store the information.  */
-	    if (h->type == bfd_link_hash_defined
-		|| h->type == bfd_link_hash_defweak)
-	      obfd = h->u.def.section->owner;
-	    else
-	      obfd = NULL;
-	    if (! ((*info->callbacks->multiple_common)
-		   (info, h->root.string, obfd, h->type, 0,
-		    abfd, bfd_link_hash_common, value)))
-	      return FALSE;
-	  }
+	  /* We have found a common definition for a symbol which
+	     was already defined.  */
+	  if (! ((*info->callbacks->multiple_common)
+		 (info, h, abfd, bfd_link_hash_common, value)))
+	    return FALSE;
 	  break;
 
 	case MIND:
@@ -1848,47 +1832,16 @@ _bfd_generic_link_add_one_symbol (struct
 	  /* Fall through.  */
 	case MDEF:
 	  /* Handle a multiple definition.  */
-	  if (!info->allow_multiple_definition)
-	    {
-	      asection *msec = NULL;
-	      bfd_vma mval = 0;
-
-	      switch (h->type)
-		{
-		case bfd_link_hash_defined:
-		  msec = h->u.def.section;
-		  mval = h->u.def.value;
-		  break;
-	        case bfd_link_hash_indirect:
-		  msec = bfd_ind_section_ptr;
-		  mval = 0;
-		  break;
-		default:
-		  abort ();
-		}
-
-	      /* Ignore a redefinition of an absolute symbol to the
-		 same value; it's harmless.  */
-	      if (h->type == bfd_link_hash_defined
-		  && bfd_is_abs_section (msec)
-		  && bfd_is_abs_section (section)
-		  && value == mval)
-		break;
-
-	      if (! ((*info->callbacks->multiple_definition)
-		     (info, h->root.string, msec->owner, msec, mval,
-		      abfd, section, value)))
-		return FALSE;
-	    }
+	  if (! ((*info->callbacks->multiple_definition)
+		 (info, h, abfd, section, value)))
+	    return FALSE;
 	  break;
 
 	case CIND:
 	  /* Create an indirect symbol from an existing common symbol.  */
 	  BFD_ASSERT (h->type == bfd_link_hash_common);
 	  if (! ((*info->callbacks->multiple_common)
-		 (info, h->root.string,
-		  h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
-		  abfd, bfd_link_hash_indirect, 0)))
+		 (info, h, abfd, bfd_link_hash_indirect, 0)))
 	    return FALSE;
 	  /* Fall through.  */
 	case IND:
Index: bfd/simple.c
===================================================================
RCS file: /cvs/src/src/bfd/simple.c,v
retrieving revision 1.34
diff -u -p -r1.34 simple.c
--- bfd/simple.c	29 Oct 2010 12:10:25 -0000	1.34
+++ bfd/simple.c	19 Apr 2011 14:45:58 -0000
@@ -82,10 +82,7 @@ simple_dummy_unattached_reloc (struct bf
 
 static bfd_boolean
 simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
-				  const char *name ATTRIBUTE_UNUSED,
-				  bfd *obfd ATTRIBUTE_UNUSED,
-				  asection *osec ATTRIBUTE_UNUSED,
-				  bfd_vma oval ATTRIBUTE_UNUSED,
+				  struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
 				  bfd *nbfd ATTRIBUTE_UNUSED,
 				  asection *nsec ATTRIBUTE_UNUSED,
 				  bfd_vma nval ATTRIBUTE_UNUSED)
Index: bfd/xcofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/xcofflink.c,v
retrieving revision 1.78
diff -u -p -r1.78 xcofflink.c
--- bfd/xcofflink.c	28 Feb 2011 18:30:16 -0000	1.78
+++ bfd/xcofflink.c	19 Apr 2011 14:46:01 -0000
@@ -1996,11 +1996,7 @@ xcoff_link_add_symbols (bfd *abfd, struc
 		     handle them, and that would only be a warning,
 		     not an error.  */
 		  if (! ((*info->callbacks->multiple_definition)
-			 (info, (*sym_hash)->root.root.string,
-			  NULL, NULL, (bfd_vma) 0,
-			  (*sym_hash)->root.u.def.section->owner,
-			  (*sym_hash)->root.u.def.section,
-			  (*sym_hash)->root.u.def.value)))
+			 (info, &(*sym_hash)->root, NULL, NULL, (bfd_vma) 0)))
 		    goto error_return;
 		  /* Try not to give this error too many times.  */
 		  (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
@@ -3119,9 +3115,7 @@ bfd_xcoff_import_symbol (bfd *output_bfd
 	      || h->root.u.def.value != val))
 	{
 	  if (! ((*info->callbacks->multiple_definition)
-		 (info, h->root.root.string, h->root.u.def.section->owner,
-		  h->root.u.def.section, h->root.u.def.value,
-		  output_bfd, bfd_abs_section_ptr, val)))
+		 (info, &h->root, output_bfd, bfd_abs_section_ptr, val)))
 	    return FALSE;
 	}
 
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.151
diff -u -p -r1.151 ldmain.c
--- ld/ldmain.c	17 Apr 2011 23:15:13 -0000	1.151
+++ ld/ldmain.c	19 Apr 2011 14:46:02 -0000
@@ -123,11 +123,11 @@ static char *get_emulation
 static bfd_boolean add_archive_element
   (struct bfd_link_info *, bfd *, const char *, bfd **);
 static bfd_boolean multiple_definition
-  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma,
+  (struct bfd_link_info *, struct bfd_link_hash_entry *,
    bfd *, asection *, bfd_vma);
 static bfd_boolean multiple_common
-  (struct bfd_link_info *, const char *, bfd *, enum bfd_link_hash_type,
-   bfd_vma, bfd *, enum bfd_link_hash_type, bfd_vma);
+  (struct bfd_link_info *, struct bfd_link_hash_entry *,
+   bfd *, enum bfd_link_hash_type, bfd_vma);
 static bfd_boolean add_to_set
   (struct bfd_link_info *, struct bfd_link_hash_entry *,
    bfd_reloc_code_real_type, bfd *, asection *, bfd_vma);
@@ -937,15 +937,44 @@ add_archive_element (struct bfd_link_inf
    multiple times.  */
 
 static bfd_boolean
-multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-		     const char *name,
-		     bfd *obfd,
-		     asection *osec,
-		     bfd_vma oval,
+multiple_definition (struct bfd_link_info *info,
+		     struct bfd_link_hash_entry *h,
 		     bfd *nbfd,
 		     asection *nsec,
 		     bfd_vma nval)
 {
+  const char *name;
+  bfd *obfd;
+  asection *osec;
+  bfd_vma oval;
+
+  if (info->allow_multiple_definition)
+    return TRUE;
+
+  switch (h->type)
+    {
+    case bfd_link_hash_defined:
+      osec = h->u.def.section;
+      oval = h->u.def.value;
+      obfd = h->u.def.section->owner;
+      break;
+    case bfd_link_hash_indirect:
+      osec = bfd_ind_section_ptr;
+      oval = 0;
+      obfd = NULL;
+      break;
+    default:
+      abort ();
+    }
+
+  /* Ignore a redefinition of an absolute symbol to the
+     same value; it's harmless.  */
+  if (h->type == bfd_link_hash_defined
+      && bfd_is_abs_section (osec)
+      && bfd_is_abs_section (nsec)
+      && nval == oval)
+    return TRUE;
+
   /* If either section has the output_section field set to
      bfd_abs_section_ptr, it means that the section is being
      discarded, and this is not really a multiple definition at all.
@@ -959,6 +988,14 @@ multiple_definition (struct bfd_link_inf
 	  && bfd_is_abs_section (nsec->output_section)))
     return TRUE;
 
+  name = h->root.string;
+  if (nbfd == NULL)
+    {
+      nbfd = obfd;
+      nsec = osec;
+      nval = oval;
+      obfd = NULL;
+    }
   einfo (_("%X%C: multiple definition of `%T'\n"),
 	 nbfd, nsec, nval, name);
   if (obfd != NULL)
@@ -980,17 +1017,41 @@ multiple_definition (struct bfd_link_inf
 
 static bfd_boolean
 multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-		 const char *name,
-		 bfd *obfd,
-		 enum bfd_link_hash_type otype,
-		 bfd_vma osize,
+		 struct bfd_link_hash_entry *h,
 		 bfd *nbfd,
 		 enum bfd_link_hash_type ntype,
 		 bfd_vma nsize)
 {
-  if (! config.warn_common)
+  const char *name;
+  bfd *obfd;
+  enum bfd_link_hash_type otype;
+  bfd_vma osize;
+
+  if (!config.warn_common)
     return TRUE;
 
+  name = h->root.string;
+  otype = h->type;
+  if (otype == bfd_link_hash_common)
+    {
+      obfd = h->u.c.p->section->owner;
+      osize = h->u.c.size;
+    }
+  else if (otype == bfd_link_hash_defined
+	   || otype == bfd_link_hash_defweak)
+    {
+      obfd = h->u.def.section->owner;
+      osize = 0;
+    }
+  else
+    {
+      /* FIXME: It would nice if we could report the BFD which defined
+	 an indirect symbol, but we don't have anywhere to store the
+	 information.  */
+      obfd = NULL;
+      osize = 0;
+    }
+
   if (ntype == bfd_link_hash_defined
       || ntype == bfd_link_hash_defweak
       || ntype == bfd_link_hash_indirect)
Index: ld/plugin.c
===================================================================
RCS file: /cvs/src/src/ld/plugin.c,v
retrieving revision 1.30
diff -u -p -r1.30 plugin.c
--- ld/plugin.c	17 Apr 2011 23:15:13 -0000	1.30
+++ ld/plugin.c	19 Apr 2011 14:46:02 -0000
@@ -97,10 +97,8 @@ static const char *error_plugin = NULL;
    cases when establishing symbol resolutions.  */
 static struct bfd_hash_table *non_ironly_hash = NULL;
 
-/* State of linker "notice" and "multiple_definition" interfaces
-   before we poked at them.  */
+/* State of linker "notice" interface before we poked at it.  */
 static bfd_boolean orig_notice_all;
-static bfd_boolean orig_allow_multiple_defs;
 
 /* Original linker callbacks, and the plugin version.  */
 static const struct bfd_link_callbacks *orig_callbacks;
@@ -138,9 +136,8 @@ static bfd_boolean plugin_notice (struct
 				  const char *name, bfd *abfd,
 				  asection *section, bfd_vma value);
 static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info,
-					       const char *name,
-					       bfd *obfd, asection *osec,
-					       bfd_vma oval, bfd *nbfd,
+					       struct bfd_link_hash_entry *h,
+					       bfd *nbfd,
 					       asection *nsec,
 					       bfd_vma nval);
 
@@ -847,12 +844,6 @@ plugin_call_all_symbols_read (void)
   /* Disable any further file-claiming.  */
   no_more_claiming = TRUE;
 
-  /* If --allow-multiple-definition is in effect, we need to disable it,
-     as the plugin infrastructure relies on the multiple_definition
-     callback to swap out the dummy IR-only BFDs for new real ones
-     when it starts opening the files added during this callback.  */
-  orig_allow_multiple_defs = link_info.allow_multiple_definition;
-  link_info.allow_multiple_definition = FALSE;
   plugin_callbacks.multiple_definition = &plugin_multiple_definition;
 
   while (curplug)
@@ -949,28 +940,18 @@ plugin_notice (struct bfd_link_info *inf
    we've fixed it up, or anyway if --allow-multiple-definition was in
    effect (before we disabled it to ensure we got called back).  */
 static bfd_boolean
-plugin_multiple_definition (struct bfd_link_info *info, const char *name,
-			    bfd *obfd, asection *osec, bfd_vma oval,
+plugin_multiple_definition (struct bfd_link_info *info,
+			    struct bfd_link_hash_entry *h,
 			    bfd *nbfd, asection *nsec, bfd_vma nval)
 {
-  if (is_ir_dummy_bfd (obfd))
+  if (h->type == bfd_link_hash_defined
+      && is_ir_dummy_bfd (h->u.def.section->owner))
     {
-      struct bfd_link_hash_entry *blhe
-	= bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
-      if (!blhe)
-	einfo (_("%P%X: %s: can't find IR symbol '%s'\n"), nbfd->filename,
-	       name);
-      else if (blhe->type != bfd_link_hash_defined)
-	einfo (_("%P%x: %s: bad IR symbol type %d\n"), name, blhe->type);
       /* Replace it with new details.  */
-      blhe->u.def.section = nsec;
-      blhe->u.def.value = nval;
+      h->u.def.section = nsec;
+      h->u.def.value = nval;
       return TRUE;
     }
 
-  if (orig_allow_multiple_defs)
-    return TRUE;
-
-  return (*orig_callbacks->multiple_definition) (info, name, obfd, osec, oval,
-						 nbfd, nsec, nval);
+  return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval);
 }

-- 
Alan Modra
Australia Development Lab, IBM


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