[llvm] r239448 - [WinEH] Emit .safeseh directives for all 32-bit exception handlers

Reid Kleckner reid at kleckner.net
Tue Jun 9 18:02:30 PDT 2015


Author: rnk
Date: Tue Jun  9 20:02:30 2015
New Revision: 239448

URL: http://llvm.org/viewvc/llvm-project?rev=239448&view=rev
Log:
[WinEH] Emit .safeseh directives for all 32-bit exception handlers

Use a "safeseh" string attribute to do this. You would think we chould
just accumulate the set of personalities like we do on dwarf, but this
fails to account for the LSDA-loading thunks we use for
__CxxFrameHandler3. Each of those needs to make it into .sxdata as well.
The string attribute seemed like the most straightforward approach.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/MC/WinCOFFStreamer.cpp
    llvm/trunk/lib/Target/X86/X86WinEHState.cpp
    llvm/trunk/test/CodeGen/X86/win32-eh-states.ll
    llvm/trunk/test/CodeGen/X86/win32-eh.ll

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=239448&r1=239447&r2=239448&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Tue Jun  9 20:02:30 2015
@@ -50,6 +50,14 @@ WinException::~WinException() {}
 /// endModule - Emit all exception information that should come after the
 /// content.
 void WinException::endModule() {
+  auto &OS = *Asm->OutStreamer;
+  const Module *M = MMI->getModule();
+  for (const Function &F : *M) {
+    if (F.hasFnAttribute("safeseh")) {
+      llvm::errs() << ".safeseh " << F.getName() << "\n";
+      OS.EmitCOFFSafeSEH(Asm->getSymbol(&F));
+    }
+  }
 }
 
 void WinException::beginFunction(const MachineFunction *MF) {

Modified: llvm/trunk/lib/MC/WinCOFFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFStreamer.cpp?rev=239448&r1=239447&r2=239448&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFStreamer.cpp Tue Jun  9 20:02:30 2015
@@ -164,7 +164,8 @@ void MCWinCOFFStreamer::EmitCOFFSafeSEH(
       Triple::x86)
     return;
 
-  if (cast<MCSymbolCOFF>(Symbol)->isSafeSEH())
+  const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol);
+  if (CSymbol->isSafeSEH())
     return;
 
   MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection();
@@ -175,7 +176,12 @@ void MCWinCOFFStreamer::EmitCOFFSafeSEH(
   new MCSafeSEHFragment(Symbol, SXData);
 
   getAssembler().registerSymbol(*Symbol);
-  cast<MCSymbolCOFF>(Symbol)->setIsSafeSEH();
+  CSymbol->setIsSafeSEH();
+
+  // The Microsoft linker requires that the symbol type of a handler be
+  // function. Go ahead and oblige it here.
+  CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION
+                   << COFF::SCT_COMPLEX_TYPE_SHIFT);
 }
 
 void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {

Modified: llvm/trunk/lib/Target/X86/X86WinEHState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86WinEHState.cpp?rev=239448&r1=239447&r2=239448&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86WinEHState.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86WinEHState.cpp Tue Jun  9 20:02:30 2015
@@ -60,7 +60,7 @@ public:
 private:
   void emitExceptionRegistrationRecord(Function *F);
 
-  void linkExceptionRegistration(IRBuilder<> &Builder, Value *Handler);
+  void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
   void unlinkExceptionRegistration(IRBuilder<> &Builder);
   void addCXXStateStores(Function &F, MachineModuleInfo &MMI);
   void addSEHStateStores(Function &F, MachineModuleInfo &MMI);
@@ -365,11 +365,14 @@ Function *WinEHStatePass::generateLSDAIn
 }
 
 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
-                                               Value *Handler) {
+                                               Function *Handler) {
+  // Emit the .safeseh directive for this function.
+  Handler->addFnAttr("safeseh");
+
   Type *LinkTy = getEHLinkRegistrationType();
   // Handler = Handler
-  Handler = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
-  Builder.CreateStore(Handler, Builder.CreateStructGEP(LinkTy, Link, 1));
+  Value *HandlerI8 = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
+  Builder.CreateStore(HandlerI8, Builder.CreateStructGEP(LinkTy, Link, 1));
   // Next = [fs:00]
   Constant *FSZero =
       Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));

Modified: llvm/trunk/test/CodeGen/X86/win32-eh-states.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win32-eh-states.ll?rev=239448&r1=239447&r2=239448&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win32-eh-states.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win32-eh-states.ll Tue Jun  9 20:02:30 2015
@@ -110,3 +110,5 @@ eh.resume:
 ; CHECK: movl $3, Lf$frame_escape_{{[0-9]+.*}}
 ; CHECK: movl $3, (%esp)
 ; CHECK: calll _may_throw
+
+; CHECK: .safeseh ___ehhandler$f

Modified: llvm/trunk/test/CodeGen/X86/win32-eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win32-eh.ll?rev=239448&r1=239447&r2=239448&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win32-eh.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win32-eh.ll Tue Jun  9 20:02:30 2015
@@ -126,3 +126,7 @@ catchall:
 ; CHECK-LABEL: ___ehhandler$use_CxxFrameHandler3:
 ; CHECK: movl $L__ehtable$use_CxxFrameHandler3, %eax
 ; CHECK: jmp  ___CxxFrameHandler3 # TAILCALL
+
+; CHECK: .safeseh __except_handler3
+; CHECK: .safeseh __except_handler4
+; CHECK: .safeseh ___ehhandler$use_CxxFrameHandler3





More information about the llvm-commits mailing list