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]

Re: PATCH: PR ld/13962: Misleading error message when linking a library with an empty library


On Mon, May 14, 2012 at 06:50:29AM -0700, H.J. Lu wrote:
> Linker should ignore object without symbols.  OK to install?

No.  elf_link_add_object_symbols does more than just read symbols.
While it would be unusual to have relocs without symbols, or need to
run check_directives without symbols, I think we should not ignore
those possibilities.

Also, having .dynsym sh_info == 1 when sh_size == 0 is somewhat
broken.  Ah yes, I knew I'd seen something like this before.
http://sourceware.org/bugzilla/show_bug.cgi?id=7023 is the same
problem but with .symtab.  For that bug I grumpily decided to make ld
reject the object file.  We could do the same here, but I think GNU ld
itself used to set sh_info wrongly, it's not too hard to fix the bad
input, and I'm feeling generous.  So..

 	PR ld/13962
 	PR ld/7023
	* elf.c (bfd_section_from_shdr): Fail when .dynsym sh_info is
	out of range.  As a special case, fix sh_info for zero sh_size.
	Do the same for .symtab.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.553
diff -u -p -r1.553 elf.c
--- bfd/elf.c	8 May 2012 17:18:21 -0000	1.553
+++ bfd/elf.c	16 May 2012 02:56:57 -0000
@@ -1646,7 +1646,15 @@ bfd_section_from_shdr (bfd *abfd, unsign
       if (hdr->sh_entsize != bed->s->sizeof_sym)
 	return FALSE;
       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
-	return FALSE;
+	{
+	  if (hdr->sh_size != 0)
+	    return FALSE;
+	  /* Some assemblers erroneously set sh_info to one with a
+	     zero sh_size.  ld sees this as a global symbol count
+	     of (unsigned) -1.  Fix it here.  */
+	  hdr->sh_info = 0;
+	  return TRUE;
+	}
       BFD_ASSERT (elf_onesymtab (abfd) == 0);
       elf_onesymtab (abfd) = shindex;
       elf_tdata (abfd)->symtab_hdr = *hdr;
@@ -1699,6 +1707,16 @@ bfd_section_from_shdr (bfd *abfd, unsign
 
       if (hdr->sh_entsize != bed->s->sizeof_sym)
 	return FALSE;
+      if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
+	{
+	  if (hdr->sh_size != 0)
+	    return FALSE;
+	  /* Some linkers erroneously set sh_info to one with a
+	     zero sh_size.  ld sees this as a global symbol count
+	     of (unsigned) -1.  Fix it here.  */
+	  hdr->sh_info = 0;
+	  return TRUE;
+	}
       BFD_ASSERT (elf_dynsymtab (abfd) == 0);
       elf_dynsymtab (abfd) = shindex;
       elf_tdata (abfd)->dynsymtab_hdr = *hdr;

-- 
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]