diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 75 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/MC/MCELFStreamer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/ELFAsmParser.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Object/RecordStreamer.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Object/RecordStreamer.h | 2 |
7 files changed, 30 insertions, 68 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index e11eaaa3060..989d4bb4eb9 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<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(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 1d7aa5a9067..d92a63adc69 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 646d0dbded4..6b1c589f038 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<MCSymbolELF>(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 510c456c775..b9fa49e131b 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 bf27a0abfda..7d847c67605 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 a9e3a46b519..56e9ce73047 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 4d119091a3d..e1e23f260ac 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<const MCSymbol *, std::vector<MCSymbol *>> &symverAliases() { |