23
23
#include " llvm/IR/Function.h"
24
24
#include " llvm/IR/IRBuilder.h"
25
25
#include " llvm/IR/Instructions.h"
26
+ #include " llvm/IR/IntrinsicInst.h"
26
27
#include " llvm/IR/Intrinsics.h"
27
28
#include " llvm/IR/IntrinsicsX86.h"
28
29
#include " llvm/IR/Module.h"
@@ -41,7 +42,7 @@ class WinEHStatePass : public FunctionPass {
41
42
public:
42
43
static char ID; // Pass identification, replacement for typeid.
43
44
44
- WinEHStatePass () : FunctionPass(ID) { }
45
+ WinEHStatePass () : FunctionPass(ID) {}
45
46
46
47
bool runOnFunction (Function &Fn) override ;
47
48
@@ -75,6 +76,8 @@ class WinEHStatePass : public FunctionPass {
75
76
int getStateForCall (DenseMap<BasicBlock *, ColorVector> &BlockColors,
76
77
WinEHFuncInfo &FuncInfo, CallBase &Call);
77
78
79
+ void updateEspForInAllocas (Function &F);
80
+
78
81
// Module-level type getters.
79
82
Type *getEHLinkRegistrationType ();
80
83
Type *getSEHRegistrationType ();
@@ -100,6 +103,9 @@ class WinEHStatePass : public FunctionPass {
100
103
// / fs:00 chain and the current state.
101
104
AllocaInst *RegNode = nullptr ;
102
105
106
+ // Struct type of RegNode. Used for GEPing.
107
+ Type *RegNodeTy = nullptr ;
108
+
103
109
// The allocation containing the EH security guard.
104
110
AllocaInst *EHGuardNode = nullptr ;
105
111
@@ -152,8 +158,7 @@ bool WinEHStatePass::runOnFunction(Function &F) {
152
158
// Check the personality. Do nothing if this personality doesn't use funclets.
153
159
if (!F.hasPersonalityFn ())
154
160
return false ;
155
- PersonalityFn =
156
- dyn_cast<Function>(F.getPersonalityFn ()->stripPointerCasts ());
161
+ PersonalityFn = dyn_cast<Function>(F.getPersonalityFn ()->stripPointerCasts ());
157
162
if (!PersonalityFn)
158
163
return false ;
159
164
Personality = classifyEHPersonality (PersonalityFn);
@@ -188,11 +193,13 @@ bool WinEHStatePass::runOnFunction(Function &F) {
188
193
// numbers into an immutable analysis pass.
189
194
WinEHFuncInfo FuncInfo;
190
195
addStateStores (F, FuncInfo);
196
+ updateEspForInAllocas (F);
191
197
192
198
// Reset per-function state.
193
199
PersonalityFn = nullptr ;
194
200
Personality = EHPersonality::Unknown;
195
201
UseStackGuard = false ;
202
+ RegNodeTy = nullptr ;
196
203
RegNode = nullptr ;
197
204
EHGuardNode = nullptr ;
198
205
@@ -269,9 +276,6 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
269
276
assert (Personality == EHPersonality::MSVC_CXX ||
270
277
Personality == EHPersonality::MSVC_X86SEH);
271
278
272
- // Struct type of RegNode. Used for GEPing.
273
- Type *RegNodeTy;
274
-
275
279
IRBuilder<> Builder (&F->getEntryBlock (), F->getEntryBlock ().begin ());
276
280
Type *Int8PtrType = Builder.getPtrTy ();
277
281
Type *Int32Ty = Builder.getInt32Ty ();
@@ -387,11 +391,11 @@ Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
387
391
FunctionType *TargetFuncTy =
388
392
FunctionType::get (Int32Ty, ArrayRef (&ArgTys[0 ], 5 ),
389
393
/* 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);
395
399
if (auto *C = ParentFunc->getComdat ())
396
400
Trampoline->setComdat (C);
397
401
BasicBlock *EntryBB = BasicBlock::Create (Context, " entry" , Trampoline);
@@ -482,8 +486,8 @@ void WinEHStatePass::rewriteSetJmpCall(IRBuilder<> &Builder, Function &F,
482
486
NewCall = NewCI;
483
487
} else {
484
488
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);
487
491
}
488
492
NewCall->setCallingConv (Call.getCallingConv ());
489
493
NewCall->setAttributes (Call.getAttributes ());
@@ -774,3 +778,27 @@ void WinEHStatePass::insertStateNumberStore(Instruction *IP, int State) {
774
778
RegNode, StateFieldIndex);
775
779
Builder.CreateStore (Builder.getInt32 (State), StateField);
776
780
}
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