From 440596ffe5bb77a202acb36d5eadd158976ff39a Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Thu, 19 May 2011 17:46:39 +0000 Subject: [PATCH] Turns out GAS does have Win64 EH directives. (It also supports WinCE EH.) Make ours compatible with GAS. In retrospect, I should have emailed binutils about this earlier. Thanks to Kai Tietz for pointing out that GAS already had SEH directives. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131652 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCStreamer.h | 8 +++--- include/llvm/MC/MCWin64EH.h | 6 ++--- lib/MC/MCAsmStreamer.cpp | 52 +++++++++++++++++++++--------------- lib/MC/MCStreamer.cpp | 44 +++++++++++++++--------------- 4 files changed, 60 insertions(+), 50 deletions(-) diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 83bcb15ae9a..b5e99305e02 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -463,16 +463,18 @@ namespace llvm { virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); - virtual void EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler = 0); + virtual void EmitWin64EHStartProc(MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); virtual void EmitWin64EHStartChained(); virtual void EmitWin64EHEndChained(); - virtual void EmitWin64EHUnwindOnly(); - virtual void EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size); + virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except); + virtual void EmitWin64EHHandlerData(); virtual void EmitWin64EHPushReg(int64_t Register); virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset); virtual void EmitWin64EHAllocStack(int64_t Size); virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset); + virtual void EmitWin64EHSaveXMM(int64_t Register, int64_t Offset); virtual void EmitWin64EHPushFrame(bool Code); virtual void EmitWin64EHEndProlog(); diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h index c772cdef2a5..4c6d91972ed 100644 --- a/include/llvm/MC/MCWin64EH.h +++ b/include/llvm/MC/MCWin64EH.h @@ -62,17 +62,15 @@ namespace llvm { }; struct MCWin64EHUnwindInfo { - MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), Lsda(0), - Function(0), UnwindOnly(false), LsdaSize(0), + MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), + Function(0), UnwindOnly(false), PrologSize(0), LastFrameInst(-1), ChainedParent(0), Instructions() {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *ExceptionHandler; - const MCSymbol *Lsda; const MCSymbol *Function; bool UnwindOnly; - unsigned LsdaSize; unsigned PrologSize; int LastFrameInst; MCWin64EHUnwindInfo *ChainedParent; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 36fa393c564..6be02988777 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -208,16 +208,18 @@ public: virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); - virtual void EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler = 0); + virtual void EmitWin64EHStartProc(MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); virtual void EmitWin64EHStartChained(); virtual void EmitWin64EHEndChained(); - virtual void EmitWin64EHUnwindOnly(); - virtual void EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size); + virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except); + virtual void EmitWin64EHHandlerData(); virtual void EmitWin64EHPushReg(int64_t Register); virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset); virtual void EmitWin64EHAllocStack(int64_t Size); virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset); + virtual void EmitWin64EHSaveXMM(int64_t Register, int64_t Offset); virtual void EmitWin64EHPushFrame(bool Code); virtual void EmitWin64EHEndProlog(); @@ -928,67 +930,75 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { EmitEOL(); } -void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) { - OS << ".w64_startproc " << *Symbol; - if (EHandler) - OS << ", " << *EHandler; +void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) { + OS << ".seh_proc " << *Symbol; EmitEOL(); } void MCAsmStreamer::EmitWin64EHEndProc() { - OS << "\t.w64_endproc"; + OS << "\t.seh_endproc"; EmitEOL(); } void MCAsmStreamer::EmitWin64EHStartChained() { - OS << "\t.w64_startchained"; + OS << "\t.seh_startchained"; EmitEOL(); } void MCAsmStreamer::EmitWin64EHEndChained() { - OS << "\t.w64_endchained"; + OS << "\t.seh_endchained"; EmitEOL(); } -void MCAsmStreamer::EmitWin64EHUnwindOnly() { - OS << "\t.w64_unwind_only"; +void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except) { + OS << "\t.seh_handler " << *Sym; + if (Unwind) + OS << ", @unwind"; + if (Except) + OS << ", @except"; EmitEOL(); } -void MCAsmStreamer::EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size) { - OS << "\t.w64_lsda " << *Sym << ", " << Size; +void MCAsmStreamer::EmitWin64EHHandlerData() { + OS << "\t.seh_handlerdata"; EmitEOL(); } void MCAsmStreamer::EmitWin64EHPushReg(int64_t Register) { - OS << "\t.w64_pushreg " << Register; + OS << "\t.seh_pushreg " << Register; EmitEOL(); } void MCAsmStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) { - OS << "\t.w64_setframe " << Register << ", " << Offset; + OS << "\t.seh_setframe " << Register << ", " << Offset; EmitEOL(); } void MCAsmStreamer::EmitWin64EHAllocStack(int64_t Size) { - OS << "\t.w64_allocstack " << Size; + OS << "\t.seh_stackalloc " << Size; EmitEOL(); } void MCAsmStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) { - OS << "\t.w64_savereg " << Register << ", " << Offset; + OS << "\t.seh_savereg " << Register << ", " << Offset; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) { + OS << "\t.seh_savexmm " << Register << ", " << Offset; EmitEOL(); } void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) { - OS << "\t.w64_pushframe"; + OS << "\t.seh_pushframe"; if (Code) - OS << " " << "code"; + OS << " @code"; EmitEOL(); } void MCAsmStreamer::EmitWin64EHEndProlog(void) { - OS << "\t.w64_endprolog"; + OS << "\t.seh_endprologue"; EmitEOL(); } diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 4163198e394..fc09369ae2b 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -321,14 +321,13 @@ void MCStreamer::EnsureValidW64UnwindInfo() { report_fatal_error("No open Win64 EH frame function!"); } -void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) { +void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) { MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; if (CurFrame && !CurFrame->End) report_fatal_error("Starting a function before ending the previous one!"); MCWin64EHUnwindInfo Frame; Frame.Begin = getContext().CreateTempSymbol(); Frame.Function = Symbol; - Frame.ExceptionHandler = EHandler; EmitLabel(Frame.Begin); setCurrentW64UnwindInfo(&Frame); } @@ -342,8 +341,7 @@ void MCStreamer::EmitWin64EHEndProc() { EmitLabel(CurFrame->End); } -void MCStreamer::EmitWin64EHStartChained() -{ +void MCStreamer::EmitWin64EHStartChained() { EnsureValidW64UnwindInfo(); MCWin64EHUnwindInfo Frame; MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; @@ -354,8 +352,7 @@ void MCStreamer::EmitWin64EHStartChained() setCurrentW64UnwindInfo(&Frame); } -void MCStreamer::EmitWin64EHEndChained() -{ +void MCStreamer::EmitWin64EHEndChained() { EnsureValidW64UnwindInfo(); MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; if (!CurFrame->ChainedParent) @@ -365,50 +362,53 @@ void MCStreamer::EmitWin64EHEndChained() CurrentW64UnwindInfo = CurFrame->ChainedParent; } -void MCStreamer::EmitWin64EHUnwindOnly() -{ +void MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except) { + EnsureValidW64UnwindInfo(); + MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; + CurFrame->ExceptionHandler = Sym; + if (Unwind) + CurFrame->UnwindOnly = true; + else if (!Except) + report_fatal_error("Don't know what kind of handler this is!"); +} + +void MCStreamer::EmitWin64EHHandlerData() { errs() << "Not implemented yet\n"; abort(); } -void MCStreamer::EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size) -{ +void MCStreamer::EmitWin64EHPushReg(int64_t Register) { errs() << "Not implemented yet\n"; abort(); } -void MCStreamer::EmitWin64EHPushReg(int64_t Register) -{ +void MCStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) { errs() << "Not implemented yet\n"; abort(); } -void MCStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) -{ +void MCStreamer::EmitWin64EHAllocStack(int64_t Size) { errs() << "Not implemented yet\n"; abort(); } -void MCStreamer::EmitWin64EHAllocStack(int64_t Size) -{ +void MCStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) { errs() << "Not implemented yet\n"; abort(); } -void MCStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) -{ +void MCStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) { errs() << "Not implemented yet\n"; abort(); } -void MCStreamer::EmitWin64EHPushFrame(bool Code) -{ +void MCStreamer::EmitWin64EHPushFrame(bool Code) { errs() << "Not implemented yet\n"; abort(); } -void MCStreamer::EmitWin64EHEndProlog() -{ +void MCStreamer::EmitWin64EHEndProlog() { errs() << "Not implemented yet\n"; abort(); } -- 2.34.1