GNU-ld behaviour does not match native linker behaviour

Ian Lance Taylor ian@zembu.com
Fri Dec 10 08:13:00 GMT 1999


   From: Andreas Schwab <schwab@suse.de>
   Date: 10 Dec 1999 13:14:14 +0100

   |> : Note that we may have some confusion with existing ELF archives in
   |> : some scenarios.  Existing ELF archives will have common symbols in the
   |> : armap.  We will now wind up pulling those in to satisfy common symbols
   |> : in the executable.  I'm not sure what to do about that.  I don't know
   |> : how often it will be a real problem.
   |> 
   |> I think we should be OK.  In the case where old archives are linked
   |> with the new linker, we may end up getting bigger than expected
   |> executables, but on the other hand we should also end up getting
   |> executables that work (becuase they have included the definition of
   |> the common as well), instead of ones that are broken.

   Unfortunately this will not always work.  Suppose you have a libarary
   (call it libgcc.a) that is created with the old ar program (and thus its
   armap contains the common symbols).  Suppose further that this library
   appears twice on the linker command line (which is always true for
   libgcc.a).  The linker will now try to link the object file that contains
   the common symbol twice whenever any symbol is referenced from it, which
   will fail due to multiple definitions of the other symbols.

Good point.

I'm also now concerned about the case in which there an undefined
symbol in an object, and a common symbol in an archive.  In the old
scenario, the archive element would satisfy the undefined reference.
In the new scenario, it would not.

I just checked /usr/ccs/bin/ar on Solaris 2.6, and it *does* put
common symbols in the armap.  Also, the ELF spec in its description of
archive symbol tables refers only to the distinction between global
and local symbols, and makes no reference to common symbols (which are
a form of global symbol in ELF).  This makes me doubt very much
whether the patch you have checked in is correct.  Sorry about that,
Nick.

When I try your original test case, with a common symbol in the main
program and a defined symbol in the archive, the Solaris 2.6 linker
does pull in the element from the archive.

When I try a test case in which an element in the archive provides a
common symbol which is also a common symbol in the main program, the
Solaris 2.6 linker does not pull in the element from the archive.

When I try a test case in which an element in the archive provides a
common symbol which is an undefined symbol in the main program, the
Solaris 2.6 linker does pull in the element from the archive.

Here is a table showing when an element is pulled in from an archive
with the Solaris 2.6 linker and ar program:

main program\archive   undefined    common    defined

undefined                no          yes       yes
common                   no          no        yes
defined                  no          no        no

In the original binutils code, the common\defined line was no.  In the
newly patched binutils code, the undefined\common line is no.

So, Nick, it now looks to me like your original patch is the right way
to go.

The old patch is not very efficient, but I suppose the inefficiency
only arises when you use a common symbol in a main program and that
symbol name appears in an archive map.  We must check whether the
symbol in the archive element is common or defined, and that is what
your patch did.

Sorry to put you through all this.  Previously I was replying without
testing other systems, because at the time I could not.

Ian


More information about the Binutils mailing list