summaryrefslogtreecommitdiff
path: root/devel/llvm60/files/patch-head-r331366.diff
diff options
context:
space:
mode:
Diffstat (limited to 'devel/llvm60/files/patch-head-r331366.diff')
-rw-r--r--devel/llvm60/files/patch-head-r331366.diff609
1 files changed, 609 insertions, 0 deletions
diff --git a/devel/llvm60/files/patch-head-r331366.diff b/devel/llvm60/files/patch-head-r331366.diff
new file mode 100644
index 000000000000..dccde7fb6bd6
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r331366.diff
@@ -0,0 +1,609 @@
+r331366 | dim | 2018-03-22 19:58:34 +0100 (Thu, 22 Mar 2018) | 61 lines
+
+Pull in r327101 from upstream llvm trunk (by Rafael Espindola):
+
+ Don't treat .symver as a regular alias definition.
+
+ This patch starts simplifying the handling of .symver.
+
+ For now it just moves the responsibility for creating an alias down to
+ the streamer. With that the asm streamer can pass a .symver unchanged,
+ which is nice since gas cannot parse "foo@bar = zed".
+
+ In a followup I hope to move the handling down to the writer so that
+ we don't need special hacks for avoiding breaking names with @@@ on
+ windows.
+
+Pull in r327160 from upstream llvm trunk (by Rafael Espindola):
+
+ Delay creating an alias for @@@.
+
+ With this we only create an alias for @@@ once we know if it should
+ use @ or @@. This avoids last minutes renames and hacks to handle MS
+ names.
+
+ This only handles the ELF writer. LTO still has issues with @@@
+ aliases.
+
+Pull in r327928 from upstream llvm trunk (by Vitaly Buka):
+
+ Object: Move attribute calculation into RecordStreamer. NFC
+
+ Summary: Preparation for D44274
+
+ Reviewers: pcc, espindola
+
+ Subscribers: hiraditya
+
+ Differential Revision: https://reviews.llvm.org/D44276
+
+Pull in r327930 from upstream llvm trunk (by Vitaly Buka):
+
+ 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
+
+Together, these changes fix handling of @@@ in .symver directives when
+doing Link Time Optimization.
+
+Reported by: Shawn Webb <shawn.webb@hardenedbsd.org>
+MFC after: 3 months
+X-MFC-With: r327952
+
+Index: include/llvm/MC/MCAssembler.h
+===================================================================
+--- include/llvm/MC/MCAssembler.h (revision 331365)
++++ include/llvm/MC/MCAssembler.h (revision 331366)
+@@ -206,6 +206,8 @@ class MCAssembler {
+ handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
+
+ public:
++ std::vector<std::pair<StringRef, const MCSymbol *>> Symvers;
++
+ /// Construct a new assembler instance.
+ //
+ // FIXME: How are we going to parameterize this? Two obvious options are stay
+Index: include/llvm/MC/MCELFStreamer.h
+===================================================================
+--- include/llvm/MC/MCELFStreamer.h (revision 331365)
++++ include/llvm/MC/MCELFStreamer.h (revision 331366)
+@@ -51,6 +51,8 @@ class MCELFStreamer : public MCObjectStreamer {
+ unsigned ByteAlignment) override;
+
+ void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
++ void emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) override;
+
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+Index: include/llvm/MC/MCStreamer.h
+===================================================================
+--- include/llvm/MC/MCStreamer.h (revision 331365)
++++ include/llvm/MC/MCStreamer.h (revision 331366)
+@@ -519,9 +519,10 @@ class MCStreamer {
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .symver _start, foo@@SOME_VERSION
+- /// \param Alias - The versioned alias (i.e. "foo@@SOME_VERSION")
++ /// \param AliasName - The versioned alias (i.e. "foo@@SOME_VERSION")
+ /// \param Aliasee - The aliased symbol (i.e. "_start")
+- virtual void emitELFSymverDirective(MCSymbol *Alias, const MCSymbol *Aliasee);
++ virtual void emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee);
+
+ /// \brief Emit a Linker Optimization Hint (LOH) directive.
+ /// \param Args - Arguments of the LOH.
+Index: lib/MC/ELFObjectWriter.cpp
+===================================================================
+--- lib/MC/ELFObjectWriter.cpp (revision 331365)
++++ lib/MC/ELFObjectWriter.cpp (revision 331366)
+@@ -128,8 +128,6 @@ class ELFObjectWriter : public MCObjectWriter {
+ /// @name Symbol Table Data
+ /// @{
+
+- BumpPtrAllocator Alloc;
+- StringSaver VersionSymSaver{Alloc};
+ StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
+
+ /// @}
+@@ -391,27 +389,29 @@ void ELFObjectWriter::executePostLayoutBinding(MCA
+ const MCAsmLayout &Layout) {
+ // The presence of symbol versions causes undefined symbols and
+ // versions declared with @@@ to be renamed.
+- for (const MCSymbol &A : Asm.symbols()) {
+- const auto &Alias = cast<MCSymbolELF>(A);
+- // Not an alias.
+- if (!Alias.isVariable())
+- continue;
+- auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue());
+- if (!Ref)
+- continue;
+- const auto &Symbol = cast<MCSymbolELF>(Ref->getSymbol());
+-
+- StringRef AliasName = Alias.getName();
++ for (const std::pair<StringRef, const MCSymbol *> &P : Asm.Symvers) {
++ StringRef AliasName = P.first;
++ const auto &Symbol = cast<MCSymbolELF>(*P.second);
+ size_t Pos = AliasName.find('@');
+- if (Pos == StringRef::npos)
+- continue;
++ assert(Pos != StringRef::npos);
+
++ StringRef Prefix = AliasName.substr(0, Pos);
++ StringRef Rest = AliasName.substr(Pos);
++ StringRef Tail = Rest;
++ if (Rest.startswith("@@@"))
++ Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
++
++ auto *Alias =
++ cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
++ Asm.registerSymbol(*Alias);
++ const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
++ Alias->setVariableValue(Value);
++
+ // Aliases defined with .symvar copy the binding from the symbol they alias.
+ // This is the first place we are able to copy this information.
+- Alias.setExternal(Symbol.isExternal());
+- Alias.setBinding(Symbol.getBinding());
++ Alias->setExternal(Symbol.isExternal());
++ Alias->setBinding(Symbol.getBinding());
+
+- StringRef Rest = AliasName.substr(Pos);
+ if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
+ continue;
+
+@@ -420,7 +420,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCA
+ !Rest.startswith("@@@"))
+ report_fatal_error("A @@ version cannot be undefined");
+
+- Renames.insert(std::make_pair(&Symbol, &Alias));
++ Renames.insert(std::make_pair(&Symbol, Alias));
+ }
+ }
+
+@@ -836,44 +836,7 @@ void ELFObjectWriter::computeSymbolTable(
+ HasLargeSectionIndex = true;
+ }
+
+- // The @@@ in symbol version is replaced with @ in undefined symbols and @@
+- // in defined ones.
+- //
+- // FIXME: All name handling should be done before we get to the writer,
+- // including dealing with GNU-style version suffixes. Fixing this isn't
+- // trivial.
+- //
+- // We thus have to be careful to not perform the symbol version replacement
+- // blindly:
+- //
+- // The ELF format is used on Windows by the MCJIT engine. Thus, on
+- // Windows, the ELFObjectWriter can encounter symbols mangled using the MS
+- // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC
+- // C++ name mangling can legally have "@@@" as a sub-string. In that case,
+- // the EFLObjectWriter should not interpret the "@@@" sub-string as
+- // specifying GNU-style symbol versioning. The ELFObjectWriter therefore
+- // checks for the MSVC C++ name mangling prefix which is either "?", "@?",
+- // "__imp_?" or "__imp_@?".
+- //
+- // It would have been interesting to perform the MS mangling prefix check
+- // only when the target triple is of the form *-pc-windows-elf. But, it
+- // seems that this information is not easily accessible from the
+- // ELFObjectWriter.
+ StringRef Name = Symbol.getName();
+- SmallString<32> Buf;
+- if (!Name.startswith("?") && !Name.startswith("@?") &&
+- !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) {
+- // This symbol isn't following the MSVC C++ name mangling convention. We
+- // can thus safely interpret the @@@ in symbol names as specifying symbol
+- // versioning.
+- size_t Pos = Name.find("@@@");
+- if (Pos != StringRef::npos) {
+- Buf += Name.substr(0, Pos);
+- unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
+- Buf += Name.substr(Pos + Skip);
+- Name = VersionSymSaver.save(Buf.c_str());
+- }
+- }
+
+ // Sections have their own string table
+ if (Symbol.getType() != ELF::STT_SECTION) {
+Index: lib/MC/MCAsmStreamer.cpp
+===================================================================
+--- lib/MC/MCAsmStreamer.cpp (revision 331365)
++++ lib/MC/MCAsmStreamer.cpp (revision 331366)
+@@ -129,6 +129,9 @@ class MCAsmStreamer final : public MCStreamer {
+
+ void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
+
++ void emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) override;
++
+ void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+
+@@ -411,6 +414,14 @@ void MCAsmStreamer::ChangeSection(MCSection *Secti
+ }
+ }
+
++void MCAsmStreamer::emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) {
++ OS << ".symver ";
++ Aliasee->print(OS, MAI);
++ OS << ", " << AliasName;
++ EmitEOL();
++}
++
+ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCStreamer::EmitLabel(Symbol, Loc);
+
+Index: lib/MC/MCELFStreamer.cpp
+===================================================================
+--- lib/MC/MCELFStreamer.cpp (revision 331365)
++++ lib/MC/MCELFStreamer.cpp (revision 331366)
+@@ -337,6 +337,11 @@ void MCELFStreamer::emitELFSize(MCSymbol *Symbol,
+ cast<MCSymbolELF>(Symbol)->setSize(Value);
+ }
+
++void MCELFStreamer::emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) {
++ getAssembler().Symvers.push_back({AliasName, Aliasee});
++}
++
+ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
+ unsigned ByteAlignment) {
+ auto *Symbol = cast<MCSymbolELF>(S);
+Index: lib/MC/MCParser/ELFAsmParser.cpp
+===================================================================
+--- lib/MC/MCParser/ELFAsmParser.cpp (revision 331365)
++++ lib/MC/MCParser/ELFAsmParser.cpp (revision 331366)
+@@ -767,12 +767,8 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef,
+ if (AliasName.find('@') == StringRef::npos)
+ return TokError("expected a '@' in the name");
+
+- MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
+ MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
+- const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext());
+-
+- getStreamer().EmitAssignment(Alias, Value);
+- getStreamer().emitELFSymverDirective(Alias, Sym);
++ getStreamer().emitELFSymverDirective(AliasName, Sym);
+ return false;
+ }
+
+Index: lib/MC/MCStreamer.cpp
+===================================================================
+--- lib/MC/MCStreamer.cpp (revision 331365)
++++ lib/MC/MCStreamer.cpp (revision 331366)
+@@ -925,7 +925,7 @@ void MCStreamer::EmitCOFFSymbolType(int Type) {
+ llvm_unreachable("this directive only supported on COFF targets");
+ }
+ void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
+-void MCStreamer::emitELFSymverDirective(MCSymbol *Alias,
++void MCStreamer::emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) {}
+ void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {}
+Index: lib/Object/ModuleSymbolTable.cpp
+===================================================================
+--- lib/Object/ModuleSymbolTable.cpp (revision 331365)
++++ lib/Object/ModuleSymbolTable.cpp (revision 331366)
+@@ -24,7 +24,6 @@
+ #include "llvm/IR/GlobalAlias.h"
+ #include "llvm/IR/GlobalValue.h"
+ #include "llvm/IR/GlobalVariable.h"
+-#include "llvm/IR/Mangler.h"
+ #include "llvm/IR/Module.h"
+ #include "llvm/MC/MCAsmInfo.h"
+ #include "llvm/MC/MCContext.h"
+@@ -69,81 +68,6 @@ void ModuleSymbolTable::addModule(Module *M) {
+ });
+ }
+
+-// Ensure ELF .symver aliases get the same binding as the defined symbol
+-// they alias with.
+-static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
+- if (Streamer.symverAliases().empty())
+- return;
+-
+- // The name in the assembler will be mangled, but the name in the IR
+- // might not, so we first compute a mapping from mangled name to GV.
+- Mangler Mang;
+- SmallString<64> MangledName;
+- StringMap<const GlobalValue *> MangledNameMap;
+- auto GetMangledName = [&](const GlobalValue &GV) {
+- if (!GV.hasName())
+- return;
+-
+- MangledName.clear();
+- MangledName.reserve(GV.getName().size() + 1);
+- Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
+- MangledNameMap[MangledName] = &GV;
+- };
+- for (const Function &F : M)
+- GetMangledName(F);
+- for (const GlobalVariable &GV : M.globals())
+- GetMangledName(GV);
+- for (const GlobalAlias &GA : M.aliases())
+- GetMangledName(GA);
+-
+- // Walk all the recorded .symver aliases, and set up the binding
+- // for each alias.
+- for (auto &Symver : Streamer.symverAliases()) {
+- const MCSymbol *Aliasee = Symver.first;
+- MCSymbolAttr Attr = MCSA_Invalid;
+-
+- // First check if the aliasee binding was recorded in the asm.
+- RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
+- switch (state) {
+- case RecordStreamer::Global:
+- case RecordStreamer::DefinedGlobal:
+- Attr = MCSA_Global;
+- break;
+- case RecordStreamer::UndefinedWeak:
+- case RecordStreamer::DefinedWeak:
+- Attr = MCSA_Weak;
+- break;
+- default:
+- 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());
+- if (!GV) {
+- auto MI = MangledNameMap.find(Aliasee->getName());
+- if (MI != MangledNameMap.end())
+- GV = MI->second;
+- else
+- continue;
+- }
+- if (GV->hasExternalLinkage())
+- Attr = MCSA_Global;
+- else if (GV->hasLocalLinkage())
+- Attr = MCSA_Local;
+- else if (GV->isWeakForLinker())
+- Attr = MCSA_Weak;
+- }
+- if (Attr == MCSA_Invalid)
+- continue;
+-
+- // Set the detected binding on each alias with this aliasee.
+- for (auto &Alias : Symver.second)
+- Streamer.EmitSymbolAttribute(Alias, Attr);
+- }
+-}
+-
+ void ModuleSymbolTable::CollectAsmSymbols(
+ const Module &M,
+ function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
+@@ -176,7 +100,7 @@ void ModuleSymbolTable::CollectAsmSymbols(
+ MCObjectFileInfo MOFI;
+ MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
+ MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
+- RecordStreamer Streamer(MCCtx);
++ RecordStreamer Streamer(MCCtx, M);
+ T->createNullTargetStreamer(Streamer);
+
+ std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
+@@ -195,7 +119,7 @@ void ModuleSymbolTable::CollectAsmSymbols(
+ if (Parser->Run(false))
+ return;
+
+- handleSymverAliases(M, Streamer);
++ Streamer.flushSymverDirectives();
+
+ for (auto &KV : Streamer) {
+ StringRef Key = KV.first();
+Index: lib/Object/RecordStreamer.cpp
+===================================================================
+--- lib/Object/RecordStreamer.cpp (revision 331365)
++++ lib/Object/RecordStreamer.cpp (revision 331366)
+@@ -8,6 +8,9 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "RecordStreamer.h"
++#include "llvm/IR/Mangler.h"
++#include "llvm/IR/Module.h"
++#include "llvm/MC/MCContext.h"
+ #include "llvm/MC/MCSymbol.h"
+
+ using namespace llvm;
+@@ -70,7 +73,8 @@ void RecordStreamer::markUsed(const MCSymbol &Symb
+
+ void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
+
+-RecordStreamer::RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
++RecordStreamer::RecordStreamer(MCContext &Context, const Module &M)
++ : MCStreamer(Context), M(M) {}
+
+ RecordStreamer::const_iterator RecordStreamer::begin() {
+ return Symbols.begin();
+@@ -112,7 +116,109 @@ void RecordStreamer::EmitCommonSymbol(MCSymbol *Sy
+ markDefined(*Symbol);
+ }
+
+-void RecordStreamer::emitELFSymverDirective(MCSymbol *Alias,
++RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
++ auto SI = Symbols.find(Sym->getName());
++ if (SI == Symbols.end())
++ return NeverSeen;
++ return SI->second;
++}
++
++void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) {
+- SymverAliasMap[Aliasee].push_back(Alias);
++ SymverAliasMap[Aliasee].push_back(AliasName);
+ }
++
++void RecordStreamer::flushSymverDirectives() {
++ // Mapping from mangled name to GV.
++ StringMap<const GlobalValue *> MangledNameMap;
++ // The name in the assembler will be mangled, but the name in the IR
++ // might not, so we first compute a mapping from mangled name to GV.
++ Mangler Mang;
++ SmallString<64> MangledName;
++ for (const GlobalValue &GV : M.global_values()) {
++ if (!GV.hasName())
++ continue;
++ MangledName.clear();
++ MangledName.reserve(GV.getName().size() + 1);
++ Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
++ MangledNameMap[MangledName] = &GV;
++ }
++
++ // Walk all the recorded .symver aliases, and set up the binding
++ // for each alias.
++ 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);
++ switch (state) {
++ case RecordStreamer::Global:
++ case RecordStreamer::DefinedGlobal:
++ Attr = MCSA_Global;
++ break;
++ case RecordStreamer::UndefinedWeak:
++ case RecordStreamer::DefinedWeak:
++ Attr = MCSA_Weak;
++ break;
++ default:
++ break;
++ }
++
++ 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 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 @@.
++ const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
++ EmitAssignment(Alias, Value);
++ if (Attr != MCSA_Invalid)
++ EmitSymbolAttribute(Alias, Attr);
++ }
++ }
++}
+Index: lib/Object/RecordStreamer.h
+===================================================================
+--- lib/Object/RecordStreamer.h (revision 331365)
++++ lib/Object/RecordStreamer.h (revision 331366)
+@@ -20,6 +20,9 @@
+
+ namespace llvm {
+
++class GlobalValue;
++class Module;
++
+ class RecordStreamer : public MCStreamer {
+ public:
+ enum State { NeverSeen, Global, Defined, DefinedGlobal, DefinedWeak, Used,
+@@ -26,12 +29,16 @@ class RecordStreamer : public MCStreamer {
+ UndefinedWeak};
+
+ private:
++ const Module &M;
+ StringMap<State> Symbols;
+ // Map of aliases created by .symver directives, saved so we can update
+ // their symbol binding after parsing complete. This maps from each
+ // aliasee to its list of aliases.
+- DenseMap<const MCSymbol *, std::vector<MCSymbol *>> SymverAliasMap;
++ DenseMap<const MCSymbol *, std::vector<StringRef>> SymverAliasMap;
+
++ /// Get the state recorded for the given symbol.
++ State getSymbolState(const MCSymbol *Sym);
++
+ void markDefined(const MCSymbol &Symbol);
+ void markGlobal(const MCSymbol &Symbol, MCSymbolAttr Attribute);
+ void markUsed(const MCSymbol &Symbol);
+@@ -38,7 +45,7 @@ class RecordStreamer : public MCStreamer {
+ void visitUsedSymbol(const MCSymbol &Sym) override;
+
+ public:
+- RecordStreamer(MCContext &Context);
++ RecordStreamer(MCContext &Context, const Module &M);
+
+ using const_iterator = StringMap<State>::const_iterator;
+
+@@ -54,20 +61,11 @@ class RecordStreamer : public MCStreamer {
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ /// Record .symver aliases for later processing.
+- void emitELFSymverDirective(MCSymbol *Alias,
++ void emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) override;
+- /// Return the map of .symver aliasee to associated aliases.
+- DenseMap<const MCSymbol *, std::vector<MCSymbol *>> &symverAliases() {
+- return SymverAliasMap;
+- }
+-
+- /// Get the state recorded for the given symbol.
+- State getSymbolState(const MCSymbol *Sym) {
+- auto SI = Symbols.find(Sym->getName());
+- if (SI == Symbols.end())
+- return NeverSeen;
+- return SI->second;
+- }
++ // Emit ELF .symver aliases and ensure they have the same binding as the
++ // defined symbol they alias with.
++ void flushSymverDirectives();
+ };
+
+ } // end namespace llvm