Created attachment 7612 [details]
test case for symbol overriding
I've been trying to dynamically link tcmalloc into my application and was troubled to see that sometimes the link didn't "take" (i.e. ldd revealed no dependency on libtcmalloc.so and the built-in libc malloc was invoked by the application). After debugging for a little while, I've produced a simple test case showing the problem. When /usr/bin/ld is symlinked to ld.bfd, the test passes. When it's symlinked to ld.gold, the test fails. This is how my binutils package layout works (I'm running Ubuntu 14.04).
I'm not familiar enough with the details of linking to understand why it's failing, but as gold is supposed to be a drop-in replacement for ld, I figured this is a reasonable place to start.
The master branch has been updated by Cary Coutant <firstname.lastname@example.org>:
Author: Cary Coutant <email@example.com>
Date: Wed Mar 30 19:14:16 2016 -0700
Don't override definition a shared object by one in a later shared object.
In PR 16979, a reference to malloc is being resolved to an unversioned
reference in libmalloc.so. When linked with --as-needed, however, the
dynamic table does not list libmalloc.so as a DT_NEEDED library.
If we have a reference to an unversioned symbol in a shared object,
and we later see a versioned definition in another shared object, we
were overriding the first definition with the second in the process of
defining the default version. As a result, we no longer think that the
first shared object was actually needed to resolve any symbols, and we
don't list it as a DT_NEEDED library.
This patch fixes the problem by treating the two definitions as separate
symbols, so the second definition does not override the first.
2016-03-30 Cary Coutant <firstname.lastname@example.org>
* symtab.cc (Symbol_table::define_default_version): Check for case
where symbols are both in different shared objects.