Index: llvm/lib/Object/RecordStreamer.cpp =================================================================== --- llvm/lib/Object/RecordStreamer.cpp +++ llvm/lib/Object/RecordStreamer.cpp @@ -149,6 +149,7 @@ for (auto &Symver : SymverAliasMap) { const MCSymbol *Aliasee = Symver.first; MCSymbolAttr Attr = MCSA_Invalid; + bool IsDefined = false; // First check if the aliasee binding was recorded in the asm. RecordStreamer::State state = getSymbolState(Aliasee); @@ -165,26 +166,53 @@ break; } - // If we don't have a symbol attribute from assembly, then check if - // the aliasee was defined in the IR. - if (Attr == MCSA_Invalid) { - const auto *GV = M.getNamedValue(Aliasee->getName()); + switch (state) { + case RecordStreamer::Defined: + case RecordStreamer::DefinedGlobal: + case RecordStreamer::DefinedWeak: + IsDefined = true; + break; + case RecordStreamer::NeverSeen: + case RecordStreamer::Global: + case RecordStreamer::Used: + case RecordStreamer::UndefinedWeak: + break; + } + + const GlobalValue *GV = nullptr; + if (Attr == MCSA_Invalid || !IsDefined) { + GV = M.getNamedValue(Aliasee->getName()); if (!GV) { auto MI = MangledNameMap.find(Aliasee->getName()); if (MI != MangledNameMap.end()) GV = MI->second; } if (GV) { - if (GV->hasExternalLinkage()) - Attr = MCSA_Global; - else if (GV->hasLocalLinkage()) - Attr = MCSA_Local; - else if (GV->isWeakForLinker()) - Attr = MCSA_Weak; + // If we don't have a symbol attribute from assembly, then check if + // the aliasee was defined in the IR. + if (Attr == MCSA_Invalid) { + if (GV->hasExternalLinkage()) + Attr = MCSA_Global; + else if (GV->hasLocalLinkage()) + Attr = MCSA_Local; + else if (GV->isWeakForLinker()) + Attr = MCSA_Weak; + } + IsDefined = !GV->isDeclarationForLinker(); } } + // Set the detected binding on each alias with this aliasee. for (auto AliasName : Symver.second) { + std::pair Split = AliasName.split("@@@"); + SmallString<128> NewName; + if (!Split.second.empty() && !Split.second.startswith("@")) { + // Special processing for "@@@" according + // https://sourceware.org/binutils/docs/as/Symver.html + const char *Separator = IsDefined ? "@@" : "@"; + AliasName = + (Split.first + Separator + Split.second).toStringRef(NewName); + } MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be // converted into @ or @@. Index: llvm/test/LTO/X86/symver-asm3.ll =================================================================== --- /dev/null +++ llvm/test/LTO/X86/symver-asm3.ll @@ -0,0 +1,21 @@ +; Test special handling of @@@. + +; RUN: llvm-as < %s >%t1 +; RUN: llvm-nm %t1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +module asm "_start1:" +module asm ".symver _start1, foo@@@SOME_VERSION1" +module asm ".symver _start2, foo@@@SOME_VERSION2" +module asm ".symver _start3, foo@@@SOME_VERSION3" +module asm "_start3:" +module asm ".local _start1" +module asm ".local _start3" + +; CHECK-DAG: t _start1 +; CHECK-DAG: U _start2 +; CHECK-DAG: t foo@@SOME_VERSION1 +; CHECK-DAG: t foo@SOME_VERSION2 +; CHECK-DAG: t foo@@SOME_VERSION3