mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-06 04:18:00 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239451 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -263,7 +263,6 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
|
|||||||
if (Personality == EHPersonality::MSVC_CXX) {
|
if (Personality == EHPersonality::MSVC_CXX) {
|
||||||
RegNodeTy = getCXXEHRegistrationType();
|
RegNodeTy = getCXXEHRegistrationType();
|
||||||
RegNode = Builder.CreateAlloca(RegNodeTy);
|
RegNode = Builder.CreateAlloca(RegNodeTy);
|
||||||
// FIXME: We can skip this in -GS- mode, when we figure that out.
|
|
||||||
// SavedESP = llvm.stacksave()
|
// SavedESP = llvm.stacksave()
|
||||||
Value *SP = Builder.CreateCall(
|
Value *SP = Builder.CreateCall(
|
||||||
Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
|
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.
|
// Iterate all the instructions and emit state number stores.
|
||||||
int CurState = 0;
|
int CurState = 0;
|
||||||
|
SmallPtrSet<BasicBlock *, 4> ExceptBlocks;
|
||||||
for (BasicBlock &BB : F) {
|
for (BasicBlock &BB : F) {
|
||||||
for (auto I = BB.begin(), E = BB.end(); I != E; ++I) {
|
for (auto I = BB.begin(), E = BB.end(); I != E; ++I) {
|
||||||
if (auto *CI = dyn_cast<CallInst>(I)) {
|
if (auto *CI = dyn_cast<CallInst>(I)) {
|
||||||
@@ -517,11 +517,29 @@ void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) {
|
|||||||
assert(!ActionList.empty());
|
assert(!ActionList.empty());
|
||||||
CurState += ActionList.size();
|
CurState += ActionList.size();
|
||||||
State += ActionList.size() - 1;
|
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);
|
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
|
/// Rewrite llvm.eh.exceptioncode and llvm.eh.exceptioninfo to memory loads in
|
||||||
|
|||||||
@@ -77,11 +77,15 @@ __try.cont:
|
|||||||
|
|
||||||
; CHECK: [[handler0:Ltmp[0-9]+]]: # Block address taken
|
; CHECK: [[handler0:Ltmp[0-9]+]]: # Block address taken
|
||||||
; CHECK: # %handler0
|
; CHECK: # %handler0
|
||||||
|
; Restore SP
|
||||||
|
; CHECK: movl {{.*}}(%ebp), %esp
|
||||||
; CHECK: calll _puts
|
; CHECK: calll _puts
|
||||||
; CHECK: jmp [[cont_bb]]
|
; CHECK: jmp [[cont_bb]]
|
||||||
|
|
||||||
; CHECK: [[handler1:Ltmp[0-9]+]]: # Block address taken
|
; CHECK: [[handler1:Ltmp[0-9]+]]: # Block address taken
|
||||||
; CHECK: # %handler1
|
; CHECK: # %handler1
|
||||||
|
; Restore SP
|
||||||
|
; CHECK: movl {{.*}}(%ebp), %esp
|
||||||
; CHECK: calll _puts
|
; CHECK: calll _puts
|
||||||
; CHECK: jmp [[cont_bb]]
|
; CHECK: jmp [[cont_bb]]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user