This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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