[llvm] 23a2b03 - [ms] [llvm-ml] Add basic support for SEH, including PROC FRAME
Eric Astor via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 14 11:34:18 PDT 2020
Author: Eric Astor
Date: 2020-09-14T14:32:55-04:00
New Revision: 23a2b03221c5664fefc658c3eb26e7b6ecd1a1e8
URL: https://github.com/llvm/llvm-project/commit/23a2b03221c5664fefc658c3eb26e7b6ecd1a1e8
DIFF: https://github.com/llvm/llvm-project/commit/23a2b03221c5664fefc658c3eb26e7b6ecd1a1e8.diff
LOG: [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
Added:
llvm/test/tools/llvm-ml/proc.test
llvm/test/tools/llvm-ml/proc_frame.test
Modified:
llvm/lib/MC/MCParser/COFFMasmParser.cpp
llvm/lib/MC/MCParser/MasmParser.cpp
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
Removed:
################################################################################
diff --git a/llvm/lib/MC/MCParser/COFFMasmParser.cpp b/llvm/lib/MC/MCParser/COFFMasmParser.cpp
index b7c48e92961b..532ded038043 100644
--- a/llvm/lib/MC/MCParser/COFFMasmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFMasmParser.cpp
@@ -53,6 +53,9 @@ class COFFMasmParser : public MCAsmParserExtension {
bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
bool ParseDirectiveIncludelib(StringRef, SMLoc);
+ bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
+ bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
+
bool IgnoreDirective(StringRef, SMLoc) {
while (!getLexer().is(AsmToken::EndOfStatement)) {
Lex();
@@ -65,13 +68,10 @@ class COFFMasmParser : public MCAsmParserExtension {
MCAsmParserExtension::Initialize(Parser);
// x64 directives
- // .allocstack
- // .endprolog
- // .pushframe
- // .pushreg
- // .savereg
- // .savexmm128
- // .setframe
+ addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
+ ".allocstack");
+ addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
+ ".endprolog");
// Code label directives
// label
@@ -92,16 +92,12 @@ class COFFMasmParser : public MCAsmParserExtension {
// Data allocation directives
// align
- // byte/sbyte
- // dword/sdword
// even
- // fword
- // qword
- // real4
- // real8
+ // mmword
// real10
// tbyte
- // word/sword
+ // xmmword
+ // ymmword
// Listing control directives
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".cref");
@@ -133,14 +129,11 @@ class COFFMasmParser : public MCAsmParserExtension {
// .fpo
addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
"includelib");
- // mmword
// option
// popcontext
// pushcontext
// .radix
// .safeseh
- // xmmword
- // ymmword
// Procedure directives
addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>("endp");
@@ -148,7 +141,7 @@ class COFFMasmParser : public MCAsmParserExtension {
addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>("proc");
// proto
- // Processor directives
+ // Processor directives; all ignored
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386");
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386P");
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".387");
@@ -202,11 +195,8 @@ class COFFMasmParser : public MCAsmParserExtension {
// substr (equivalent to <name> TEXTEQU @SubStr(<params>))
// Structure and record directives
- // ends
// record
- // struct
// typedef
- // union
}
bool ParseSectionDirectiveCode(StringRef, SMLoc) {
@@ -234,6 +224,7 @@ class COFFMasmParser : public MCAsmParserExtension {
}
StringRef CurrentProcedure;
+ bool CurrentProcedureFramed;
public:
COFFMasmParser() = default;
@@ -361,8 +352,17 @@ bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
getStreamer().EmitCOFFSymbolType(0x20);
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);
+
CurrentProcedure = Label;
+ CurrentProcedureFramed = Framed;
return false;
}
bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
@@ -376,6 +376,30 @@ bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
else if (CurrentProcedure != Label)
return Error(LabelLoc, "endp does not match current procedure '" +
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;
}
diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index cc82ffbcb7cb..ca9b2df7cf23 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -726,7 +726,12 @@ class MasmParser : public MCAsmParser {
DK_STRUCT,
DK_UNION,
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
@@ -6333,6 +6338,11 @@ void MasmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".erridni"] = DK_ERRIDNI;
DirectiveKindMap[".erre"] = DK_ERRE;
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[".noaltmacro"] = DK_NOALTMACRO;
DirectiveKindMap["db"] = DK_DB;
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 361a6c04e3f2..3270932a76d0 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -4172,15 +4172,20 @@ bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
else if (IDVal == ".cv_fpo_endproc")
return parseDirectiveFPOEndProc(DirectiveID.getLoc());
- else if (IDVal == ".seh_pushreg")
+ else if (IDVal == ".seh_pushreg" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".pushreg")))
return parseDirectiveSEHPushReg(DirectiveID.getLoc());
- else if (IDVal == ".seh_setframe")
+ else if (IDVal == ".seh_setframe" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".setframe")))
return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
- else if (IDVal == ".seh_savereg")
+ else if (IDVal == ".seh_savereg" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".savereg")))
return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
- else if (IDVal == ".seh_savexmm")
+ else if (IDVal == ".seh_savexmm" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".savexmm128")))
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 true;
diff --git a/llvm/test/tools/llvm-ml/proc.test b/llvm/test/tools/llvm-ml/proc.test
new file mode 100644
index 000000000000..ad117f7fb1dd
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/proc.test
@@ -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
diff --git a/llvm/test/tools/llvm-ml/proc_frame.test b/llvm/test/tools/llvm-ml/proc_frame.test
new file mode 100644
index 000000000000..3bf1c3a3ca4b
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/proc_frame.test
@@ -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
More information about the llvm-commits
mailing list