Coverage Report

Created: 2017-10-03 07:32

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