diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 4c7fa40a806..9dd8d4b5335 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 1df5c074746..9376d55e717 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 7fde4fec38b..64f635517b1 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 8b27542fb32..d4f7625e885 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