[IR] Reformulate LLVM's EH funclet IR
[oota-llvm.git] / lib / Target / X86 / X86WinEHState.cpp
1 //===-- X86WinEHState - Insert EH state updates for win32 exceptions ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // All functions using an MSVC EH personality use an explicitly updated state
11 // number stored in an exception registration stack object. The registration
12 // object is linked into a thread-local chain of registrations stored at fs:00.
13 // This pass adds the registration object and EH state updates.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "X86.h"
18 #include "llvm/Analysis/CFG.h"
19 #include "llvm/Analysis/EHPersonalities.h"
20 #include "llvm/CodeGen/MachineModuleInfo.h"
21 #include "llvm/CodeGen/Passes.h"
22 #include "llvm/CodeGen/WinEHFuncInfo.h"
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/IRBuilder.h"
26 #include "llvm/IR/Instructions.h"
27 #include "llvm/IR/IntrinsicInst.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/PatternMatch.h"
30 #include "llvm/Pass.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
34 #include "llvm/Transforms/Utils/Cloning.h"
35 #include "llvm/Transforms/Utils/Local.h"
36
37 using namespace llvm;
38 using namespace llvm::PatternMatch;
39
40 #define DEBUG_TYPE "winehstate"
41
42 namespace llvm { void initializeWinEHStatePassPass(PassRegistry &); }
43
44 namespace {
45 class WinEHStatePass : public FunctionPass {
46 public:
47   static char ID; // Pass identification, replacement for typeid.
48
49   WinEHStatePass() : FunctionPass(ID) {
50     initializeWinEHStatePassPass(*PassRegistry::getPassRegistry());
51   }
52
53   bool runOnFunction(Function &Fn) override;
54
55   bool doInitialization(Module &M) override;
56
57   bool doFinalization(Module &M) override;
58
59   void getAnalysisUsage(AnalysisUsage &AU) const override;
60
61   const char *getPassName() const override {
62     return "Windows 32-bit x86 EH state insertion";
63   }
64
65 private:
66   void emitExceptionRegistrationRecord(Function *F);
67
68   void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
69   void unlinkExceptionRegistration(IRBuilder<> &Builder);
70   void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
71   void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State);
72
73   Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
74
75   Function *generateLSDAInEAXThunk(Function *ParentFunc);
76
77   // Module-level type getters.
78   Type *getEHLinkRegistrationType();
79   Type *getSEHRegistrationType();
80   Type *getCXXEHRegistrationType();
81
82   // Per-module data.
83   Module *TheModule = nullptr;
84   StructType *EHLinkRegistrationTy = nullptr;
85   StructType *CXXEHRegistrationTy = nullptr;
86   StructType *SEHRegistrationTy = nullptr;
87   Function *FrameRecover = nullptr;
88   Function *FrameAddress = nullptr;
89   Function *FrameEscape = nullptr;
90   Function *RestoreFrame = nullptr;
91
92   // Per-function state
93   EHPersonality Personality = EHPersonality::Unknown;
94   Function *PersonalityFn = nullptr;
95
96   /// The stack allocation containing all EH data, including the link in the
97   /// fs:00 chain and the current state.
98   AllocaInst *RegNode = nullptr;
99
100   /// Struct type of RegNode. Used for GEPing.
101   Type *RegNodeTy = nullptr;
102
103   /// The index of the state field of RegNode.
104   int StateFieldIndex = ~0U;
105
106   /// The linked list node subobject inside of RegNode.
107   Value *Link = nullptr;
108 };
109 }
110
111 FunctionPass *llvm::createX86WinEHStatePass() { return new WinEHStatePass(); }
112
113 char WinEHStatePass::ID = 0;
114
115 INITIALIZE_PASS(WinEHStatePass, "x86-winehstate",
116                 "Insert stores for EH state numbers", false, false)
117
118 bool WinEHStatePass::doInitialization(Module &M) {
119   TheModule = &M;
120   FrameEscape = Intrinsic::getDeclaration(TheModule, Intrinsic::localescape);
121   FrameRecover = Intrinsic::getDeclaration(TheModule, Intrinsic::localrecover);
122   FrameAddress = Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress);
123   RestoreFrame =
124       Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_restoreframe);
125   return false;
126 }
127
128 bool WinEHStatePass::doFinalization(Module &M) {
129   assert(TheModule == &M);
130   TheModule = nullptr;
131   EHLinkRegistrationTy = nullptr;
132   CXXEHRegistrationTy = nullptr;
133   SEHRegistrationTy = nullptr;
134   FrameEscape = nullptr;
135   FrameRecover = nullptr;
136   FrameAddress = nullptr;
137   return false;
138 }
139
140 void WinEHStatePass::getAnalysisUsage(AnalysisUsage &AU) const {
141   // This pass should only insert a stack allocation, memory accesses, and
142   // localrecovers.
143   AU.setPreservesCFG();
144 }
145
146 bool WinEHStatePass::runOnFunction(Function &F) {
147   // Check the personality. Do nothing if this personality doesn't use funclets.
148   if (!F.hasPersonalityFn())
149     return false;
150   PersonalityFn =
151       dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
152   if (!PersonalityFn)
153     return false;
154   Personality = classifyEHPersonality(PersonalityFn);
155   if (!isFuncletEHPersonality(Personality))
156     return false;
157
158   // Skip this function if there are no EH pads and we aren't using IR-level
159   // outlining.
160   bool HasPads = false;
161   for (BasicBlock &BB : F) {
162     if (BB.isEHPad()) {
163       HasPads = true;
164       break;
165     }
166   }
167   if (!HasPads)
168     return false;
169
170   // Disable frame pointer elimination in this function.
171   // FIXME: Do the nested handlers need to keep the parent ebp in ebp, or can we
172   // use an arbitrary register?
173   F.addFnAttr("no-frame-pointer-elim", "true");
174
175   emitExceptionRegistrationRecord(&F);
176
177   // The state numbers calculated here in IR must agree with what we calculate
178   // later on for the MachineFunction. In particular, if an IR pass deletes an
179   // unreachable EH pad after this point before machine CFG construction, we
180   // will be in trouble. If this assumption is ever broken, we should turn the
181   // numbers into an immutable analysis pass.
182   WinEHFuncInfo FuncInfo;
183   addStateStores(F, FuncInfo);
184
185   // Reset per-function state.
186   PersonalityFn = nullptr;
187   Personality = EHPersonality::Unknown;
188   return true;
189 }
190
191 /// Get the common EH registration subobject:
192 ///   typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
193 ///       _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
194 ///   struct EHRegistrationNode {
195 ///     EHRegistrationNode *Next;
196 ///     PEXCEPTION_ROUTINE Handler;
197 ///   };
198 Type *WinEHStatePass::getEHLinkRegistrationType() {
199   if (EHLinkRegistrationTy)
200     return EHLinkRegistrationTy;
201   LLVMContext &Context = TheModule->getContext();
202   EHLinkRegistrationTy = StructType::create(Context, "EHRegistrationNode");
203   Type *FieldTys[] = {
204       EHLinkRegistrationTy->getPointerTo(0), // EHRegistrationNode *Next
205       Type::getInt8PtrTy(Context) // EXCEPTION_DISPOSITION (*Handler)(...)
206   };
207   EHLinkRegistrationTy->setBody(FieldTys, false);
208   return EHLinkRegistrationTy;
209 }
210
211 /// The __CxxFrameHandler3 registration node:
212 ///   struct CXXExceptionRegistration {
213 ///     void *SavedESP;
214 ///     EHRegistrationNode SubRecord;
215 ///     int32_t TryLevel;
216 ///   };
217 Type *WinEHStatePass::getCXXEHRegistrationType() {
218   if (CXXEHRegistrationTy)
219     return CXXEHRegistrationTy;
220   LLVMContext &Context = TheModule->getContext();
221   Type *FieldTys[] = {
222       Type::getInt8PtrTy(Context), // void *SavedESP
223       getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
224       Type::getInt32Ty(Context)    // int32_t TryLevel
225   };
226   CXXEHRegistrationTy =
227       StructType::create(FieldTys, "CXXExceptionRegistration");
228   return CXXEHRegistrationTy;
229 }
230
231 /// The _except_handler3/4 registration node:
232 ///   struct EH4ExceptionRegistration {
233 ///     void *SavedESP;
234 ///     _EXCEPTION_POINTERS *ExceptionPointers;
235 ///     EHRegistrationNode SubRecord;
236 ///     int32_t EncodedScopeTable;
237 ///     int32_t TryLevel;
238 ///   };
239 Type *WinEHStatePass::getSEHRegistrationType() {
240   if (SEHRegistrationTy)
241     return SEHRegistrationTy;
242   LLVMContext &Context = TheModule->getContext();
243   Type *FieldTys[] = {
244       Type::getInt8PtrTy(Context), // void *SavedESP
245       Type::getInt8PtrTy(Context), // void *ExceptionPointers
246       getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
247       Type::getInt32Ty(Context),   // int32_t EncodedScopeTable
248       Type::getInt32Ty(Context)    // int32_t TryLevel
249   };
250   SEHRegistrationTy = StructType::create(FieldTys, "SEHExceptionRegistration");
251   return SEHRegistrationTy;
252 }
253
254 // Emit an exception registration record. These are stack allocations with the
255 // common subobject of two pointers: the previous registration record (the old
256 // fs:00) and the personality function for the current frame. The data before
257 // and after that is personality function specific.
258 void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
259   assert(Personality == EHPersonality::MSVC_CXX ||
260          Personality == EHPersonality::MSVC_X86SEH);
261
262   StringRef PersonalityName = PersonalityFn->getName();
263   IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
264   Type *Int8PtrType = Builder.getInt8PtrTy();
265   if (Personality == EHPersonality::MSVC_CXX) {
266     RegNodeTy = getCXXEHRegistrationType();
267     RegNode = Builder.CreateAlloca(RegNodeTy);
268     // SavedESP = llvm.stacksave()
269     Value *SP = Builder.CreateCall(
270         Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
271     Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
272     // TryLevel = -1
273     StateFieldIndex = 2;
274     insertStateNumberStore(RegNode, &*Builder.GetInsertPoint(), -1);
275     // Handler = __ehhandler$F
276     Function *Trampoline = generateLSDAInEAXThunk(F);
277     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
278     linkExceptionRegistration(Builder, Trampoline);
279   } else if (Personality == EHPersonality::MSVC_X86SEH) {
280     // If _except_handler4 is in use, some additional guard checks and prologue
281     // stuff is required.
282     bool UseStackGuard = (PersonalityName == "_except_handler4");
283     RegNodeTy = getSEHRegistrationType();
284     RegNode = Builder.CreateAlloca(RegNodeTy);
285     // SavedESP = llvm.stacksave()
286     Value *SP = Builder.CreateCall(
287         Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
288     Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
289     // TryLevel = -2 / -1
290     StateFieldIndex = 4;
291     insertStateNumberStore(RegNode, &*Builder.GetInsertPoint(),
292                            UseStackGuard ? -2 : -1);
293     // ScopeTable = llvm.x86.seh.lsda(F)
294     Value *FI8 = Builder.CreateBitCast(F, Int8PtrType);
295     Value *LSDA = Builder.CreateCall(
296         Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
297     Type *Int32Ty = Type::getInt32Ty(TheModule->getContext());
298     LSDA = Builder.CreatePtrToInt(LSDA, Int32Ty);
299     // If using _except_handler4, xor the address of the table with
300     // __security_cookie.
301     if (UseStackGuard) {
302       Value *Cookie =
303           TheModule->getOrInsertGlobal("__security_cookie", Int32Ty);
304       Value *Val = Builder.CreateLoad(Int32Ty, Cookie);
305       LSDA = Builder.CreateXor(LSDA, Val);
306     }
307     Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 3));
308     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
309     linkExceptionRegistration(Builder, PersonalityFn);
310   } else {
311     llvm_unreachable("unexpected personality function");
312   }
313
314   // Insert an unlink before all returns.
315   for (BasicBlock &BB : *F) {
316     TerminatorInst *T = BB.getTerminator();
317     if (!isa<ReturnInst>(T))
318       continue;
319     Builder.SetInsertPoint(T);
320     unlinkExceptionRegistration(Builder);
321   }
322 }
323
324 Value *WinEHStatePass::emitEHLSDA(IRBuilder<> &Builder, Function *F) {
325   Value *FI8 = Builder.CreateBitCast(F, Type::getInt8PtrTy(F->getContext()));
326   return Builder.CreateCall(
327       Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
328 }
329
330 /// Generate a thunk that puts the LSDA of ParentFunc in EAX and then calls
331 /// PersonalityFn, forwarding the parameters passed to PEXCEPTION_ROUTINE:
332 ///   typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
333 ///       _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
334 /// We essentially want this code:
335 ///   movl $lsda, %eax
336 ///   jmpl ___CxxFrameHandler3
337 Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
338   LLVMContext &Context = ParentFunc->getContext();
339   Type *Int32Ty = Type::getInt32Ty(Context);
340   Type *Int8PtrType = Type::getInt8PtrTy(Context);
341   Type *ArgTys[5] = {Int8PtrType, Int8PtrType, Int8PtrType, Int8PtrType,
342                      Int8PtrType};
343   FunctionType *TrampolineTy =
344       FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 4),
345                         /*isVarArg=*/false);
346   FunctionType *TargetFuncTy =
347       FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 5),
348                         /*isVarArg=*/false);
349   Function *Trampoline =
350       Function::Create(TrampolineTy, GlobalValue::InternalLinkage,
351                        Twine("__ehhandler$") + GlobalValue::getRealLinkageName(
352                                                    ParentFunc->getName()),
353                        TheModule);
354   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", Trampoline);
355   IRBuilder<> Builder(EntryBB);
356   Value *LSDA = emitEHLSDA(Builder, ParentFunc);
357   Value *CastPersonality =
358       Builder.CreateBitCast(PersonalityFn, TargetFuncTy->getPointerTo());
359   auto AI = Trampoline->arg_begin();
360   Value *Args[5] = {LSDA, &*AI++, &*AI++, &*AI++, &*AI++};
361   CallInst *Call = Builder.CreateCall(CastPersonality, Args);
362   // Can't use musttail due to prototype mismatch, but we can use tail.
363   Call->setTailCall(true);
364   // Set inreg so we pass it in EAX.
365   Call->addAttribute(1, Attribute::InReg);
366   Builder.CreateRet(Call);
367   return Trampoline;
368 }
369
370 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
371                                                Function *Handler) {
372   // Emit the .safeseh directive for this function.
373   Handler->addFnAttr("safeseh");
374
375   Type *LinkTy = getEHLinkRegistrationType();
376   // Handler = Handler
377   Value *HandlerI8 = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
378   Builder.CreateStore(HandlerI8, Builder.CreateStructGEP(LinkTy, Link, 1));
379   // Next = [fs:00]
380   Constant *FSZero =
381       Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
382   Value *Next = Builder.CreateLoad(FSZero);
383   Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
384   // [fs:00] = Link
385   Builder.CreateStore(Link, FSZero);
386 }
387
388 void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
389   // Clone Link into the current BB for better address mode folding.
390   if (auto *GEP = dyn_cast<GetElementPtrInst>(Link)) {
391     GEP = cast<GetElementPtrInst>(GEP->clone());
392     Builder.Insert(GEP);
393     Link = GEP;
394   }
395   Type *LinkTy = getEHLinkRegistrationType();
396   // [fs:00] = Link->Next
397   Value *Next =
398       Builder.CreateLoad(Builder.CreateStructGEP(LinkTy, Link, 0));
399   Constant *FSZero =
400       Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
401   Builder.CreateStore(Next, FSZero);
402 }
403
404 void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
405   // Mark the registration node. The backend needs to know which alloca it is so
406   // that it can recover the original frame pointer.
407   IRBuilder<> Builder(RegNode->getParent(), std::next(RegNode->getIterator()));
408   Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
409   Builder.CreateCall(
410       Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
411       {RegNodeI8});
412
413   // Calculate state numbers.
414   if (isAsynchronousEHPersonality(Personality))
415     calculateSEHStateNumbers(&F, FuncInfo);
416   else
417     calculateWinCXXEHStateNumbers(&F, FuncInfo);
418
419   // Iterate all the instructions and emit state number stores.
420   DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(F);
421   for (BasicBlock &BB : F) {
422     // Figure out what state we should assign calls in this block.
423     int BaseState = -1;
424     auto &BBColors = BlockColors[&BB];
425
426     assert(BBColors.size() == 1 &&
427            "multi-color BB not removed by preparation");
428     BasicBlock *FuncletEntryBB = BBColors.front();
429     if (auto *FuncletPad =
430             dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI())) {
431       auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
432       if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
433         BaseState = BaseStateI->second;
434     }
435
436     for (Instruction &I : BB) {
437       if (auto *CI = dyn_cast<CallInst>(&I)) {
438         // Possibly throwing call instructions have no actions to take after
439         // an unwind. Ensure they are in the -1 state.
440         if (CI->doesNotThrow())
441           continue;
442         insertStateNumberStore(RegNode, CI, BaseState);
443       } else if (auto *II = dyn_cast<InvokeInst>(&I)) {
444         // Look up the state number of the landingpad this unwinds to.
445         assert(FuncInfo.InvokeStateMap.count(II) && "invoke has no state!");
446         int State = FuncInfo.InvokeStateMap[II];
447         insertStateNumberStore(RegNode, II, State);
448       }
449     }
450   }
451 }
452
453 void WinEHStatePass::insertStateNumberStore(Value *ParentRegNode,
454                                             Instruction *IP, int State) {
455   IRBuilder<> Builder(IP);
456   Value *StateField =
457       Builder.CreateStructGEP(RegNodeTy, ParentRegNode, StateFieldIndex);
458   Builder.CreateStore(Builder.getInt32(State), StateField);
459 }