PATCH: A strang symbol versioning problem

H. J. Lu hjl@lucon.org
Sat Aug 10 23:58:00 GMT 2002


On Sat, Aug 10, 2002 at 03:06:10PM -0700, H. J. Lu wrote:
> 
> Here is a small testcase
> 
> # make
> gcc  -B./ -g -fPIC   -c -o foo.o foo.c
> gcc: file path prefix `./' never used
> gcc  -B./ -g -fPIC   -c -o new.o new.c
> gcc: file path prefix `./' never used
> gcc  -B./ -Wl,--version-script=bar.map  -shared -o libnew.so new.o
> gcc: file path prefix `./' never used
> gcc  -B./ -shared -o libfoo.so -Wl,-rpath,. foo.o libnew.so
> gcc: file path prefix `./' never used
> gcc  -B./ -g -fPIC   -c -o old.o old.c
> gcc: file path prefix `./' never used
> gcc  -B./ -Wl,--version-script=bar.map  -shared -o libold.so old.o
> gcc: file path prefix `./' never used
> gcc  -B./ -o main -Wl,-rpath,. main.c libfoo.so libold.so new.o
> ./libnew.so(*IND*+0x0): multiple definition of `bar@VERS.0'
> libold.so(.text+0x12c): first defined here
> collect2: ld returned 1 exit status
> gcc: file path prefix `./' never used
> make: *** [main] Error 1
> 
> I will see what I can do.

The problem is the section pointer got changed across the call to
elf_merge_symbol. If the first call changes the section pointer to
undefined due to override, the next call to elf_merge_symbol will
be confused. I am enclosing a patch here. Do we expect/want the
section pointer gets changed after elf_add_default_symbol? Any
comments?


H.J.
-------------- next part --------------
2002-08-10  H.J. Lu <hjl@gnu.org>

	* elflink.h (elf_add_default_symbol): Preserve section across
	elf_merge_symbol.

--- bfd/elflink.h.version	Thu Aug  8 22:16:02 2002
+++ bfd/elflink.h	Sat Aug 10 23:48:57 2002
@@ -899,19 +899,19 @@ elf_merge_symbol (abfd, info, name, sym,
 
 /* This function is called to create an indirect symbol from the
    default for the symbol with the default version if needed. The
-   symbol is described by H, NAME, SYM, SEC, VALUE, and OVERRIDE.  We
+   symbol is described by H, NAME, SYM, PSEC, VALUE, and OVERRIDE.  We
    set DYNSYM if the new indirect symbol is dynamic. DT_NEEDED
    indicates if it comes from a DT_NEEDED entry of a shared object.  */
 
 static boolean
-elf_add_default_symbol (abfd, info, h, name, sym, sec, value,
+elf_add_default_symbol (abfd, info, h, name, sym, psec, value,
 			dynsym, override, dt_needed)
      bfd *abfd;
      struct bfd_link_info *info;
      struct elf_link_hash_entry *h;
      const char *name;
      Elf_Internal_Sym *sym;
-     asection **sec;
+     asection **psec;
      bfd_vma *value;
      boolean *dynsym;
      boolean override;
@@ -926,6 +926,7 @@ elf_add_default_symbol (abfd, info, h, n
   boolean dynamic;
   char *p;
   size_t len, shortlen;
+  asection *sec;
 
   /* If this symbol has a version, and it is the default version, we
      create an indirect symbol from the default name to the fully
@@ -970,7 +971,8 @@ elf_add_default_symbol (abfd, info, h, n
      actually going to define an indirect symbol.  */
   type_change_ok = false;
   size_change_ok = false;
-  if (! elf_merge_symbol (abfd, info, shortname, sym, sec, value,
+  sec = *psec;
+  if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
 			  &hi, &override, &type_change_ok,
 			  &size_change_ok, dt_needed))
     return false;
@@ -1077,7 +1079,8 @@ elf_add_default_symbol (abfd, info, h, n
   /* Once again, merge with any existing symbol.  */
   type_change_ok = false;
   size_change_ok = false;
-  if (! elf_merge_symbol (abfd, info, shortname, sym, sec, value,
+  sec = *psec;
+  if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
 			  &hi, &override, &type_change_ok,
 			  &size_change_ok, dt_needed))
     return false;


More information about the Binutils mailing list