aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2011-05-19 02:49:00 +0000
committerCharles Davis <cdavis@mines.edu>2011-05-19 02:49:00 +0000
commit0855bc5b973320052c87bdcc2fa17b9711edc3de (patch)
tree76a6f5858ae1e8af13a4dbf664b6bc43cf7ee3cd
parentfa89218a438c0fcafb40775bdc04dbe95c59fba3 (diff)
Implement the StartProc and EndProc Win64 EH methods on the base MCStreamer.
Based largely on Rafael Espindola's work on CFI. Other methods soon to follow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131623 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/MC/MCStreamer.h5
-rw-r--r--lib/MC/MCStreamer.cpp37
2 files changed, 34 insertions, 8 deletions
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index aceba76120..8fb46317db 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -18,6 +18,7 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCWin64EH.h"
namespace llvm {
class MCAsmInfo;
@@ -57,6 +58,10 @@ namespace llvm {
MCDwarfFrameInfo *getCurrentFrameInfo();
void EnsureValidFrame();
+ std::vector<MCWin64EHUnwindInfo> W64UnwindInfos;
+ MCWin64EHUnwindInfo *getCurrentW64UnwindInfo();
+ void EnsureValidW64UnwindInfo();
+
const MCSymbol* LastNonPrivate;
/// SectionStack - This is stack of current and previous section
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index bf63f8faee..ed73c1b3a3 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -310,16 +310,37 @@ void MCStreamer::EmitCFISameValue(int64_t Register) {
CurFrame->Instructions.push_back(Instruction);
}
-void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler)
-{
- errs() << "Not implemented yet\n";
- abort();
+MCWin64EHUnwindInfo *MCStreamer::getCurrentW64UnwindInfo() {
+ if (W64UnwindInfos.empty())
+ return NULL;
+ return &W64UnwindInfos.back();
}
-void MCStreamer::EmitWin64EHEndProc()
-{
- errs() << "Not implemented yet\n";
- abort();
+void MCStreamer::EnsureValidW64UnwindInfo() {
+ MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+ if (!CurFrame || CurFrame->End)
+ report_fatal_error("No open Win64 EH frame function!");
+}
+
+void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) {
+ MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+ if (CurFrame && !CurFrame->End)
+ report_fatal_error("Starting a function before ending the previous one!");
+ MCWin64EHUnwindInfo Frame;
+ Frame.Begin = getContext().CreateTempSymbol();
+ Frame.Function = Symbol;
+ Frame.ExceptionHandler = EHandler;
+ EmitLabel(Frame.Begin);
+ W64UnwindInfos.push_back(Frame);
+}
+
+void MCStreamer::EmitWin64EHEndProc() {
+ EnsureValidW64UnwindInfo();
+ MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+ if (CurFrame->Chained)
+ report_fatal_error("Not all chained regions terminated!");
+ CurFrame->End = getContext().CreateTempSymbol();
+ EmitLabel(CurFrame->End);
}
void MCStreamer::EmitWin64EHStartChained()