aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86WinEHState.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-06-10 01:34:54 +0000
committerReid Kleckner <reid@kleckner.net>2015-06-10 01:34:54 +0000
commit673de15af9db9c5082c4c15d6960d7f669295a42 (patch)
tree45e58aba504569398249a64a1f66391dd1e71b62 /llvm/lib/Target/X86/X86WinEHState.cpp
parent18f4c9f5a065322f1263fcd0d151581da45a815b (diff)
downloadllvm-673de15af9db9c5082c4c15d6960d7f669295a42.zip
llvm-673de15af9db9c5082c4c15d6960d7f669295a42.tar.gz
llvm-673de15af9db9c5082c4c15d6960d7f669295a42.tar.bz2
[WinEH] Call llvm.stackrestore in __except blocks
We have to do this manually, the runtime only sets up ebp. Fixes a crash when returning after catching an exception. llvm-svn: 239451
Diffstat (limited to 'llvm/lib/Target/X86/X86WinEHState.cpp')
-rw-r--r--llvm/lib/Target/X86/X86WinEHState.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp
index 16a94da..afad3f9 100644
--- a/llvm/lib/Target/X86/X86WinEHState.cpp
+++ b/llvm/lib/Target/X86/X86WinEHState.cpp
@@ -263,7 +263,6 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
if (Personality == EHPersonality::MSVC_CXX) {
RegNodeTy = getCXXEHRegistrationType();
RegNode = Builder.CreateAlloca(RegNodeTy);
- // FIXME: We can skip this in -GS- mode, when we figure that out.
// SavedESP = llvm.stacksave()
Value *SP = Builder.CreateCall(
Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
@@ -490,6 +489,7 @@ void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) {
// Iterate all the instructions and emit state number stores.
int CurState = 0;
+ SmallPtrSet<BasicBlock *, 4> ExceptBlocks;
for (BasicBlock &BB : F) {
for (auto I = BB.begin(), E = BB.end(); I != E; ++I) {
if (auto *CI = dyn_cast<CallInst>(I)) {
@@ -517,11 +517,29 @@ void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) {
assert(!ActionList.empty());
CurState += ActionList.size();
State += ActionList.size() - 1;
+
+ // Remember all the __except block targets.
+ for (auto &Handler : ActionList) {
+ if (auto *CH = dyn_cast<CatchHandler>(Handler.get())) {
+ auto *BA = cast<BlockAddress>(CH->getHandlerBlockOrFunc());
+ ExceptBlocks.insert(BA->getBasicBlock());
+ }
+ }
}
insertStateNumberStore(RegNode, II, State);
}
}
}
+
+ // Insert llvm.stackrestore into each __except block.
+ Function *StackRestore =
+ Intrinsic::getDeclaration(TheModule, Intrinsic::stackrestore);
+ for (BasicBlock *ExceptBB : ExceptBlocks) {
+ IRBuilder<> Builder(ExceptBB->begin());
+ Value *SP =
+ Builder.CreateLoad(Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
+ Builder.CreateCall(StackRestore, {SP});
+ }
}
/// Rewrite llvm.eh.exceptioncode and llvm.eh.exceptioninfo to memory loads in