Don't let default version in a shared object override prior unversioned definition in another 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 gold/ PR gold/16979 * symtab.cc (Symbol_table::define_default_version): Check for case where symbols are both in different shared objects. diff --git a/gold/symtab.cc b/gold/symtab.cc index fd75aff..a7edbb1 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -865,6 +865,9 @@ Symbol_table::define_default_version(Sized_symbol* sym, // other is defined in a shared object, then they are different // symbols. + // If the two symbols are from different shared objects, + // they are different symbols. + // Otherwise, we just resolve the symbols as though they were // the same. @@ -876,6 +879,10 @@ Symbol_table::define_default_version(Sized_symbol* sym, else if (pdef->second->visibility() != elfcpp::STV_DEFAULT && sym->is_from_dynobj()) ; + else if (pdef->second->is_from_dynobj() + && sym->is_from_dynobj() + && pdef->second->object() != sym->object()) + ; else { const Sized_symbol* symdef;