Coverage Report

Created: 2019-07-24 05:18

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