2323#include " llvm/IR/Function.h"
2424#include " llvm/IR/IRBuilder.h"
2525#include " llvm/IR/Instructions.h"
26+ #include " llvm/IR/IntrinsicInst.h"
2627#include " llvm/IR/Intrinsics.h"
2728#include " llvm/IR/IntrinsicsX86.h"
2829#include " llvm/IR/Module.h"
@@ -41,7 +42,7 @@ class WinEHStatePass : public FunctionPass {
4142public:
4243 static char ID; // Pass identification, replacement for typeid.
4344
44- WinEHStatePass () : FunctionPass(ID) { }
45+ WinEHStatePass () : FunctionPass(ID) {}
4546
4647 bool runOnFunction (Function &Fn) override ;
4748
@@ -75,6 +76,8 @@ class WinEHStatePass : public FunctionPass {
7576 int getStateForCall (DenseMap<BasicBlock *, ColorVector> &BlockColors,
7677 WinEHFuncInfo &FuncInfo, CallBase &Call);
7778
79+ void updateEspForInAllocas (Function &F);
80+
7881 // Module-level type getters.
7982 Type *getEHLinkRegistrationType ();
8083 Type *getSEHRegistrationType ();
@@ -100,6 +103,9 @@ class WinEHStatePass : public FunctionPass {
100103 // / fs:00 chain and the current state.
101104 AllocaInst *RegNode = nullptr ;
102105
106+ // Struct type of RegNode. Used for GEPing.
107+ Type *RegNodeTy = nullptr ;
108+
103109 // The allocation containing the EH security guard.
104110 AllocaInst *EHGuardNode = nullptr ;
105111
@@ -152,8 +158,7 @@ bool WinEHStatePass::runOnFunction(Function &F) {
152158 // Check the personality. Do nothing if this personality doesn't use funclets.
153159 if (!F.hasPersonalityFn ())
154160 return false ;
155- PersonalityFn =
156- dyn_cast<Function>(F.getPersonalityFn ()->stripPointerCasts ());
161+ PersonalityFn = dyn_cast<Function>(F.getPersonalityFn ()->stripPointerCasts ());
157162 if (!PersonalityFn)
158163 return false ;
159164 Personality = classifyEHPersonality (PersonalityFn);
@@ -188,11 +193,13 @@ bool WinEHStatePass::runOnFunction(Function &F) {
188193 // numbers into an immutable analysis pass.
189194 WinEHFuncInfo FuncInfo;
190195 addStateStores (F, FuncInfo);
196+ updateEspForInAllocas (F);
191197
192198 // Reset per-function state.
193199 PersonalityFn = nullptr ;
194200 Personality = EHPersonality::Unknown;
195201 UseStackGuard = false ;
202+ RegNodeTy = nullptr ;
196203 RegNode = nullptr ;
197204 EHGuardNode = nullptr ;
198205
@@ -269,9 +276,6 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
269276 assert (Personality == EHPersonality::MSVC_CXX ||
270277 Personality == EHPersonality::MSVC_X86SEH);
271278
272- // Struct type of RegNode. Used for GEPing.
273- Type *RegNodeTy;
274-
275279 IRBuilder<> Builder (&F->getEntryBlock (), F->getEntryBlock ().begin ());
276280 Type *Int8PtrType = Builder.getPtrTy ();
277281 Type *Int32Ty = Builder.getInt32Ty ();
@@ -387,11 +391,11 @@ Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
387391 FunctionType *TargetFuncTy =
388392 FunctionType::get (Int32Ty, ArrayRef (&ArgTys[0 ], 5 ),
389393 /* isVarArg=*/ false );
390- Function *Trampoline =
391- Function::Create ( TrampolineTy, GlobalValue::InternalLinkage,
392- Twine (" __ehhandler$" ) + GlobalValue::dropLLVMManglingEscape (
393- ParentFunc->getName ()),
394- TheModule);
394+ Function *Trampoline = Function::Create (
395+ TrampolineTy, GlobalValue::InternalLinkage,
396+ Twine (" __ehhandler$" ) +
397+ GlobalValue::dropLLVMManglingEscape ( ParentFunc->getName ()),
398+ TheModule);
395399 if (auto *C = ParentFunc->getComdat ())
396400 Trampoline->setComdat (C);
397401 BasicBlock *EntryBB = BasicBlock::Create (Context, " entry" , Trampoline);
@@ -482,8 +486,8 @@ void WinEHStatePass::rewriteSetJmpCall(IRBuilder<> &Builder, Function &F,
482486 NewCall = NewCI;
483487 } else {
484488 auto *II = cast<InvokeInst>(&Call);
485- NewCall = Builder.CreateInvoke (
486- SetJmp3, II-> getNormalDest (), II->getUnwindDest (), Args, OpBundles);
489+ NewCall = Builder.CreateInvoke (SetJmp3, II-> getNormalDest (),
490+ II->getUnwindDest (), Args, OpBundles);
487491 }
488492 NewCall->setCallingConv (Call.getCallingConv ());
489493 NewCall->setAttributes (Call.getAttributes ());
@@ -774,3 +778,27 @@ void WinEHStatePass::insertStateNumberStore(Instruction *IP, int State) {
774778 RegNode, StateFieldIndex);
775779 Builder.CreateStore (Builder.getInt32 (State), StateField);
776780}
781+
782+ void WinEHStatePass::updateEspForInAllocas (Function &F) {
783+ for (BasicBlock &BB : F) {
784+ for (Instruction &I : BB) {
785+ if (auto *Alloca = dyn_cast<AllocaInst>(&I)) {
786+ if (Alloca->isStaticAlloca ())
787+ continue ;
788+ IRBuilder<> Builder (Alloca->getNextNonDebugInstruction ());
789+ // SavedESP = llvm.stacksave()
790+ Value *SP = Builder.CreateStackSave ();
791+ Builder.CreateStore (SP, Builder.CreateStructGEP (RegNodeTy, RegNode, 0 ));
792+ }
793+
794+ if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
795+ if (II->getIntrinsicID () != Intrinsic::stackrestore)
796+ continue ;
797+ IRBuilder<> Builder (II->getNextNonDebugInstruction ());
798+ // SavedESP = llvm.stacksave()
799+ Value *SP = Builder.CreateStackSave ();
800+ Builder.CreateStore (SP, Builder.CreateStructGEP (RegNodeTy, RegNode, 0 ));
801+ }
802+ }
803+ }
804+ }
0 commit comments