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
This commit is contained in:
Charles Davis
2011-05-19 17:46:39 +00:00
parent 6635b04a43
commit 440596ffe5
4 changed files with 60 additions and 50 deletions

View File

@ -463,16 +463,18 @@ namespace llvm {
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
virtual void EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler = 0); virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
virtual void EmitWin64EHEndProc(); virtual void EmitWin64EHEndProc();
virtual void EmitWin64EHStartChained(); virtual void EmitWin64EHStartChained();
virtual void EmitWin64EHEndChained(); virtual void EmitWin64EHEndChained();
virtual void EmitWin64EHUnwindOnly(); virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
virtual void EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size); bool Except);
virtual void EmitWin64EHHandlerData();
virtual void EmitWin64EHPushReg(int64_t Register); virtual void EmitWin64EHPushReg(int64_t Register);
virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset); virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset);
virtual void EmitWin64EHAllocStack(int64_t Size); virtual void EmitWin64EHAllocStack(int64_t Size);
virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset); 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 EmitWin64EHPushFrame(bool Code);
virtual void EmitWin64EHEndProlog(); virtual void EmitWin64EHEndProlog();

View File

@ -62,17 +62,15 @@ namespace llvm {
}; };
struct MCWin64EHUnwindInfo { struct MCWin64EHUnwindInfo {
MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), Lsda(0), MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0),
Function(0), UnwindOnly(false), LsdaSize(0), Function(0), UnwindOnly(false),
PrologSize(0), LastFrameInst(-1), ChainedParent(0), PrologSize(0), LastFrameInst(-1), ChainedParent(0),
Instructions() {} Instructions() {}
MCSymbol *Begin; MCSymbol *Begin;
MCSymbol *End; MCSymbol *End;
const MCSymbol *ExceptionHandler; const MCSymbol *ExceptionHandler;
const MCSymbol *Lsda;
const MCSymbol *Function; const MCSymbol *Function;
bool UnwindOnly; bool UnwindOnly;
unsigned LsdaSize;
unsigned PrologSize; unsigned PrologSize;
int LastFrameInst; int LastFrameInst;
MCWin64EHUnwindInfo *ChainedParent; MCWin64EHUnwindInfo *ChainedParent;

View File

@ -208,16 +208,18 @@ public:
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
virtual void EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler = 0); virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
virtual void EmitWin64EHEndProc(); virtual void EmitWin64EHEndProc();
virtual void EmitWin64EHStartChained(); virtual void EmitWin64EHStartChained();
virtual void EmitWin64EHEndChained(); virtual void EmitWin64EHEndChained();
virtual void EmitWin64EHUnwindOnly(); virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
virtual void EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size); bool Except);
virtual void EmitWin64EHHandlerData();
virtual void EmitWin64EHPushReg(int64_t Register); virtual void EmitWin64EHPushReg(int64_t Register);
virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset); virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset);
virtual void EmitWin64EHAllocStack(int64_t Size); virtual void EmitWin64EHAllocStack(int64_t Size);
virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset); 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 EmitWin64EHPushFrame(bool Code);
virtual void EmitWin64EHEndProlog(); virtual void EmitWin64EHEndProlog();
@ -928,67 +930,75 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) { void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
OS << ".w64_startproc " << *Symbol; OS << ".seh_proc " << *Symbol;
if (EHandler)
OS << ", " << *EHandler;
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHEndProc() { void MCAsmStreamer::EmitWin64EHEndProc() {
OS << "\t.w64_endproc"; OS << "\t.seh_endproc";
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHStartChained() { void MCAsmStreamer::EmitWin64EHStartChained() {
OS << "\t.w64_startchained"; OS << "\t.seh_startchained";
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHEndChained() { void MCAsmStreamer::EmitWin64EHEndChained() {
OS << "\t.w64_endchained"; OS << "\t.seh_endchained";
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHUnwindOnly() { void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
OS << "\t.w64_unwind_only"; bool Except) {
OS << "\t.seh_handler " << *Sym;
if (Unwind)
OS << ", @unwind";
if (Except)
OS << ", @except";
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size) { void MCAsmStreamer::EmitWin64EHHandlerData() {
OS << "\t.w64_lsda " << *Sym << ", " << Size; OS << "\t.seh_handlerdata";
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHPushReg(int64_t Register) { void MCAsmStreamer::EmitWin64EHPushReg(int64_t Register) {
OS << "\t.w64_pushreg " << Register; OS << "\t.seh_pushreg " << Register;
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) { void MCAsmStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) {
OS << "\t.w64_setframe " << Register << ", " << Offset; OS << "\t.seh_setframe " << Register << ", " << Offset;
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHAllocStack(int64_t Size) { void MCAsmStreamer::EmitWin64EHAllocStack(int64_t Size) {
OS << "\t.w64_allocstack " << Size; OS << "\t.seh_stackalloc " << Size;
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) { 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(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) { void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
OS << "\t.w64_pushframe"; OS << "\t.seh_pushframe";
if (Code) if (Code)
OS << " " << "code"; OS << " @code";
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitWin64EHEndProlog(void) { void MCAsmStreamer::EmitWin64EHEndProlog(void) {
OS << "\t.w64_endprolog"; OS << "\t.seh_endprologue";
EmitEOL(); EmitEOL();
} }

View File

@ -321,14 +321,13 @@ void MCStreamer::EnsureValidW64UnwindInfo() {
report_fatal_error("No open Win64 EH frame function!"); report_fatal_error("No open Win64 EH frame function!");
} }
void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) { void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
if (CurFrame && !CurFrame->End) if (CurFrame && !CurFrame->End)
report_fatal_error("Starting a function before ending the previous one!"); report_fatal_error("Starting a function before ending the previous one!");
MCWin64EHUnwindInfo Frame; MCWin64EHUnwindInfo Frame;
Frame.Begin = getContext().CreateTempSymbol(); Frame.Begin = getContext().CreateTempSymbol();
Frame.Function = Symbol; Frame.Function = Symbol;
Frame.ExceptionHandler = EHandler;
EmitLabel(Frame.Begin); EmitLabel(Frame.Begin);
setCurrentW64UnwindInfo(&Frame); setCurrentW64UnwindInfo(&Frame);
} }
@ -342,8 +341,7 @@ void MCStreamer::EmitWin64EHEndProc() {
EmitLabel(CurFrame->End); EmitLabel(CurFrame->End);
} }
void MCStreamer::EmitWin64EHStartChained() void MCStreamer::EmitWin64EHStartChained() {
{
EnsureValidW64UnwindInfo(); EnsureValidW64UnwindInfo();
MCWin64EHUnwindInfo Frame; MCWin64EHUnwindInfo Frame;
MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
@ -354,8 +352,7 @@ void MCStreamer::EmitWin64EHStartChained()
setCurrentW64UnwindInfo(&Frame); setCurrentW64UnwindInfo(&Frame);
} }
void MCStreamer::EmitWin64EHEndChained() void MCStreamer::EmitWin64EHEndChained() {
{
EnsureValidW64UnwindInfo(); EnsureValidW64UnwindInfo();
MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
if (!CurFrame->ChainedParent) if (!CurFrame->ChainedParent)
@ -365,50 +362,53 @@ void MCStreamer::EmitWin64EHEndChained()
CurrentW64UnwindInfo = CurFrame->ChainedParent; 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"; errs() << "Not implemented yet\n";
abort(); abort();
} }
void MCStreamer::EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size) void MCStreamer::EmitWin64EHPushReg(int64_t Register) {
{
errs() << "Not implemented yet\n"; errs() << "Not implemented yet\n";
abort(); abort();
} }
void MCStreamer::EmitWin64EHPushReg(int64_t Register) void MCStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) {
{
errs() << "Not implemented yet\n"; errs() << "Not implemented yet\n";
abort(); abort();
} }
void MCStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) void MCStreamer::EmitWin64EHAllocStack(int64_t Size) {
{
errs() << "Not implemented yet\n"; errs() << "Not implemented yet\n";
abort(); abort();
} }
void MCStreamer::EmitWin64EHAllocStack(int64_t Size) void MCStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) {
{
errs() << "Not implemented yet\n"; errs() << "Not implemented yet\n";
abort(); abort();
} }
void MCStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) void MCStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) {
{
errs() << "Not implemented yet\n"; errs() << "Not implemented yet\n";
abort(); abort();
} }
void MCStreamer::EmitWin64EHPushFrame(bool Code) void MCStreamer::EmitWin64EHPushFrame(bool Code) {
{
errs() << "Not implemented yet\n"; errs() << "Not implemented yet\n";
abort(); abort();
} }
void MCStreamer::EmitWin64EHEndProlog() void MCStreamer::EmitWin64EHEndProlog() {
{
errs() << "Not implemented yet\n"; errs() << "Not implemented yet\n";
abort(); abort();
} }