Home | History | Annotate | Download | only in X86
      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/ADT/PostOrderIterator.h"
     19 #include "llvm/Analysis/CFG.h"
     20 #include "llvm/Analysis/EHPersonalities.h"
     21 #include "llvm/CodeGen/MachineModuleInfo.h"
     22 #include "llvm/CodeGen/WinEHFuncInfo.h"
     23 #include "llvm/IR/CallSite.h"
     24 #include "llvm/IR/Function.h"
     25 #include "llvm/IR/Instructions.h"
     26 #include "llvm/IR/IntrinsicInst.h"
     27 #include "llvm/IR/IRBuilder.h"
     28 #include "llvm/IR/Module.h"
     29 #include "llvm/Pass.h"
     30 #include "llvm/Support/Debug.h"
     31 #include <deque>
     32 
     33 using namespace llvm;
     34 
     35 #define DEBUG_TYPE "winehstate"
     36 
     37 namespace llvm {
     38 void initializeWinEHStatePassPass(PassRegistry &);
     39 }
     40 
     41 namespace {
     42 const int OverdefinedState = INT_MIN;
     43 
     44 class WinEHStatePass : public FunctionPass {
     45 public:
     46   static char ID; // Pass identification, replacement for typeid.
     47 
     48   WinEHStatePass() : FunctionPass(ID) {
     49     initializeWinEHStatePassPass(*PassRegistry::getPassRegistry());
     50   }
     51 
     52   bool runOnFunction(Function &Fn) override;
     53 
     54   bool doInitialization(Module &M) override;
     55 
     56   bool doFinalization(Module &M) override;
     57 
     58   void getAnalysisUsage(AnalysisUsage &AU) const override;
     59 
     60   const char *getPassName() const override {
     61     return "Windows 32-bit x86 EH state insertion";
     62   }
     63 
     64 private:
     65   void emitExceptionRegistrationRecord(Function *F);
     66 
     67   void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
     68   void unlinkExceptionRegistration(IRBuilder<> &Builder);
     69   void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
     70   void insertStateNumberStore(Instruction *IP, int State);
     71 
     72   Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
     73 
     74   Function *generateLSDAInEAXThunk(Function *ParentFunc);
     75 
     76   bool isStateStoreNeeded(EHPersonality Personality, CallSite CS);
     77   void rewriteSetJmpCallSite(IRBuilder<> &Builder, Function &F, CallSite CS,
     78                              Value *State);
     79   int getBaseStateForBB(DenseMap<BasicBlock *, ColorVector> &BlockColors,
     80                         WinEHFuncInfo &FuncInfo, BasicBlock *BB);
     81   int getStateForCallSite(DenseMap<BasicBlock *, ColorVector> &BlockColors,
     82                           WinEHFuncInfo &FuncInfo, CallSite CS);
     83 
     84   // Module-level type getters.
     85   Type *getEHLinkRegistrationType();
     86   Type *getSEHRegistrationType();
     87   Type *getCXXEHRegistrationType();
     88 
     89   // Per-module data.
     90   Module *TheModule = nullptr;
     91   StructType *EHLinkRegistrationTy = nullptr;
     92   StructType *CXXEHRegistrationTy = nullptr;
     93   StructType *SEHRegistrationTy = nullptr;
     94   Constant *SetJmp3 = nullptr;
     95   Constant *CxxLongjmpUnwind = nullptr;
     96 
     97   // Per-function state
     98   EHPersonality Personality = EHPersonality::Unknown;
     99   Function *PersonalityFn = nullptr;
    100   bool UseStackGuard = false;
    101   int ParentBaseState;
    102   Constant *SehLongjmpUnwind = nullptr;
    103   Constant *Cookie = nullptr;
    104 
    105   /// The stack allocation containing all EH data, including the link in the
    106   /// fs:00 chain and the current state.
    107   AllocaInst *RegNode = nullptr;
    108 
    109   // The allocation containing the EH security guard.
    110   AllocaInst *EHGuardNode = nullptr;
    111 
    112   /// The index of the state field of RegNode.
    113   int StateFieldIndex = ~0U;
    114 
    115   /// The linked list node subobject inside of RegNode.
    116   Value *Link = nullptr;
    117 };
    118 }
    119 
    120 FunctionPass *llvm::createX86WinEHStatePass() { return new WinEHStatePass(); }
    121 
    122 char WinEHStatePass::ID = 0;
    123 
    124 INITIALIZE_PASS(WinEHStatePass, "x86-winehstate",
    125                 "Insert stores for EH state numbers", false, false)
    126 
    127 bool WinEHStatePass::doInitialization(Module &M) {
    128   TheModule = &M;
    129   return false;
    130 }
    131 
    132 bool WinEHStatePass::doFinalization(Module &M) {
    133   assert(TheModule == &M);
    134   TheModule = nullptr;
    135   EHLinkRegistrationTy = nullptr;
    136   CXXEHRegistrationTy = nullptr;
    137   SEHRegistrationTy = nullptr;
    138   SetJmp3 = nullptr;
    139   CxxLongjmpUnwind = nullptr;
    140   SehLongjmpUnwind = nullptr;
    141   Cookie = nullptr;
    142   return false;
    143 }
    144 
    145 void WinEHStatePass::getAnalysisUsage(AnalysisUsage &AU) const {
    146   // This pass should only insert a stack allocation, memory accesses, and
    147   // localrecovers.
    148   AU.setPreservesCFG();
    149 }
    150 
    151 bool WinEHStatePass::runOnFunction(Function &F) {
    152   // Check the personality. Do nothing if this personality doesn't use funclets.
    153   if (!F.hasPersonalityFn())
    154     return false;
    155   PersonalityFn =
    156       dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
    157   if (!PersonalityFn)
    158     return false;
    159   Personality = classifyEHPersonality(PersonalityFn);
    160   if (!isFuncletEHPersonality(Personality))
    161     return false;
    162 
    163   // Skip this function if there are no EH pads and we aren't using IR-level
    164   // outlining.
    165   bool HasPads = false;
    166   for (BasicBlock &BB : F) {
    167     if (BB.isEHPad()) {
    168       HasPads = true;
    169       break;
    170     }
    171   }
    172   if (!HasPads)
    173     return false;
    174 
    175   Type *Int8PtrType = Type::getInt8PtrTy(TheModule->getContext());
    176   SetJmp3 = TheModule->getOrInsertFunction(
    177       "_setjmp3", FunctionType::get(
    178                       Type::getInt32Ty(TheModule->getContext()),
    179                       {Int8PtrType, Type::getInt32Ty(TheModule->getContext())},
    180                       /*isVarArg=*/true));
    181 
    182   // Disable frame pointer elimination in this function.
    183   // FIXME: Do the nested handlers need to keep the parent ebp in ebp, or can we
    184   // use an arbitrary register?
    185   F.addFnAttr("no-frame-pointer-elim", "true");
    186 
    187   emitExceptionRegistrationRecord(&F);
    188 
    189   // The state numbers calculated here in IR must agree with what we calculate
    190   // later on for the MachineFunction. In particular, if an IR pass deletes an
    191   // unreachable EH pad after this point before machine CFG construction, we
    192   // will be in trouble. If this assumption is ever broken, we should turn the
    193   // numbers into an immutable analysis pass.
    194   WinEHFuncInfo FuncInfo;
    195   addStateStores(F, FuncInfo);
    196 
    197   // Reset per-function state.
    198   PersonalityFn = nullptr;
    199   Personality = EHPersonality::Unknown;
    200   UseStackGuard = false;
    201   RegNode = nullptr;
    202   EHGuardNode = nullptr;
    203 
    204   return true;
    205 }
    206 
    207 /// Get the common EH registration subobject:
    208 ///   typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
    209 ///       _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
    210 ///   struct EHRegistrationNode {
    211 ///     EHRegistrationNode *Next;
    212 ///     PEXCEPTION_ROUTINE Handler;
    213 ///   };
    214 Type *WinEHStatePass::getEHLinkRegistrationType() {
    215   if (EHLinkRegistrationTy)
    216     return EHLinkRegistrationTy;
    217   LLVMContext &Context = TheModule->getContext();
    218   EHLinkRegistrationTy = StructType::create(Context, "EHRegistrationNode");
    219   Type *FieldTys[] = {
    220       EHLinkRegistrationTy->getPointerTo(0), // EHRegistrationNode *Next
    221       Type::getInt8PtrTy(Context) // EXCEPTION_DISPOSITION (*Handler)(...)
    222   };
    223   EHLinkRegistrationTy->setBody(FieldTys, false);
    224   return EHLinkRegistrationTy;
    225 }
    226 
    227 /// The __CxxFrameHandler3 registration node:
    228 ///   struct CXXExceptionRegistration {
    229 ///     void *SavedESP;
    230 ///     EHRegistrationNode SubRecord;
    231 ///     int32_t TryLevel;
    232 ///   };
    233 Type *WinEHStatePass::getCXXEHRegistrationType() {
    234   if (CXXEHRegistrationTy)
    235     return CXXEHRegistrationTy;
    236   LLVMContext &Context = TheModule->getContext();
    237   Type *FieldTys[] = {
    238       Type::getInt8PtrTy(Context), // void *SavedESP
    239       getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
    240       Type::getInt32Ty(Context)    // int32_t TryLevel
    241   };
    242   CXXEHRegistrationTy =
    243       StructType::create(FieldTys, "CXXExceptionRegistration");
    244   return CXXEHRegistrationTy;
    245 }
    246 
    247 /// The _except_handler3/4 registration node:
    248 ///   struct EH4ExceptionRegistration {
    249 ///     void *SavedESP;
    250 ///     _EXCEPTION_POINTERS *ExceptionPointers;
    251 ///     EHRegistrationNode SubRecord;
    252 ///     int32_t EncodedScopeTable;
    253 ///     int32_t TryLevel;
    254 ///   };
    255 Type *WinEHStatePass::getSEHRegistrationType() {
    256   if (SEHRegistrationTy)
    257     return SEHRegistrationTy;
    258   LLVMContext &Context = TheModule->getContext();
    259   Type *FieldTys[] = {
    260       Type::getInt8PtrTy(Context), // void *SavedESP
    261       Type::getInt8PtrTy(Context), // void *ExceptionPointers
    262       getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
    263       Type::getInt32Ty(Context),   // int32_t EncodedScopeTable
    264       Type::getInt32Ty(Context)    // int32_t TryLevel
    265   };
    266   SEHRegistrationTy = StructType::create(FieldTys, "SEHExceptionRegistration");
    267   return SEHRegistrationTy;
    268 }
    269 
    270 // Emit an exception registration record. These are stack allocations with the
    271 // common subobject of two pointers: the previous registration record (the old
    272 // fs:00) and the personality function for the current frame. The data before
    273 // and after that is personality function specific.
    274 void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
    275   assert(Personality == EHPersonality::MSVC_CXX ||
    276          Personality == EHPersonality::MSVC_X86SEH);
    277 
    278   // Struct type of RegNode. Used for GEPing.
    279   Type *RegNodeTy;
    280 
    281   IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
    282   Type *Int8PtrType = Builder.getInt8PtrTy();
    283   Type *Int32Ty = Builder.getInt32Ty();
    284   Type *VoidTy = Builder.getVoidTy();
    285 
    286   if (Personality == EHPersonality::MSVC_CXX) {
    287     RegNodeTy = getCXXEHRegistrationType();
    288     RegNode = Builder.CreateAlloca(RegNodeTy);
    289     // SavedESP = llvm.stacksave()
    290     Value *SP = Builder.CreateCall(
    291         Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
    292     Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
    293     // TryLevel = -1
    294     StateFieldIndex = 2;
    295     ParentBaseState = -1;
    296     insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
    297     // Handler = __ehhandler$F
    298     Function *Trampoline = generateLSDAInEAXThunk(F);
    299     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
    300     linkExceptionRegistration(Builder, Trampoline);
    301 
    302     CxxLongjmpUnwind = TheModule->getOrInsertFunction(
    303         "__CxxLongjmpUnwind",
    304         FunctionType::get(VoidTy, Int8PtrType, /*isVarArg=*/false));
    305     cast<Function>(CxxLongjmpUnwind->stripPointerCasts())
    306         ->setCallingConv(CallingConv::X86_StdCall);
    307   } else if (Personality == EHPersonality::MSVC_X86SEH) {
    308     // If _except_handler4 is in use, some additional guard checks and prologue
    309     // stuff is required.
    310     StringRef PersonalityName = PersonalityFn->getName();
    311     UseStackGuard = (PersonalityName == "_except_handler4");
    312 
    313     // Allocate local structures.
    314     RegNodeTy = getSEHRegistrationType();
    315     RegNode = Builder.CreateAlloca(RegNodeTy);
    316     if (UseStackGuard)
    317       EHGuardNode = Builder.CreateAlloca(Int32Ty);
    318 
    319     // SavedESP = llvm.stacksave()
    320     Value *SP = Builder.CreateCall(
    321         Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
    322     Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
    323     // TryLevel = -2 / -1
    324     StateFieldIndex = 4;
    325     ParentBaseState = UseStackGuard ? -2 : -1;
    326     insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
    327     // ScopeTable = llvm.x86.seh.lsda(F)
    328     Value *LSDA = emitEHLSDA(Builder, F);
    329     LSDA = Builder.CreatePtrToInt(LSDA, Int32Ty);
    330     // If using _except_handler4, xor the address of the table with
    331     // __security_cookie.
    332     if (UseStackGuard) {
    333       Cookie = TheModule->getOrInsertGlobal("__security_cookie", Int32Ty);
    334       Value *Val = Builder.CreateLoad(Int32Ty, Cookie, "cookie");
    335       LSDA = Builder.CreateXor(LSDA, Val);
    336     }
    337     Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 3));
    338 
    339     // If using _except_handler4, the EHGuard contains: FramePtr xor Cookie.
    340     if (UseStackGuard) {
    341       Value *Val = Builder.CreateLoad(Int32Ty, Cookie);
    342       Value *FrameAddr = Builder.CreateCall(
    343           Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress),
    344           Builder.getInt32(0), "frameaddr");
    345       Value *FrameAddrI32 = Builder.CreatePtrToInt(FrameAddr, Int32Ty);
    346       FrameAddrI32 = Builder.CreateXor(FrameAddrI32, Val);
    347       Builder.CreateStore(FrameAddrI32, EHGuardNode);
    348     }
    349 
    350     // Register the exception handler.
    351     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
    352     linkExceptionRegistration(Builder, PersonalityFn);
    353 
    354     SehLongjmpUnwind = TheModule->getOrInsertFunction(
    355         UseStackGuard ? "_seh_longjmp_unwind4" : "_seh_longjmp_unwind",
    356         FunctionType::get(Type::getVoidTy(TheModule->getContext()), Int8PtrType,
    357                           /*isVarArg=*/false));
    358     cast<Function>(SehLongjmpUnwind->stripPointerCasts())
    359         ->setCallingConv(CallingConv::X86_StdCall);
    360   } else {
    361     llvm_unreachable("unexpected personality function");
    362   }
    363 
    364   // Insert an unlink before all returns.
    365   for (BasicBlock &BB : *F) {
    366     TerminatorInst *T = BB.getTerminator();
    367     if (!isa<ReturnInst>(T))
    368       continue;
    369     Builder.SetInsertPoint(T);
    370     unlinkExceptionRegistration(Builder);
    371   }
    372 }
    373 
    374 Value *WinEHStatePass::emitEHLSDA(IRBuilder<> &Builder, Function *F) {
    375   Value *FI8 = Builder.CreateBitCast(F, Type::getInt8PtrTy(F->getContext()));
    376   return Builder.CreateCall(
    377       Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
    378 }
    379 
    380 /// Generate a thunk that puts the LSDA of ParentFunc in EAX and then calls
    381 /// PersonalityFn, forwarding the parameters passed to PEXCEPTION_ROUTINE:
    382 ///   typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
    383 ///       _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
    384 /// We essentially want this code:
    385 ///   movl $lsda, %eax
    386 ///   jmpl ___CxxFrameHandler3
    387 Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
    388   LLVMContext &Context = ParentFunc->getContext();
    389   Type *Int32Ty = Type::getInt32Ty(Context);
    390   Type *Int8PtrType = Type::getInt8PtrTy(Context);
    391   Type *ArgTys[5] = {Int8PtrType, Int8PtrType, Int8PtrType, Int8PtrType,
    392                      Int8PtrType};
    393   FunctionType *TrampolineTy =
    394       FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 4),
    395                         /*isVarArg=*/false);
    396   FunctionType *TargetFuncTy =
    397       FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 5),
    398                         /*isVarArg=*/false);
    399   Function *Trampoline =
    400       Function::Create(TrampolineTy, GlobalValue::InternalLinkage,
    401                        Twine("__ehhandler$") + GlobalValue::getRealLinkageName(
    402                                                    ParentFunc->getName()),
    403                        TheModule);
    404   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", Trampoline);
    405   IRBuilder<> Builder(EntryBB);
    406   Value *LSDA = emitEHLSDA(Builder, ParentFunc);
    407   Value *CastPersonality =
    408       Builder.CreateBitCast(PersonalityFn, TargetFuncTy->getPointerTo());
    409   auto AI = Trampoline->arg_begin();
    410   Value *Args[5] = {LSDA, &*AI++, &*AI++, &*AI++, &*AI++};
    411   CallInst *Call = Builder.CreateCall(CastPersonality, Args);
    412   // Can't use musttail due to prototype mismatch, but we can use tail.
    413   Call->setTailCall(true);
    414   // Set inreg so we pass it in EAX.
    415   Call->addAttribute(1, Attribute::InReg);
    416   Builder.CreateRet(Call);
    417   return Trampoline;
    418 }
    419 
    420 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
    421                                                Function *Handler) {
    422   // Emit the .safeseh directive for this function.
    423   Handler->addFnAttr("safeseh");
    424 
    425   Type *LinkTy = getEHLinkRegistrationType();
    426   // Handler = Handler
    427   Value *HandlerI8 = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
    428   Builder.CreateStore(HandlerI8, Builder.CreateStructGEP(LinkTy, Link, 1));
    429   // Next = [fs:00]
    430   Constant *FSZero =
    431       Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
    432   Value *Next = Builder.CreateLoad(FSZero);
    433   Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
    434   // [fs:00] = Link
    435   Builder.CreateStore(Link, FSZero);
    436 }
    437 
    438 void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
    439   // Clone Link into the current BB for better address mode folding.
    440   if (auto *GEP = dyn_cast<GetElementPtrInst>(Link)) {
    441     GEP = cast<GetElementPtrInst>(GEP->clone());
    442     Builder.Insert(GEP);
    443     Link = GEP;
    444   }
    445   Type *LinkTy = getEHLinkRegistrationType();
    446   // [fs:00] = Link->Next
    447   Value *Next =
    448       Builder.CreateLoad(Builder.CreateStructGEP(LinkTy, Link, 0));
    449   Constant *FSZero =
    450       Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
    451   Builder.CreateStore(Next, FSZero);
    452 }
    453 
    454 // Calls to setjmp(p) are lowered to _setjmp3(p, 0) by the frontend.
    455 // The idea behind _setjmp3 is that it takes an optional number of personality
    456 // specific parameters to indicate how to restore the personality-specific frame
    457 // state when longjmp is initiated.  Typically, the current TryLevel is saved.
    458 void WinEHStatePass::rewriteSetJmpCallSite(IRBuilder<> &Builder, Function &F,
    459                                            CallSite CS, Value *State) {
    460   // Don't rewrite calls with a weird number of arguments.
    461   if (CS.getNumArgOperands() != 2)
    462     return;
    463 
    464   Instruction *Inst = CS.getInstruction();
    465 
    466   SmallVector<OperandBundleDef, 1> OpBundles;
    467   CS.getOperandBundlesAsDefs(OpBundles);
    468 
    469   SmallVector<Value *, 3> OptionalArgs;
    470   if (Personality == EHPersonality::MSVC_CXX) {
    471     OptionalArgs.push_back(CxxLongjmpUnwind);
    472     OptionalArgs.push_back(State);
    473     OptionalArgs.push_back(emitEHLSDA(Builder, &F));
    474   } else if (Personality == EHPersonality::MSVC_X86SEH) {
    475     OptionalArgs.push_back(SehLongjmpUnwind);
    476     OptionalArgs.push_back(State);
    477     if (UseStackGuard)
    478       OptionalArgs.push_back(Cookie);
    479   } else {
    480     llvm_unreachable("unhandled personality!");
    481   }
    482 
    483   SmallVector<Value *, 5> Args;
    484   Args.push_back(
    485       Builder.CreateBitCast(CS.getArgOperand(0), Builder.getInt8PtrTy()));
    486   Args.push_back(Builder.getInt32(OptionalArgs.size()));
    487   Args.append(OptionalArgs.begin(), OptionalArgs.end());
    488 
    489   CallSite NewCS;
    490   if (CS.isCall()) {
    491     auto *CI = cast<CallInst>(Inst);
    492     CallInst *NewCI = Builder.CreateCall(SetJmp3, Args, OpBundles);
    493     NewCI->setTailCallKind(CI->getTailCallKind());
    494     NewCS = NewCI;
    495   } else {
    496     auto *II = cast<InvokeInst>(Inst);
    497     NewCS = Builder.CreateInvoke(
    498         SetJmp3, II->getNormalDest(), II->getUnwindDest(), Args, OpBundles);
    499   }
    500   NewCS.setCallingConv(CS.getCallingConv());
    501   NewCS.setAttributes(CS.getAttributes());
    502   NewCS->setDebugLoc(CS->getDebugLoc());
    503 
    504   Instruction *NewInst = NewCS.getInstruction();
    505   NewInst->takeName(Inst);
    506   Inst->replaceAllUsesWith(NewInst);
    507   Inst->eraseFromParent();
    508 }
    509 
    510 // Figure out what state we should assign calls in this block.
    511 int WinEHStatePass::getBaseStateForBB(
    512     DenseMap<BasicBlock *, ColorVector> &BlockColors, WinEHFuncInfo &FuncInfo,
    513     BasicBlock *BB) {
    514   int BaseState = ParentBaseState;
    515   auto &BBColors = BlockColors[BB];
    516 
    517   assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
    518   BasicBlock *FuncletEntryBB = BBColors.front();
    519   if (auto *FuncletPad =
    520           dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI())) {
    521     auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
    522     if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
    523       BaseState = BaseStateI->second;
    524   }
    525 
    526   return BaseState;
    527 }
    528 
    529 // Calculate the state a call-site is in.
    530 int WinEHStatePass::getStateForCallSite(
    531     DenseMap<BasicBlock *, ColorVector> &BlockColors, WinEHFuncInfo &FuncInfo,
    532     CallSite CS) {
    533   if (auto *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
    534     // Look up the state number of the EH pad this unwinds to.
    535     assert(FuncInfo.InvokeStateMap.count(II) && "invoke has no state!");
    536     return FuncInfo.InvokeStateMap[II];
    537   }
    538   // Possibly throwing call instructions have no actions to take after
    539   // an unwind. Ensure they are in the -1 state.
    540   return getBaseStateForBB(BlockColors, FuncInfo, CS.getParent());
    541 }
    542 
    543 // Calculate the intersection of all the FinalStates for a BasicBlock's
    544 // predecessors.
    545 static int getPredState(DenseMap<BasicBlock *, int> &FinalStates, Function &F,
    546                         int ParentBaseState, BasicBlock *BB) {
    547   // The entry block has no predecessors but we know that the prologue always
    548   // sets us up with a fixed state.
    549   if (&F.getEntryBlock() == BB)
    550     return ParentBaseState;
    551 
    552   // This is an EH Pad, conservatively report this basic block as overdefined.
    553   if (BB->isEHPad())
    554     return OverdefinedState;
    555 
    556   int CommonState = OverdefinedState;
    557   for (BasicBlock *PredBB : predecessors(BB)) {
    558     // We didn't manage to get a state for one of these predecessors,
    559     // conservatively report this basic block as overdefined.
    560     auto PredEndState = FinalStates.find(PredBB);
    561     if (PredEndState == FinalStates.end())
    562       return OverdefinedState;
    563 
    564     // This code is reachable via exceptional control flow,
    565     // conservatively report this basic block as overdefined.
    566     if (isa<CatchReturnInst>(PredBB->getTerminator()))
    567       return OverdefinedState;
    568 
    569     int PredState = PredEndState->second;
    570     assert(PredState != OverdefinedState &&
    571            "overdefined BBs shouldn't be in FinalStates");
    572     if (CommonState == OverdefinedState)
    573       CommonState = PredState;
    574 
    575     // At least two predecessors have different FinalStates,
    576     // conservatively report this basic block as overdefined.
    577     if (CommonState != PredState)
    578       return OverdefinedState;
    579   }
    580 
    581   return CommonState;
    582 }
    583 
    584 // Calculate the intersection of all the InitialStates for a BasicBlock's
    585 // successors.
    586 static int getSuccState(DenseMap<BasicBlock *, int> &InitialStates, Function &F,
    587                         int ParentBaseState, BasicBlock *BB) {
    588   // This block rejoins normal control flow,
    589   // conservatively report this basic block as overdefined.
    590   if (isa<CatchReturnInst>(BB->getTerminator()))
    591     return OverdefinedState;
    592 
    593   int CommonState = OverdefinedState;
    594   for (BasicBlock *SuccBB : successors(BB)) {
    595     // We didn't manage to get a state for one of these predecessors,
    596     // conservatively report this basic block as overdefined.
    597     auto SuccStartState = InitialStates.find(SuccBB);
    598     if (SuccStartState == InitialStates.end())
    599       return OverdefinedState;
    600 
    601     // This is an EH Pad, conservatively report this basic block as overdefined.
    602     if (SuccBB->isEHPad())
    603       return OverdefinedState;
    604 
    605     int SuccState = SuccStartState->second;
    606     assert(SuccState != OverdefinedState &&
    607            "overdefined BBs shouldn't be in FinalStates");
    608     if (CommonState == OverdefinedState)
    609       CommonState = SuccState;
    610 
    611     // At least two successors have different InitialStates,
    612     // conservatively report this basic block as overdefined.
    613     if (CommonState != SuccState)
    614       return OverdefinedState;
    615   }
    616 
    617   return CommonState;
    618 }
    619 
    620 bool WinEHStatePass::isStateStoreNeeded(EHPersonality Personality,
    621                                         CallSite CS) {
    622   if (!CS)
    623     return false;
    624 
    625   // If the function touches memory, it needs a state store.
    626   if (isAsynchronousEHPersonality(Personality))
    627     return !CS.doesNotAccessMemory();
    628 
    629   // If the function throws, it needs a state store.
    630   return !CS.doesNotThrow();
    631 }
    632 
    633 void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
    634   // Mark the registration node. The backend needs to know which alloca it is so
    635   // that it can recover the original frame pointer.
    636   IRBuilder<> Builder(RegNode->getNextNode());
    637   Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
    638   Builder.CreateCall(
    639       Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
    640       {RegNodeI8});
    641 
    642   if (EHGuardNode) {
    643     IRBuilder<> Builder(EHGuardNode->getNextNode());
    644     Value *EHGuardNodeI8 =
    645         Builder.CreateBitCast(EHGuardNode, Builder.getInt8PtrTy());
    646     Builder.CreateCall(
    647         Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehguard),
    648         {EHGuardNodeI8});
    649   }
    650 
    651   // Calculate state numbers.
    652   if (isAsynchronousEHPersonality(Personality))
    653     calculateSEHStateNumbers(&F, FuncInfo);
    654   else
    655     calculateWinCXXEHStateNumbers(&F, FuncInfo);
    656 
    657   // Iterate all the instructions and emit state number stores.
    658   DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(F);
    659   ReversePostOrderTraversal<Function *> RPOT(&F);
    660 
    661   // InitialStates yields the state of the first call-site for a BasicBlock.
    662   DenseMap<BasicBlock *, int> InitialStates;
    663   // FinalStates yields the state of the last call-site for a BasicBlock.
    664   DenseMap<BasicBlock *, int> FinalStates;
    665   // Worklist used to revisit BasicBlocks with indeterminate
    666   // Initial/Final-States.
    667   std::deque<BasicBlock *> Worklist;
    668   // Fill in InitialStates and FinalStates for BasicBlocks with call-sites.
    669   for (BasicBlock *BB : RPOT) {
    670     int InitialState = OverdefinedState;
    671     int FinalState;
    672     if (&F.getEntryBlock() == BB)
    673       InitialState = FinalState = ParentBaseState;
    674     for (Instruction &I : *BB) {
    675       CallSite CS(&I);
    676       if (!isStateStoreNeeded(Personality, CS))
    677         continue;
    678 
    679       int State = getStateForCallSite(BlockColors, FuncInfo, CS);
    680       if (InitialState == OverdefinedState)
    681         InitialState = State;
    682       FinalState = State;
    683     }
    684     // No call-sites in this basic block? That's OK, we will come back to these
    685     // in a later pass.
    686     if (InitialState == OverdefinedState) {
    687       Worklist.push_back(BB);
    688       continue;
    689     }
    690     DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
    691                  << " InitialState=" << InitialState << '\n');
    692     DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
    693                  << " FinalState=" << FinalState << '\n');
    694     InitialStates.insert({BB, InitialState});
    695     FinalStates.insert({BB, FinalState});
    696   }
    697 
    698   // Try to fill-in InitialStates and FinalStates which have no call-sites.
    699   while (!Worklist.empty()) {
    700     BasicBlock *BB = Worklist.front();
    701     Worklist.pop_front();
    702     // This BasicBlock has already been figured out, nothing more we can do.
    703     if (InitialStates.count(BB) != 0)
    704       continue;
    705 
    706     int PredState = getPredState(FinalStates, F, ParentBaseState, BB);
    707     if (PredState == OverdefinedState)
    708       continue;
    709 
    710     // We successfully inferred this BasicBlock's state via it's predecessors;
    711     // enqueue it's successors to see if we can infer their states.
    712     InitialStates.insert({BB, PredState});
    713     FinalStates.insert({BB, PredState});
    714     for (BasicBlock *SuccBB : successors(BB))
    715       Worklist.push_back(SuccBB);
    716   }
    717 
    718   // Try to hoist stores from successors.
    719   for (BasicBlock *BB : RPOT) {
    720     int SuccState = getSuccState(InitialStates, F, ParentBaseState, BB);
    721     if (SuccState == OverdefinedState)
    722       continue;
    723 
    724     // Update our FinalState to reflect the common InitialState of our
    725     // successors.
    726     FinalStates.insert({BB, SuccState});
    727   }
    728 
    729   // Finally, insert state stores before call-sites which transition us to a new
    730   // state.
    731   for (BasicBlock *BB : RPOT) {
    732     auto &BBColors = BlockColors[BB];
    733     BasicBlock *FuncletEntryBB = BBColors.front();
    734     if (isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHI()))
    735       continue;
    736 
    737     int PrevState = getPredState(FinalStates, F, ParentBaseState, BB);
    738     DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
    739                  << " PrevState=" << PrevState << '\n');
    740 
    741     for (Instruction &I : *BB) {
    742       CallSite CS(&I);
    743       if (!isStateStoreNeeded(Personality, CS))
    744         continue;
    745 
    746       int State = getStateForCallSite(BlockColors, FuncInfo, CS);
    747       if (State != PrevState)
    748         insertStateNumberStore(&I, State);
    749       PrevState = State;
    750     }
    751 
    752     // We might have hoisted a state store into this block, emit it now.
    753     auto EndState = FinalStates.find(BB);
    754     if (EndState != FinalStates.end())
    755       if (EndState->second != PrevState)
    756         insertStateNumberStore(BB->getTerminator(), EndState->second);
    757   }
    758 
    759   SmallVector<CallSite, 1> SetJmp3CallSites;
    760   for (BasicBlock *BB : RPOT) {
    761     for (Instruction &I : *BB) {
    762       CallSite CS(&I);
    763       if (!CS)
    764         continue;
    765       if (CS.getCalledValue()->stripPointerCasts() !=
    766           SetJmp3->stripPointerCasts())
    767         continue;
    768 
    769       SetJmp3CallSites.push_back(CS);
    770     }
    771   }
    772 
    773   for (CallSite CS : SetJmp3CallSites) {
    774     auto &BBColors = BlockColors[CS->getParent()];
    775     BasicBlock *FuncletEntryBB = BBColors.front();
    776     bool InCleanup = isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHI());
    777 
    778     IRBuilder<> Builder(CS.getInstruction());
    779     Value *State;
    780     if (InCleanup) {
    781       Value *StateField =
    782           Builder.CreateStructGEP(nullptr, RegNode, StateFieldIndex);
    783       State = Builder.CreateLoad(StateField);
    784     } else {
    785       State = Builder.getInt32(getStateForCallSite(BlockColors, FuncInfo, CS));
    786     }
    787     rewriteSetJmpCallSite(Builder, F, CS, State);
    788   }
    789 }
    790 
    791 void WinEHStatePass::insertStateNumberStore(Instruction *IP, int State) {
    792   IRBuilder<> Builder(IP);
    793   Value *StateField =
    794       Builder.CreateStructGEP(nullptr, RegNode, StateFieldIndex);
    795   Builder.CreateStore(Builder.getInt32(State), StateField);
    796 }
    797