LLVM  4.0.0
X86WinEHState.cpp
Go to the documentation of this file.
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"
19 #include "llvm/Analysis/CFG.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 {
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) {
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  StringRef 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
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 =
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 =
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 =
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 =
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 
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 
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.
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.
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 }
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:76
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:226
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Definition: CallSite.h:539
LLVMContext & Context
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
Definition: WinEHFuncInfo.h:95
BBTy * getParent() const
Get the basic block containing the call site.
Definition: CallSite.h:98
This class represents a function call, abstracting a target machine's calling convention.
InvokeInst * CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef< Value * > Args=None, const Twine &Name="")
Create an invoke instruction.
Definition: IRBuilder.h:737
bool isEHPad() const
Return true if this basic block is an exception handling block.
Definition: BasicBlock.h:315
const Instruction & front() const
Definition: BasicBlock.h:240
Hexagon Common GEP
static int getPredState(DenseMap< BasicBlock *, int > &FinalStates, Function &F, int ParentBaseState, BasicBlock *BB)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:195
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:228
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:172
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
void calculateSEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
Class to represent struct types.
Definition: DerivedTypes.h:199
ValTy * getCalledValue() const
getCalledValue - Return the pointer to function that is being called.
Definition: CallSite.h:102
Instruction * getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Definition: BasicBlock.cpp:180
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:674
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:588
bool isCall() const
isCall - true if a CallInst is enclosed.
Definition: CallSite.h:87
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Definition: Function.cpp:1218
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1094
Class to represent function types.
Definition: DerivedTypes.h:102
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1362
#define F(x, y, z)
Definition: MD5.cpp:51
CallingConv::ID getCallingConv() const
getCallingConv/setCallingConv - get or set the calling convention of the call.
Definition: CallSite.h:308
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:291
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Definition: IRBuilder.h:639
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:949
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:401
void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:263
LoadInst * CreateLoad(Value *Ptr, const char *Name)
Definition: IRBuilder.h:1082
Subclasses of this class are all able to terminate a basic block.
Definition: InstrTypes.h:52
Constant * stripPointerCasts()
Definition: Constant.h:155
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
This is an important base class in LLVM.
Definition: Constant.h:42
X86_StdCall - stdcall is the calling conventions mostly used by the Win32 API.
Definition: CallingConv.h:86
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:115
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition: Function.h:581
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:154
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:93
arg_iterator arg_begin()
Definition: Function.h:550
DenseMap< const InvokeInst *, int > InvokeStateMap
Definition: WinEHFuncInfo.h:96
void setTailCallKind(TailCallKind TCK)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
void setTailCall(bool isTC=true)
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
Definition: IRBuilder.h:385
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:213
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool doesNotAccessMemory() const
Determine if the call does not access memory.
Definition: CallSite.h:421
AttributeSet getAttributes() const
getAttributes/setAttributes - get or set the parameter attributes of the call.
Definition: CallSite.h:325
void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which describes the state number...
InstrTy * getInstruction() const
Definition: CallSite.h:93
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
static int getSuccState(DenseMap< BasicBlock *, int > &InitialStates, Function &F, int ParentBaseState, BasicBlock *BB)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Module.h This file contains the declarations for the Module class.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:307
Value * stripPointerCasts()
Strip off pointer casts, all-zero GEPs, and aliases.
Definition: Value.cpp:490
pred_range predecessors(BasicBlock *BB)
Definition: IR/CFG.h:110
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:276
const BasicBlock & getEntryBlock() const
Definition: Function.h:519
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:122
unsigned getNumArgOperands() const
Definition: CallSite.h:288
INITIALIZE_PASS(WinEHStatePass,"x86-winehstate","Insert stores for EH state numbers", false, false) bool WinEHStatePass
static StringRef getRealLinkageName(StringRef Name)
If special LLVM prefix that is used to inform the asm printer to not emit usual symbol prefix before ...
Definition: GlobalValue.h:444
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:169
#define I(x, y, z)
Definition: MD5.cpp:54
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:124
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1579
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
Rename collisions when linking (static functions).
Definition: GlobalValue.h:56
void initializeWinEHStatePassPass(PassRegistry &)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
LLVM Value Representation.
Definition: Value.h:71
succ_range successors(BasicBlock *BB)
Definition: IR/CFG.h:143
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:417
ValTy * getArgOperand(unsigned i) const
Definition: CallSite.h:292
void setCallingConv(CallingConv::ID CC)
Value * CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name="")
Definition: IRBuilder.h:1279
#define DEBUG(X)
Definition: Debug.h:100
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.h:182
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:678
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:40
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
Definition: Function.h:117
void addAttribute(unsigned i, Attribute::AttrKind Kind)
adds the attribute to the list of attributes.
FunctionPass * createX86WinEHStatePass()
Return an IR pass that inserts EH registration stack objects and explicit EH state updates...
DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
bool doesNotThrow() const
Determine if the call cannot unwind.
Definition: CallSite.h:462
IntegerType * Int32Ty
an instruction to allocate memory on the stack
Definition: Instructions.h:60