public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Alan Modra <amodra@gmail.com>
To: binutils@sourceware.org
Subject: PR12365 and common symbols
Date: Wed, 20 Apr 2011 00:25:00 -0000	[thread overview]
Message-ID: <20110420002520.GG19947@bubble.grove.modra.org> (raw)

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

             reply	other threads:[~2011-04-20  0:25 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-20  0:25 Alan Modra [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110420002520.GG19947@bubble.grove.modra.org \
    --to=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).