aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2011-05-22 21:12:15 +0000
committerCharles Davis <cdavis@mines.edu>2011-05-22 21:12:15 +0000
commitfbc539ff37ddd08c2480be9185e7a40919ce8940 (patch)
tree3db166d9c6426a454eca4b90dab90b0e3dcaf4c3
parent87943e36989bd7ac03647004272fe054191e19e7 (diff)
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
-rw-r--r--include/llvm/MC/MCStreamer.h2
-rw-r--r--lib/MC/MCAsmStreamer.cpp4
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp157
-rw-r--r--lib/MC/MCStreamer.cpp2
4 files changed, 161 insertions, 4 deletions
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index c12caf01b0..4c7fa40a80 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -473,7 +473,7 @@ namespace llvm {
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
- virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
+ virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
virtual void EmitWin64EHEndProc();
virtual void EmitWin64EHStartChained();
virtual void EmitWin64EHEndChained();
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 9bd614acfc..1df5c07474 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -208,7 +208,7 @@ public:
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
- virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
+ virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
virtual void EmitWin64EHEndProc();
virtual void EmitWin64EHStartChained();
virtual void EmitWin64EHEndChained();
@@ -930,7 +930,7 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
+void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
MCStreamer::EmitWin64EHStartProc(Symbol);
OS << ".seh_proc " << *Symbol;
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index 5ecab03b00..0045950dca 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -14,6 +14,7 @@
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/Support/COFF.h"
using namespace llvm;
@@ -41,6 +42,34 @@ class COFFAsmParser : public MCAsmParserExtension {
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
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) {
@@ -70,6 +99,22 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseDirectiveType(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:
COFFAsmParser() {}
};
@@ -135,6 +180,118 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
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 {
MCAsmParserExtension *createCOFFAsmParser() {
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index f268f9e375..1402033d41 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -316,7 +316,7 @@ void MCStreamer::EnsureValidW64UnwindInfo() {
report_fatal_error("No open Win64 EH frame function!");
}
-void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
+void MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
if (CurFrame && !CurFrame->End)
report_fatal_error("Starting a function before ending the previous one!");