mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-25 17:20:48 +00:00
Add methods to parse the SEH directives to the COFFAsmParser. Implement some
of them, particularly the ones that don't take arguments. Also implement .seh_proc and .seh_handler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131866 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -473,7 +473,7 @@ 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);
|
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
|
||||||
virtual void EmitWin64EHEndProc();
|
virtual void EmitWin64EHEndProc();
|
||||||
virtual void EmitWin64EHStartChained();
|
virtual void EmitWin64EHStartChained();
|
||||||
virtual void EmitWin64EHEndChained();
|
virtual void EmitWin64EHEndChained();
|
||||||
|
@@ -208,7 +208,7 @@ 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);
|
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
|
||||||
virtual void EmitWin64EHEndProc();
|
virtual void EmitWin64EHEndProc();
|
||||||
virtual void EmitWin64EHStartChained();
|
virtual void EmitWin64EHStartChained();
|
||||||
virtual void EmitWin64EHEndChained();
|
virtual void EmitWin64EHEndChained();
|
||||||
@@ -930,7 +930,7 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
|
|||||||
EmitEOL();
|
EmitEOL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
|
void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
|
||||||
MCStreamer::EmitWin64EHStartProc(Symbol);
|
MCStreamer::EmitWin64EHStartProc(Symbol);
|
||||||
|
|
||||||
OS << ".seh_proc " << *Symbol;
|
OS << ".seh_proc " << *Symbol;
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||||
#include "llvm/MC/MCSectionCOFF.h"
|
#include "llvm/MC/MCSectionCOFF.h"
|
||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
|
#include "llvm/MC/MCExpr.h"
|
||||||
#include "llvm/Support/COFF.h"
|
#include "llvm/Support/COFF.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -41,6 +42,34 @@ class COFFAsmParser : public MCAsmParserExtension {
|
|||||||
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
|
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
|
||||||
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
|
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
|
||||||
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
|
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
|
||||||
|
|
||||||
|
// Win64 EH directives.
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
|
||||||
|
".seh_proc");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
|
||||||
|
".seh_endproc");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
|
||||||
|
".seh_startchained");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
|
||||||
|
".seh_endchained");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
|
||||||
|
".seh_handler");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
|
||||||
|
".seh_handlerdata");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
|
||||||
|
".seh_pushreg");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
|
||||||
|
".seh_setframe");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
|
||||||
|
".seh_stackalloc");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
|
||||||
|
".seh_savereg");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
|
||||||
|
".seh_savexmm");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
|
||||||
|
".seh_pushframe");
|
||||||
|
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
|
||||||
|
".seh_endprologue");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParseSectionDirectiveText(StringRef, SMLoc) {
|
bool ParseSectionDirectiveText(StringRef, SMLoc) {
|
||||||
@@ -70,6 +99,22 @@ class COFFAsmParser : public MCAsmParserExtension {
|
|||||||
bool ParseDirectiveType(StringRef, SMLoc);
|
bool ParseDirectiveType(StringRef, SMLoc);
|
||||||
bool ParseDirectiveEndef(StringRef, SMLoc);
|
bool ParseDirectiveEndef(StringRef, SMLoc);
|
||||||
|
|
||||||
|
// Win64 EH directives.
|
||||||
|
bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
|
||||||
|
bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
|
||||||
|
bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
|
||||||
|
bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
|
||||||
|
bool ParseSEHDirectiveHandler(StringRef, SMLoc);
|
||||||
|
bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
|
||||||
|
bool ParseSEHDirectivePushReg(StringRef, SMLoc L);
|
||||||
|
bool ParseSEHDirectiveSetFrame(StringRef, SMLoc L);
|
||||||
|
bool ParseSEHDirectiveAllocStack(StringRef, SMLoc L);
|
||||||
|
bool ParseSEHDirectiveSaveReg(StringRef, SMLoc L);
|
||||||
|
bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc L);
|
||||||
|
bool ParseSEHDirectivePushFrame(StringRef, SMLoc L);
|
||||||
|
bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
|
||||||
|
|
||||||
|
bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
|
||||||
public:
|
public:
|
||||||
COFFAsmParser() {}
|
COFFAsmParser() {}
|
||||||
};
|
};
|
||||||
@@ -135,6 +180,118 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
|
||||||
|
const MCExpr *e;
|
||||||
|
const MCSymbolRefExpr *funcExpr;
|
||||||
|
SMLoc startLoc = getLexer().getLoc();
|
||||||
|
if (getParser().ParseExpression(e))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
|
||||||
|
return Error(startLoc, "expected symbol");
|
||||||
|
|
||||||
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||||
|
return TokError("unexpected token in directive");
|
||||||
|
|
||||||
|
Lex();
|
||||||
|
getStreamer().EmitWin64EHStartProc(&funcExpr->getSymbol());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
|
||||||
|
Lex();
|
||||||
|
getStreamer().EmitWin64EHEndProc();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
|
||||||
|
Lex();
|
||||||
|
getStreamer().EmitWin64EHStartChained();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
|
||||||
|
Lex();
|
||||||
|
getStreamer().EmitWin64EHEndChained();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
|
||||||
|
const MCExpr *e;
|
||||||
|
const MCSymbolRefExpr *funcExpr;
|
||||||
|
SMLoc startLoc = getLexer().getLoc();
|
||||||
|
if (getParser().ParseExpression(e))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
|
||||||
|
return Error(startLoc, "expected symbol");
|
||||||
|
|
||||||
|
bool unwind = false, except = false;
|
||||||
|
if (!ParseAtUnwindOrAtExcept(unwind, except))
|
||||||
|
return true;
|
||||||
|
if (getLexer().is(AsmToken::Comma)) {
|
||||||
|
Lex();
|
||||||
|
if (!ParseAtUnwindOrAtExcept(unwind, except))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||||
|
return TokError("unexpected token in directive");
|
||||||
|
|
||||||
|
Lex();
|
||||||
|
getStreamer().EmitWin64EHHandler(&funcExpr->getSymbol(), unwind, except);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
|
||||||
|
Lex();
|
||||||
|
getStreamer().EmitWin64EHHandlerData();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
|
||||||
|
return Error(L, "not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
|
||||||
|
return Error(L, "not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc L) {
|
||||||
|
return Error(L, "not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
|
||||||
|
return Error(L, "not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
|
||||||
|
return Error(L, "not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc L) {
|
||||||
|
return Error(L, "not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
|
||||||
|
Lex();
|
||||||
|
getStreamer().EmitWin64EHEndProlog();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
|
||||||
|
StringRef identifier;
|
||||||
|
SMLoc startLoc = getLexer().getLoc();
|
||||||
|
if (!getParser().ParseIdentifier(identifier))
|
||||||
|
return Error(startLoc, "expected @unwind or @except");
|
||||||
|
if (identifier == "@unwind")
|
||||||
|
unwind = true;
|
||||||
|
else if (identifier == "@except")
|
||||||
|
except = true;
|
||||||
|
else
|
||||||
|
return Error(startLoc, "expected @unwind or @except");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
MCAsmParserExtension *createCOFFAsmParser() {
|
MCAsmParserExtension *createCOFFAsmParser() {
|
||||||
|
@@ -316,7 +316,7 @@ 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) {
|
void MCStreamer::EmitWin64EHStartProc(const 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!");
|
||||||
|
Reference in New Issue
Block a user