forked from OSchip/llvm-project
[ms] [llvm-ml] Add basic support for SEH, including PROC FRAME
Add basic support for SEH, including PROC FRAME Reviewed By: thakis Differential Revision: https://reviews.llvm.org/D86948
This commit is contained in:
parent
20201dc76a
commit
23a2b03221
|
@ -53,6 +53,9 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||||
bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
|
bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
|
||||||
bool ParseDirectiveIncludelib(StringRef, SMLoc);
|
bool ParseDirectiveIncludelib(StringRef, SMLoc);
|
||||||
|
|
||||||
|
bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
|
||||||
|
bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
|
||||||
|
|
||||||
bool IgnoreDirective(StringRef, SMLoc) {
|
bool IgnoreDirective(StringRef, SMLoc) {
|
||||||
while (!getLexer().is(AsmToken::EndOfStatement)) {
|
while (!getLexer().is(AsmToken::EndOfStatement)) {
|
||||||
Lex();
|
Lex();
|
||||||
|
@ -65,13 +68,10 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||||
MCAsmParserExtension::Initialize(Parser);
|
MCAsmParserExtension::Initialize(Parser);
|
||||||
|
|
||||||
// x64 directives
|
// x64 directives
|
||||||
// .allocstack
|
addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
|
||||||
// .endprolog
|
".allocstack");
|
||||||
// .pushframe
|
addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
|
||||||
// .pushreg
|
".endprolog");
|
||||||
// .savereg
|
|
||||||
// .savexmm128
|
|
||||||
// .setframe
|
|
||||||
|
|
||||||
// Code label directives
|
// Code label directives
|
||||||
// label
|
// label
|
||||||
|
@ -92,16 +92,12 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||||
|
|
||||||
// Data allocation directives
|
// Data allocation directives
|
||||||
// align
|
// align
|
||||||
// byte/sbyte
|
|
||||||
// dword/sdword
|
|
||||||
// even
|
// even
|
||||||
// fword
|
// mmword
|
||||||
// qword
|
|
||||||
// real4
|
|
||||||
// real8
|
|
||||||
// real10
|
// real10
|
||||||
// tbyte
|
// tbyte
|
||||||
// word/sword
|
// xmmword
|
||||||
|
// ymmword
|
||||||
|
|
||||||
// Listing control directives
|
// Listing control directives
|
||||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".cref");
|
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".cref");
|
||||||
|
@ -133,14 +129,11 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||||
// .fpo
|
// .fpo
|
||||||
addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
|
addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
|
||||||
"includelib");
|
"includelib");
|
||||||
// mmword
|
|
||||||
// option
|
// option
|
||||||
// popcontext
|
// popcontext
|
||||||
// pushcontext
|
// pushcontext
|
||||||
// .radix
|
// .radix
|
||||||
// .safeseh
|
// .safeseh
|
||||||
// xmmword
|
|
||||||
// ymmword
|
|
||||||
|
|
||||||
// Procedure directives
|
// Procedure directives
|
||||||
addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>("endp");
|
addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>("endp");
|
||||||
|
@ -148,7 +141,7 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||||
addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>("proc");
|
addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>("proc");
|
||||||
// proto
|
// proto
|
||||||
|
|
||||||
// Processor directives
|
// Processor directives; all ignored
|
||||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386");
|
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386");
|
||||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386P");
|
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386P");
|
||||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".387");
|
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".387");
|
||||||
|
@ -202,11 +195,8 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||||
// substr (equivalent to <name> TEXTEQU @SubStr(<params>))
|
// substr (equivalent to <name> TEXTEQU @SubStr(<params>))
|
||||||
|
|
||||||
// Structure and record directives
|
// Structure and record directives
|
||||||
// ends
|
|
||||||
// record
|
// record
|
||||||
// struct
|
|
||||||
// typedef
|
// typedef
|
||||||
// union
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParseSectionDirectiveCode(StringRef, SMLoc) {
|
bool ParseSectionDirectiveCode(StringRef, SMLoc) {
|
||||||
|
@ -234,6 +224,7 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef CurrentProcedure;
|
StringRef CurrentProcedure;
|
||||||
|
bool CurrentProcedureFramed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
COFFMasmParser() = default;
|
COFFMasmParser() = default;
|
||||||
|
@ -361,8 +352,17 @@ bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
|
||||||
getStreamer().EmitCOFFSymbolType(0x20);
|
getStreamer().EmitCOFFSymbolType(0x20);
|
||||||
getStreamer().EndCOFFSymbolDef();
|
getStreamer().EndCOFFSymbolDef();
|
||||||
|
|
||||||
|
bool Framed = false;
|
||||||
|
if (getLexer().is(AsmToken::Identifier) &&
|
||||||
|
getTok().getString().equals_lower("frame")) {
|
||||||
|
Lex();
|
||||||
|
Framed = true;
|
||||||
|
getStreamer().EmitWinCFIStartProc(Sym, Loc);
|
||||||
|
}
|
||||||
getStreamer().emitLabel(Sym, Loc);
|
getStreamer().emitLabel(Sym, Loc);
|
||||||
|
|
||||||
CurrentProcedure = Label;
|
CurrentProcedure = Label;
|
||||||
|
CurrentProcedureFramed = Framed;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
|
bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
|
||||||
|
@ -376,6 +376,30 @@ bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
|
||||||
else if (CurrentProcedure != Label)
|
else if (CurrentProcedure != Label)
|
||||||
return Error(LabelLoc, "endp does not match current procedure '" +
|
return Error(LabelLoc, "endp does not match current procedure '" +
|
||||||
CurrentProcedure + "'");
|
CurrentProcedure + "'");
|
||||||
|
|
||||||
|
if (CurrentProcedureFramed) {
|
||||||
|
getStreamer().EmitWinCFIEndProc(Loc);
|
||||||
|
}
|
||||||
|
CurrentProcedure = "";
|
||||||
|
CurrentProcedureFramed = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
|
||||||
|
SMLoc Loc) {
|
||||||
|
int64_t Size;
|
||||||
|
SMLoc SizeLoc = getTok().getLoc();
|
||||||
|
if (getParser().parseAbsoluteExpression(Size))
|
||||||
|
return Error(SizeLoc, "expected integer size");
|
||||||
|
if (Size % 8 != 0)
|
||||||
|
return Error(SizeLoc, "stack size must be a multiple of 8");
|
||||||
|
getStreamer().EmitWinCFIAllocStack(static_cast<unsigned>(Size), Loc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COFFMasmParser::ParseSEHDirectiveEndProlog(StringRef Directive,
|
||||||
|
SMLoc Loc) {
|
||||||
|
getStreamer().EmitWinCFIEndProlog(Loc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -726,7 +726,12 @@ private:
|
||||||
DK_STRUCT,
|
DK_STRUCT,
|
||||||
DK_UNION,
|
DK_UNION,
|
||||||
DK_ENDS,
|
DK_ENDS,
|
||||||
DK_END
|
DK_END,
|
||||||
|
DK_PUSHFRAME,
|
||||||
|
DK_PUSHREG,
|
||||||
|
DK_SAVEREG,
|
||||||
|
DK_SAVEXMM128,
|
||||||
|
DK_SETFRAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Maps directive name --> DirectiveKind enum, for directives parsed by this
|
/// Maps directive name --> DirectiveKind enum, for directives parsed by this
|
||||||
|
@ -6333,6 +6338,11 @@ void MasmParser::initializeDirectiveKindMap() {
|
||||||
DirectiveKindMap[".erridni"] = DK_ERRIDNI;
|
DirectiveKindMap[".erridni"] = DK_ERRIDNI;
|
||||||
DirectiveKindMap[".erre"] = DK_ERRE;
|
DirectiveKindMap[".erre"] = DK_ERRE;
|
||||||
DirectiveKindMap[".errnz"] = DK_ERRNZ;
|
DirectiveKindMap[".errnz"] = DK_ERRNZ;
|
||||||
|
DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
|
||||||
|
DirectiveKindMap[".pushreg"] = DK_PUSHREG;
|
||||||
|
DirectiveKindMap[".savereg"] = DK_SAVEREG;
|
||||||
|
DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
|
||||||
|
DirectiveKindMap[".setframe"] = DK_SETFRAME;
|
||||||
// DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
|
// DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
|
||||||
// DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
|
// DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
|
||||||
DirectiveKindMap["db"] = DK_DB;
|
DirectiveKindMap["db"] = DK_DB;
|
||||||
|
|
|
@ -4172,15 +4172,20 @@ bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||||
return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
|
return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
|
||||||
else if (IDVal == ".cv_fpo_endproc")
|
else if (IDVal == ".cv_fpo_endproc")
|
||||||
return parseDirectiveFPOEndProc(DirectiveID.getLoc());
|
return parseDirectiveFPOEndProc(DirectiveID.getLoc());
|
||||||
else if (IDVal == ".seh_pushreg")
|
else if (IDVal == ".seh_pushreg" ||
|
||||||
|
(Parser.isParsingMasm() && IDVal.equals_lower(".pushreg")))
|
||||||
return parseDirectiveSEHPushReg(DirectiveID.getLoc());
|
return parseDirectiveSEHPushReg(DirectiveID.getLoc());
|
||||||
else if (IDVal == ".seh_setframe")
|
else if (IDVal == ".seh_setframe" ||
|
||||||
|
(Parser.isParsingMasm() && IDVal.equals_lower(".setframe")))
|
||||||
return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
|
return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
|
||||||
else if (IDVal == ".seh_savereg")
|
else if (IDVal == ".seh_savereg" ||
|
||||||
|
(Parser.isParsingMasm() && IDVal.equals_lower(".savereg")))
|
||||||
return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
|
return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
|
||||||
else if (IDVal == ".seh_savexmm")
|
else if (IDVal == ".seh_savexmm" ||
|
||||||
|
(Parser.isParsingMasm() && IDVal.equals_lower(".savexmm128")))
|
||||||
return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());
|
return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());
|
||||||
else if (IDVal == ".seh_pushframe")
|
else if (IDVal == ".seh_pushframe" ||
|
||||||
|
(Parser.isParsingMasm() && IDVal.equals_lower(".pushframe")))
|
||||||
return parseDirectiveSEHPushFrame(DirectiveID.getLoc());
|
return parseDirectiveSEHPushFrame(DirectiveID.getLoc());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# RUN: llvm-ml -m32 -filetype=asm %s | FileCheck %s
|
||||||
|
# RUN: llvm-ml -m64 -filetype=asm %s | FileCheck %s
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
t1 PROC
|
||||||
|
ret
|
||||||
|
t1 ENDP
|
||||||
|
|
||||||
|
; CHECK: .def t1
|
||||||
|
; CHECK-NEXT: .scl 2
|
||||||
|
; CHECK-NEXT: .type 32
|
||||||
|
; CHECK-NEXT: .endef
|
||||||
|
|
||||||
|
; CHECK: t1:
|
||||||
|
; CHECK: ret
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,34 @@
|
||||||
|
# RUN: llvm-ml -m64 -filetype=asm %s | FileCheck %s
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
t1 PROC FRAME
|
||||||
|
push rbp
|
||||||
|
.pushreg rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
.setframe rbp, 0
|
||||||
|
pushfq
|
||||||
|
.allocstack 8
|
||||||
|
.endprolog
|
||||||
|
ret
|
||||||
|
t1 ENDP
|
||||||
|
|
||||||
|
; CHECK: .def t1
|
||||||
|
; CHECK-NEXT: .scl 2
|
||||||
|
; CHECK-NEXT: .type 32
|
||||||
|
; CHECK-NEXT: .endef
|
||||||
|
|
||||||
|
; CHECK: .seh_proc t1
|
||||||
|
|
||||||
|
; CHECK: t1:
|
||||||
|
; CHECK: push rbp
|
||||||
|
; CHECK: .seh_pushreg rbp
|
||||||
|
; CHECK: mov rbp, rsp
|
||||||
|
; CHECK: .seh_setframe rbp, 0
|
||||||
|
; CHECK: pushfq
|
||||||
|
; CHECK: .seh_stackalloc 8
|
||||||
|
; CHECK: .seh_endprologue
|
||||||
|
; CHECK: ret
|
||||||
|
; CHECK: .seh_endproc
|
||||||
|
|
||||||
|
END
|
Loading…
Reference in New Issue