From: Rafael Espindola Date: Fri, 9 Mar 2018 18:42:25 +0000 (+0000) Subject: Delay creating an alias for @@@. X-Git-Tag: llvmorg-7.0.0-rc1~10969 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=47b4d6ba196d09900284caff7ed372b3878f28ef;p=platform%2Fupstream%2Fllvm.git 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. llvm-svn: 327160 --- diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index 0346055..b91b044 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -206,6 +206,8 @@ private: handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup); public: + std::vector> Symvers; + /// Construct a new assembler instance. // // FIXME: How are we going to parameterize this? Two obvious options are stay diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 4b3e6aa..2f23cd6 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -51,7 +51,7 @@ public: unsigned ByteAlignment) override; void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; - void emitELFSymverDirective(MCSymbol *Alias, + void emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) override; void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 8f0230d..288bcba 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -525,9 +525,10 @@ public: /// /// 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. diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index e11eaaa..989d4bb 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -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(MCAssembler &Asm, 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(A); - // Not an alias. - if (!Alias.isVariable()) - continue; - auto *Ref = dyn_cast(Alias.getVariableValue()); - if (!Ref) - continue; - const auto &Symbol = cast(Ref->getSymbol()); - - StringRef AliasName = Alias.getName(); + for (const std::pair &P : Asm.Symvers) { + StringRef AliasName = P.first; + const auto &Symbol = cast(*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(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(MCAssembler &Asm, !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) { diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 1d7aa5a..d92a63a 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -130,7 +130,7 @@ public: void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; - void emitELFSymverDirective(MCSymbol *Alias, + void emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) override; void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override; @@ -417,12 +417,11 @@ void MCAsmStreamer::ChangeSection(MCSection *Section, } } -void MCAsmStreamer::emitELFSymverDirective(MCSymbol *Alias, +void MCAsmStreamer::emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) { OS << ".symver "; Aliasee->print(OS, MAI); - OS << ", "; - Alias->print(OS, MAI); + OS << ", " << AliasName; EmitEOL(); } diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 646d0db..6b1c589 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -337,10 +337,9 @@ void MCELFStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) { cast(Symbol)->setSize(Value); } -void MCELFStreamer::emitELFSymverDirective(MCSymbol *Alias, +void MCELFStreamer::emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) { - const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext()); - EmitAssignment(Alias, Value); + getAssembler().Symvers.push_back({AliasName, Aliasee}); } void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size, diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 510c456..b9fa49e 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -769,9 +769,8 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { if (AliasName.find('@') == StringRef::npos) return TokError("expected a '@' in the name"); - MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); MCSymbol *Sym = getContext().getOrCreateSymbol(Name); - getStreamer().emitELFSymverDirective(Alias, Sym); + getStreamer().emitELFSymverDirective(AliasName, Sym); return false; } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index bf27a0a..7d847c6 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -929,7 +929,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) {} diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp index a9e3a46..56e9ce7 100644 --- a/llvm/lib/Object/RecordStreamer.cpp +++ b/llvm/lib/Object/RecordStreamer.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "RecordStreamer.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCSymbol.h" using namespace llvm; @@ -112,8 +113,9 @@ void RecordStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, markDefined(*Symbol); } -void RecordStreamer::emitELFSymverDirective(MCSymbol *Alias, +void RecordStreamer::emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) { + MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext()); EmitAssignment(Alias, Value); SymverAliasMap[Aliasee].push_back(Alias); diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h index 4d11909..e1e23f2 100644 --- a/llvm/lib/Object/RecordStreamer.h +++ b/llvm/lib/Object/RecordStreamer.h @@ -54,7 +54,7 @@ public: 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> &symverAliases() {