PR26103, Assertion failure with symbols defined in link-once sections

Message ID 20200615024603.GC26163@bubble.grove.modra.org
State New
Headers show
Series
  • PR26103, Assertion failure with symbols defined in link-once sections
Related show

Commit Message

Cui, Lili via Binutils June 15, 2020, 2:46 a.m.
PR 26103
	* elflink.c (elf_link_add_archive_symbols): Exclude undefined
	symbols that were defined in discarded sections.
	* cofflink.c (coff_link_check_archive_element): Likewise.
	(coff_link_add_symbols): Set indx to -3 for symbols defined in
	discarded sections.
	(_bfd_coff_write_global_sym): Don't emit such symbols.
	libcoff-in.h (struct coff_link_hash_entry): Update indx comment.
	libcoff.h: Regenerate.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 27ac20e80d..63bdcde115 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -212,6 +212,12 @@  coff_link_check_archive_element (bfd *abfd,
   if (h->type != bfd_link_hash_undefined)
     return TRUE;
 
+  /* If the archive element has already been loaded then one
+     of the symbols defined by that element might have been
+     made undefined due to being in a discarded section.  */
+  if (((struct coff_link_hash_entry *) h)->indx == -3)
+    return TRUE;
+
   /* PR 22369 - Skip non COFF objects in the archive.  */
   if (! bfd_family_coff (abfd))
     return TRUE;
@@ -286,6 +292,7 @@  coff_link_add_symbols (bfd *abfd,
 	  asection *section;
 	  bfd_vma value;
 	  bfd_boolean addit;
+	  bfd_boolean discarded = FALSE;
 
 	  /* This symbol is externally visible.  */
 
@@ -311,7 +318,10 @@  coff_link_add_symbols (bfd *abfd,
 	      flags = BSF_EXPORT | BSF_GLOBAL;
 	      section = coff_section_from_bfd_index (abfd, sym.n_scnum);
 	      if (discarded_section (section))
-		section = bfd_und_section_ptr;
+		{
+		  discarded = TRUE;
+		  section = bfd_und_section_ptr;
+		}
 	      else if (! obj_pe (abfd))
 		value -= section->vma;
 	      break;
@@ -408,6 +418,9 @@  coff_link_add_symbols (bfd *abfd,
 		      (const char *) NULL, copy, FALSE,
 		      (struct bfd_link_hash_entry **) sym_hash)))
 		goto error_return;
+
+	      if (discarded)
+		(*sym_hash)->indx = -3;
 	    }
 
 	  if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
@@ -2567,6 +2580,9 @@  _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
       return FALSE;
 
     case bfd_link_hash_undefined:
+      if (h->indx == -3)
+	return TRUE;
+      /* Fall through.  */
     case bfd_link_hash_undefweak:
       isym.n_scnum = N_UNDEF;
       isym.n_value = 0;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 3e56a297f6..ac00f2984e 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5813,7 +5813,15 @@  elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 	  if (h == NULL)
 	    continue;
 
-	  if (h->root.type == bfd_link_hash_common)
+	  if (h->root.type == bfd_link_hash_undefined)
+	    {
+	      /* If the archive element has already been loaded then one
+		 of the symbols defined by that element might have been
+		 made undefined due to being in a discarded section.  */
+	      if (h->indx == -3)
+		continue;
+	    }
+	  else if (h->root.type == bfd_link_hash_common)
 	    {
 	      /* We currently have a common symbol.  The archive map contains
 		 a reference to this symbol, so we may want to include it.  We
@@ -5830,7 +5838,7 @@  elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 	      if (! elf_link_is_defined_archive_symbol (abfd, symdef))
 		continue;
 	    }
-	  else if (h->root.type != bfd_link_hash_undefined)
+	  else
 	    {
 	      if (h->root.type != bfd_link_hash_undefweak)
 		/* Symbol must be defined.  Don't check it again.  */
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
index 3f0227c4ac..b7fcea30bb 100644
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -243,8 +243,9 @@  struct coff_link_hash_entry
 {
   struct bfd_link_hash_entry root;
 
-  /* Symbol index in output file.  Set to -1 initially.  Set to -2 if
-     there is a reloc against this symbol.  */
+  /* Symbol index in output file.  This is initialized to -1.  It is
+     set to -2 if the symbol is used by a reloc.  It is set to -3 if
+     this symbol is defined in a discarded section.  */
   long indx;
 
   /* Symbol type.  */