diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-06-10 01:02:30 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-06-10 01:02:30 +0000 |
commit | 2bc93ca84606399da5ae5ac68c2140d5d2855adb (patch) | |
tree | fdb91ed61f6631483898fad400f79cc6d077bf32 /llvm | |
parent | 1469b9196ce4394486371b39e9fa5d44975d3a29 (diff) | |
download | bcm5719-llvm-2bc93ca84606399da5ae5ac68c2140d5d2855adb.tar.gz bcm5719-llvm-2bc93ca84606399da5ae5ac68c2140d5d2855adb.zip |
[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.
llvm-svn: 239448
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/MC/WinCOFFStreamer.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86WinEHState.cpp | 11 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/win32-eh-states.ll | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/win32-eh.ll | 4 |
5 files changed, 29 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 7e3a6d5a76f..ffa0ceb1a60 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -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) { diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp index 41fc8e4681e..36dd691f07b 100644 --- a/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/llvm/lib/MC/WinCOFFStreamer.cpp @@ -164,7 +164,8 @@ void MCWinCOFFStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { 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(MCSymbol const *Symbol) { 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) { diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp index 0c4aabab880..16a94daa819 100644 --- a/llvm/lib/Target/X86/X86WinEHState.cpp +++ b/llvm/lib/Target/X86/X86WinEHState.cpp @@ -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::generateLSDAInEAXThunk(Function *ParentFunc) { } 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)); diff --git a/llvm/test/CodeGen/X86/win32-eh-states.ll b/llvm/test/CodeGen/X86/win32-eh-states.ll index 8db127df6da..7bcd51c44f0 100644 --- a/llvm/test/CodeGen/X86/win32-eh-states.ll +++ b/llvm/test/CodeGen/X86/win32-eh-states.ll @@ -110,3 +110,5 @@ eh.resume: ; preds = %catch.dispatch.4 ; CHECK: movl $3, Lf$frame_escape_{{[0-9]+.*}} ; CHECK: movl $3, (%esp) ; CHECK: calll _may_throw + +; CHECK: .safeseh ___ehhandler$f diff --git a/llvm/test/CodeGen/X86/win32-eh.ll b/llvm/test/CodeGen/X86/win32-eh.ll index ed8402aeab0..3abaa49653b 100644 --- a/llvm/test/CodeGen/X86/win32-eh.ll +++ b/llvm/test/CodeGen/X86/win32-eh.ll @@ -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 |