Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -231,7 +231,7 @@ Symbol *Sym; if (IsNew) { Sym = make(); - Sym->InVersionScript = false; + Sym->GotVersionFromName = false; Sym->Binding = STB_WEAK; Sym->Visibility = STV_DEFAULT; Sym->IsUsedInRegularObj = false; @@ -697,10 +697,11 @@ // Assign the version. for (SymbolBody *B : Syms) { Symbol *Sym = B->symbol(); - if (Sym->InVersionScript) + if (Sym->GotVersionFromName) + continue; + if (Sym->VersionId != Config->DefaultSymbolVersion) warn("duplicate symbol '" + Ver.Name + "' in version script"); Sym->VersionId = VersionId; - Sym->InVersionScript = true; } } Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -363,8 +363,10 @@ // True if this symbol is specified by --trace-symbol option. unsigned Traced : 1; - // This symbol version was found in a version script. - unsigned InVersionScript : 1; + // Symbols can have version baked in their names. If flag is true + // that means version was set from name, such version has priority + // over versions from script. + unsigned GotVersionFromName : 1; bool includeInDynsym() const; uint8_t computeBinding() const; Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -253,6 +253,7 @@ if (IsDefault) Verstr = Verstr.substr(1); + symbol()->GotVersionFromName = true; for (VersionDefinition &Ver : Config->VersionDefinitions) { if (Ver.Name != Verstr) continue; Index: test/ELF/version-script-symver2.s =================================================================== --- test/ELF/version-script-symver2.s +++ 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