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

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


On Sun, Jul 14, 2002 at 07:09:53AM -0700, H. J. Lu wrote:
> On Sun, Jul 14, 2002 at 06:56:20AM -0700, H. J. Lu wrote:
> > On Sat, Jul 13, 2002 at 07:56:44PM -0700, H. J. Lu wrote:
> > > 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
> > > 
> > 
> > Second thought. I think it should work. Here is the new patch and a
> > testcase. Now I got:
> > 
> > # make
> > cc    -c -o foo.o foo.c
> > cc    -c -o c0.o c0.c
> > cc -Wl,-soname,lib-c.so -shared -o lib-c.so c0.o
> > cc -o foo -Wl,-rpath,. foo.o lib-c.so
> > cc -fPIC -c c1.c
> > cc -fPIC -c c2.c
> > /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 -soname lib-c.so --version-script=c.map -shared -o lib-c2.so c2.o c1.o
> > objdump --dynamic-sym lib-c1.so | grep VER
> > 00000280 g    DF .text  00000021 (VERS.0)     foo
> > 00000000 g    DO *ABS*  00000000  VERS.0      VERS.0
> > 0000025c g    DF .text  00000021 (VERS.0)     bar
> > objdump --dynamic-sym lib-c2.so | grep VER
> > 0000028c g    DF .text  00000021 (VERS.0)     foo
> > 00000000 g    DO *ABS*  00000000  VERS.0      VERS.0
> > 00000268 g    DF .text  00000021 (VERS.0)     bar
> > ./foo
> > bar: 0
> > foo: 0
> > cp lib-c1.so lib-c.so
> > ./foo
> > bar: 1
> > foo: 2
> > cp lib-c2.so lib-c.so
> > ./foo
> > bar: 1
> > foo: 2
> > 
> > Jack, please try this to see if gcc 2.95.4 works without any glibc
> > changes.
> > 
> 
> Ooops. Wrong one. Please use this one.
> 
> 

Ooops. I missed the weak definition. Here is the new patch.


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

	* elflink.h (elf_link_assign_sym_version): Hide the default
	definition if there is a hidden versioned definition.

--- bfd/elflink.h.dup	Mon Jul  8 08:58:42 2002
+++ bfd/elflink.h	Sun Jul 14 07:41:59 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,46 @@ elf_link_assign_sym_version (h, data)
 	      (*bed->elf_backend_hide_symbol) (info, h, true);
 	    }
 	}
+
+      /* We need to check if a hidden versioned definition should
+	 hide the default one.  */
+      if (h->dynindx != -1 && h->verinfo.vertree != NULL)
+	{
+	  const char *verstr, *name;
+	  size_t namelen, verlen, newlen;
+	  char *newname;
+	  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 versioned definition.  */
+	  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
+		  || newh->root.type == bfd_link_hash_defweak))
+	    /* We find a hidden versioned definition. Hide the default
+	       one.  */
+	    (*bed->elf_backend_hide_symbol) (info, h, true);
+
+	  free (newname);
+	}
     }
 
   return true;


More information about the Binutils mailing list