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: static link problems with alias


Hi Carmelo,

I switched the link order of the archives
gcc -static -L. main.c -lfoo -lfoo_alias
and this works fine.

so does the link take the foo symbol from libfoo:foo.o without further
searching?

Yes.


When the linker scans libfoo_alias.a it only looks for symbols which it currently has marked as "unresolved". So it finds the "bar" symbol in libfoo_alias:bar.o, and links in that entire object file. This brings in an unresolved symbol "foo", but it now has a definition of that symbol in libfoo:foo.o (which it has already linked in because it contains a definition of "other" which is needed by "main"). So the linker resolves the reference to "foo" by using the definition in libfoo:foo.o.

Here is an interesting test.

  1.  Rerun your test but add "-Wl,-Map,main-calls-other" to the final
      gcc command line.
  2.  Edit main.c, comment out the call to "other", recompile main.c.
  3.  Rerun the final gcc command line again, but this time use
      "-Wl,-Map,main-only-calls-bar".

You should now have two linker map files called "main-calls-other" and "main-only-calls-bar". Have a look through the files. They are fairly self-documenting. In particular you should see something like this in main-calls-other:

 .text          0x0000000000400264       0x16 ./libfoo.a(foo.o)
                0x000000000040026f                other
                0x0000000000400264                foo

Showing that the "foo" symbol has been resolved from the definition in foo.o, whereas in main-only-calls-bar you should see:

 .text          0x000000000040026c        0xb ./libfoo_alias.a(foo_alias.o)
                0x000000000040026c                foo_alias
                0x000000000040026c                foo

Showing that this time the "foo" symbol has been resolved to come from the definition in the foo_alias.o.

It is all about what symbols are undefined at the time that the linker encounters a library on the command line. So when main calls "other" we have this:

  1. Linker see main.o on the command line and adds it to its output
     list.  The linker sees that it needs definitions of "bar" and
     "other"

  2. Linker encounters libfoo.a on the command line.
     This contains libfoo.a:foo.o which provides a definition of
     "other".  So this object file is linked in, and as a consequence a
     definition of the symbol "foo" is also brought in.

  3. The linker then *forgets* about any other object files contained in
     libfoo.a which it has decided not to link in.  (There are none in
     this particular case, but it becomes important in a moment).

  4. The linker encounters libfoo_alias.a on the command line.  This
     contains libfoo.a:bar.o which defines "bar", so this object file is
     linked in.  bar.o also refers to the "foo" symbol, but the linker
     already has a definition of this symbol from its inclusion of
     libfoo:foo.o.

OK ? So now when we look at the second case, where main does not call "other":

  1. Linker see main.o on the command line and adds it to its output
     list.  The linker sees that it needs definitions of "bar" (but not
     a definition of "other").

  2. Linker encounters libfoo.a on the command line.
     This does not contain a definition of "bar".  So *none* of the
     object files in libfoo.a are included in the link.  In particular
     libfoo.a:foo.o is not included, so the linker does not gain a
     definition of the symbol "foo".

  3. The linker encounters libfoo_alias.a on the command line.  This
     contains libfoo.a:bar.o which defines "bar", so this object file is
     linked in.  bar.o also refers to the "foo" symbol, but since the
     linker has now forgotten all about the contents of libfoo.a it
     keeps on searching and finds a definition in
     libfoo_alias:foo_alias.o.  So this object file is included in the
     link.

Does this make things clear ?



I know the order is important, so I'd like to understand if the
following statements are correct:
1) when using alias (strong or weak) the symbol's searching is
perfomed through all the
libraries (failing if multiple definition will be found)

no.


2) while referring to a 'real' symbol the linker will stop at the
first occurrence

no.


:-)


The linker uses the same algorithm for resolving undefined weak symbols as for resolving undefined undefined strong symbols. Have a read of the linker manual. (In particular have a look at the actions of the --startgroup and --endgroup switches which relate to whether the linker will repeatedly scan a group of libraries).


Cheers
  Nick


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]