PACTH: Fix duplicated version (Re: A symbol version bug?)

H. J. Lu hjl@lucon.org
Sun Jul 14 00:32:00 GMT 2002


On Fri, Jul 12, 2002 at 10:43:33PM -0700, H. J. Lu wrote:
> On Fri, Jul 12, 2002 at 08:51:03PM -0700, H. J. Lu wrote:
> > I got
> > 
> > # make
> > cc -fPIC -c c1.c
> > cc -fPIC -c c2.c
> > ld --version-script=c.map -shared -o lib-c1.so c1.o c2.o
> > objdump --dynamic-sym lib-c1.so| grep bar
> > 00000264 g    DF .text  0000000a  VERS.0      bar
> > 00000258 g    DF .text  0000000a (VERS.0)     bar
> > 
> > I am expecting
> > 
> 
> Corretion. I am expecting a fatal error.
> 

Here is the patch. Now I got

/export/build/gnu/binutils-debug/build-full-i686-linux/ld/ld-new -soname
lib-c.so --version-script=c.map -shared -o lib-c1.so c1.o c2.o
/export/build/gnu/binutils-debug/build-full-i686-linux/ld/ld-new: foo (c2.o):
duplicated versioned symbol: foo@VERS.0 (c1.o)
/export/build/gnu/binutils-debug/build-full-i686-linux/ld/ld-new: failed to set
dynamic section sizes: Bad value


H.J.
-------------- next part --------------
2002-07-13  H.J. Lu <hjl@gnu.org>

	* elflink.h (elf_link_assign_sym_version): Bail out if a symbol
	with a default version conflicts with a hidden symbol with the
	same version.

--- bfd/elflink.h.dup	Mon Jul  8 08:58:42 2002
+++ bfd/elflink.h	Sat Jul 13 19:48:37 2002
@@ -4345,6 +4345,7 @@ elf_link_assign_sym_version (h, data)
 	    (_("%s: undefined versioned symbol name %s"),
 	     bfd_get_filename (sinfo->output_bfd), h->root.root.string);
 	  bfd_set_error (bfd_error_bad_value);
+error_return:
 	  sinfo->failed = true;
 	  return false;
 	}
@@ -4416,6 +4417,52 @@ elf_link_assign_sym_version (h, data)
 	      (*bed->elf_backend_hide_symbol) (info, h, true);
 	    }
 	}
+
+      /* We need to check if there is a conflict.  */
+      if (h->dynindx != -1)
+	{
+	  const char *verstr, *name;
+	  size_t namelen, verlen, newlen;
+	  char *newname, *p;
+	  struct elf_link_hash_entry *newh;
+
+	  name = h->root.root.string;
+	  namelen = strlen (name);
+	  verstr = h->verinfo.vertree->name;
+	  verlen = strlen (verstr);
+	  newlen = namelen + verlen + 2;
+
+	  newname = (char *) bfd_malloc ((bfd_size_type) newlen);
+	  if (newname == NULL)
+	    {
+	      bfd_set_error (bfd_error_no_memory);
+	      goto error_return;
+	    }
+	  memcpy (newname, name, namelen);
+
+	  /* Check the hidden symbol.  */
+	  p = newname + namelen;
+	  *p++ = ELF_VER_CHR;
+	  memcpy (p, verstr, verlen + 1);
+	  newh = elf_link_hash_lookup (elf_hash_table (info), newname,
+				    false, false, false);
+
+	  if (newh && newh->root.type == bfd_link_hash_defined)
+	    {
+	      /* We find a versioned definition. Bail out.  */
+	      (*_bfd_error_handler)
+		(_("%s (%s): duplicated versioned symbol: %s (%s)"),
+		 h->root.root.string, 
+		 bfd_get_filename (h->root.u.def.section->owner),
+		 newname,
+		 bfd_get_filename (newh->root.u.def.section->owner));
+	      free (newname);
+	      bfd_set_error (bfd_error_bad_value);
+	      goto error_return;
+	    }
+
+	  free (newname);
+	}
     }
 
   return true;


More information about the Binutils mailing list