diff options
author | Reid Kleckner <rnk@google.com> | 2015-12-15 23:47:40 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-12-15 23:47:40 +0000 |
commit | cf2626600cdece9ed17f0ec76bb506f01db78508 (patch) | |
tree | 6143bc5f334222c146effea45462a50f613c5ef1 /clang/lib/CodeGen/CGException.cpp | |
parent | 8f3118f4499cb7a6d086a1d55dac3fe1485ab7ce (diff) | |
download | bcm5719-llvm-cf2626600cdece9ed17f0ec76bb506f01db78508.tar.gz bcm5719-llvm-cf2626600cdece9ed17f0ec76bb506f01db78508.zip |
[SEH] Use llvm.x86.seh.recoverfp for SEH filters on x64 as well as 32bit
llvm-svn: 255710
Diffstat (limited to 'clang/lib/CodeGen/CGException.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index a064e6246a7..bd95cdeff39 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -1548,27 +1548,32 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, return; } - llvm::Value *EntryEBP = nullptr; - llvm::Value *ParentFP; + llvm::Value *EntryFP = nullptr; + CGBuilderTy Builder(CGM, AllocaInsertPt); if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) { // 32-bit SEH filters need to be careful about FP recovery. The end of the // EH registration is passed in as the EBP physical register. We can - // recover that with llvm.frameaddress(1), and adjust that to recover the - // parent's true frame pointer. - CGBuilderTy Builder(CGM, AllocaInsertPt); - EntryEBP = Builder.CreateCall( + // recover that with llvm.frameaddress(1). + EntryFP = Builder.CreateCall( CGM.getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)}); - llvm::Function *RecoverFPIntrin = - CGM.getIntrinsic(llvm::Intrinsic::x86_seh_recoverfp); - llvm::Constant *ParentI8Fn = - llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy); - ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryEBP}); } else { // Otherwise, for x64 and 32-bit finally functions, the parent FP is the // second parameter. auto AI = CurFn->arg_begin(); ++AI; - ParentFP = &*AI; + EntryFP = &*AI; + } + + llvm::Value *ParentFP; + if (IsFilter) { + // Given whatever FP the runtime provided us in EntryFP, recover the true + // frame pointer of the parent function. We only need to do this in filters, + // since finally funclets recover the parent FP for us. + llvm::Function *RecoverFPIntrin = + CGM.getIntrinsic(llvm::Intrinsic::x86_seh_recoverfp); + llvm::Constant *ParentI8Fn = + llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy); + ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP}); } // Create llvm.localrecover calls for all captures. @@ -1602,7 +1607,7 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, } if (IsFilter) - EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryEBP); + EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP); } /// Arrange a function prototype that can be called by Windows exception @@ -1718,7 +1723,7 @@ CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, - llvm::Value *EntryEBP) { + llvm::Value *EntryFP) { // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the // __exception_info intrinsic. if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) { @@ -1731,7 +1736,7 @@ void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, // exception registration object. It contains 6 32-bit fields, and the info // pointer is stored in the second field. So, GEP 20 bytes backwards and // load the pointer. - SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryEBP, -20); + SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20); SEHInfo = Builder.CreateBitCast(SEHInfo, Int8PtrTy->getPointerTo()); SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign()); SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal( |