Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -695,6 +695,12 @@ // Assign the version. for (SymbolBody *B : Syms) { + // Skip symbols containing version info because symbol versions + // specified by symbol names take precedence over version scripts. + // See parseSymbolVersion(). + if (B->getName().find('@') != StringRef::npos) + continue; + Symbol *Sym = B->symbol(); if (Sym->VersionId != Config->DefaultSymbolVersion) warn("duplicate symbol '" + Ver.Name + "' in version script"); @@ -719,17 +725,9 @@ // 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 and update their names to exclude version suffix. - for (Symbol *Sym : SymVector) - Sym->body()->parseSymbolVersion(); - // Handle edge cases first. handleAnonymousVersion(); - if (Config->VersionDefinitions.empty()) - return; // Now we have version definitions, so we need to set version ids to symbols. // Each version definition has a glob pattern, and all symbols that match @@ -748,6 +746,12 @@ for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions)) for (SymbolVersion &Ver : V.Globals) assignWildcardVersion(Ver, V.Id); + + // Symbol themselves might know their versions because symbols + // can contain versions in the form of @. + // Let them parse and update their names to exclude version suffix. + for (Symbol *Sym : SymVector) + Sym->body()->parseSymbolVersion(); } template class elf::SymbolTable; Index: lld/trunk/test/ELF/version-script-symver2.s =================================================================== --- lld/trunk/test/ELF/version-script-symver2.s +++ lld/trunk/test/ELF/version-script-symver2.s @@ -0,0 +1,28 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "VER1 { global: foo; local: *; }; VER2 { global: foo; }; VER3 { global: foo; };" > %t.map +# RUN: ld.lld -shared %t.o --version-script %t.map -o %t.so --fatal-warnings +# RUN: llvm-readobj -V %t.so | FileCheck %s + +# CHECK: Symbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 0 +# CHECK-NEXT: Name: @ +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 3 +# CHECK-NEXT: Name: foo@@VER2 +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 2 +# CHECK-NEXT: Name: foo@VER1 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.global bar +bar: +.symver bar, foo@VER1 + +.global zed +zed: +.symver zed, foo@@VER2