Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -715,15 +715,33 @@ B->symbol()->VersionId = VersionId; } +static bool isDefaultVersion(SymbolBody *Body) { + if (!Body->isInCurrentDSO()) + return false; + return Body->getName().find("@@") != StringRef::npos; +} + // This function processes version scripts by updating VersionId // member of symbols. template void SymbolTable::scanVersionScript() { // Symbol themselves might know their versions because symbols // can contain versions in the form of @. // Let them parse their names. - if (!Config->VersionDefinitions.empty()) - for (Symbol *Sym : SymVector) - Sym->body()->parseSymbolVersion(); + // Below we resolve references to symbols that have default version. We use + // additional temp vector because addRegular() call may change SymVector. + std::vector DefaultV; + for (Symbol *Sym : SymVector) { + if (isDefaultVersion(Sym->body())) + DefaultV.push_back(cast(Sym->body())); + Sym->body()->parseSymbolVersion(); + } + + // @@ means symbol has 'default' version. We should use it to + // resolve references to . + for (DefinedRegular *D : DefaultV) + if (find(D->getName())) + addRegular(D->getName(), D->StOther, D->Type, D->Value, D->Size, + D->symbol()->Binding, D->Section, D->File); // Handle edge cases first. handleAnonymousVersion(); Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -256,7 +256,9 @@ } // It is an error if the specified version is not defined. - error(toString(File) + ": symbol " + S + " has undefined version " + Verstr); + if (Config->Shared) + error(toString(File) + ": symbol " + S + " has undefined version " + + Verstr); } Defined::Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, Index: test/ELF/version-script-symver-err.s =================================================================== --- test/ELF/version-script-symver-err.s +++ test/ELF/version-script-symver-err.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s +# CHECK: error: duplicate symbol: bar +# CHECK-NEXT: >>> defined at {{.*}}.o +# CHECK-NEXT: >>> defined at {{.*}}.o + +.global _start +.global bar +.symver _start, bar@@VERSION +_start: + jmp bar + +bar: Index: test/ELF/version-script-symver.s =================================================================== --- test/ELF/version-script-symver.s +++ test/ELF/version-script-symver.s @@ -0,0 +1,10 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t + +.global _start +.global bar +.symver _start, bar@@VERSION +_start: + jmp bar