public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PR12365 and common symbols
@ 2011-04-20  0:25 Alan Modra
  2011-04-22 22:33 ` H.J. Lu
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Modra @ 2011-04-20  0:25 UTC (permalink / raw)
  To: binutils

This patch makes ld keep IR-only common symbols in their own specially
marked common section, so that ld can report an error if such a symbol
is referenced.

bfd/
	PR ld/12365
	* elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols
	in their own common section.
	* elflink.c (elf_link_add_object_symbols): Likewise.
	* linker.c (generic_link_check_archive_element): Don't lose flags
	if common section is pre-existing.
	(_bfd_generic_link_add_one_symbol): Likewise.
ld/
	PR ld/12365
	* ldfile.c (ldfile_try_open_bfd): Move code creating and switching
	to plugin IR BFD..
	* ldmain.c (add_archive_element): ..and similar code here..
	* plugin.c (plugin_maybe_claim): ..to here.  New function.
	(plugin_call_claim_file): Make static.
	(asymbol_from_plugin_symbol): Set ELF st_shndx for common syms.
	(plugin_multiple_common): New function.
	(plugin_call_all_symbols_read): Hook in plugin_multiple_common.
	* plugin.h (plugin_call_claim_file): Don't declare.
	(plugin_maybe_claim): Declare.

Index: bfd/elfcode.h
===================================================================
RCS file: /cvs/src/src/bfd/elfcode.h,v
retrieving revision 1.105
diff -u -p -r1.105 elfcode.h
--- bfd/elfcode.h	14 Mar 2011 15:54:58 -0000	1.105
+++ bfd/elfcode.h	20 Apr 2011 00:12:16 -0000
@@ -1282,6 +1282,20 @@ elf_slurp_symbol_table (bfd *abfd, asymb
 	  else if (isym->st_shndx == SHN_COMMON)
 	    {
 	      sym->symbol.section = bfd_com_section_ptr;
+	      if ((abfd->flags & BFD_PLUGIN) != 0)
+		{
+		  asection *xc = bfd_get_section_by_name (abfd, "COMMON");
+
+		  if (xc == NULL)
+		    {
+		      flagword flags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
+					| SEC_EXCLUDE);
+		      xc = bfd_make_section_with_flags (abfd, "COMMON", flags);
+		      if (xc == NULL)
+			goto error_return;
+		    }
+		  sym->symbol.section = xc;
+		}
 	      /* Elf puts the alignment into the `value' field, and
 		 the size into the `size' field.  BFD wants to see the
 		 size in the value field, and doesn't care (at the
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.398
diff -u -p -r1.398 elflink.c
--- bfd/elflink.c	20 Apr 2011 00:11:31 -0000	1.398
+++ bfd/elflink.c	20 Apr 2011 00:12:21 -0000
@@ -3937,18 +3937,31 @@ error_free_dyn:
 	goto error_free_vers;
 
       if (isym->st_shndx == SHN_COMMON
-	  && ELF_ST_TYPE (isym->st_info) == STT_TLS
-	  && !info->relocatable)
+	  && (abfd->flags & BFD_PLUGIN) != 0)
+	{
+	  asection *xc = bfd_get_section_by_name (abfd, "COMMON");
+
+	  if (xc == NULL)
+	    {
+	      flagword sflags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
+				 | SEC_EXCLUDE);
+	      xc = bfd_make_section_with_flags (abfd, "COMMON", sflags);
+	      if (xc == NULL)
+		goto error_free_vers;
+	    }
+	  sec = xc;
+	}
+      else if (isym->st_shndx == SHN_COMMON
+	       && ELF_ST_TYPE (isym->st_info) == STT_TLS
+	       && !info->relocatable)
 	{
 	  asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
 
 	  if (tcomm == NULL)
 	    {
-	      tcomm = bfd_make_section_with_flags (abfd, ".tcommon",
-						   (SEC_ALLOC
-						    | SEC_IS_COMMON
-						    | SEC_LINKER_CREATED
-						    | SEC_THREAD_LOCAL));
+	      flagword sflags = (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_IS_COMMON
+				 | SEC_LINKER_CREATED);
+	      tcomm = bfd_make_section_with_flags (abfd, ".tcommon", sflags);
 	      if (tcomm == NULL)
 		goto error_free_vers;
 	    }
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.79
diff -u -p -r1.79 linker.c
--- bfd/linker.c	20 Apr 2011 00:11:32 -0000	1.79
+++ bfd/linker.c	20 Apr 2011 00:12:23 -0000
@@ -1296,7 +1296,7 @@ generic_link_check_archive_element (bfd 
 	  else
 	    h->u.c.p->section = bfd_make_section_old_way (symbfd,
 							  p->section->name);
-	  h->u.c.p->section->flags = SEC_ALLOC;
+	  h->u.c.p->section->flags |= SEC_ALLOC;
 	}
       else
 	{
@@ -1756,13 +1756,13 @@ _bfd_generic_link_add_one_symbol (struct
 	  if (section == bfd_com_section_ptr)
 	    {
 	      h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON");
-	      h->u.c.p->section->flags = SEC_ALLOC;
+	      h->u.c.p->section->flags |= SEC_ALLOC;
 	    }
 	  else if (section->owner != abfd)
 	    {
 	      h->u.c.p->section = bfd_make_section_old_way (abfd,
 							    section->name);
-	      h->u.c.p->section->flags = SEC_ALLOC;
+	      h->u.c.p->section->flags |= SEC_ALLOC;
 	    }
 	  else
 	    h->u.c.p->section = section;
@@ -1803,13 +1803,13 @@ _bfd_generic_link_add_one_symbol (struct
 		{
 		  h->u.c.p->section
 		    = bfd_make_section_old_way (abfd, "COMMON");
-		  h->u.c.p->section->flags = SEC_ALLOC;
+		  h->u.c.p->section->flags |= SEC_ALLOC;
 		}
 	      else if (section->owner != abfd)
 		{
 		  h->u.c.p->section
 		    = bfd_make_section_old_way (abfd, section->name);
-		  h->u.c.p->section->flags = SEC_ALLOC;
+		  h->u.c.p->section->flags |= SEC_ALLOC;
 		}
 	      else
 		h->u.c.p->section = section;
Index: ld/ldfile.c
===================================================================
RCS file: /cvs/src/src/ld/ldfile.c,v
retrieving revision 1.62
diff -u -p -r1.62 ldfile.c
--- ld/ldfile.c	17 Apr 2011 23:15:13 -0000	1.62
+++ ld/ldfile.c	20 Apr 2011 00:12:44 -0000
@@ -320,35 +320,12 @@ success:
       if (fd >= 0)
 	{
 	  struct ld_plugin_input_file file;
-	  int claimed = 0;
 
 	  file.name = attempt;
 	  file.offset = 0;
 	  file.filesize = lseek (fd, 0, SEEK_END);
 	  file.fd = fd;
-	  /* We create a dummy BFD, initially empty, to house
-	     whatever symbols the plugin may want to add.  */
-	  file.handle = plugin_get_ir_dummy_bfd (attempt, entry->the_bfd);
-	  if (plugin_call_claim_file (&file, &claimed))
-	    einfo (_("%P%F: %s: plugin reported error claiming file\n"),
-		   plugin_error_plugin ());
-	  /* fd belongs to us, not the plugin; but we don't need it.  */
-	  close (fd);
-	  if (claimed)
-	    {
-	      /* Discard the real file's BFD and substitute the dummy one.  */
-	      bfd_close (entry->the_bfd);
-	      entry->the_bfd = file.handle;
-	      entry->claimed = TRUE;
-	      bfd_make_readable (entry->the_bfd);
-	    }
-	  else
-	    {
-	      /* If plugin didn't claim the file, we don't need the dummy
-		 bfd.  Can't avoid speculatively creating it, alas.  */
-	      bfd_close_all_done (file.handle);
-	      entry->claimed = FALSE;
-	    }
+	  plugin_maybe_claim (&file, entry);
 	}
     }
 #endif /* ENABLE_PLUGINS */
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.152
diff -u -p -r1.152 ldmain.c
--- ld/ldmain.c	20 Apr 2011 00:11:33 -0000	1.152
+++ ld/ldmain.c	20 Apr 2011 00:12:45 -0000
@@ -813,7 +813,7 @@ add_archive_element (struct bfd_link_inf
       if (fd >= 0)
 	{
 	  struct ld_plugin_input_file file;
-	  int claimed = 0;
+
 	  /* Offset and filesize must refer to the individual archive
 	     member, not the whole file, and must exclude the header.
 	     Fortunately for us, that is how the data is stored in the
@@ -822,29 +822,12 @@ add_archive_element (struct bfd_link_inf
 	  file.offset = abfd->origin;
 	  file.filesize = arelt_size (abfd);
 	  file.fd = fd;
-	  /* We create a dummy BFD, initially empty, to house
-	     whatever symbols the plugin may want to add.  */
-	  file.handle = plugin_get_ir_dummy_bfd (abfd->filename, abfd);
-	  if (plugin_call_claim_file (&file, &claimed))
-	    einfo (_("%P%F: %s: plugin reported error claiming file\n"),
-		   plugin_error_plugin ());
-	  /* fd belongs to us, not the plugin; but we don't need it.  */
-	  close (fd);
-	  if (claimed)
+	  plugin_maybe_claim (&file, input);
+	  if (input->claimed)
 	    {
-	      /* Substitute the dummy BFD.  */
-	      input->the_bfd = file.handle;
-	      input->claimed = TRUE;
 	      input->claim_archive = TRUE;
-	      bfd_make_readable (input->the_bfd);
 	      *subsbfd = input->the_bfd;
 	    }
-	  else
-	    {
-	      /* Abandon the dummy BFD.  */
-	      bfd_close_all_done (file.handle);
-	      input->claimed = FALSE;
-	    }
 	}
     }
 #endif /* ENABLE_PLUGINS */
Index: ld/plugin.c
===================================================================
RCS file: /cvs/src/src/ld/plugin.c,v
retrieving revision 1.31
diff -u -p -r1.31 plugin.c
--- ld/plugin.c	20 Apr 2011 00:11:33 -0000	1.31
+++ ld/plugin.c	20 Apr 2011 00:12:45 -0000
@@ -140,6 +140,11 @@ static bfd_boolean plugin_multiple_defin
 					       bfd *nbfd,
 					       asection *nsec,
 					       bfd_vma nval);
+static bfd_boolean plugin_multiple_common (struct bfd_link_info *info,
+					   struct bfd_link_hash_entry *h,
+					   bfd *nbfd,
+					   enum bfd_link_hash_type ntype,
+					   bfd_vma nsize);
 
 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
 
@@ -312,7 +317,10 @@ asymbol_from_plugin_symbol (bfd *abfd, a
       asym->value = ldsym->size;
       /* For ELF targets, set alignment of common symbol to 1.  */
       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-	((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
+	{
+	  ((elf_symbol_type *) asym)->internal_elf_sym.st_shndx = SHN_COMMON;
+	  ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
+	}
       break;
 
     default:
@@ -812,7 +820,7 @@ plugin_load_plugins (void)
 }
 
 /* Call 'claim file' hook for all plugins.  */
-int
+static int
 plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
 {
   plugin_t *curplug = plugins_list;
@@ -835,6 +843,42 @@ plugin_call_claim_file (const struct ld_
   return plugin_error_p () ? -1 : 0;
 }
 
+void
+plugin_maybe_claim (struct ld_plugin_input_file *file,
+		    lang_input_statement_type *entry)
+{
+  int claimed = 0;
+
+  /* We create a dummy BFD, initially empty, to house whatever symbols
+     the plugin may want to add.  */
+  file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename,
+					  entry->the_bfd);
+  if (plugin_call_claim_file (file, &claimed))
+    einfo (_("%P%F: %s: plugin reported error claiming file\n"),
+	   plugin_error_plugin ());
+  /* fd belongs to us, not the plugin; but we don't need it.  */
+  close (file->fd);
+  if (claimed)
+    {
+      /* Discard the real file's BFD and substitute the dummy one.  */
+
+      /* BFD archive handling caches elements so we can't call
+	 bfd_close for archives.  */
+      if (entry->the_bfd->my_archive == NULL)
+	bfd_close (entry->the_bfd);
+      entry->the_bfd = file->handle;
+      entry->claimed = TRUE;
+      bfd_make_readable (entry->the_bfd);
+    }
+  else
+    {
+      /* If plugin didn't claim the file, we don't need the dummy bfd.
+	 Can't avoid speculatively creating it, alas.  */
+      bfd_close_all_done (file->handle);
+      entry->claimed = FALSE;
+    }
+}
+
 /* Call 'all symbols read' hook for all plugins.  */
 int
 plugin_call_all_symbols_read (void)
@@ -845,6 +889,7 @@ plugin_call_all_symbols_read (void)
   no_more_claiming = TRUE;
 
   plugin_callbacks.multiple_definition = &plugin_multiple_definition;
+  plugin_callbacks.multiple_common = &plugin_multiple_common;
 
   while (curplug)
     {
@@ -955,3 +1000,22 @@ plugin_multiple_definition (struct bfd_l
 
   return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval);
 }
+
+static bfd_boolean
+plugin_multiple_common (struct bfd_link_info *info,
+			struct bfd_link_hash_entry *h,
+			bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize)
+{
+  if (h->type == bfd_link_hash_common
+      && is_ir_dummy_bfd (h->u.c.p->section->owner)
+      && ntype == bfd_link_hash_common
+      && !is_ir_dummy_bfd (nbfd))
+    {
+      /* Arrange to have it replaced.  */
+      ASSERT (nsize != 0);
+      h->u.c.size = 0;
+      return TRUE;
+    }
+
+  return (*orig_callbacks->multiple_common) (info, h, nbfd, ntype, nsize);
+}
Index: ld/plugin.h
===================================================================
RCS file: /cvs/src/src/ld/plugin.h,v
retrieving revision 1.8
diff -u -p -r1.8 plugin.h
--- ld/plugin.h	17 Apr 2011 23:15:13 -0000	1.8
+++ ld/plugin.h	20 Apr 2011 00:12:45 -0000
@@ -50,8 +50,8 @@ extern int plugin_load_plugins (void);
 extern const char *plugin_error_plugin (void);
 
 /* Call 'claim file' hook for all plugins.  */
-extern int plugin_call_claim_file (const struct ld_plugin_input_file *file,
-				   int *claimed);
+extern void plugin_maybe_claim (struct ld_plugin_input_file *,
+				lang_input_statement_type *);
 
 /* Call 'all symbols read' hook for all plugins.  */
 extern int plugin_call_all_symbols_read (void);

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Change bfd_link_hash_entry.type to a bitfield?
@ 2011-04-21  1:58 Alan Modra
  2011-04-21  2:55 ` H.J. Lu
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Modra @ 2011-04-21  1:58 UTC (permalink / raw)
  To: binutils

How do people feel about poking some flags into bfd_link_hash_entry?
This can be done without increasing the size of the struct, since
"type" is an unsigned int but only needs 3 bits.  The negative side is
that hosts without efficient byte read access will see a linker
slowdown.  "type" is the most used field of bfd_link_hash_entry.
On the positive side, this would allow the linker lto plugin code to
lose a potentially very large symbol hash table.  Also, other fields
from elf_link_hash_entry and coff_link_hash_entry could move into
bfd_link_hash_entry, reducing the size of the linker hash table.

include/
	* bfdlink.h (ENUM_BITFIELD): Define.
	(struct bfd_link_hash_entry): Make "type" a bitfield.  Add "non_ir_ref".
	(struct bfd_link_callbacks <notice>): Pass bfd_link_hash_entry pointer
	rather than "name".
bfd/
	* coff-aux.c (coff_m68k_aux_link_add_one_symbol): Update "notice" call.
	* linker.c (_bfd_link_hash_newfunc): Clear bitfields.
	(_bfd_generic_link_add_one_symbol): Update "notice" call.
ld/
	* ldmain.c (notice): Delete "name" param, add "h".
	* plugin.c (plugin_notice): Likewise.  Set non_ir_ref.
	(non_ironly_hash, init_non_ironly_hash): Delete.
	(is_visible_from_outside): Traverse entry_symbol chain.
	(get_symbols): Use non_ir_ref flag rather than hash lookup.

Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.83
diff -u -p -r1.83 bfdlink.h
--- include/bfdlink.h	20 Apr 2011 00:11:29 -0000	1.83
+++ include/bfdlink.h	20 Apr 2011 07:58:23 -0000
@@ -24,6 +24,12 @@
 #ifndef BFDLINK_H
 #define BFDLINK_H
 
+#if (__GNUC__ * 1000 + __GNUC_MINOR__ > 2000)
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
 /* Which symbols to strip during a link.  */
 enum bfd_link_strip
 {
@@ -91,7 +97,9 @@ struct bfd_link_hash_entry
   struct bfd_hash_entry root;
 
   /* Type of this entry.  */
-  enum bfd_link_hash_type type;
+  ENUM_BITFIELD (bfd_link_hash_type) type : 8;
+
+  unsigned int non_ir_ref : 1;
 
   /* A union of information depending upon the type.  */
   union
@@ -570,11 +578,11 @@ struct bfd_link_callbacks
     (struct bfd_link_info *, const char *name,
      bfd *abfd, asection *section, bfd_vma address);
   /* A function which is called when a symbol in notice_hash is
-     defined or referenced.  NAME is the symbol.  ABFD, SECTION and
-     ADDRESS are the value of the symbol.  If SECTION is
+     defined or referenced.  H is the symbol.  ABFD, SECTION and
+     ADDRESS are the (new) value of the symbol.  If SECTION is
      bfd_und_section, this is a reference.  */
   bfd_boolean (*notice)
-    (struct bfd_link_info *, const char *name,
+    (struct bfd_link_info *, struct bfd_link_hash_entry *h,
      bfd *abfd, asection *section, bfd_vma address);
   /* Error or warning link info message.  */
   void (*einfo)
Index: bfd/coff-aux.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-aux.c,v
retrieving revision 1.10
diff -u -p -r1.10 coff-aux.c
--- bfd/coff-aux.c	2 Sep 2009 07:18:36 -0000	1.10
+++ bfd/coff-aux.c	20 Apr 2011 07:57:20 -0000
@@ -105,7 +105,7 @@ coff_m68k_aux_link_add_one_symbol (info,
 	  && (bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE)
 	      != (struct bfd_hash_entry *) NULL))
 	{
-	  if (! (*info->callbacks->notice) (info, name, abfd, section, value))
+	  if (! (*info->callbacks->notice) (info, h, abfd, section, value))
 	    return FALSE;
 	}
 
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.80
diff -u -p -r1.80 linker.c
--- bfd/linker.c	20 Apr 2011 00:22:08 -0000	1.80
+++ bfd/linker.c	20 Apr 2011 07:57:50 -0000
@@ -465,10 +465,8 @@ _bfd_link_hash_newfunc (struct bfd_hash_
       struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry;
 
       /* Initialize the local fields.  */
-      h->type = bfd_link_hash_new;
-      memset (&h->u.undef.next, 0,
-	      (sizeof (struct bfd_link_hash_entry)
-	       - offsetof (struct bfd_link_hash_entry, u.undef.next)));
+      memset ((char *) &h->root + sizeof (h->root), 0,
+	      sizeof (*h) - sizeof (h->root));
     }
 
   return entry;
@@ -1609,8 +1608,7 @@ _bfd_generic_link_add_one_symbol (struct
       || (info->notice_hash != NULL
 	  && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
     {
-      if (! (*info->callbacks->notice) (info, h->root.string, abfd, section,
-					value))
+      if (! (*info->callbacks->notice) (info, h, abfd, section, value))
 	return FALSE;
     }
 
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.153
diff -u -p -r1.153 ldmain.c
--- ld/ldmain.c	20 Apr 2011 00:22:08 -0000	1.153
+++ ld/ldmain.c	20 Apr 2011 07:58:25 -0000
@@ -150,7 +150,8 @@ static bfd_boolean reloc_dangerous
 static bfd_boolean unattached_reloc
   (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
 static bfd_boolean notice
-  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
+  (struct bfd_link_info *, struct bfd_link_hash_entry *,
+   bfd *, asection *, bfd_vma);
 
 static struct bfd_link_callbacks link_callbacks =
 {
@@ -1479,18 +1480,21 @@ unattached_reloc (struct bfd_link_info *
 
 static bfd_boolean
 notice (struct bfd_link_info *info,
-	const char *name,
+	struct bfd_link_hash_entry *h,
 	bfd *abfd,
 	asection *section,
 	bfd_vma value)
 {
-  if (name == NULL)
+  const char *name;
+
+  if (h == NULL)
     {
       if (command_line.cref || nocrossref_list != NULL)
 	return handle_asneeded_cref (abfd, (enum notice_asneeded_action) value);
       return TRUE;
     }
 
+  name = h->root.string;
   if (info->notice_hash != NULL
       && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)
     {
Index: ld/plugin.c
===================================================================
RCS file: /cvs/src/src/ld/plugin.c,v
retrieving revision 1.32
diff -u -p -r1.32 plugin.c
--- ld/plugin.c	20 Apr 2011 00:22:08 -0000	1.32
+++ ld/plugin.c	20 Apr 2011 07:58:26 -0000
@@ -90,13 +90,6 @@ static plugin_t *called_plugin = NULL;
 /* Last plugin to cause an error, if any.  */
 static const char *error_plugin = NULL;
 
-/* A hash table that records symbols referenced by non-IR files.  Used
-   at get_symbols time to determine whether any prevailing defs from
-   IR files are referenced only from other IR files, so tthat we can
-   we can distinguish the LDPR_PREVAILING_DEF and LDPR_PREVAILING_DEF_IRONLY
-   cases when establishing symbol resolutions.  */
-static struct bfd_hash_table *non_ironly_hash = NULL;
-
 /* State of linker "notice" interface before we poked at it.  */
 static bfd_boolean orig_notice_all;
 
@@ -133,7 +126,7 @@ static const size_t tv_header_size = ARR
 
 /* Forward references.  */
 static bfd_boolean plugin_notice (struct bfd_link_info *info,
-				  const char *name, bfd *abfd,
+				  struct bfd_link_hash_entry *h, bfd *abfd,
 				  asection *section, bfd_vma value);
 static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info,
 					       struct bfd_link_hash_entry *h,
@@ -438,6 +431,8 @@ static inline bfd_boolean
 is_visible_from_outside (struct ld_plugin_symbol *lsym, asection *section,
 			 struct bfd_link_hash_entry *blhe)
 {
+  struct bfd_sym_chain *sym;
+
   /* Section's owner may be NULL if it is the absolute
      section, fortunately is_ir_dummy_bfd handles that.  */
   if (!is_ir_dummy_bfd (section->owner))
@@ -466,6 +461,12 @@ is_visible_from_outside (struct ld_plugi
       return (lsym->visibility == LDPV_DEFAULT
 	      || lsym->visibility == LDPV_PROTECTED);
     }
+
+  for (sym = &entry_symbol; sym != NULL; sym = sym->next)
+    if (sym->name
+	&& strcmp (sym->name, blhe->root.string) == 0)
+      return TRUE;
+
   return FALSE;
 }
 
@@ -520,9 +521,8 @@ get_symbols (const void *handle, int nsy
 	 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.  */
-      ironly = (!is_visible_from_outside (&syms[n], owner_sec, blhe)
-		&& !bfd_hash_lookup (non_ironly_hash, syms[n].name,
-				     FALSE, FALSE));
+      ironly = !(blhe->non_ir_ref
+		 || is_visible_from_outside (&syms[n], owner_sec, blhe));
 
       /* If it was originally undefined or common, then it has been
 	 resolved; determine how.  */
@@ -740,27 +740,6 @@ plugin_active_plugins_p (void)
   return plugins_list != NULL;
 }
 
-/* Init the non_ironly hash table.  */
-static void
-init_non_ironly_hash (void)
-{
-  struct bfd_sym_chain *sym;
-
-  non_ironly_hash
-    = (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table));
-  if (!bfd_hash_table_init_n (non_ironly_hash,
-			      bfd_hash_newfunc,
-			      sizeof (struct bfd_hash_entry),
-			      61))
-    einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
-
-  for (sym = &entry_symbol; sym != NULL; sym = sym->next)
-    if (sym->name
-	&& !bfd_hash_lookup (non_ironly_hash, sym->name, TRUE, TRUE))
-      einfo (_("%P%X: hash table failure adding symbol %s\n"),
-	     sym->name);
-}
-
 /* Load up and initialise all plugins after argument parsing.  */
 int
 plugin_load_plugins (void)
@@ -814,7 +793,6 @@ plugin_load_plugins (void)
   plugin_callbacks.notice = &plugin_notice;
   link_info.notice_all = TRUE;
   link_info.callbacks = &plugin_callbacks;
-  init_non_ironly_hash ();
 
   return 0;
 }
@@ -934,20 +912,18 @@ plugin_call_cleanup (void)
 
 /* To determine which symbols should be resolved LDPR_PREVAILING_DEF
    and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
-   the linker adds them to the linker hash table.  If we see a symbol
-   being referenced from a non-IR file, we add it to the non_ironly hash
-   table.  If we can't find it there at get_symbols time, we know that
-   it was referenced only by IR files.  We have to notice_all symbols,
-   because we won't necessarily know until later which ones will be
-   contributed by IR files.  */
+   the linker adds them to the linker hash table.  Mark those
+   referenced from a non-IR file with non_ir_ref.  We have to
+   notice_all symbols, because we won't necessarily know until later
+   which ones will be contributed by IR files.  */
 static bfd_boolean
 plugin_notice (struct bfd_link_info *info,
-	       const char *name,
+	       struct bfd_link_hash_entry *h,
 	       bfd *abfd,
 	       asection *section,
 	       bfd_vma value)
 {
-  if (name != NULL)
+  if (h != NULL)
     {
       /* No further processing if this def/ref is from an IR dummy BFD.  */
       if (is_ir_dummy_bfd (abfd))
@@ -957,21 +933,16 @@ plugin_notice (struct bfd_link_info *inf
 	 pointing to the undefined section (according to the bfd
 	 linker notice callback interface definition).  */
       if (bfd_is_und_section (section))
-	{
-	  /* This is a ref from a non-IR file, so note the ref'd
-	     symbol in the non-IR-only hash.  */
-	  if (!bfd_hash_lookup (non_ironly_hash, name, TRUE, TRUE))
-	    einfo (_("%P%X: %s: hash table failure adding symbol %s\n"),
-		   abfd->filename, name);
-	}
+	h->non_ir_ref = TRUE;
     }
 
   /* Continue with cref/nocrossref/trace-sym processing.  */
-  if (name == NULL
+  if (h == NULL
       || orig_notice_all
       || (info->notice_hash != NULL
-	  && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
-    return (*orig_callbacks->notice) (info, name, abfd, section, value);
+	  && bfd_hash_lookup (info->notice_hash, h->root.string,
+			      FALSE, FALSE) != NULL))
+    return (*orig_callbacks->notice) (info, h, abfd, section, value);
   return TRUE;
 }
 

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Change bfd_link_hash_entry.type to a bitfield?
  2011-04-21  1:58 Change bfd_link_hash_entry.type to a bitfield? Alan Modra
@ 2011-04-21  2:55 ` H.J. Lu
  2011-04-21 11:55   ` Richard Sandiford
  0 siblings, 1 reply; 11+ messages in thread
From: H.J. Lu @ 2011-04-21  2:55 UTC (permalink / raw)
  To: binutils

On Wed, Apr 20, 2011 at 6:57 PM, Alan Modra <amodra@gmail.com> wrote:
> How do people feel about poking some flags into bfd_link_hash_entry?
> This can be done without increasing the size of the struct, since
> "type" is an unsigned int but only needs 3 bits.  The negative side is
> that hosts without efficient byte read access will see a linker
> slowdown.  "type" is the most used field of bfd_link_hash_entry.
> On the positive side, this would allow the linker lto plugin code to
> lose a potentially very large symbol hash table.  Also, other fields
> from elf_link_hash_entry and coff_link_hash_entry could move into
> bfd_link_hash_entry, reducing the size of the linker hash table.
>

I like it,

-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Change bfd_link_hash_entry.type to a bitfield?
  2011-04-21  2:55 ` H.J. Lu
@ 2011-04-21 11:55   ` Richard Sandiford
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Sandiford @ 2011-04-21 11:55 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:
> On Wed, Apr 20, 2011 at 6:57 PM, Alan Modra <amodra@gmail.com> wrote:
>> How do people feel about poking some flags into bfd_link_hash_entry?
>> This can be done without increasing the size of the struct, since
>> "type" is an unsigned int but only needs 3 bits.  The negative side is
>> that hosts without efficient byte read access will see a linker
>> slowdown.  "type" is the most used field of bfd_link_hash_entry.
>> On the positive side, this would allow the linker lto plugin code to
>> lose a potentially very large symbol hash table.  Also, other fields
>> from elf_link_hash_entry and coff_link_hash_entry could move into
>> bfd_link_hash_entry, reducing the size of the linker hash table.
>>
>
> I like it,

+1.  How about defining ENUM_BITFIELD in ansidecl.h, so that other
headers could use it too?

Richard

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PR12365 and common symbols
  2011-04-20  0:25 PR12365 and common symbols Alan Modra
@ 2011-04-22 22:33 ` H.J. Lu
  2011-04-24 10:14   ` Change bfd_link_hash_entry.type to a bitfield? Alan Modra
  0 siblings, 1 reply; 11+ messages in thread
From: H.J. Lu @ 2011-04-22 22:33 UTC (permalink / raw)
  To: binutils; +Cc: Alan Modra

On Tue, Apr 19, 2011 at 5:25 PM, Alan Modra <amodra@gmail.com> wrote:
> This patch makes ld keep IR-only common symbols in their own specially
> marked common section, so that ld can report an error if such a symbol
> is referenced.
>
> bfd/
>        PR ld/12365
>        * elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols
>        in their own common section.
>        * elflink.c (elf_link_add_object_symbols): Likewise.
>        * linker.c (generic_link_check_archive_element): Don't lose flags
>        if common section is pre-existing.
>        (_bfd_generic_link_add_one_symbol): Likewise.
> ld/
>        PR ld/12365
>        * ldfile.c (ldfile_try_open_bfd): Move code creating and switching
>        to plugin IR BFD..
>        * ldmain.c (add_archive_element): ..and similar code here..
>        * plugin.c (plugin_maybe_claim): ..to here.  New function.
>        (plugin_call_claim_file): Make static.
>        (asymbol_from_plugin_symbol): Set ELF st_shndx for common syms.
>        (plugin_multiple_common): New function.
>        (plugin_call_all_symbols_read): Hook in plugin_multiple_common.
>        * plugin.h (plugin_call_claim_file): Don't declare.
>        (plugin_maybe_claim): Declare.
>

BFD linker still doesn't work right:

http://www.sourceware.org/bugzilla/show_bug.cgi?id=12696


-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Change bfd_link_hash_entry.type to a bitfield?
  2011-04-22 22:33 ` H.J. Lu
@ 2011-04-24 10:14   ` Alan Modra
  2011-04-24 14:49     ` [patch] ENUM_BITFIELD broke GDB [Re: Change bfd_link_hash_entry.type to a bitfield?] Jan Kratochvil
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Modra @ 2011-04-24 10:14 UTC (permalink / raw)
  To: H.J. Lu, binutils, richard.sandiford

On Thu, Apr 21, 2011 at 12:54:57PM +0100, Richard Sandiford wrote:
> > On Wed, Apr 20, 2011 at 6:57 PM, Alan Modra <amodra@gmail.com> wrote:
> >> How do people feel about poking some flags into bfd_link_hash_entry?
> >> This can be done without increasing the size of the struct, since
> >> "type" is an unsigned int but only needs 3 bits.  The negative side is
> >> that hosts without efficient byte read access will see a linker
> >> slowdown.  "type" is the most used field of bfd_link_hash_entry.
> >> On the positive side, this would allow the linker lto plugin code to
> >> lose a potentially very large symbol hash table.  Also, other fields
> >> from elf_link_hash_entry and coff_link_hash_entry could move into
> >> bfd_link_hash_entry, reducing the size of the linker hash table.
> >>
> >
> "H.J. Lu" <hjl.tools@gmail.com> writes:
> > I like it,
> 
> +1.  How about defining ENUM_BITFIELD in ansidecl.h, so that other
> headers could use it too?

That would be a good idea.  Maybe for a later patch..

This version fixes PR 12696 as well.  Committed.

include/
	PR ld/12365
	PR ld/12696
	* bfdlink.h (ENUM_BITFIELD): Define.
	(struct bfd_link_hash_entry): Make "type" a bitfield.  Add "non_ir_ref".
	(struct bfd_link_callbacks <notice>): Pass bfd_link_hash_entry pointer
	rather than "name".
bfd/
	PR ld/12365
	PR ld/12696
	* coff-aux.c (coff_m68k_aux_link_add_one_symbol): Update "notice" call.
	* linker.c (_bfd_link_hash_newfunc): Clear bitfields.
	(_bfd_generic_link_add_one_symbol): Update "notice" call.
	* elflink.c (_bfd_elf_merge_symbol): Don't skip weak redefs when
	it is a redef of an IR symbol in a real BFD.
ld/
	PR ld/12365
	PR ld/12696
	* ldmain.c (notice): Delete "name" param, add "h".
	* plugin.c (plugin_notice): Likewise.  Set non_ir_ref.  Handle
	redefinitions of IR symbols in real BFDs.
	(plugin_multiple_definition, plugin_multiple_common): Delete.
	(non_ironly_hash, init_non_ironly_hash): Delete.
	(is_visible_from_outside): Traverse entry_symbol chain.
	(get_symbols): Use non_ir_ref flag rather than hash lookup.

Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.83
diff -u -p -r1.83 bfdlink.h
--- include/bfdlink.h	20 Apr 2011 00:11:29 -0000	1.83
+++ include/bfdlink.h	24 Apr 2011 07:35:37 -0000
@@ -24,6 +24,12 @@
 #ifndef BFDLINK_H
 #define BFDLINK_H
 
+#if (__GNUC__ * 1000 + __GNUC_MINOR__ > 2000)
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
 /* Which symbols to strip during a link.  */
 enum bfd_link_strip
 {
@@ -91,7 +97,9 @@ struct bfd_link_hash_entry
   struct bfd_hash_entry root;
 
   /* Type of this entry.  */
-  enum bfd_link_hash_type type;
+  ENUM_BITFIELD (bfd_link_hash_type) type : 8;
+
+  unsigned int non_ir_ref : 1;
 
   /* A union of information depending upon the type.  */
   union
@@ -570,11 +578,11 @@ struct bfd_link_callbacks
     (struct bfd_link_info *, const char *name,
      bfd *abfd, asection *section, bfd_vma address);
   /* A function which is called when a symbol in notice_hash is
-     defined or referenced.  NAME is the symbol.  ABFD, SECTION and
-     ADDRESS are the value of the symbol.  If SECTION is
+     defined or referenced.  H is the symbol.  ABFD, SECTION and
+     ADDRESS are the (new) value of the symbol.  If SECTION is
      bfd_und_section, this is a reference.  */
   bfd_boolean (*notice)
-    (struct bfd_link_info *, const char *name,
+    (struct bfd_link_info *, struct bfd_link_hash_entry *h,
      bfd *abfd, asection *section, bfd_vma address);
   /* Error or warning link info message.  */
   void (*einfo)
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.401
diff -u -p -r1.401 elflink.c
--- bfd/elflink.c	20 Apr 2011 07:17:01 -0000	1.401
+++ bfd/elflink.c	24 Apr 2011 07:35:20 -0000
@@ -1427,7 +1427,10 @@ _bfd_elf_merge_symbol (bfd *abfd,
   /* Skip weak definitions of symbols that are already defined.  */
   if (newdef && olddef && newweak)
     {
-      *skip = TRUE;
+      /* Don't skip new non-IR weak syms.  */
+      if (!((oldbfd->flags & BFD_PLUGIN) != 0
+	    && (abfd->flags & BFD_PLUGIN) == 0))
+	*skip = TRUE;
 
       /* Merge st_other.  If the symbol already has a dynamic index,
 	 but visibility says it should not be visible, turn it into a
Index: bfd/coff-aux.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-aux.c,v
retrieving revision 1.10
diff -u -p -r1.10 coff-aux.c
--- bfd/coff-aux.c	2 Sep 2009 07:18:36 -0000	1.10
+++ bfd/coff-aux.c	24 Apr 2011 07:35:10 -0000
@@ -105,7 +105,7 @@ coff_m68k_aux_link_add_one_symbol (info,
 	  && (bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE)
 	      != (struct bfd_hash_entry *) NULL))
 	{
-	  if (! (*info->callbacks->notice) (info, name, abfd, section, value))
+	  if (! (*info->callbacks->notice) (info, h, abfd, section, value))
 	    return FALSE;
 	}
 
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.80
diff -u -p -r1.80 linker.c
--- bfd/linker.c	20 Apr 2011 00:22:08 -0000	1.80
+++ bfd/linker.c	24 Apr 2011 07:35:23 -0000
@@ -465,10 +465,8 @@ _bfd_link_hash_newfunc (struct bfd_hash_
       struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry;
 
       /* Initialize the local fields.  */
-      h->type = bfd_link_hash_new;
-      memset (&h->u.undef.next, 0,
-	      (sizeof (struct bfd_link_hash_entry)
-	       - offsetof (struct bfd_link_hash_entry, u.undef.next)));
+      memset ((char *) &h->root + sizeof (h->root), 0,
+	      sizeof (*h) - sizeof (h->root));
     }
 
   return entry;
@@ -1609,8 +1607,7 @@ _bfd_generic_link_add_one_symbol (struct
       || (info->notice_hash != NULL
 	  && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
     {
-      if (! (*info->callbacks->notice) (info, h->root.string, abfd, section,
-					value))
+      if (! (*info->callbacks->notice) (info, h, abfd, section, value))
 	return FALSE;
     }
 
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.153
diff -u -p -r1.153 ldmain.c
--- ld/ldmain.c	20 Apr 2011 00:22:08 -0000	1.153
+++ ld/ldmain.c	24 Apr 2011 07:35:38 -0000
@@ -150,7 +150,8 @@ static bfd_boolean reloc_dangerous
 static bfd_boolean unattached_reloc
   (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
 static bfd_boolean notice
-  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
+  (struct bfd_link_info *, struct bfd_link_hash_entry *,
+   bfd *, asection *, bfd_vma);
 
 static struct bfd_link_callbacks link_callbacks =
 {
@@ -1479,18 +1480,21 @@ unattached_reloc (struct bfd_link_info *
 
 static bfd_boolean
 notice (struct bfd_link_info *info,
-	const char *name,
+	struct bfd_link_hash_entry *h,
 	bfd *abfd,
 	asection *section,
 	bfd_vma value)
 {
-  if (name == NULL)
+  const char *name;
+
+  if (h == NULL)
     {
       if (command_line.cref || nocrossref_list != NULL)
 	return handle_asneeded_cref (abfd, (enum notice_asneeded_action) value);
       return TRUE;
     }
 
+  name = h->root.string;
   if (info->notice_hash != NULL
       && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)
     {
Index: ld/plugin.c
===================================================================
RCS file: /cvs/src/src/ld/plugin.c,v
retrieving revision 1.32
diff -u -p -r1.32 plugin.c
--- ld/plugin.c	20 Apr 2011 00:22:08 -0000	1.32
+++ ld/plugin.c	24 Apr 2011 07:35:38 -0000
@@ -90,13 +90,6 @@ static plugin_t *called_plugin = NULL;
 /* Last plugin to cause an error, if any.  */
 static const char *error_plugin = NULL;
 
-/* A hash table that records symbols referenced by non-IR files.  Used
-   at get_symbols time to determine whether any prevailing defs from
-   IR files are referenced only from other IR files, so tthat we can
-   we can distinguish the LDPR_PREVAILING_DEF and LDPR_PREVAILING_DEF_IRONLY
-   cases when establishing symbol resolutions.  */
-static struct bfd_hash_table *non_ironly_hash = NULL;
-
 /* State of linker "notice" interface before we poked at it.  */
 static bfd_boolean orig_notice_all;
 
@@ -133,18 +126,8 @@ static const size_t tv_header_size = ARR
 
 /* Forward references.  */
 static bfd_boolean plugin_notice (struct bfd_link_info *info,
-				  const char *name, bfd *abfd,
+				  struct bfd_link_hash_entry *h, bfd *abfd,
 				  asection *section, bfd_vma value);
-static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info,
-					       struct bfd_link_hash_entry *h,
-					       bfd *nbfd,
-					       asection *nsec,
-					       bfd_vma nval);
-static bfd_boolean plugin_multiple_common (struct bfd_link_info *info,
-					   struct bfd_link_hash_entry *h,
-					   bfd *nbfd,
-					   enum bfd_link_hash_type ntype,
-					   bfd_vma nsize);
 
 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
 
@@ -438,6 +421,8 @@ static inline bfd_boolean
 is_visible_from_outside (struct ld_plugin_symbol *lsym, asection *section,
 			 struct bfd_link_hash_entry *blhe)
 {
+  struct bfd_sym_chain *sym;
+
   /* Section's owner may be NULL if it is the absolute
      section, fortunately is_ir_dummy_bfd handles that.  */
   if (!is_ir_dummy_bfd (section->owner))
@@ -466,6 +451,12 @@ is_visible_from_outside (struct ld_plugi
       return (lsym->visibility == LDPV_DEFAULT
 	      || lsym->visibility == LDPV_PROTECTED);
     }
+
+  for (sym = &entry_symbol; sym != NULL; sym = sym->next)
+    if (sym->name
+	&& strcmp (sym->name, blhe->root.string) == 0)
+      return TRUE;
+
   return FALSE;
 }
 
@@ -520,9 +511,8 @@ get_symbols (const void *handle, int nsy
 	 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.  */
-      ironly = (!is_visible_from_outside (&syms[n], owner_sec, blhe)
-		&& !bfd_hash_lookup (non_ironly_hash, syms[n].name,
-				     FALSE, FALSE));
+      ironly = !(blhe->non_ir_ref
+		 || is_visible_from_outside (&syms[n], owner_sec, blhe));
 
       /* If it was originally undefined or common, then it has been
 	 resolved; determine how.  */
@@ -740,27 +730,6 @@ plugin_active_plugins_p (void)
   return plugins_list != NULL;
 }
 
-/* Init the non_ironly hash table.  */
-static void
-init_non_ironly_hash (void)
-{
-  struct bfd_sym_chain *sym;
-
-  non_ironly_hash
-    = (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table));
-  if (!bfd_hash_table_init_n (non_ironly_hash,
-			      bfd_hash_newfunc,
-			      sizeof (struct bfd_hash_entry),
-			      61))
-    einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
-
-  for (sym = &entry_symbol; sym != NULL; sym = sym->next)
-    if (sym->name
-	&& !bfd_hash_lookup (non_ironly_hash, sym->name, TRUE, TRUE))
-      einfo (_("%P%X: hash table failure adding symbol %s\n"),
-	     sym->name);
-}
-
 /* Load up and initialise all plugins after argument parsing.  */
 int
 plugin_load_plugins (void)
@@ -814,7 +783,6 @@ plugin_load_plugins (void)
   plugin_callbacks.notice = &plugin_notice;
   link_info.notice_all = TRUE;
   link_info.callbacks = &plugin_callbacks;
-  init_non_ironly_hash ();
 
   return 0;
 }
@@ -888,9 +856,6 @@ plugin_call_all_symbols_read (void)
   /* Disable any further file-claiming.  */
   no_more_claiming = TRUE;
 
-  plugin_callbacks.multiple_definition = &plugin_multiple_definition;
-  plugin_callbacks.multiple_common = &plugin_multiple_common;
-
   while (curplug)
     {
       if (curplug->all_symbols_read_handler)
@@ -934,88 +899,47 @@ plugin_call_cleanup (void)
 
 /* To determine which symbols should be resolved LDPR_PREVAILING_DEF
    and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
-   the linker adds them to the linker hash table.  If we see a symbol
-   being referenced from a non-IR file, we add it to the non_ironly hash
-   table.  If we can't find it there at get_symbols time, we know that
-   it was referenced only by IR files.  We have to notice_all symbols,
-   because we won't necessarily know until later which ones will be
-   contributed by IR files.  */
+   the linker adds them to the linker hash table.  Mark those
+   referenced from a non-IR file with non_ir_ref.  We have to
+   notice_all symbols, because we won't necessarily know until later
+   which ones will be contributed by IR files.  */
 static bfd_boolean
 plugin_notice (struct bfd_link_info *info,
-	       const char *name,
+	       struct bfd_link_hash_entry *h,
 	       bfd *abfd,
 	       asection *section,
 	       bfd_vma value)
 {
-  if (name != NULL)
+  if (h != NULL)
     {
       /* No further processing if this def/ref is from an IR dummy BFD.  */
       if (is_ir_dummy_bfd (abfd))
 	return TRUE;
 
-      /* We only care about refs, not defs, indicated by section
-	 pointing to the undefined section (according to the bfd
-	 linker notice callback interface definition).  */
+      /* If this is a ref, set non_ir_ref.  */
       if (bfd_is_und_section (section))
-	{
-	  /* This is a ref from a non-IR file, so note the ref'd
-	     symbol in the non-IR-only hash.  */
-	  if (!bfd_hash_lookup (non_ironly_hash, name, TRUE, TRUE))
-	    einfo (_("%P%X: %s: hash table failure adding symbol %s\n"),
-		   abfd->filename, name);
-	}
+	h->non_ir_ref = TRUE;
+
+      /* Otherwise, it must be a new def.  Ensure any symbol defined
+	 in an IR dummy BFD takes on a new value from a real BFD.
+	 Weak symbols are not normally overridden by a new weak
+	 definition, and strong symbols will normally cause multiple
+	 definition errors.  Avoid this by making the symbol appear
+	 to be undefined.  */
+      else if (((h->type == bfd_link_hash_defweak
+		 || h->type == bfd_link_hash_defined)
+		&& is_ir_dummy_bfd (h->u.def.section->owner))
+	       || (h->type == bfd_link_hash_common
+		   && is_ir_dummy_bfd (h->u.c.p->section->owner)))
+	h->type = bfd_link_hash_undefweak;
     }
 
   /* Continue with cref/nocrossref/trace-sym processing.  */
-  if (name == NULL
+  if (h == NULL
       || orig_notice_all
       || (info->notice_hash != NULL
-	  && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
-    return (*orig_callbacks->notice) (info, name, abfd, section, value);
+	  && bfd_hash_lookup (info->notice_hash, h->root.string,
+			      FALSE, FALSE) != NULL))
+    return (*orig_callbacks->notice) (info, h, abfd, section, value);
   return TRUE;
 }
-
-/* When we add new object files to the link at all symbols read time,
-   these contain the real code and symbols generated from the IR files,
-   and so duplicate all the definitions already supplied by the dummy
-   IR-only BFDs that we created at claim files time.  We use the linker's
-   multiple-definitions callback hook to fix up the clash, discarding
-   the symbol from the IR-only BFD in favour of the symbol from the
-   real BFD.  We return true if this was not-really-a-clash because
-   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,
-			    struct bfd_link_hash_entry *h,
-			    bfd *nbfd, asection *nsec, bfd_vma nval)
-{
-  if (h->type == bfd_link_hash_defined
-      && is_ir_dummy_bfd (h->u.def.section->owner))
-    {
-      /* Replace it with new details.  */
-      h->u.def.section = nsec;
-      h->u.def.value = nval;
-      return TRUE;
-    }
-
-  return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval);
-}
-
-static bfd_boolean
-plugin_multiple_common (struct bfd_link_info *info,
-			struct bfd_link_hash_entry *h,
-			bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize)
-{
-  if (h->type == bfd_link_hash_common
-      && is_ir_dummy_bfd (h->u.c.p->section->owner)
-      && ntype == bfd_link_hash_common
-      && !is_ir_dummy_bfd (nbfd))
-    {
-      /* Arrange to have it replaced.  */
-      ASSERT (nsize != 0);
-      h->u.c.size = 0;
-      return TRUE;
-    }
-
-  return (*orig_callbacks->multiple_common) (info, h, nbfd, ntype, nsize);
-}

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch] ENUM_BITFIELD broke GDB  [Re: Change bfd_link_hash_entry.type to a bitfield?]
  2011-04-24 10:14   ` Change bfd_link_hash_entry.type to a bitfield? Alan Modra
@ 2011-04-24 14:49     ` Jan Kratochvil
  2011-04-24 15:28       ` Andreas Schwab
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Kratochvil @ 2011-04-24 14:49 UTC (permalink / raw)
  To: binutils; +Cc: H.J. Lu, richard.sandiford

On Sun, 24 Apr 2011 12:14:01 +0200, Alan Modra wrote:
> include/
> 	PR ld/12365
> 	PR ld/12696
> 	* bfdlink.h (ENUM_BITFIELD): Define.

This broke GDB HEAD:
In file included from ../bfd/elf-bfd.h:30:0,
                 from arm-symbian-tdep.c:27:
./../include/bfdlink.h:28:0: error: "ENUM_BITFIELD" redefined [-Werror]
defs.h:278:0: note: this is the location of the previous definition

OK to apply the include/ part?


Thanks,
Jan


include/
2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* bfdlink.h (ENUM_BITFIELD): Move to ...
	* ansidecl.h (ENUM_BITFIELD): ... here, use the one from GCC sources.

gdb/
2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* defs.h (ENUM_BITFIELD): Remove.

--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -24,12 +24,6 @@
 #ifndef BFDLINK_H
 #define BFDLINK_H
 
-#if (__GNUC__ * 1000 + __GNUC_MINOR__ > 2000)
-#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
-#else
-#define ENUM_BITFIELD(TYPE) unsigned int
-#endif
-
 /* Which symbols to strip during a link.  */
 enum bfd_link_strip
 {
--- a/include/ansidecl.h
+++ b/include/ansidecl.h
@@ -416,6 +416,16 @@ So instead we use the macro below and test it against specific values.  */
 #define EXPORTED_CONST const
 #endif
 
+/* Be conservative and only use enum bitfields with GCC.
+   FIXME: provide a complete autoconf test for buggy enum bitfields.
+   This is copied from gcc 4.7.8, system.h.  */
+
+#if (GCC_VERSION > 2000)
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
 #ifdef __cplusplus
 }
 #endif
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -271,15 +271,6 @@ struct cleanup
     void *arg;
   };
 
-/* Be conservative and use enum bitfields only with GCC.
-   This is copied from gcc 3.3.1, system.h.  */
-
-#if defined(__GNUC__) && (__GNUC__ >= 2)
-#define ENUM_BITFIELD(TYPE) enum TYPE
-#else
-#define ENUM_BITFIELD(TYPE) unsigned int
-#endif
-
 /* vec.h-style vectors of strings want a typedef for char * .  */
 
 typedef char * char_ptr;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] ENUM_BITFIELD broke GDB  [Re: Change bfd_link_hash_entry.type to a bitfield?]
  2011-04-24 14:49     ` [patch] ENUM_BITFIELD broke GDB [Re: Change bfd_link_hash_entry.type to a bitfield?] Jan Kratochvil
@ 2011-04-24 15:28       ` Andreas Schwab
  2011-04-24 15:31         ` [patch] ENUM_BITFIELD broke GDB Jan Kratochvil
  0 siblings, 1 reply; 11+ messages in thread
From: Andreas Schwab @ 2011-04-24 15:28 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: binutils, H.J. Lu, richard.sandiford

Jan Kratochvil <jan.kratochvil@redhat.com> writes:

> +/* Be conservative and only use enum bitfields with GCC.
> +   FIXME: provide a complete autoconf test for buggy enum bitfields.
> +   This is copied from gcc 4.7.8, system.h.  */

What is gcc 4.7.8?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] ENUM_BITFIELD broke GDB
  2011-04-24 15:28       ` Andreas Schwab
@ 2011-04-24 15:31         ` Jan Kratochvil
  2011-04-25  4:04           ` Alan Modra
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Kratochvil @ 2011-04-24 15:31 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: binutils, H.J. Lu, richard.sandiford

On Sun, 24 Apr 2011 17:28:15 +0200, Andreas Schwab wrote:
> Jan Kratochvil <jan.kratochvil@redhat.com> writes:
> 
> > +/* Be conservative and only use enum bitfields with GCC.
> > +   FIXME: provide a complete autoconf test for buggy enum bitfields.
> > +   This is copied from gcc 4.7.8, system.h.  */
> 
> What is gcc 4.7.8?

A typo, thanks.


Jan


include/
2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* bfdlink.h (ENUM_BITFIELD): Move to ...
	* ansidecl.h (ENUM_BITFIELD): ... here, use the one from GCC sources.

gdb/
2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* defs.h (ENUM_BITFIELD): Remove.

--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -24,12 +24,6 @@
 #ifndef BFDLINK_H
 #define BFDLINK_H
 
-#if (__GNUC__ * 1000 + __GNUC_MINOR__ > 2000)
-#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
-#else
-#define ENUM_BITFIELD(TYPE) unsigned int
-#endif
-
 /* Which symbols to strip during a link.  */
 enum bfd_link_strip
 {
--- a/include/ansidecl.h
+++ b/include/ansidecl.h
@@ -416,6 +416,16 @@ So instead we use the macro below and test it against specific values.  */
 #define EXPORTED_CONST const
 #endif
 
+/* Be conservative and only use enum bitfields with GCC.
+   FIXME: provide a complete autoconf test for buggy enum bitfields.
+   This is copied from gcc 4.7.0 20110424, system.h.  */
+
+#if (GCC_VERSION > 2000)
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
 #ifdef __cplusplus
 }
 #endif
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -271,15 +271,6 @@ struct cleanup
     void *arg;
   };
 
-/* Be conservative and use enum bitfields only with GCC.
-   This is copied from gcc 3.3.1, system.h.  */
-
-#if defined(__GNUC__) && (__GNUC__ >= 2)
-#define ENUM_BITFIELD(TYPE) enum TYPE
-#else
-#define ENUM_BITFIELD(TYPE) unsigned int
-#endif
-
 /* vec.h-style vectors of strings want a typedef for char * .  */
 
 typedef char * char_ptr;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] ENUM_BITFIELD broke GDB
  2011-04-24 15:31         ` [patch] ENUM_BITFIELD broke GDB Jan Kratochvil
@ 2011-04-25  4:04           ` Alan Modra
  2011-04-25 18:33             ` [commit include/+gdb/] " Jan Kratochvil
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Modra @ 2011-04-25  4:04 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Andreas Schwab, binutils, H.J. Lu, richard.sandiford

On Sun, Apr 24, 2011 at 05:31:28PM +0200, Jan Kratochvil wrote:
> include/
> 2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
> 
> 	* bfdlink.h (ENUM_BITFIELD): Move to ...
> 	* ansidecl.h (ENUM_BITFIELD): ... here, use the one from GCC sources.
> 
> gdb/
> 2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
> 
> 	* defs.h (ENUM_BITFIELD): Remove.

Sorry for the breakage.  I'm not sure I have approval rights for
ansidecl.h as this file is shared with gcc (and patches should be
applied to both src and gcc repos), but the patch ought to come under
the obvious rule..  However, given that gcc's system.h pulls
in ansidecl.h via libiberty.h, the ENUM_BITFIELD in system.h should go
too.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [commit include/+gdb/] Re: [patch] ENUM_BITFIELD broke GDB
  2011-04-25  4:04           ` Alan Modra
@ 2011-04-25 18:33             ` Jan Kratochvil
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Kratochvil @ 2011-04-25 18:33 UTC (permalink / raw)
  To: binutils, gdb-patches; +Cc: Andreas Schwab, H.J. Lu, richard.sandiford

On Mon, 25 Apr 2011 06:04:04 +0200, Alan Modra wrote:
> On Sun, Apr 24, 2011 at 05:31:28PM +0200, Jan Kratochvil wrote:
> > include/
> > 2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
> > 
> > 	* bfdlink.h (ENUM_BITFIELD): Move to ...
> > 	* ansidecl.h (ENUM_BITFIELD): ... here, use the one from GCC sources.
> > 
> > gdb/
> > 2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
> > 
> > 	* defs.h (ENUM_BITFIELD): Remove.
> 
> Sorry for the breakage.  I'm not sure I have approval rights for
> ansidecl.h as this file is shared with gcc (and patches should be
> applied to both src and gcc repos), but the patch ought to come under
> the obvious rule..  However, given that gcc's system.h pulls
> in ansidecl.h via libiberty.h, the ENUM_BITFIELD in system.h should go
> too.

Therefore checked in gcc, merged from gcc ansidecl.h and fixed gdb/ as
obvious / self-approved and include/bfdlink.h as pre-approved by you.

Both binutils and gdb build now.


Thanks,
Jan


http://sourceware.org/ml/gdb-cvs/2011-04/msg00153.html
http://sourceware.org/ml/binutils-cvs/2011-04/msg00153.html

--- src/gdb/ChangeLog	2011/04/24 08:02:15	1.12947
+++ src/gdb/ChangeLog	2011/04/25 18:28:51	1.12948
@@ -1,3 +1,7 @@
+2011-04-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* defs.h (ENUM_BITFIELD): Remove.
+
 2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
 	    Eli Zaretskii  <eliz@gnu.org>
 
--- src/include/ChangeLog	2011/04/24 10:02:10	1.528
+++ src/include/ChangeLog	2011/04/25 18:28:52	1.529
@@ -1,3 +1,11 @@
+2011-04-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* bfdlink.h (ENUM_BITFIELD): Remove.
+
+2011-04-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* ansidecl.h (ENUM_BITFIELD): New, from gcc/system.h.
+
 2011-04-24  Alan Modra  <amodra@gmail.com>
 
 	PR ld/12365
--- src/gdb/defs.h	2011/04/19 18:04:07	1.290
+++ src/gdb/defs.h	2011/04/25 18:28:52	1.291
@@ -271,15 +271,6 @@
     void *arg;
   };
 
-/* Be conservative and use enum bitfields only with GCC.
-   This is copied from gcc 3.3.1, system.h.  */
-
-#if defined(__GNUC__) && (__GNUC__ >= 2)
-#define ENUM_BITFIELD(TYPE) enum TYPE
-#else
-#define ENUM_BITFIELD(TYPE) unsigned int
-#endif
-
 /* vec.h-style vectors of strings want a typedef for char * .  */
 
 typedef char * char_ptr;
--- src/include/ansidecl.h	2010/01/05 21:10:23	1.28
+++ src/include/ansidecl.h	2011/04/25 18:28:52	1.29
@@ -416,6 +416,15 @@
 #define EXPORTED_CONST const
 #endif
 
+/* Be conservative and only use enum bitfields with GCC.
+   FIXME: provide a complete autoconf test for buggy enum bitfields.  */
+
+#if (GCC_VERSION > 2000)
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
 #ifdef __cplusplus
 }
 #endif
--- src/include/bfdlink.h	2011/04/24 10:02:11	1.84
+++ src/include/bfdlink.h	2011/04/25 18:28:53	1.85
@@ -24,12 +24,6 @@
 #ifndef BFDLINK_H
 #define BFDLINK_H
 
-#if (__GNUC__ * 1000 + __GNUC_MINOR__ > 2000)
-#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
-#else
-#define ENUM_BITFIELD(TYPE) unsigned int
-#endif
-
 /* Which symbols to strip during a link.  */
 enum bfd_link_strip
 {

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-04-25 18:33 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-20  0:25 PR12365 and common symbols Alan Modra
2011-04-22 22:33 ` H.J. Lu
2011-04-24 10:14   ` Change bfd_link_hash_entry.type to a bitfield? Alan Modra
2011-04-24 14:49     ` [patch] ENUM_BITFIELD broke GDB [Re: Change bfd_link_hash_entry.type to a bitfield?] Jan Kratochvil
2011-04-24 15:28       ` Andreas Schwab
2011-04-24 15:31         ` [patch] ENUM_BITFIELD broke GDB Jan Kratochvil
2011-04-25  4:04           ` Alan Modra
2011-04-25 18:33             ` [commit include/+gdb/] " Jan Kratochvil
2011-04-21  1:58 Change bfd_link_hash_entry.type to a bitfield? Alan Modra
2011-04-21  2:55 ` H.J. Lu
2011-04-21 11:55   ` Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).