blob: 18d3e019e0b08a81cadbd5400045d246649ad0d5 [file] [log] [blame]
Reid Kleckner0738a9c2015-05-05 17:44:16 +00001//===-- X86WinEHState - Insert EH state updates for win32 exceptions ------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Reid Kleckner0738a9c2015-05-05 17:44:16 +00006//
7//===----------------------------------------------------------------------===//
8//
9// All functions using an MSVC EH personality use an explicitly updated state
10// number stored in an exception registration stack object. The registration
11// object is linked into a thread-local chain of registrations stored at fs:00.
12// This pass adds the registration object and EH state updates.
13//
14//===----------------------------------------------------------------------===//
15
16#include "X86.h"
David Majnemer7e5937b2016-02-17 18:37:11 +000017#include "llvm/ADT/PostOrderIterator.h"
18#include "llvm/Analysis/CFG.h"
David Majnemer70497c62015-12-02 23:06:39 +000019#include "llvm/Analysis/EHPersonalities.h"
Reid Klecknerfe4d4912015-05-28 22:00:24 +000020#include "llvm/CodeGen/MachineModuleInfo.h"
Reid Kleckner0738a9c2015-05-05 17:44:16 +000021#include "llvm/CodeGen/WinEHFuncInfo.h"
David Majnemer7e5937b2016-02-17 18:37:11 +000022#include "llvm/IR/CallSite.h"
23#include "llvm/IR/Function.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000024#include "llvm/IR/IRBuilder.h"
Reid Kleckner0738a9c2015-05-05 17:44:16 +000025#include "llvm/IR/Instructions.h"
26#include "llvm/IR/IntrinsicInst.h"
27#include "llvm/IR/Module.h"
Reid Kleckner0738a9c2015-05-05 17:44:16 +000028#include "llvm/Pass.h"
David Majnemer7e5937b2016-02-17 18:37:11 +000029#include "llvm/Support/Debug.h"
30#include <deque>
Reid Kleckner0738a9c2015-05-05 17:44:16 +000031
32using namespace llvm;
Reid Kleckner0738a9c2015-05-05 17:44:16 +000033
34#define DEBUG_TYPE "winehstate"
35
36namespace {
David Majnemer7e5937b2016-02-17 18:37:11 +000037const int OverdefinedState = INT_MIN;
38
Reid Kleckner0738a9c2015-05-05 17:44:16 +000039class WinEHStatePass : public FunctionPass {
40public:
41 static char ID; // Pass identification, replacement for typeid.
42
David Majnemer0ad363e2015-08-18 19:07:12 +000043 WinEHStatePass() : FunctionPass(ID) {
44 initializeWinEHStatePassPass(*PassRegistry::getPassRegistry());
45 }
Reid Kleckner0738a9c2015-05-05 17:44:16 +000046
47 bool runOnFunction(Function &Fn) override;
48
49 bool doInitialization(Module &M) override;
50
51 bool doFinalization(Module &M) override;
52
53 void getAnalysisUsage(AnalysisUsage &AU) const override;
54
Mehdi Amini117296c2016-10-01 02:56:57 +000055 StringRef getPassName() const override {
Reid Kleckner0738a9c2015-05-05 17:44:16 +000056 return "Windows 32-bit x86 EH state insertion";
57 }
58
59private:
60 void emitExceptionRegistrationRecord(Function *F);
61
Reid Kleckner2bc93ca2015-06-10 01:02:30 +000062 void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
Reid Klecknerfe4d4912015-05-28 22:00:24 +000063 void unlinkExceptionRegistration(IRBuilder<> &Builder);
Reid Klecknerc20276d2015-11-17 21:10:25 +000064 void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
David Majnemerefb41742016-02-01 04:28:59 +000065 void insertStateNumberStore(Instruction *IP, int State);
Reid Kleckner0738a9c2015-05-05 17:44:16 +000066
Reid Kleckner2632f0d2015-05-20 23:08:04 +000067 Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
68
69 Function *generateLSDAInEAXThunk(Function *ParentFunc);
70
David Majnemere60ee3b2016-02-29 19:16:03 +000071 bool isStateStoreNeeded(EHPersonality Personality, CallSite CS);
72 void rewriteSetJmpCallSite(IRBuilder<> &Builder, Function &F, CallSite CS,
73 Value *State);
74 int getBaseStateForBB(DenseMap<BasicBlock *, ColorVector> &BlockColors,
75 WinEHFuncInfo &FuncInfo, BasicBlock *BB);
76 int getStateForCallSite(DenseMap<BasicBlock *, ColorVector> &BlockColors,
77 WinEHFuncInfo &FuncInfo, CallSite CS);
78
Reid Kleckner0738a9c2015-05-05 17:44:16 +000079 // Module-level type getters.
Reid Klecknere6531a552015-05-29 22:57:46 +000080 Type *getEHLinkRegistrationType();
81 Type *getSEHRegistrationType();
82 Type *getCXXEHRegistrationType();
Reid Kleckner0738a9c2015-05-05 17:44:16 +000083
84 // Per-module data.
85 Module *TheModule = nullptr;
Reid Klecknere6531a552015-05-29 22:57:46 +000086 StructType *EHLinkRegistrationTy = nullptr;
87 StructType *CXXEHRegistrationTy = nullptr;
88 StructType *SEHRegistrationTy = nullptr;
James Y Knight13680222019-02-01 02:28:03 +000089 FunctionCallee SetJmp3 = nullptr;
90 FunctionCallee CxxLongjmpUnwind = nullptr;
Reid Kleckner0738a9c2015-05-05 17:44:16 +000091
92 // Per-function state
93 EHPersonality Personality = EHPersonality::Unknown;
94 Function *PersonalityFn = nullptr;
David Majnemer7e5937b2016-02-17 18:37:11 +000095 bool UseStackGuard = false;
96 int ParentBaseState;
James Y Knight13680222019-02-01 02:28:03 +000097 FunctionCallee SehLongjmpUnwind = nullptr;
David Majnemere60ee3b2016-02-29 19:16:03 +000098 Constant *Cookie = nullptr;
Reid Klecknerfe4d4912015-05-28 22:00:24 +000099
100 /// The stack allocation containing all EH data, including the link in the
101 /// fs:00 chain and the current state.
102 AllocaInst *RegNode = nullptr;
103
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000104 // The allocation containing the EH security guard.
105 AllocaInst *EHGuardNode = nullptr;
106
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000107 /// The index of the state field of RegNode.
108 int StateFieldIndex = ~0U;
109
110 /// The linked list node subobject inside of RegNode.
111 Value *Link = nullptr;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000112};
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000113}
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000114
115FunctionPass *llvm::createX86WinEHStatePass() { return new WinEHStatePass(); }
116
117char WinEHStatePass::ID = 0;
118
David Majnemer0ad363e2015-08-18 19:07:12 +0000119INITIALIZE_PASS(WinEHStatePass, "x86-winehstate",
120 "Insert stores for EH state numbers", false, false)
121
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000122bool WinEHStatePass::doInitialization(Module &M) {
123 TheModule = &M;
124 return false;
125}
126
127bool WinEHStatePass::doFinalization(Module &M) {
128 assert(TheModule == &M);
129 TheModule = nullptr;
Reid Klecknere6531a552015-05-29 22:57:46 +0000130 EHLinkRegistrationTy = nullptr;
131 CXXEHRegistrationTy = nullptr;
132 SEHRegistrationTy = nullptr;
David Majnemere60ee3b2016-02-29 19:16:03 +0000133 SetJmp3 = nullptr;
134 CxxLongjmpUnwind = nullptr;
135 SehLongjmpUnwind = nullptr;
136 Cookie = nullptr;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000137 return false;
138}
139
140void WinEHStatePass::getAnalysisUsage(AnalysisUsage &AU) const {
141 // This pass should only insert a stack allocation, memory accesses, and
Reid Kleckner60381792015-07-07 22:25:32 +0000142 // localrecovers.
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000143 AU.setPreservesCFG();
144}
145
146bool WinEHStatePass::runOnFunction(Function &F) {
Reid Klecknera2d119a2017-12-28 18:41:31 +0000147 // Don't insert state stores or exception handler thunks for
148 // available_externally functions. The handler needs to reference the LSDA,
149 // which will not be emitted in this case.
150 if (F.hasAvailableExternallyLinkage())
151 return false;
152
Joseph Tremoulet2afea542015-10-06 20:28:16 +0000153 // Check the personality. Do nothing if this personality doesn't use funclets.
David Majnemer7fddecc2015-06-17 20:52:32 +0000154 if (!F.hasPersonalityFn())
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000155 return false;
156 PersonalityFn =
David Majnemer7fddecc2015-06-17 20:52:32 +0000157 dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000158 if (!PersonalityFn)
159 return false;
160 Personality = classifyEHPersonality(PersonalityFn);
Joseph Tremoulet2afea542015-10-06 20:28:16 +0000161 if (!isFuncletEHPersonality(Personality))
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000162 return false;
163
Reid Kleckner84ebff42015-09-16 17:19:44 +0000164 // Skip this function if there are no EH pads and we aren't using IR-level
165 // outlining.
David Majnemerbfa5b982015-10-10 00:04:29 +0000166 bool HasPads = false;
167 for (BasicBlock &BB : F) {
168 if (BB.isEHPad()) {
169 HasPads = true;
170 break;
Reid Kleckner84ebff42015-09-16 17:19:44 +0000171 }
Reid Kleckner84ebff42015-09-16 17:19:44 +0000172 }
David Majnemerbfa5b982015-10-10 00:04:29 +0000173 if (!HasPads)
174 return false;
Reid Kleckner84ebff42015-09-16 17:19:44 +0000175
David Majnemere60ee3b2016-02-29 19:16:03 +0000176 Type *Int8PtrType = Type::getInt8PtrTy(TheModule->getContext());
177 SetJmp3 = TheModule->getOrInsertFunction(
178 "_setjmp3", FunctionType::get(
179 Type::getInt32Ty(TheModule->getContext()),
180 {Int8PtrType, Type::getInt32Ty(TheModule->getContext())},
181 /*isVarArg=*/true));
David Majnemer862c5ba32016-02-20 07:34:21 +0000182
Reid Kleckner173a7252015-05-29 21:58:11 +0000183 // Disable frame pointer elimination in this function.
184 // FIXME: Do the nested handlers need to keep the parent ebp in ebp, or can we
185 // use an arbitrary register?
186 F.addFnAttr("no-frame-pointer-elim", "true");
187
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000188 emitExceptionRegistrationRecord(&F);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000189
Reid Klecknerc20276d2015-11-17 21:10:25 +0000190 // The state numbers calculated here in IR must agree with what we calculate
191 // later on for the MachineFunction. In particular, if an IR pass deletes an
192 // unreachable EH pad after this point before machine CFG construction, we
193 // will be in trouble. If this assumption is ever broken, we should turn the
194 // numbers into an immutable analysis pass.
195 WinEHFuncInfo FuncInfo;
196 addStateStores(F, FuncInfo);
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000197
198 // Reset per-function state.
199 PersonalityFn = nullptr;
200 Personality = EHPersonality::Unknown;
David Majnemer7e5937b2016-02-17 18:37:11 +0000201 UseStackGuard = false;
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000202 RegNode = nullptr;
203 EHGuardNode = nullptr;
204
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000205 return true;
206}
207
208/// Get the common EH registration subobject:
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000209/// typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
210/// _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000211/// struct EHRegistrationNode {
212/// EHRegistrationNode *Next;
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000213/// PEXCEPTION_ROUTINE Handler;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000214/// };
Reid Klecknere6531a552015-05-29 22:57:46 +0000215Type *WinEHStatePass::getEHLinkRegistrationType() {
216 if (EHLinkRegistrationTy)
217 return EHLinkRegistrationTy;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000218 LLVMContext &Context = TheModule->getContext();
Reid Klecknere6531a552015-05-29 22:57:46 +0000219 EHLinkRegistrationTy = StructType::create(Context, "EHRegistrationNode");
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000220 Type *FieldTys[] = {
Reid Klecknere6531a552015-05-29 22:57:46 +0000221 EHLinkRegistrationTy->getPointerTo(0), // EHRegistrationNode *Next
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000222 Type::getInt8PtrTy(Context) // EXCEPTION_DISPOSITION (*Handler)(...)
223 };
Reid Klecknere6531a552015-05-29 22:57:46 +0000224 EHLinkRegistrationTy->setBody(FieldTys, false);
225 return EHLinkRegistrationTy;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000226}
227
228/// The __CxxFrameHandler3 registration node:
229/// struct CXXExceptionRegistration {
230/// void *SavedESP;
231/// EHRegistrationNode SubRecord;
232/// int32_t TryLevel;
233/// };
Reid Klecknere6531a552015-05-29 22:57:46 +0000234Type *WinEHStatePass::getCXXEHRegistrationType() {
235 if (CXXEHRegistrationTy)
236 return CXXEHRegistrationTy;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000237 LLVMContext &Context = TheModule->getContext();
238 Type *FieldTys[] = {
239 Type::getInt8PtrTy(Context), // void *SavedESP
Reid Klecknere6531a552015-05-29 22:57:46 +0000240 getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000241 Type::getInt32Ty(Context) // int32_t TryLevel
242 };
Reid Klecknere6531a552015-05-29 22:57:46 +0000243 CXXEHRegistrationTy =
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000244 StructType::create(FieldTys, "CXXExceptionRegistration");
Reid Klecknere6531a552015-05-29 22:57:46 +0000245 return CXXEHRegistrationTy;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000246}
247
Reid Klecknere6531a552015-05-29 22:57:46 +0000248/// The _except_handler3/4 registration node:
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000249/// struct EH4ExceptionRegistration {
250/// void *SavedESP;
251/// _EXCEPTION_POINTERS *ExceptionPointers;
252/// EHRegistrationNode SubRecord;
253/// int32_t EncodedScopeTable;
254/// int32_t TryLevel;
255/// };
Reid Klecknere6531a552015-05-29 22:57:46 +0000256Type *WinEHStatePass::getSEHRegistrationType() {
257 if (SEHRegistrationTy)
258 return SEHRegistrationTy;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000259 LLVMContext &Context = TheModule->getContext();
260 Type *FieldTys[] = {
261 Type::getInt8PtrTy(Context), // void *SavedESP
262 Type::getInt8PtrTy(Context), // void *ExceptionPointers
Reid Klecknere6531a552015-05-29 22:57:46 +0000263 getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000264 Type::getInt32Ty(Context), // int32_t EncodedScopeTable
265 Type::getInt32Ty(Context) // int32_t TryLevel
266 };
Reid Klecknere6531a552015-05-29 22:57:46 +0000267 SEHRegistrationTy = StructType::create(FieldTys, "SEHExceptionRegistration");
268 return SEHRegistrationTy;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000269}
270
271// Emit an exception registration record. These are stack allocations with the
272// common subobject of two pointers: the previous registration record (the old
273// fs:00) and the personality function for the current frame. The data before
274// and after that is personality function specific.
275void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
276 assert(Personality == EHPersonality::MSVC_CXX ||
277 Personality == EHPersonality::MSVC_X86SEH);
278
David Majnemerefb41742016-02-01 04:28:59 +0000279 // Struct type of RegNode. Used for GEPing.
280 Type *RegNodeTy;
281
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000282 IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
283 Type *Int8PtrType = Builder.getInt8PtrTy();
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000284 Type *Int32Ty = Builder.getInt32Ty();
285 Type *VoidTy = Builder.getVoidTy();
286
Reid Klecknere6531a552015-05-29 22:57:46 +0000287 if (Personality == EHPersonality::MSVC_CXX) {
288 RegNodeTy = getCXXEHRegistrationType();
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000289 RegNode = Builder.CreateAlloca(RegNodeTy);
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000290 // SavedESP = llvm.stacksave()
291 Value *SP = Builder.CreateCall(
David Blaikieff6409d2015-05-18 22:13:54 +0000292 Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000293 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
294 // TryLevel = -1
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000295 StateFieldIndex = 2;
David Majnemer7e5937b2016-02-17 18:37:11 +0000296 ParentBaseState = -1;
297 insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000298 // Handler = __ehhandler$F
299 Function *Trampoline = generateLSDAInEAXThunk(F);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000300 Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
301 linkExceptionRegistration(Builder, Trampoline);
David Majnemere60ee3b2016-02-29 19:16:03 +0000302
303 CxxLongjmpUnwind = TheModule->getOrInsertFunction(
304 "__CxxLongjmpUnwind",
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000305 FunctionType::get(VoidTy, Int8PtrType, /*isVarArg=*/false));
James Y Knight13680222019-02-01 02:28:03 +0000306 cast<Function>(CxxLongjmpUnwind.getCallee()->stripPointerCasts())
David Majnemere60ee3b2016-02-29 19:16:03 +0000307 ->setCallingConv(CallingConv::X86_StdCall);
Reid Klecknere6531a552015-05-29 22:57:46 +0000308 } else if (Personality == EHPersonality::MSVC_X86SEH) {
309 // If _except_handler4 is in use, some additional guard checks and prologue
310 // stuff is required.
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000311 StringRef PersonalityName = PersonalityFn->getName();
312 UseStackGuard = (PersonalityName == "_except_handler4");
313
314 // Allocate local structures.
Reid Klecknere6531a552015-05-29 22:57:46 +0000315 RegNodeTy = getSEHRegistrationType();
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000316 RegNode = Builder.CreateAlloca(RegNodeTy);
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000317 if (UseStackGuard)
318 EHGuardNode = Builder.CreateAlloca(Int32Ty);
319
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000320 // SavedESP = llvm.stacksave()
321 Value *SP = Builder.CreateCall(
David Blaikieff6409d2015-05-18 22:13:54 +0000322 Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000323 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
Reid Klecknere6531a552015-05-29 22:57:46 +0000324 // TryLevel = -2 / -1
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000325 StateFieldIndex = 4;
David Majnemer7e5937b2016-02-17 18:37:11 +0000326 ParentBaseState = UseStackGuard ? -2 : -1;
327 insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000328 // ScopeTable = llvm.x86.seh.lsda(F)
David Majnemere60ee3b2016-02-29 19:16:03 +0000329 Value *LSDA = emitEHLSDA(Builder, F);
Reid Klecknere6531a552015-05-29 22:57:46 +0000330 LSDA = Builder.CreatePtrToInt(LSDA, Int32Ty);
331 // If using _except_handler4, xor the address of the table with
332 // __security_cookie.
333 if (UseStackGuard) {
David Majnemere60ee3b2016-02-29 19:16:03 +0000334 Cookie = TheModule->getOrInsertGlobal("__security_cookie", Int32Ty);
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000335 Value *Val = Builder.CreateLoad(Int32Ty, Cookie, "cookie");
Reid Klecknere6531a552015-05-29 22:57:46 +0000336 LSDA = Builder.CreateXor(LSDA, Val);
337 }
338 Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 3));
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000339
340 // If using _except_handler4, the EHGuard contains: FramePtr xor Cookie.
341 if (UseStackGuard) {
342 Value *Val = Builder.CreateLoad(Int32Ty, Cookie);
343 Value *FrameAddr = Builder.CreateCall(
344 Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress),
345 Builder.getInt32(0), "frameaddr");
346 Value *FrameAddrI32 = Builder.CreatePtrToInt(FrameAddr, Int32Ty);
347 FrameAddrI32 = Builder.CreateXor(FrameAddrI32, Val);
348 Builder.CreateStore(FrameAddrI32, EHGuardNode);
349 }
350
351 // Register the exception handler.
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000352 Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
353 linkExceptionRegistration(Builder, PersonalityFn);
David Majnemere60ee3b2016-02-29 19:16:03 +0000354
355 SehLongjmpUnwind = TheModule->getOrInsertFunction(
356 UseStackGuard ? "_seh_longjmp_unwind4" : "_seh_longjmp_unwind",
357 FunctionType::get(Type::getVoidTy(TheModule->getContext()), Int8PtrType,
358 /*isVarArg=*/false));
James Y Knight13680222019-02-01 02:28:03 +0000359 cast<Function>(SehLongjmpUnwind.getCallee()->stripPointerCasts())
David Majnemere60ee3b2016-02-29 19:16:03 +0000360 ->setCallingConv(CallingConv::X86_StdCall);
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000361 } else {
362 llvm_unreachable("unexpected personality function");
363 }
364
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000365 // Insert an unlink before all returns.
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000366 for (BasicBlock &BB : *F) {
Chandler Carruthedb12a82018-10-15 10:04:59 +0000367 Instruction *T = BB.getTerminator();
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000368 if (!isa<ReturnInst>(T))
369 continue;
370 Builder.SetInsertPoint(T);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000371 unlinkExceptionRegistration(Builder);
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000372 }
373}
374
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000375Value *WinEHStatePass::emitEHLSDA(IRBuilder<> &Builder, Function *F) {
376 Value *FI8 = Builder.CreateBitCast(F, Type::getInt8PtrTy(F->getContext()));
377 return Builder.CreateCall(
378 Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
379}
380
381/// Generate a thunk that puts the LSDA of ParentFunc in EAX and then calls
382/// PersonalityFn, forwarding the parameters passed to PEXCEPTION_ROUTINE:
383/// typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
384/// _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
385/// We essentially want this code:
386/// movl $lsda, %eax
387/// jmpl ___CxxFrameHandler3
388Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
389 LLVMContext &Context = ParentFunc->getContext();
390 Type *Int32Ty = Type::getInt32Ty(Context);
391 Type *Int8PtrType = Type::getInt8PtrTy(Context);
392 Type *ArgTys[5] = {Int8PtrType, Int8PtrType, Int8PtrType, Int8PtrType,
393 Int8PtrType};
394 FunctionType *TrampolineTy =
395 FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 4),
396 /*isVarArg=*/false);
397 FunctionType *TargetFuncTy =
398 FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 5),
399 /*isVarArg=*/false);
Reid Kleckner5f4dd922015-07-13 17:55:14 +0000400 Function *Trampoline =
401 Function::Create(TrampolineTy, GlobalValue::InternalLinkage,
Peter Collingbourne6f0ecca2017-05-16 00:39:01 +0000402 Twine("__ehhandler$") + GlobalValue::dropLLVMManglingEscape(
Reid Kleckner5f4dd922015-07-13 17:55:14 +0000403 ParentFunc->getName()),
404 TheModule);
Dave Leef9b72322017-10-20 17:04:43 +0000405 if (auto *C = ParentFunc->getComdat())
406 Trampoline->setComdat(C);
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000407 BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", Trampoline);
408 IRBuilder<> Builder(EntryBB);
409 Value *LSDA = emitEHLSDA(Builder, ParentFunc);
410 Value *CastPersonality =
411 Builder.CreateBitCast(PersonalityFn, TargetFuncTy->getPointerTo());
412 auto AI = Trampoline->arg_begin();
Duncan P. N. Exon Smithd77de642015-10-19 21:48:29 +0000413 Value *Args[5] = {LSDA, &*AI++, &*AI++, &*AI++, &*AI++};
James Y Knight7976eb52019-02-01 20:43:25 +0000414 CallInst *Call = Builder.CreateCall(TargetFuncTy, CastPersonality, Args);
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000415 // Can't use musttail due to prototype mismatch, but we can use tail.
416 Call->setTailCall(true);
417 // Set inreg so we pass it in EAX.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000418 Call->addParamAttr(0, Attribute::InReg);
Reid Kleckner2632f0d2015-05-20 23:08:04 +0000419 Builder.CreateRet(Call);
420 return Trampoline;
421}
422
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000423void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
Reid Kleckner2bc93ca2015-06-10 01:02:30 +0000424 Function *Handler) {
425 // Emit the .safeseh directive for this function.
426 Handler->addFnAttr("safeseh");
427
Reid Klecknere6531a552015-05-29 22:57:46 +0000428 Type *LinkTy = getEHLinkRegistrationType();
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000429 // Handler = Handler
Reid Kleckner2bc93ca2015-06-10 01:02:30 +0000430 Value *HandlerI8 = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
431 Builder.CreateStore(HandlerI8, Builder.CreateStructGEP(LinkTy, Link, 1));
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000432 // Next = [fs:00]
433 Constant *FSZero =
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000434 Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000435 Value *Next = Builder.CreateLoad(FSZero);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000436 Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
437 // [fs:00] = Link
438 Builder.CreateStore(Link, FSZero);
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000439}
440
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000441void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
442 // Clone Link into the current BB for better address mode folding.
443 if (auto *GEP = dyn_cast<GetElementPtrInst>(Link)) {
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000444 GEP = cast<GetElementPtrInst>(GEP->clone());
445 Builder.Insert(GEP);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000446 Link = GEP;
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000447 }
Reid Klecknere6531a552015-05-29 22:57:46 +0000448 Type *LinkTy = getEHLinkRegistrationType();
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000449 // [fs:00] = Link->Next
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000450 Value *Next =
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000451 Builder.CreateLoad(Builder.CreateStructGEP(LinkTy, Link, 0));
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000452 Constant *FSZero =
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000453 Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
Reid Kleckner0738a9c2015-05-05 17:44:16 +0000454 Builder.CreateStore(Next, FSZero);
455}
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000456
David Majnemere60ee3b2016-02-29 19:16:03 +0000457// Calls to setjmp(p) are lowered to _setjmp3(p, 0) by the frontend.
458// The idea behind _setjmp3 is that it takes an optional number of personality
459// specific parameters to indicate how to restore the personality-specific frame
460// state when longjmp is initiated. Typically, the current TryLevel is saved.
461void WinEHStatePass::rewriteSetJmpCallSite(IRBuilder<> &Builder, Function &F,
462 CallSite CS, Value *State) {
463 // Don't rewrite calls with a weird number of arguments.
464 if (CS.getNumArgOperands() != 2)
465 return;
466
467 Instruction *Inst = CS.getInstruction();
468
469 SmallVector<OperandBundleDef, 1> OpBundles;
470 CS.getOperandBundlesAsDefs(OpBundles);
471
472 SmallVector<Value *, 3> OptionalArgs;
473 if (Personality == EHPersonality::MSVC_CXX) {
James Y Knight13680222019-02-01 02:28:03 +0000474 OptionalArgs.push_back(CxxLongjmpUnwind.getCallee());
David Majnemere60ee3b2016-02-29 19:16:03 +0000475 OptionalArgs.push_back(State);
476 OptionalArgs.push_back(emitEHLSDA(Builder, &F));
477 } else if (Personality == EHPersonality::MSVC_X86SEH) {
James Y Knight13680222019-02-01 02:28:03 +0000478 OptionalArgs.push_back(SehLongjmpUnwind.getCallee());
David Majnemere60ee3b2016-02-29 19:16:03 +0000479 OptionalArgs.push_back(State);
480 if (UseStackGuard)
481 OptionalArgs.push_back(Cookie);
482 } else {
483 llvm_unreachable("unhandled personality!");
484 }
485
486 SmallVector<Value *, 5> Args;
487 Args.push_back(
488 Builder.CreateBitCast(CS.getArgOperand(0), Builder.getInt8PtrTy()));
489 Args.push_back(Builder.getInt32(OptionalArgs.size()));
490 Args.append(OptionalArgs.begin(), OptionalArgs.end());
491
492 CallSite NewCS;
493 if (CS.isCall()) {
494 auto *CI = cast<CallInst>(Inst);
495 CallInst *NewCI = Builder.CreateCall(SetJmp3, Args, OpBundles);
496 NewCI->setTailCallKind(CI->getTailCallKind());
497 NewCS = NewCI;
498 } else {
499 auto *II = cast<InvokeInst>(Inst);
500 NewCS = Builder.CreateInvoke(
501 SetJmp3, II->getNormalDest(), II->getUnwindDest(), Args, OpBundles);
502 }
503 NewCS.setCallingConv(CS.getCallingConv());
504 NewCS.setAttributes(CS.getAttributes());
505 NewCS->setDebugLoc(CS->getDebugLoc());
506
507 Instruction *NewInst = NewCS.getInstruction();
508 NewInst->takeName(Inst);
509 Inst->replaceAllUsesWith(NewInst);
510 Inst->eraseFromParent();
511}
512
David Majnemer7e5937b2016-02-17 18:37:11 +0000513// Figure out what state we should assign calls in this block.
David Majnemere60ee3b2016-02-29 19:16:03 +0000514int WinEHStatePass::getBaseStateForBB(
515 DenseMap<BasicBlock *, ColorVector> &BlockColors, WinEHFuncInfo &FuncInfo,
516 BasicBlock *BB) {
517 int BaseState = ParentBaseState;
David Majnemer7e5937b2016-02-17 18:37:11 +0000518 auto &BBColors = BlockColors[BB];
519
520 assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
521 BasicBlock *FuncletEntryBB = BBColors.front();
522 if (auto *FuncletPad =
523 dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI())) {
524 auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
525 if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
526 BaseState = BaseStateI->second;
527 }
528
529 return BaseState;
530}
531
532// Calculate the state a call-site is in.
David Majnemere60ee3b2016-02-29 19:16:03 +0000533int WinEHStatePass::getStateForCallSite(
534 DenseMap<BasicBlock *, ColorVector> &BlockColors, WinEHFuncInfo &FuncInfo,
535 CallSite CS) {
David Majnemer7e5937b2016-02-17 18:37:11 +0000536 if (auto *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
537 // Look up the state number of the EH pad this unwinds to.
538 assert(FuncInfo.InvokeStateMap.count(II) && "invoke has no state!");
539 return FuncInfo.InvokeStateMap[II];
540 }
541 // Possibly throwing call instructions have no actions to take after
542 // an unwind. Ensure they are in the -1 state.
543 return getBaseStateForBB(BlockColors, FuncInfo, CS.getParent());
544}
545
546// Calculate the intersection of all the FinalStates for a BasicBlock's
David Majnemera822c882016-02-18 21:13:35 +0000547// predecessors.
David Majnemer7e5937b2016-02-17 18:37:11 +0000548static int getPredState(DenseMap<BasicBlock *, int> &FinalStates, Function &F,
549 int ParentBaseState, BasicBlock *BB) {
550 // The entry block has no predecessors but we know that the prologue always
551 // sets us up with a fixed state.
552 if (&F.getEntryBlock() == BB)
553 return ParentBaseState;
554
555 // This is an EH Pad, conservatively report this basic block as overdefined.
556 if (BB->isEHPad())
557 return OverdefinedState;
558
559 int CommonState = OverdefinedState;
560 for (BasicBlock *PredBB : predecessors(BB)) {
561 // We didn't manage to get a state for one of these predecessors,
562 // conservatively report this basic block as overdefined.
563 auto PredEndState = FinalStates.find(PredBB);
564 if (PredEndState == FinalStates.end())
565 return OverdefinedState;
566
567 // This code is reachable via exceptional control flow,
568 // conservatively report this basic block as overdefined.
569 if (isa<CatchReturnInst>(PredBB->getTerminator()))
570 return OverdefinedState;
571
572 int PredState = PredEndState->second;
573 assert(PredState != OverdefinedState &&
574 "overdefined BBs shouldn't be in FinalStates");
575 if (CommonState == OverdefinedState)
576 CommonState = PredState;
577
578 // At least two predecessors have different FinalStates,
579 // conservatively report this basic block as overdefined.
580 if (CommonState != PredState)
581 return OverdefinedState;
582 }
583
584 return CommonState;
Nico Weber32ac2732016-02-17 18:48:08 +0000585}
David Majnemer7e5937b2016-02-17 18:37:11 +0000586
David Majnemera822c882016-02-18 21:13:35 +0000587// Calculate the intersection of all the InitialStates for a BasicBlock's
588// successors.
589static int getSuccState(DenseMap<BasicBlock *, int> &InitialStates, Function &F,
590 int ParentBaseState, BasicBlock *BB) {
591 // This block rejoins normal control flow,
592 // conservatively report this basic block as overdefined.
593 if (isa<CatchReturnInst>(BB->getTerminator()))
594 return OverdefinedState;
595
596 int CommonState = OverdefinedState;
597 for (BasicBlock *SuccBB : successors(BB)) {
598 // We didn't manage to get a state for one of these predecessors,
599 // conservatively report this basic block as overdefined.
600 auto SuccStartState = InitialStates.find(SuccBB);
601 if (SuccStartState == InitialStates.end())
602 return OverdefinedState;
603
604 // This is an EH Pad, conservatively report this basic block as overdefined.
605 if (SuccBB->isEHPad())
606 return OverdefinedState;
607
608 int SuccState = SuccStartState->second;
609 assert(SuccState != OverdefinedState &&
610 "overdefined BBs shouldn't be in FinalStates");
611 if (CommonState == OverdefinedState)
612 CommonState = SuccState;
613
614 // At least two successors have different InitialStates,
615 // conservatively report this basic block as overdefined.
616 if (CommonState != SuccState)
617 return OverdefinedState;
618 }
619
620 return CommonState;
621}
622
David Majnemere60ee3b2016-02-29 19:16:03 +0000623bool WinEHStatePass::isStateStoreNeeded(EHPersonality Personality,
624 CallSite CS) {
David Majnemer7e5937b2016-02-17 18:37:11 +0000625 if (!CS)
626 return false;
627
David Majnemere60ee3b2016-02-29 19:16:03 +0000628 // If the function touches memory, it needs a state store.
David Majnemer7e5937b2016-02-17 18:37:11 +0000629 if (isAsynchronousEHPersonality(Personality))
630 return !CS.doesNotAccessMemory();
631
David Majnemere60ee3b2016-02-29 19:16:03 +0000632 // If the function throws, it needs a state store.
David Majnemer7e5937b2016-02-17 18:37:11 +0000633 return !CS.doesNotThrow();
634}
635
Reid Klecknerc20276d2015-11-17 21:10:25 +0000636void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
637 // Mark the registration node. The backend needs to know which alloca it is so
638 // that it can recover the original frame pointer.
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000639 IRBuilder<> Builder(RegNode->getNextNode());
Reid Klecknerc20276d2015-11-17 21:10:25 +0000640 Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
641 Builder.CreateCall(
642 Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
643 {RegNodeI8});
Reid Kleckner14e77352015-10-09 23:34:53 +0000644
Etienne Bergeronf6be62f2016-06-21 15:58:55 +0000645 if (EHGuardNode) {
646 IRBuilder<> Builder(EHGuardNode->getNextNode());
647 Value *EHGuardNodeI8 =
648 Builder.CreateBitCast(EHGuardNode, Builder.getInt8PtrTy());
649 Builder.CreateCall(
650 Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehguard),
651 {EHGuardNodeI8});
652 }
653
Reid Klecknerc20276d2015-11-17 21:10:25 +0000654 // Calculate state numbers.
655 if (isAsynchronousEHPersonality(Personality))
656 calculateSEHStateNumbers(&F, FuncInfo);
657 else
658 calculateWinCXXEHStateNumbers(&F, FuncInfo);
Reid Kleckner14e77352015-10-09 23:34:53 +0000659
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000660 // Iterate all the instructions and emit state number stores.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000661 DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(F);
David Majnemer7e5937b2016-02-17 18:37:11 +0000662 ReversePostOrderTraversal<Function *> RPOT(&F);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000663
David Majnemer7e5937b2016-02-17 18:37:11 +0000664 // InitialStates yields the state of the first call-site for a BasicBlock.
665 DenseMap<BasicBlock *, int> InitialStates;
666 // FinalStates yields the state of the last call-site for a BasicBlock.
667 DenseMap<BasicBlock *, int> FinalStates;
668 // Worklist used to revisit BasicBlocks with indeterminate
669 // Initial/Final-States.
670 std::deque<BasicBlock *> Worklist;
671 // Fill in InitialStates and FinalStates for BasicBlocks with call-sites.
672 for (BasicBlock *BB : RPOT) {
673 int InitialState = OverdefinedState;
674 int FinalState;
675 if (&F.getEntryBlock() == BB)
676 InitialState = FinalState = ParentBaseState;
677 for (Instruction &I : *BB) {
678 CallSite CS(&I);
679 if (!isStateStoreNeeded(Personality, CS))
David Majnemerf2bb7102016-01-29 05:33:15 +0000680 continue;
681
David Majnemer7e5937b2016-02-17 18:37:11 +0000682 int State = getStateForCallSite(BlockColors, FuncInfo, CS);
683 if (InitialState == OverdefinedState)
684 InitialState = State;
685 FinalState = State;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000686 }
David Majnemer7e5937b2016-02-17 18:37:11 +0000687 // No call-sites in this basic block? That's OK, we will come back to these
688 // in a later pass.
689 if (InitialState == OverdefinedState) {
690 Worklist.push_back(BB);
691 continue;
692 }
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000693 LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
694 << " InitialState=" << InitialState << '\n');
695 LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
696 << " FinalState=" << FinalState << '\n');
David Majnemer7e5937b2016-02-17 18:37:11 +0000697 InitialStates.insert({BB, InitialState});
698 FinalStates.insert({BB, FinalState});
699 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000700
David Majnemer7e5937b2016-02-17 18:37:11 +0000701 // Try to fill-in InitialStates and FinalStates which have no call-sites.
702 while (!Worklist.empty()) {
703 BasicBlock *BB = Worklist.front();
704 Worklist.pop_front();
705 // This BasicBlock has already been figured out, nothing more we can do.
706 if (InitialStates.count(BB) != 0)
707 continue;
708
709 int PredState = getPredState(FinalStates, F, ParentBaseState, BB);
710 if (PredState == OverdefinedState)
711 continue;
712
713 // We successfully inferred this BasicBlock's state via it's predecessors;
714 // enqueue it's successors to see if we can infer their states.
715 InitialStates.insert({BB, PredState});
716 FinalStates.insert({BB, PredState});
717 for (BasicBlock *SuccBB : successors(BB))
718 Worklist.push_back(SuccBB);
719 }
720
David Majnemera822c882016-02-18 21:13:35 +0000721 // Try to hoist stores from successors.
722 for (BasicBlock *BB : RPOT) {
723 int SuccState = getSuccState(InitialStates, F, ParentBaseState, BB);
724 if (SuccState == OverdefinedState)
725 continue;
726
727 // Update our FinalState to reflect the common InitialState of our
728 // successors.
729 FinalStates.insert({BB, SuccState});
730 }
731
David Majnemer7e5937b2016-02-17 18:37:11 +0000732 // Finally, insert state stores before call-sites which transition us to a new
733 // state.
734 for (BasicBlock *BB : RPOT) {
735 auto &BBColors = BlockColors[BB];
736 BasicBlock *FuncletEntryBB = BBColors.front();
737 if (isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHI()))
738 continue;
739
740 int PrevState = getPredState(FinalStates, F, ParentBaseState, BB);
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000741 LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
742 << " PrevState=" << PrevState << '\n');
David Majnemer7e5937b2016-02-17 18:37:11 +0000743
744 for (Instruction &I : *BB) {
745 CallSite CS(&I);
746 if (!isStateStoreNeeded(Personality, CS))
747 continue;
748
749 int State = getStateForCallSite(BlockColors, FuncInfo, CS);
750 if (State != PrevState)
751 insertStateNumberStore(&I, State);
752 PrevState = State;
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000753 }
David Majnemera822c882016-02-18 21:13:35 +0000754
755 // We might have hoisted a state store into this block, emit it now.
756 auto EndState = FinalStates.find(BB);
757 if (EndState != FinalStates.end())
758 if (EndState->second != PrevState)
759 insertStateNumberStore(BB->getTerminator(), EndState->second);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000760 }
David Majnemere60ee3b2016-02-29 19:16:03 +0000761
762 SmallVector<CallSite, 1> SetJmp3CallSites;
763 for (BasicBlock *BB : RPOT) {
764 for (Instruction &I : *BB) {
765 CallSite CS(&I);
766 if (!CS)
767 continue;
768 if (CS.getCalledValue()->stripPointerCasts() !=
James Y Knight13680222019-02-01 02:28:03 +0000769 SetJmp3.getCallee()->stripPointerCasts())
David Majnemere60ee3b2016-02-29 19:16:03 +0000770 continue;
771
772 SetJmp3CallSites.push_back(CS);
773 }
774 }
775
776 for (CallSite CS : SetJmp3CallSites) {
777 auto &BBColors = BlockColors[CS->getParent()];
778 BasicBlock *FuncletEntryBB = BBColors.front();
779 bool InCleanup = isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHI());
780
781 IRBuilder<> Builder(CS.getInstruction());
782 Value *State;
783 if (InCleanup) {
784 Value *StateField =
785 Builder.CreateStructGEP(nullptr, RegNode, StateFieldIndex);
786 State = Builder.CreateLoad(StateField);
787 } else {
788 State = Builder.getInt32(getStateForCallSite(BlockColors, FuncInfo, CS));
789 }
790 rewriteSetJmpCallSite(Builder, F, CS, State);
791 }
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000792}
793
David Majnemerefb41742016-02-01 04:28:59 +0000794void WinEHStatePass::insertStateNumberStore(Instruction *IP, int State) {
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000795 IRBuilder<> Builder(IP);
796 Value *StateField =
David Majnemerefb41742016-02-01 04:28:59 +0000797 Builder.CreateStructGEP(nullptr, RegNode, StateFieldIndex);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000798 Builder.CreateStore(Builder.getInt32(State), StateField);
799}