Add tests for .seh_setframe and .seh_handlerdata parsing. Fix issues with
authorCharles Davis <cdavis@mines.edu>
Wed, 25 May 2011 21:43:45 +0000 (21:43 +0000)
committerCharles Davis <cdavis@mines.edu>
Wed, 25 May 2011 21:43:45 +0000 (21:43 +0000)
them.

I had to add a special SwitchSectionNoChange method to MCStreamer just for
.seh_handlerdata. If this isn't OK, please let me know, and I'll find some
other way to fix .seh_handlerdata streaming.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132084 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCStreamer.h
lib/MC/MCAsmStreamer.cpp
lib/MC/MCParser/COFFAsmParser.cpp
test/MC/AsmParser/directive_seh.s

index 4c7fa40a8065c9abd89148e789b93b802c6f19d8..9dd8d4b533513f7391498a4dc90a689e66412939 100644 (file)
@@ -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;
 
index 1df5c074746305a16540ea260c41849a438a8e44..9376d55e71755ed4c8515c9ae277881d1ef4d216 100644 (file)
@@ -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();
 }
index 7fde4fec38bfd535d9c786143b256373e03f7229..64f635517b11d1ed8a9720483621f01d1b90178c 100644 (file)
@@ -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();
index 8b27542fb3286e21429a3e3dea827e4714eec6d5..d4f7625e8857ffab50d1b70ff0934fa6182a75c0 100644 (file)
@@ -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