X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCAsmStreamer.cpp;h=0f405ad1193ec3081517feaab6148faf6c0c9baf;hb=79e04c584474f81e3faef29e33b7195bc7e4d1f6;hp=f60c7fc50415ffa4840656a8e131bc9800c7b013;hpb=b9cb76d3f3d37855bffc20eb63825d90a54a5644;p=oota-llvm.git diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index f60c7fc5041..0f405ad1193 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -8,8 +8,8 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCStreamer.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmBackend.h" @@ -24,7 +24,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionMachO.h" -#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" @@ -32,16 +32,14 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include -#include using namespace llvm; namespace { -class MCAsmStreamer : public MCStreamer { -protected: +class MCAsmStreamer final : public MCStreamer { + std::unique_ptr OSOwner; formatted_raw_ostream &OS; const MCAsmInfo *MAI; -private: std::unique_ptr InstPrinter; std::unique_ptr Emitter; std::unique_ptr AsmBackend; @@ -58,16 +56,18 @@ private: void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; public: - MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, + MCAsmStreamer(MCContext &Context, std::unique_ptr os, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *printer, MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst) - : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), - InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), - CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), - ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) { - if (InstPrinter && IsVerboseAsm) - InstPrinter->setCommentStream(CommentStream); + : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner), + MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), + AsmBackend(asmbackend), CommentStream(CommentToEmit), + IsVerboseAsm(isVerboseAsm), ShowInst(showInst), + UseDwarfDirectory(useDwarfDirectory) { + assert(InstPrinter); + if (IsVerboseAsm) + InstPrinter->setCommentStream(CommentStream); } inline void EmitEOL() { @@ -115,8 +115,7 @@ public: /// @name MCStreamer Interface /// @{ - void ChangeSection(const MCSection *Section, - const MCExpr *Subsection) override; + void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override; void EmitLabel(MCSymbol *Symbol) override; @@ -137,9 +136,10 @@ public: void EmitCOFFSymbolStorageClass(int StorageClass) override; void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; + void EmitCOFFSafeSEH(MCSymbol const *Symbol) override; void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; void EmitCOFFSecRel32(MCSymbol const *Symbol) override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; + void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override; void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; @@ -151,11 +151,11 @@ public: void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr, + void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, uint64_t Size = 0, unsigned ByteAlignment = 0) override; - void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment = 0) override; + void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment = 0) override; void EmitBytes(StringRef Data) override; @@ -268,7 +268,7 @@ void MCAsmStreamer::EmitCommentsAndEOL() { } CommentStream.flush(); - StringRef Comments = CommentToEmit.str(); + StringRef Comments = CommentToEmit; assert(Comments.back() == '\n' && "Comment array not newline terminated"); @@ -298,7 +298,7 @@ void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) { EmitEOL(); } -void MCAsmStreamer::ChangeSection(const MCSection *Section, +void MCAsmStreamer::ChangeSection(MCSection *Section, const MCExpr *Subsection) { assert(Section && "Cannot switch to a null section!"); Section->PrintSwitchToSection(*MAI, OS, Subsection); @@ -308,7 +308,9 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); MCStreamer::EmitLabel(Symbol); - OS << *Symbol << MAI->getLabelSuffix(); + Symbol->print(OS, MAI); + OS << MAI->getLabelSuffix(); + EmitEOL(); } @@ -328,7 +330,7 @@ void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) { if (!IsFirst) OS << ", "; IsFirst = false; - OS << **It; + (*It)->print(OS, MAI); } EmitEOL(); } @@ -384,20 +386,28 @@ void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) { // MCSymbols when they have spaces in them. OS << "\t.thumb_func"; // Only Mach-O hasSubsectionsViaSymbols() - if (MAI->hasSubsectionsViaSymbols()) - OS << '\t' << *Func; + if (MAI->hasSubsectionsViaSymbols()) { + OS << '\t'; + Func->print(OS, MAI); + } EmitEOL(); } void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { - OS << *Symbol << " = " << *Value; + Symbol->print(OS, MAI); + OS << " = "; + Value->print(OS, MAI); + EmitEOL(); MCStreamer::EmitAssignment(Symbol, Value); } void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { - OS << ".weakref " << *Alias << ", " << *Symbol; + OS << ".weakref "; + Alias->print(OS, MAI); + OS << ", "; + Symbol->print(OS, MAI); EmitEOL(); } @@ -414,8 +424,9 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object if (!MAI->hasDotTypeDotSizeDirective()) return false; // Symbol attribute not supported - OS << "\t.type\t" << *Symbol << ',' - << ((MAI->getCommentString()[0] != '@') ? '@' : '%'); + OS << "\t.type\t"; + Symbol->print(OS, MAI); + OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%'); switch (Attribute) { default: return false; case MCSA_ELF_TypeFunction: OS << "function"; break; @@ -436,14 +447,18 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_Internal: OS << "\t.internal\t"; break; case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break; case MCSA_Local: OS << "\t.local\t"; break; - case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break; + case MCSA_NoDeadStrip: + if (!MAI->hasNoDeadStrip()) + return false; + OS << "\t.no_dead_strip\t"; + break; case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break; case MCSA_PrivateExtern: OS << "\t.private_extern\t"; break; case MCSA_Protected: OS << "\t.protected\t"; break; case MCSA_Reference: OS << "\t.reference\t"; break; - case MCSA_Weak: OS << "\t.weak\t"; break; + case MCSA_Weak: OS << MAI->getWeakDirective(); break; case MCSA_WeakDefinition: OS << "\t.weak_definition\t"; break; @@ -452,19 +467,23 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break; } - OS << *Symbol; + Symbol->print(OS, MAI); EmitEOL(); return true; } void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { - OS << ".desc" << ' ' << *Symbol << ',' << DescValue; + OS << ".desc" << ' '; + Symbol->print(OS, MAI); + OS << ',' << DescValue; EmitEOL(); } void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { - OS << "\t.def\t " << *Symbol << ';'; + OS << "\t.def\t "; + Symbol->print(OS, MAI); + OS << ';'; EmitEOL(); } @@ -483,19 +502,30 @@ void MCAsmStreamer::EndCOFFSymbolDef() { EmitEOL(); } +void MCAsmStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { + OS << "\t.safeseh\t" << *Symbol; + EmitEOL(); +} + void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { - OS << "\t.secidx\t" << *Symbol; + OS << "\t.secidx\t"; + Symbol->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { - OS << "\t.secrel32\t" << *Symbol; + OS << "\t.secrel32\t"; + Symbol->print(OS, MAI); EmitEOL(); } -void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { +void MCAsmStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) { assert(MAI->hasDotTypeDotSizeDirective()); - OS << "\t.size\t" << *Symbol << ", " << *Value << '\n'; + OS << "\t.size\t"; + Symbol->print(OS, MAI); + OS << ", "; + Value->print(OS, MAI); + OS << '\n'; } void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -503,7 +533,10 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, // Common symbols do not belong to any actual section. AssignSection(Symbol, nullptr); - OS << "\t.comm\t" << *Symbol << ',' << Size; + OS << "\t.comm\t"; + Symbol->print(OS, MAI); + OS << ',' << Size; + if (ByteAlignment != 0) { if (MAI->getCOMMDirectiveAlignmentIsInBytes()) OS << ',' << ByteAlignment; @@ -522,7 +555,10 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, // Common symbols do not belong to any actual section. AssignSection(Symbol, nullptr); - OS << "\t.lcomm\t" << *Symbol << ',' << Size; + OS << "\t.lcomm\t"; + Symbol->print(OS, MAI); + OS << ',' << Size; + if (ByteAlign > 1) { switch (MAI->getLCOMMDirectiveAlignmentType()) { case LCOMM::NoAlignment: @@ -539,7 +575,7 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, EmitEOL(); } -void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, +void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { if (Symbol) AssignSection(Symbol, Section); @@ -552,7 +588,9 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, OS << MOSection->getSegmentName() << "," << MOSection->getSectionName(); if (Symbol) { - OS << ',' << *Symbol << ',' << Size; + OS << ','; + Symbol->print(OS, MAI); + OS << ',' << Size; if (ByteAlignment != 0) OS << ',' << Log2_32(ByteAlignment); } @@ -562,14 +600,16 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, // .tbss sym, size, align // This depends that the symbol has already been mangled from the original, // e.g. _a. -void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, +void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { AssignSection(Symbol, Section); assert(Symbol && "Symbol shouldn't be NULL!"); // Instead of using the Section we'll just use the shortcut. // This is a mach-o specific directive and section. - OS << ".tbss " << *Symbol << ", " << Size; + OS << ".tbss "; + Symbol->print(OS, MAI); + OS << ", " << Size; // Output align if we have it. We default to 1 so don't bother printing // that. @@ -640,7 +680,7 @@ void MCAsmStreamer::EmitBytes(StringRef Data) { } void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) { - EmitValue(MCConstantExpr::Create(Value, getContext()), Size); + EmitValue(MCConstantExpr::create(Value, getContext()), Size); } void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, @@ -659,7 +699,7 @@ void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, if (!Directive) { int64_t IntValue; - if (!Value->EvaluateAsAbsolute(IntValue)) + if (!Value->evaluateAsAbsolute(IntValue)) report_fatal_error("Don't know how to emit this value."); // We couldn't handle the requested integer size so we fallback by breaking @@ -682,7 +722,11 @@ void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, // We truncate our partial emission to fit within the bounds of the // emission domain. This produces nicer output and silences potential // truncation warnings when round tripping through another assembler. - ValueToEmit &= ~0ULL >> (64 - EmissionSize * 8); + uint64_t Shift = 64 - EmissionSize * 8; + assert(Shift < static_cast( + std::numeric_limits::digits) && + "undefined behavior"); + ValueToEmit &= ~0ULL >> Shift; EmitIntValue(ValueToEmit, EmissionSize); Emitted += EmissionSize; } @@ -690,39 +734,44 @@ void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, } assert(Directive && "Invalid size for machine code value!"); - OS << Directive << *Value; + OS << Directive; + Value->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) { int64_t IntValue; - if (Value->EvaluateAsAbsolute(IntValue)) { + if (Value->evaluateAsAbsolute(IntValue)) { EmitULEB128IntValue(IntValue); return; } - OS << ".uleb128 " << *Value; + OS << ".uleb128 "; + Value->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { int64_t IntValue; - if (Value->EvaluateAsAbsolute(IntValue)) { + if (Value->evaluateAsAbsolute(IntValue)) { EmitSLEB128IntValue(IntValue); return; } - OS << ".sleb128 " << *Value; + OS << ".sleb128 "; + Value->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) { assert(MAI->getGPRel64Directive() != nullptr); - OS << MAI->getGPRel64Directive() << *Value; + OS << MAI->getGPRel64Directive(); + Value->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { assert(MAI->getGPRel32Directive() != nullptr); - OS << MAI->getGPRel32Directive() << *Value; + OS << MAI->getGPRel32Directive(); + Value->print(OS, MAI); EmitEOL(); } @@ -809,7 +858,9 @@ void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment, bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { // FIXME: Verify that Offset is associated with the current section. - OS << ".org " << *Offset << ", " << (unsigned) Value; + OS << ".org "; + Offset->print(OS, MAI); + OS << ", " << (unsigned)Value; EmitEOL(); return false; } @@ -865,8 +916,6 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Isa, unsigned Discriminator, StringRef FileName) { - this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, - Isa, Discriminator, FileName); OS << "\t.loc\t" << FileNo << " " << Line << " " << Column; if (Flags & DWARF2_FLAG_BASIC_BLOCK) OS << " basic_block"; @@ -896,6 +945,8 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, << Line << ':' << Column; } EmitEOL(); + this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, + Isa, Discriminator, FileName); } MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) { @@ -939,7 +990,7 @@ void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { } void MCAsmStreamer::EmitRegisterName(int64_t Register) { - if (InstPrinter && !MAI->useDwarfRegNumForCFI()) { + if (!MAI->useDwarfRegNumForCFI()) { const MCRegisterInfo *MRI = getContext().getRegisterInfo(); unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true); InstPrinter->printRegName(OS, LLVMRegister); @@ -980,13 +1031,15 @@ void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) { MCStreamer::EmitCFIPersonality(Sym, Encoding); - OS << "\t.cfi_personality " << Encoding << ", " << *Sym; + OS << "\t.cfi_personality " << Encoding << ", "; + Sym->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { MCStreamer::EmitCFILsda(Sym, Encoding); - OS << "\t.cfi_lsda " << Encoding << ", " << *Sym; + OS << "\t.cfi_lsda " << Encoding << ", "; + Sym->print(OS, MAI); EmitEOL(); } @@ -1050,7 +1103,8 @@ void MCAsmStreamer::EmitCFIWindowSave() { void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { MCStreamer::EmitWinCFIStartProc(Symbol); - OS << ".seh_proc " << *Symbol; + OS << ".seh_proc "; + Symbol->print(OS, MAI); EmitEOL(); } @@ -1079,7 +1133,8 @@ void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) { MCStreamer::EmitWinEHHandler(Sym, Unwind, Except); - OS << "\t.seh_handler " << *Sym; + OS << "\t.seh_handler "; + Sym->print(OS, MAI); if (Unwind) OS << ", @unwind"; if (Except) @@ -1095,9 +1150,9 @@ void MCAsmStreamer::EmitWinEHHandlerData() { // We only do this so the section switch that terminates the handler // data block is visible. WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo(); - if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection( - CurFrame->Function, getContext())) - SwitchSectionNoChange(XData); + MCSection *XData = + WinEH::UnwindEmitter::getXDataSection(CurFrame->Function, getContext()); + SwitchSectionNoChange(XData); OS << "\t.seh_handlerdata"; EmitEOL(); @@ -1160,7 +1215,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, SmallString<256> Code; SmallVector Fixups; raw_svector_ostream VecOS(Code); - Emitter->EncodeInstruction(Inst, VecOS, Fixups, STI); + Emitter->encodeInstruction(Inst, VecOS, Fixups, STI); VecOS.flush(); // If we are showing fixups, create symbolic markers in the encoded @@ -1249,15 +1304,12 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &S // Show the MCInst if enabled. if (ShowInst) { - Inst.dump_pretty(GetCommentOS(), MAI, InstPrinter.get(), "\n "); + Inst.dump_pretty(GetCommentOS(), InstPrinter.get(), "\n "); GetCommentOS() << "\n"; } - // If we have an AsmPrinter, use that to print, otherwise print the MCInst. - if (InstPrinter) - InstPrinter->printInst(&Inst, OS, ""); - else - Inst.print(OS, MAI); + InstPrinter->printInst(&Inst, OS, "", STI); + EmitEOL(); } @@ -1307,10 +1359,10 @@ void MCAsmStreamer::FinishImpl() { } MCStreamer *llvm::createAsmStreamer(MCContext &Context, - formatted_raw_ostream &OS, + std::unique_ptr OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *IP, MCCodeEmitter *CE, MCAsmBackend *MAB, bool ShowInst) { - return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE, - MAB, ShowInst); + return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm, + useDwarfDirectory, IP, CE, MAB, ShowInst); }