summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCStreamer.h11
-rw-r--r--lib/MC/MCAsmStreamer.cpp9
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp8
-rw-r--r--test/MC/AsmParser/directive_seh.s14
4 files changed, 40 insertions, 2 deletions
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 4c7fa40a80..9dd8d4b533 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -195,6 +195,17 @@ namespace llvm {
}
}
+ /// SwitchSectionNoChange - Set the current section where code is being
+ /// emitted to @p Section. This is required to update CurSection. This
+ /// version does not call ChangeSection.
+ void SwitchSectionNoChange(const MCSection *Section) {
+ assert(Section && "Cannot switch to a null section!");
+ const MCSection *curSection = SectionStack.back().first;
+ SectionStack.back().second = curSection;
+ if (Section != curSection)
+ SectionStack.back().first = Section;
+ }
+
/// InitSections - Create the default sections and set the initial one.
virtual void InitSections() = 0;
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 1df5c07474..9376d55e71 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -973,6 +973,15 @@ void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
void MCAsmStreamer::EmitWin64EHHandlerData() {
MCStreamer::EmitWin64EHHandlerData();
+ // Switch sections. Don't call SwitchSection directly, because that will
+ // cause the section switch to be visible in the emitted assembly.
+ // We only do this so the section switch that terminates the handler
+ // data block is visible.
+ const MCSection *xdataSect =
+ getContext().getTargetAsmInfo().getWin64EHTableSection();
+ if (xdataSect)
+ SwitchSectionNoChange(xdataSect);
+
OS << "\t.seh_handlerdata";
EmitEOL();
}
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index 7fde4fec38..64f635517b 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -266,6 +266,10 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
int64_t Off;
if (ParseSEHRegisterNumber(Reg))
return true;
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("you must specify a stack pointer offset");
+
+ Lex();
SMLoc startLoc = getLexer().getLoc();
if (getParser().ParseAbsoluteExpression(Off))
return true;
@@ -304,7 +308,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
if (ParseSEHRegisterNumber(Reg))
return true;
if (getLexer().isNot(AsmToken::Comma))
- return TokError("expected comma");
+ return TokError("you must specify an offset on the stack");
Lex();
SMLoc startLoc = getLexer().getLoc();
@@ -331,7 +335,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
if (ParseSEHRegisterNumber(Reg))
return true;
if (getLexer().isNot(AsmToken::Comma))
- return TokError("expected comma");
+ return TokError("you must specify an offset on the stack");
Lex();
SMLoc startLoc = getLexer().getLoc();
diff --git a/test/MC/AsmParser/directive_seh.s b/test/MC/AsmParser/directive_seh.s
index 8b27542fb3..d4f7625e88 100644
--- a/test/MC/AsmParser/directive_seh.s
+++ b/test/MC/AsmParser/directive_seh.s
@@ -5,8 +5,13 @@
# CHECK: .seh_stackalloc 24
# CHECK: .seh_savereg 6, 16
# CHECK: .seh_savexmm 8, 0
+# CHECK: .seh_pushreg 3
+# CHECK: .seh_setframe 3, 0
# CHECK: .seh_endprologue
# CHECK: .seh_handler __C_specific_handler, @except
+# CHECK-NOT: .section{{.*}}.xdata
+# CHECK: .seh_handlerdata
+# CHECK: .text
# CHECK: .seh_endproc
.text
@@ -21,8 +26,17 @@ func:
.seh_savereg %rsi, 16
movups %xmm8, (%rsp)
.seh_savexmm %xmm8, 0
+ pushq %rbx
+ .seh_pushreg 3
+ mov %rsp, %rbx
+ .seh_setframe 3, 0
.seh_endprologue
.seh_handler __C_specific_handler, @except
+ .seh_handlerdata
+ .long 0
+ .text
+ lea (%rbx), %rsp
+ pop %rbx
addq $24, %rsp
ret
.seh_endproc