Index: llvm/include/llvm/MC/MCObjectStreamer.h =================================================================== --- llvm/include/llvm/MC/MCObjectStreamer.h +++ llvm/include/llvm/MC/MCObjectStreamer.h @@ -14,6 +14,7 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCWinEH.h" namespace llvm { class MCAssembler; @@ -40,6 +41,10 @@ bool EmitDebugFrame; SmallVector PendingLabels; + std::vector WinFrameInfos; + WinEH::FrameInfo *CurrentWinFrameInfo = nullptr; + void EnsureValidWinFrameInfo(); + virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; @@ -49,6 +54,10 @@ MCCodeEmitter *Emitter); ~MCObjectStreamer() override; + WinEH::FrameInfo *getCurrentWinFrameInfo() { + return CurrentWinFrameInfo; + } + public: /// state management void reset() override; @@ -72,6 +81,11 @@ /// fragment is not a data fragment. MCDataFragment *getOrCreateDataFragment(); + unsigned getNumWinFrameInfos() { return WinFrameInfos.size(); } + ArrayRef getWinFrameInfos() const { + return WinFrameInfos; + } + protected: bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection); @@ -170,6 +184,26 @@ unsigned Size) override; bool mayHaveInstructions(MCSection &Sec) const override; + + /// \name Unwind information directives + /// @{ + + void EmitWinCFIStartProc(const MCSymbol *Symbol) override; + void EmitWinCFIEndProc() override; + void EmitWinCFIStartChained() override; + void EmitWinCFIEndChained() override; + void EmitWinCFIPushReg(unsigned Register) override; + void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override; + void EmitWinCFIAllocStack(unsigned Size) override; + void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override; + void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override; + void EmitWinCFIPushFrame(bool Code) override; + void EmitWinCFIEndProlog() override; + + void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override; + void EmitWinEHHandlerData() override; + + /// @} }; } // end namespace llvm Index: llvm/include/llvm/MC/MCStreamer.h =================================================================== --- llvm/include/llvm/MC/MCStreamer.h +++ llvm/include/llvm/MC/MCStreamer.h @@ -22,7 +22,6 @@ #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCWinEH.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/TargetParser.h" #include @@ -173,13 +172,6 @@ MCDwarfFrameInfo *getCurrentDwarfFrameInfo(); void EnsureValidDwarfFrame(); - MCSymbol *EmitCFILabel(); - MCSymbol *EmitCFICommon(); - - std::vector WinFrameInfos; - WinEH::FrameInfo *CurrentWinFrameInfo; - void EnsureValidWinFrameInfo(); - /// \brief Tracks an index to represent the order a symbol was emitted in. /// Zero means we did not emit that symbol. DenseMap SymbolOrdering; @@ -197,13 +189,12 @@ protected: MCStreamer(MCContext &Ctx); + MCSymbol *EmitCFILabel(); + MCSymbol *EmitCFICommon(); + virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame); - WinEH::FrameInfo *getCurrentWinFrameInfo() { - return CurrentWinFrameInfo; - } - virtual void EmitWindowsUnwindTables(); virtual void EmitRawTextImpl(StringRef String); @@ -237,11 +228,6 @@ bool hasUnfinishedDwarfFrameInfo(); - unsigned getNumWinFrameInfos() { return WinFrameInfos.size(); } - ArrayRef getWinFrameInfos() const { - return WinFrameInfos; - } - void generateCompactUnwindEncodings(MCAsmBackend *MAB); /// \name Assembly File Formatting. @@ -814,20 +800,20 @@ virtual void EmitCFIRegister(int64_t Register1, int64_t Register2); virtual void EmitCFIWindowSave(); - virtual void EmitWinCFIStartProc(const MCSymbol *Symbol); - virtual void EmitWinCFIEndProc(); - virtual void EmitWinCFIStartChained(); - virtual void EmitWinCFIEndChained(); - virtual void EmitWinCFIPushReg(unsigned Register); - virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset); - virtual void EmitWinCFIAllocStack(unsigned Size); - virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset); - virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset); - virtual void EmitWinCFIPushFrame(bool Code); - virtual void EmitWinCFIEndProlog(); - - virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except); - virtual void EmitWinEHHandlerData(); + virtual void EmitWinCFIStartProc(const MCSymbol *Symbol) {} + virtual void EmitWinCFIEndProc() {} + virtual void EmitWinCFIStartChained() {} + virtual void EmitWinCFIEndChained() {} + virtual void EmitWinCFIPushReg(unsigned Register) {} + virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset) {} + virtual void EmitWinCFIAllocStack(unsigned Size) {} + virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset) {} + virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {} + virtual void EmitWinCFIPushFrame(bool Code) {} + virtual void EmitWinCFIEndProlog() {} + + virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) {} + virtual void EmitWinEHHandlerData() {} /// Get the .pdata section used for the given section. Typically the given /// section is either the main .text section or some other COMDAT .text Index: llvm/include/llvm/MC/MCWin64EH.h =================================================================== --- llvm/include/llvm/MC/MCWin64EH.h +++ llvm/include/llvm/MC/MCWin64EH.h @@ -19,7 +19,7 @@ #include "llvm/Support/Win64EH.h" namespace llvm { -class MCStreamer; +class MCObjectStreamer; class MCSymbol; namespace Win64EH { @@ -53,8 +53,9 @@ class UnwindEmitter : public WinEH::UnwindEmitter { public: - void Emit(MCStreamer &Streamer) const override; - void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const override; + void Emit(MCObjectStreamer &Streamer) const override; + void EmitUnwindInfo(MCObjectStreamer &Streamer, + WinEH::FrameInfo *FI) const override; }; } } // end namespace llvm Index: llvm/include/llvm/MC/MCWinEH.h =================================================================== --- llvm/include/llvm/MC/MCWinEH.h +++ llvm/include/llvm/MC/MCWinEH.h @@ -14,7 +14,7 @@ namespace llvm { class MCSection; -class MCStreamer; +class MCObjectStreamer; class MCSymbol; namespace WinEH { @@ -58,8 +58,9 @@ virtual ~UnwindEmitter(); /// This emits the unwind info sections (.pdata and .xdata in PE/COFF). - virtual void Emit(MCStreamer &Streamer) const = 0; - virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI) const = 0; + virtual void Emit(MCObjectStreamer &Streamer) const = 0; + virtual void EmitUnwindInfo(MCObjectStreamer &Streamer, + FrameInfo *FI) const = 0; }; } } Index: llvm/lib/MC/MCAsmStreamer.cpp =================================================================== --- llvm/lib/MC/MCAsmStreamer.cpp +++ llvm/lib/MC/MCAsmStreamer.cpp @@ -26,6 +26,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCWinEH.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" @@ -1426,38 +1427,28 @@ } void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { - MCStreamer::EmitWinCFIStartProc(Symbol); - OS << ".seh_proc "; Symbol->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitWinCFIEndProc() { - MCStreamer::EmitWinCFIEndProc(); - OS << "\t.seh_endproc"; EmitEOL(); } void MCAsmStreamer::EmitWinCFIStartChained() { - MCStreamer::EmitWinCFIStartChained(); - OS << "\t.seh_startchained"; EmitEOL(); } void MCAsmStreamer::EmitWinCFIEndChained() { - MCStreamer::EmitWinCFIEndChained(); - OS << "\t.seh_endchained"; EmitEOL(); } void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) { - MCStreamer::EmitWinEHHandler(Sym, Unwind, Except); - OS << "\t.seh_handler "; Sym->print(OS, MAI); if (Unwind) @@ -1468,15 +1459,12 @@ } void MCAsmStreamer::EmitWinEHHandlerData() { - MCStreamer::EmitWinEHHandlerData(); - - // Switch sections. Don't call SwitchSection directly, because that will - // cause the section switch to be visible in the emitted assembly. - // We only do this so the section switch that terminates the handler - // data block is visible. - WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo(); - MCSection *TextSec = &CurFrame->Function->getSection(); - MCSection *XData = getAssociatedXDataSection(TextSec); + // Switch sections. Don't call SwitchSection directly, because that will cause + // the section switch to be visible in the emitted assembly. We only do this + // so the section switch that terminates the handler data block is visible. We + // don't have to have precisely the right .xdata section when printing textual + // assembly. + MCSection *XData = getAssociatedXDataSection(getCurrentSectionOnly()); SwitchSectionNoChange(XData); OS << "\t.seh_handlerdata"; @@ -1484,43 +1472,31 @@ } void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) { - MCStreamer::EmitWinCFIPushReg(Register); - OS << "\t.seh_pushreg " << Register; EmitEOL(); } void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { - MCStreamer::EmitWinCFISetFrame(Register, Offset); - OS << "\t.seh_setframe " << Register << ", " << Offset; EmitEOL(); } void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) { - MCStreamer::EmitWinCFIAllocStack(Size); - OS << "\t.seh_stackalloc " << Size; EmitEOL(); } void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { - MCStreamer::EmitWinCFISaveReg(Register, Offset); - OS << "\t.seh_savereg " << Register << ", " << Offset; EmitEOL(); } void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { - MCStreamer::EmitWinCFISaveXMM(Register, Offset); - OS << "\t.seh_savexmm " << Register << ", " << Offset; EmitEOL(); } void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) { - MCStreamer::EmitWinCFIPushFrame(Code); - OS << "\t.seh_pushframe"; if (Code) OS << " @code"; @@ -1528,8 +1504,6 @@ } void MCAsmStreamer::EmitWinCFIEndProlog() { - MCStreamer::EmitWinCFIEndProlog(); - OS << "\t.seh_endprologue"; EmitEOL(); } Index: llvm/lib/MC/MCObjectStreamer.cpp =================================================================== --- llvm/lib/MC/MCObjectStreamer.cpp +++ llvm/lib/MC/MCObjectStreamer.cpp @@ -20,6 +20,7 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCWin64EH.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" @@ -34,6 +35,8 @@ EmitEHFrame(true), EmitDebugFrame(false) {} MCObjectStreamer::~MCObjectStreamer() { + for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) + delete WinFrameInfos[i]; delete &Assembler->getBackend(); delete &Assembler->getEmitter(); delete &Assembler->getWriter(); @@ -72,7 +75,11 @@ void MCObjectStreamer::reset() { if (Assembler) Assembler->reset(); + for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) + delete WinFrameInfos[i]; + WinFrameInfos.clear(); CurInsertionPoint = MCSection::iterator(); + CurrentWinFrameInfo = nullptr; EmitEHFrame = true; EmitDebugFrame = false; PendingLabels.clear(); @@ -595,6 +602,161 @@ getAssembler().addFileName(Filename); } +void MCObjectStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { + const MCAsmInfo *MAI = getContext().getAsmInfo(); + if (!MAI->usesWindowsCFI()) + report_fatal_error(".seh_* directives are not supported on this target"); + if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End) + report_fatal_error("Starting a function before ending the previous one!"); + MCSymbol *StartProc = EmitCFILabel(); + + WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc)); + CurrentWinFrameInfo = WinFrameInfos.back(); + CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); +} + +void MCObjectStreamer::EnsureValidWinFrameInfo() { + const MCAsmInfo *MAI = getContext().getAsmInfo(); + if (!MAI->usesWindowsCFI()) + report_fatal_error(".seh_* directives are not supported on this target"); + if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) + report_fatal_error("No open Win64 EH frame function!"); +} + +void MCObjectStreamer::EmitWinCFIEndProc() { + EnsureValidWinFrameInfo(); + if (CurrentWinFrameInfo->ChainedParent) + report_fatal_error("Not all chained regions terminated!"); + + MCSymbol *Label = EmitCFILabel(); + CurrentWinFrameInfo->End = Label; +} + +void MCObjectStreamer::EmitWinCFIStartChained() { + EnsureValidWinFrameInfo(); + + MCSymbol *StartProc = EmitCFILabel(); + + WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function, + StartProc, CurrentWinFrameInfo)); + CurrentWinFrameInfo = WinFrameInfos.back(); + CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); +} + +void MCObjectStreamer::EmitWinCFIEndChained() { + EnsureValidWinFrameInfo(); + if (!CurrentWinFrameInfo->ChainedParent) + report_fatal_error("End of a chained region outside a chained region!"); + + MCSymbol *Label = EmitCFILabel(); + + CurrentWinFrameInfo->End = Label; + CurrentWinFrameInfo = + const_cast(CurrentWinFrameInfo->ChainedParent); +} + +void MCObjectStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, + bool Except) { + EnsureValidWinFrameInfo(); + if (CurrentWinFrameInfo->ChainedParent) + report_fatal_error("Chained unwind areas can't have handlers!"); + CurrentWinFrameInfo->ExceptionHandler = Sym; + if (!Except && !Unwind) + report_fatal_error("Don't know what kind of handler this is!"); + if (Unwind) + CurrentWinFrameInfo->HandlesUnwind = true; + if (Except) + CurrentWinFrameInfo->HandlesExceptions = true; +} + +void MCObjectStreamer::EmitWinEHHandlerData() { + EnsureValidWinFrameInfo(); + if (CurrentWinFrameInfo->ChainedParent) + report_fatal_error("Chained unwind areas can't have handlers!"); +} + +void MCObjectStreamer::EmitWinCFIPushReg(unsigned Register) { + EnsureValidWinFrameInfo(); + + MCSymbol *Label = EmitCFILabel(); + + WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register); + CurrentWinFrameInfo->Instructions.push_back(Inst); +} + +void MCObjectStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { + EnsureValidWinFrameInfo(); + if (CurrentWinFrameInfo->LastFrameInst >= 0) + report_fatal_error("Frame register and offset already specified!"); + if (Offset & 0x0F) + report_fatal_error("Misaligned frame pointer offset!"); + if (Offset > 240) + report_fatal_error("Frame offset must be less than or equal to 240!"); + + MCSymbol *Label = EmitCFILabel(); + + WinEH::Instruction Inst = + Win64EH::Instruction::SetFPReg(Label, Register, Offset); + CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size(); + CurrentWinFrameInfo->Instructions.push_back(Inst); +} + +void MCObjectStreamer::EmitWinCFIAllocStack(unsigned Size) { + EnsureValidWinFrameInfo(); + if (Size == 0) + report_fatal_error("Allocation size must be non-zero!"); + if (Size & 7) + report_fatal_error("Misaligned stack allocation!"); + + MCSymbol *Label = EmitCFILabel(); + + WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size); + CurrentWinFrameInfo->Instructions.push_back(Inst); +} + +void MCObjectStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { + EnsureValidWinFrameInfo(); + if (Offset & 7) + report_fatal_error("Misaligned saved register offset!"); + + MCSymbol *Label = EmitCFILabel(); + + WinEH::Instruction Inst = + Win64EH::Instruction::SaveNonVol(Label, Register, Offset); + CurrentWinFrameInfo->Instructions.push_back(Inst); +} + +void MCObjectStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { + EnsureValidWinFrameInfo(); + if (Offset & 0x0F) + report_fatal_error("Misaligned saved vector register offset!"); + + MCSymbol *Label = EmitCFILabel(); + + WinEH::Instruction Inst = + Win64EH::Instruction::SaveXMM(Label, Register, Offset); + CurrentWinFrameInfo->Instructions.push_back(Inst); +} + +void MCObjectStreamer::EmitWinCFIPushFrame(bool Code) { + EnsureValidWinFrameInfo(); + if (!CurrentWinFrameInfo->Instructions.empty()) + report_fatal_error("If present, PushMachFrame must be the first UOP"); + + MCSymbol *Label = EmitCFILabel(); + + WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code); + CurrentWinFrameInfo->Instructions.push_back(Inst); +} + +void MCObjectStreamer::EmitWinCFIEndProlog() { + EnsureValidWinFrameInfo(); + + MCSymbol *Label = EmitCFILabel(); + + CurrentWinFrameInfo->PrologEnd = Label; +} + void MCObjectStreamer::FinishImpl() { // If we are generating dwarf for assembly source files dump out the sections. if (getContext().getGenDwarfForAssembly()) Index: llvm/lib/MC/MCStreamer.cpp =================================================================== --- llvm/lib/MC/MCStreamer.cpp +++ llvm/lib/MC/MCStreamer.cpp @@ -24,8 +24,6 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCWin64EH.h" -#include "llvm/MC/MCWinEH.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LEB128.h" @@ -51,22 +49,14 @@ void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} -MCStreamer::MCStreamer(MCContext &Ctx) - : Context(Ctx), CurrentWinFrameInfo(nullptr) { +MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx) { SectionStack.push_back(std::pair()); } -MCStreamer::~MCStreamer() { - for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) - delete WinFrameInfos[i]; -} +MCStreamer::~MCStreamer() {} void MCStreamer::reset() { DwarfFrameInfos.clear(); - for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) - delete WinFrameInfos[i]; - WinFrameInfos.clear(); - CurrentWinFrameInfo = nullptr; SymbolOrdering.clear(); SectionStack.clear(); SectionStack.push_back(std::pair()); @@ -521,80 +511,6 @@ CurFrame->RAReg = Register; } -void MCStreamer::EnsureValidWinFrameInfo() { - const MCAsmInfo *MAI = Context.getAsmInfo(); - if (!MAI->usesWindowsCFI()) - report_fatal_error(".seh_* directives are not supported on this target"); - if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) - report_fatal_error("No open Win64 EH frame function!"); -} - -void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { - const MCAsmInfo *MAI = Context.getAsmInfo(); - if (!MAI->usesWindowsCFI()) - report_fatal_error(".seh_* directives are not supported on this target"); - if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End) - report_fatal_error("Starting a function before ending the previous one!"); - - MCSymbol *StartProc = EmitCFILabel(); - - WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc)); - CurrentWinFrameInfo = WinFrameInfos.back(); - CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); -} - -void MCStreamer::EmitWinCFIEndProc() { - EnsureValidWinFrameInfo(); - if (CurrentWinFrameInfo->ChainedParent) - report_fatal_error("Not all chained regions terminated!"); - - MCSymbol *Label = EmitCFILabel(); - CurrentWinFrameInfo->End = Label; -} - -void MCStreamer::EmitWinCFIStartChained() { - EnsureValidWinFrameInfo(); - - MCSymbol *StartProc = EmitCFILabel(); - - WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function, - StartProc, CurrentWinFrameInfo)); - CurrentWinFrameInfo = WinFrameInfos.back(); - CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); -} - -void MCStreamer::EmitWinCFIEndChained() { - EnsureValidWinFrameInfo(); - if (!CurrentWinFrameInfo->ChainedParent) - report_fatal_error("End of a chained region outside a chained region!"); - - MCSymbol *Label = EmitCFILabel(); - - CurrentWinFrameInfo->End = Label; - CurrentWinFrameInfo = - const_cast(CurrentWinFrameInfo->ChainedParent); -} - -void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, - bool Except) { - EnsureValidWinFrameInfo(); - if (CurrentWinFrameInfo->ChainedParent) - report_fatal_error("Chained unwind areas can't have handlers!"); - CurrentWinFrameInfo->ExceptionHandler = Sym; - if (!Except && !Unwind) - report_fatal_error("Don't know what kind of handler this is!"); - if (Unwind) - CurrentWinFrameInfo->HandlesUnwind = true; - if (Except) - CurrentWinFrameInfo->HandlesExceptions = true; -} - -void MCStreamer::EmitWinEHHandlerData() { - EnsureValidWinFrameInfo(); - if (CurrentWinFrameInfo->ChainedParent) - report_fatal_error("Chained unwind areas can't have handlers!"); -} - static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID, MCSection *MainCFISec, const MCSection *TextSec) { @@ -629,88 +545,6 @@ void MCStreamer::EmitSyntaxDirective() {} -void MCStreamer::EmitWinCFIPushReg(unsigned Register) { - EnsureValidWinFrameInfo(); - - MCSymbol *Label = EmitCFILabel(); - - WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register); - CurrentWinFrameInfo->Instructions.push_back(Inst); -} - -void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { - EnsureValidWinFrameInfo(); - if (CurrentWinFrameInfo->LastFrameInst >= 0) - report_fatal_error("Frame register and offset already specified!"); - if (Offset & 0x0F) - report_fatal_error("Misaligned frame pointer offset!"); - if (Offset > 240) - report_fatal_error("Frame offset must be less than or equal to 240!"); - - MCSymbol *Label = EmitCFILabel(); - - WinEH::Instruction Inst = - Win64EH::Instruction::SetFPReg(Label, Register, Offset); - CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size(); - CurrentWinFrameInfo->Instructions.push_back(Inst); -} - -void MCStreamer::EmitWinCFIAllocStack(unsigned Size) { - EnsureValidWinFrameInfo(); - if (Size == 0) - report_fatal_error("Allocation size must be non-zero!"); - if (Size & 7) - report_fatal_error("Misaligned stack allocation!"); - - MCSymbol *Label = EmitCFILabel(); - - WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size); - CurrentWinFrameInfo->Instructions.push_back(Inst); -} - -void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { - EnsureValidWinFrameInfo(); - if (Offset & 7) - report_fatal_error("Misaligned saved register offset!"); - - MCSymbol *Label = EmitCFILabel(); - - WinEH::Instruction Inst = - Win64EH::Instruction::SaveNonVol(Label, Register, Offset); - CurrentWinFrameInfo->Instructions.push_back(Inst); -} - -void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { - EnsureValidWinFrameInfo(); - if (Offset & 0x0F) - report_fatal_error("Misaligned saved vector register offset!"); - - MCSymbol *Label = EmitCFILabel(); - - WinEH::Instruction Inst = - Win64EH::Instruction::SaveXMM(Label, Register, Offset); - CurrentWinFrameInfo->Instructions.push_back(Inst); -} - -void MCStreamer::EmitWinCFIPushFrame(bool Code) { - EnsureValidWinFrameInfo(); - if (!CurrentWinFrameInfo->Instructions.empty()) - report_fatal_error("If present, PushMachFrame must be the first UOP"); - - MCSymbol *Label = EmitCFILabel(); - - WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code); - CurrentWinFrameInfo->Instructions.push_back(Inst); -} - -void MCStreamer::EmitWinCFIEndProlog() { - EnsureValidWinFrameInfo(); - - MCSymbol *Label = EmitCFILabel(); - - CurrentWinFrameInfo->PrologEnd = Label; -} - void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { } Index: llvm/lib/MC/MCWin64EH.cpp =================================================================== --- llvm/lib/MC/MCWin64EH.cpp +++ llvm/lib/MC/MCWin64EH.cpp @@ -13,7 +13,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSectionCOFF.h" -#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Win64EH.h" @@ -47,7 +47,7 @@ return Count; } -static void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS, +static void EmitAbsDifference(MCObjectStreamer &Streamer, const MCSymbol *LHS, const MCSymbol *RHS) { MCContext &Context = Streamer.getContext(); const MCExpr *Diff = @@ -56,7 +56,7 @@ Streamer.EmitValue(Diff, 1); } -static void EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin, +static void EmitUnwindCode(MCObjectStreamer &streamer, const MCSymbol *begin, WinEH::Instruction &inst) { uint8_t b2; uint16_t w; @@ -122,7 +122,7 @@ } } -static void EmitSymbolRefWithOfs(MCStreamer &streamer, +static void EmitSymbolRefWithOfs(MCObjectStreamer &streamer, const MCSymbol *Base, const MCSymbol *Other) { MCContext &Context = streamer.getContext(); @@ -135,7 +135,7 @@ streamer.EmitValue(MCBinaryExpr::createAdd(BaseRefRel, Ofs, Context), 4); } -static void EmitRuntimeFunction(MCStreamer &streamer, +static void EmitRuntimeFunction(MCObjectStreamer &streamer, const WinEH::FrameInfo *info) { MCContext &context = streamer.getContext(); @@ -147,7 +147,7 @@ context), 4); } -static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { +static void EmitUnwindInfo(MCObjectStreamer &streamer, WinEH::FrameInfo *info) { // If this UNWIND_INFO already has a symbol, it's already been emitted. if (info->Symbol) return; @@ -218,7 +218,7 @@ } } -void llvm::Win64EH::UnwindEmitter::Emit(MCStreamer &Streamer) const { +void llvm::Win64EH::UnwindEmitter::Emit(MCObjectStreamer &Streamer) const { // Emit the unwind info structs first. for (WinEH::FrameInfo *CFI : Streamer.getWinFrameInfos()) { MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection); @@ -235,7 +235,7 @@ } void llvm::Win64EH::UnwindEmitter::EmitUnwindInfo( - MCStreamer &Streamer, WinEH::FrameInfo *info) const { + MCObjectStreamer &Streamer, WinEH::FrameInfo *info) const { // Switch sections (the static function above is meant to be called from // here and from Emit(). MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection); Index: llvm/test/MC/AsmParser/directive_seh.s =================================================================== --- llvm/test/MC/AsmParser/directive_seh.s +++ llvm/test/MC/AsmParser/directive_seh.s @@ -31,10 +31,12 @@ .seh_endprologue .seh_endchained # CHECK: .seh_setframe 3, 0 +# CHECK-NOT: .Lcfi # CHECK: .seh_endprologue # CHECK: .seh_handler __C_specific_handler, @except # CHECK-NOT: .section{{.*}}.xdata # CHECK: .seh_handlerdata +# CHECK: .long 0 # CHECK: .text # CHECK: .seh_startchained # CHECK: .seh_endprologue