diff options
| author | Vitaly Buka <vitalybuka@google.com> | 2018-03-20 00:45:03 +0000 |
|---|---|---|
| committer | Vitaly Buka <vitalybuka@google.com> | 2018-03-20 00:45:03 +0000 |
| commit | 849217abdf784fa3babec81b6d3387a2e4096e56 (patch) | |
| tree | 22d36df3abefc613a50b796d51870b5ce33f18e8 | |
| parent | dc09ebf71b5ad1ac45340ccd24cbb8c2ecffb762 (diff) | |
| download | bcm5719-llvm-849217abdf784fa3babec81b6d3387a2e4096e56.tar.gz bcm5719-llvm-849217abdf784fa3babec81b6d3387a2e4096e56.zip | |
Object: Fix handling of @@@ in .symver directive
Summary:
name@@@nodename is going to be replaced with name@@nodename if symbols is
defined in the assembled file, or name@nodename if undefined.
https://sourceware.org/binutils/docs/as/Symver.html
Fixes PR36623
Reviewers: pcc, espindola
Subscribers: mehdi_amini, hiraditya
Differential Revision: https://reviews.llvm.org/D44274
llvm-svn: 327930
| -rw-r--r-- | llvm/lib/Object/RecordStreamer.cpp | 47 | ||||
| -rw-r--r-- | llvm/test/LTO/X86/symver-asm3.ll | 40 |
2 files changed, 77 insertions, 10 deletions
diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp index 76beff08d73..74130901d32 100644 --- a/llvm/lib/Object/RecordStreamer.cpp +++ b/llvm/lib/Object/RecordStreamer.cpp @@ -149,6 +149,7 @@ void RecordStreamer::flushSymverDirectives() { 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,52 @@ void RecordStreamer::flushSymverDirectives() { 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; + } + + if (Attr == MCSA_Invalid || !IsDefined) { + const GlobalValue *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 = IsDefined || !GV->isDeclarationForLinker(); } } + // Set the detected binding on each alias with this aliasee. for (auto AliasName : Symver.second) { + std::pair<StringRef, StringRef> 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 @@. diff --git a/llvm/test/LTO/X86/symver-asm3.ll b/llvm/test/LTO/X86/symver-asm3.ll new file mode 100644 index 00000000000..90cee28bf60 --- /dev/null +++ b/llvm/test/LTO/X86/symver-asm3.ll @@ -0,0 +1,40 @@ +; 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 "foo1:" +; CHECK-DAG: t foo1 + +module asm ".symver foo1, foo@@@VER1" +; CHECK-DAG: t foo@@VER1 + +module asm ".symver foo2, foo@@@VER2" +; CHECK-DAG: U foo2 +; CHECK-DAG: t foo@VER2 + +module asm ".symver foo3, foo@@@VER3" +; CHECK-DAG: t foo@@VER3 + +module asm ".symver foo4, foo@@@VER4" +; CHECK-DAG: T foo@@VER4 + +module asm ".symver foo5, foo@@@VER5" +; CHECK-DAG: T foo@VER5 + +module asm "foo3:" +; CHECK-DAG: t foo3 + +module asm ".local foo1" +module asm ".local foo3" + +define void @foo4() { +; CHECK-DAG: T foo4 + ret void +} + +declare void @foo5() +; CHECK-DAG: U foo5 |

