]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304460, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Transforms / Instrumentation / SanitizerCoverage.cpp
1 //===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===//
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 // Coverage instrumentation done on LLVM IR level, works with Sanitizers.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/Analysis/EHPersonalities.h"
17 #include "llvm/Analysis/PostDominators.h"
18 #include "llvm/IR/CFG.h"
19 #include "llvm/IR/CallSite.h"
20 #include "llvm/IR/DataLayout.h"
21 #include "llvm/IR/DebugInfo.h"
22 #include "llvm/IR/Dominators.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/IR/IRBuilder.h"
25 #include "llvm/IR/InlineAsm.h"
26 #include "llvm/IR/LLVMContext.h"
27 #include "llvm/IR/MDBuilder.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Transforms/Instrumentation.h"
34 #include "llvm/Transforms/Scalar.h"
35 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
36 #include "llvm/Transforms/Utils/ModuleUtils.h"
37
38 using namespace llvm;
39
40 #define DEBUG_TYPE "sancov"
41
42 static const char *const SanCovTracePCIndirName =
43     "__sanitizer_cov_trace_pc_indir";
44 static const char *const SanCovTracePCName = "__sanitizer_cov_trace_pc";
45 static const char *const SanCovTraceCmp1 = "__sanitizer_cov_trace_cmp1";
46 static const char *const SanCovTraceCmp2 = "__sanitizer_cov_trace_cmp2";
47 static const char *const SanCovTraceCmp4 = "__sanitizer_cov_trace_cmp4";
48 static const char *const SanCovTraceCmp8 = "__sanitizer_cov_trace_cmp8";
49 static const char *const SanCovTraceDiv4 = "__sanitizer_cov_trace_div4";
50 static const char *const SanCovTraceDiv8 = "__sanitizer_cov_trace_div8";
51 static const char *const SanCovTraceGep = "__sanitizer_cov_trace_gep";
52 static const char *const SanCovTraceSwitchName = "__sanitizer_cov_trace_switch";
53 static const char *const SanCovModuleCtorName = "sancov.module_ctor";
54 static const uint64_t SanCtorAndDtorPriority = 2;
55
56 static const char *const SanCovTracePCGuardName =
57     "__sanitizer_cov_trace_pc_guard";
58 static const char *const SanCovTracePCGuardInitName =
59     "__sanitizer_cov_trace_pc_guard_init";
60
61 static cl::opt<int> ClCoverageLevel(
62     "sanitizer-coverage-level",
63     cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
64              "3: all blocks and critical edges"),
65     cl::Hidden, cl::init(0));
66
67 static cl::opt<bool> ClExperimentalTracePC("sanitizer-coverage-trace-pc",
68                                            cl::desc("Experimental pc tracing"),
69                                            cl::Hidden, cl::init(false));
70
71 static cl::opt<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
72                                     cl::desc("pc tracing with a guard"),
73                                     cl::Hidden, cl::init(false));
74
75 static cl::opt<bool>
76     ClCMPTracing("sanitizer-coverage-trace-compares",
77                  cl::desc("Tracing of CMP and similar instructions"),
78                  cl::Hidden, cl::init(false));
79
80 static cl::opt<bool> ClDIVTracing("sanitizer-coverage-trace-divs",
81                                   cl::desc("Tracing of DIV instructions"),
82                                   cl::Hidden, cl::init(false));
83
84 static cl::opt<bool> ClGEPTracing("sanitizer-coverage-trace-geps",
85                                   cl::desc("Tracing of GEP instructions"),
86                                   cl::Hidden, cl::init(false));
87
88 static cl::opt<bool>
89     ClPruneBlocks("sanitizer-coverage-prune-blocks",
90                   cl::desc("Reduce the number of instrumented blocks"),
91                   cl::Hidden, cl::init(true));
92
93 namespace {
94
95 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
96   SanitizerCoverageOptions Res;
97   switch (LegacyCoverageLevel) {
98   case 0:
99     Res.CoverageType = SanitizerCoverageOptions::SCK_None;
100     break;
101   case 1:
102     Res.CoverageType = SanitizerCoverageOptions::SCK_Function;
103     break;
104   case 2:
105     Res.CoverageType = SanitizerCoverageOptions::SCK_BB;
106     break;
107   case 3:
108     Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
109     break;
110   case 4:
111     Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
112     Res.IndirectCalls = true;
113     break;
114   }
115   return Res;
116 }
117
118 SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
119   // Sets CoverageType and IndirectCalls.
120   SanitizerCoverageOptions CLOpts = getOptions(ClCoverageLevel);
121   Options.CoverageType = std::max(Options.CoverageType, CLOpts.CoverageType);
122   Options.IndirectCalls |= CLOpts.IndirectCalls;
123   Options.TraceCmp |= ClCMPTracing;
124   Options.TraceDiv |= ClDIVTracing;
125   Options.TraceGep |= ClGEPTracing;
126   Options.TracePC |= ClExperimentalTracePC;
127   Options.TracePCGuard |= ClTracePCGuard;
128   if (!Options.TracePCGuard && !Options.TracePC)
129     Options.TracePCGuard = true; // TracePCGuard is default.
130   Options.NoPrune |= !ClPruneBlocks;
131   return Options;
132 }
133
134 class SanitizerCoverageModule : public ModulePass {
135 public:
136   SanitizerCoverageModule(
137       const SanitizerCoverageOptions &Options = SanitizerCoverageOptions())
138       : ModulePass(ID), Options(OverrideFromCL(Options)) {
139     initializeSanitizerCoverageModulePass(*PassRegistry::getPassRegistry());
140   }
141   bool runOnModule(Module &M) override;
142   bool runOnFunction(Function &F);
143   static char ID; // Pass identification, replacement for typeid
144   StringRef getPassName() const override { return "SanitizerCoverageModule"; }
145
146   void getAnalysisUsage(AnalysisUsage &AU) const override {
147     AU.addRequired<DominatorTreeWrapperPass>();
148     AU.addRequired<PostDominatorTreeWrapperPass>();
149   }
150
151 private:
152   void InjectCoverageForIndirectCalls(Function &F,
153                                       ArrayRef<Instruction *> IndirCalls);
154   void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
155   void InjectTraceForDiv(Function &F,
156                          ArrayRef<BinaryOperator *> DivTraceTargets);
157   void InjectTraceForGep(Function &F,
158                          ArrayRef<GetElementPtrInst *> GepTraceTargets);
159   void InjectTraceForSwitch(Function &F,
160                             ArrayRef<Instruction *> SwitchTraceTargets);
161   bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks);
162   void CreateFunctionGuardArray(size_t NumGuards, Function &F);
163   void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx);
164   StringRef getSanCovTracePCGuardSection() const;
165   StringRef getSanCovTracePCGuardSectionStart() const;
166   StringRef getSanCovTracePCGuardSectionEnd() const;
167   Function *SanCovTracePCIndir;
168   Function *SanCovTracePC, *SanCovTracePCGuard;
169   Function *SanCovTraceCmpFunction[4];
170   Function *SanCovTraceDivFunction[2];
171   Function *SanCovTraceGepFunction;
172   Function *SanCovTraceSwitchFunction;
173   InlineAsm *EmptyAsm;
174   Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy;
175   Module *CurModule;
176   Triple TargetTriple;
177   LLVMContext *C;
178   const DataLayout *DL;
179
180   GlobalVariable *FunctionGuardArray;  // for trace-pc-guard.
181   bool HasSancovGuardsSection;
182
183   SanitizerCoverageOptions Options;
184 };
185
186 } // namespace
187
188 bool SanitizerCoverageModule::runOnModule(Module &M) {
189   if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
190     return false;
191   C = &(M.getContext());
192   DL = &M.getDataLayout();
193   CurModule = &M;
194   TargetTriple = Triple(M.getTargetTriple());
195   HasSancovGuardsSection = false;
196   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
197   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
198   Type *VoidTy = Type::getVoidTy(*C);
199   IRBuilder<> IRB(*C);
200   Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
201   Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
202   Int64Ty = IRB.getInt64Ty();
203   Int32Ty = IRB.getInt32Ty();
204
205   SanCovTracePCIndir = checkSanitizerInterfaceFunction(
206       M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy));
207   SanCovTraceCmpFunction[0] =
208       checkSanitizerInterfaceFunction(M.getOrInsertFunction(
209           SanCovTraceCmp1, VoidTy, IRB.getInt8Ty(), IRB.getInt8Ty()));
210   SanCovTraceCmpFunction[1] = checkSanitizerInterfaceFunction(
211       M.getOrInsertFunction(SanCovTraceCmp2, VoidTy, IRB.getInt16Ty(),
212                             IRB.getInt16Ty()));
213   SanCovTraceCmpFunction[2] = checkSanitizerInterfaceFunction(
214       M.getOrInsertFunction(SanCovTraceCmp4, VoidTy, IRB.getInt32Ty(),
215                             IRB.getInt32Ty()));
216   SanCovTraceCmpFunction[3] =
217       checkSanitizerInterfaceFunction(M.getOrInsertFunction(
218           SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty));
219
220   SanCovTraceDivFunction[0] =
221       checkSanitizerInterfaceFunction(M.getOrInsertFunction(
222           SanCovTraceDiv4, VoidTy, IRB.getInt32Ty()));
223   SanCovTraceDivFunction[1] =
224       checkSanitizerInterfaceFunction(M.getOrInsertFunction(
225           SanCovTraceDiv8, VoidTy, Int64Ty));
226   SanCovTraceGepFunction =
227       checkSanitizerInterfaceFunction(M.getOrInsertFunction(
228           SanCovTraceGep, VoidTy, IntptrTy));
229   SanCovTraceSwitchFunction =
230       checkSanitizerInterfaceFunction(M.getOrInsertFunction(
231           SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy));
232
233   // We insert an empty inline asm after cov callbacks to avoid callback merge.
234   EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
235                             StringRef(""), StringRef(""),
236                             /*hasSideEffects=*/true);
237
238   SanCovTracePC = checkSanitizerInterfaceFunction(
239       M.getOrInsertFunction(SanCovTracePCName, VoidTy));
240   SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
241       SanCovTracePCGuardName, VoidTy, Int32PtrTy));
242
243   for (auto &F : M)
244     runOnFunction(F);
245
246   // Create variable for module (compilation unit) name
247   if (Options.TracePCGuard) {
248     if (HasSancovGuardsSection) {
249       Function *CtorFunc;
250       GlobalVariable *SecStart = new GlobalVariable(
251           M, Int32PtrTy, false, GlobalVariable::ExternalLinkage, nullptr,
252           getSanCovTracePCGuardSectionStart());
253       SecStart->setVisibility(GlobalValue::HiddenVisibility);
254       GlobalVariable *SecEnd = new GlobalVariable(
255           M, Int32PtrTy, false, GlobalVariable::ExternalLinkage, nullptr,
256           getSanCovTracePCGuardSectionEnd());
257       SecEnd->setVisibility(GlobalValue::HiddenVisibility);
258
259       std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
260           M, SanCovModuleCtorName, SanCovTracePCGuardInitName,
261           {Int32PtrTy, Int32PtrTy},
262           {IRB.CreatePointerCast(SecStart, Int32PtrTy),
263             IRB.CreatePointerCast(SecEnd, Int32PtrTy)});
264
265       if (TargetTriple.supportsCOMDAT()) {
266         // Use comdat to dedup CtorFunc.
267         CtorFunc->setComdat(M.getOrInsertComdat(SanCovModuleCtorName));
268         appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc);
269       } else {
270         appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
271       }
272     }
273   }
274   return true;
275 }
276
277 // True if block has successors and it dominates all of them.
278 static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
279   if (succ_begin(BB) == succ_end(BB))
280     return false;
281
282   for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) {
283     if (!DT->dominates(BB, SUCC))
284       return false;
285   }
286
287   return true;
288 }
289
290 // True if block has predecessors and it postdominates all of them.
291 static bool isFullPostDominator(const BasicBlock *BB,
292                                 const PostDominatorTree *PDT) {
293   if (pred_begin(BB) == pred_end(BB))
294     return false;
295
296   for (const BasicBlock *PRED : make_range(pred_begin(BB), pred_end(BB))) {
297     if (!PDT->dominates(BB, PRED))
298       return false;
299   }
300
301   return true;
302 }
303
304 static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
305                                   const DominatorTree *DT,
306                                   const PostDominatorTree *PDT,
307                                   const SanitizerCoverageOptions &Options) {
308   // Don't insert coverage for unreachable blocks: we will never call
309   // __sanitizer_cov() for them, so counting them in
310   // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
311   // percentage. Also, unreachable instructions frequently have no debug
312   // locations.
313   if (isa<UnreachableInst>(BB->getTerminator()))
314     return false;
315
316   // Don't insert coverage into blocks without a valid insertion point
317   // (catchswitch blocks).
318   if (BB->getFirstInsertionPt() == BB->end())
319     return false;
320
321   if (Options.NoPrune || &F.getEntryBlock() == BB)
322     return true;
323
324   // Do not instrument full dominators, or full post-dominators with multiple
325   // predecessors.
326   return !isFullDominator(BB, DT)
327     && !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
328 }
329
330 bool SanitizerCoverageModule::runOnFunction(Function &F) {
331   if (F.empty())
332     return false;
333   if (F.getName().find(".module_ctor") != std::string::npos)
334     return false; // Should not instrument sanitizer init functions.
335   if (F.getName().startswith("__sanitizer_"))
336     return false;  // Don't instrument __sanitizer_* callbacks.
337   // Don't instrument MSVC CRT configuration helpers. They may run before normal
338   // initialization.
339   if (F.getName() == "__local_stdio_printf_options" ||
340       F.getName() == "__local_stdio_scanf_options")
341     return false;
342   // Don't instrument functions using SEH for now. Splitting basic blocks like
343   // we do for coverage breaks WinEHPrepare.
344   // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
345   if (F.hasPersonalityFn() &&
346       isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
347     return false;
348   if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
349     SplitAllCriticalEdges(F);
350   SmallVector<Instruction *, 8> IndirCalls;
351   SmallVector<BasicBlock *, 16> BlocksToInstrument;
352   SmallVector<Instruction *, 8> CmpTraceTargets;
353   SmallVector<Instruction *, 8> SwitchTraceTargets;
354   SmallVector<BinaryOperator *, 8> DivTraceTargets;
355   SmallVector<GetElementPtrInst *, 8> GepTraceTargets;
356
357   const DominatorTree *DT =
358       &getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
359   const PostDominatorTree *PDT =
360       &getAnalysis<PostDominatorTreeWrapperPass>(F).getPostDomTree();
361
362   for (auto &BB : F) {
363     if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
364       BlocksToInstrument.push_back(&BB);
365     for (auto &Inst : BB) {
366       if (Options.IndirectCalls) {
367         CallSite CS(&Inst);
368         if (CS && !CS.getCalledFunction())
369           IndirCalls.push_back(&Inst);
370       }
371       if (Options.TraceCmp) {
372         if (isa<ICmpInst>(&Inst))
373           CmpTraceTargets.push_back(&Inst);
374         if (isa<SwitchInst>(&Inst))
375           SwitchTraceTargets.push_back(&Inst);
376       }
377       if (Options.TraceDiv)
378         if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&Inst))
379           if (BO->getOpcode() == Instruction::SDiv ||
380               BO->getOpcode() == Instruction::UDiv)
381             DivTraceTargets.push_back(BO);
382       if (Options.TraceGep)
383         if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&Inst))
384           GepTraceTargets.push_back(GEP);
385    }
386   }
387
388   InjectCoverage(F, BlocksToInstrument);
389   InjectCoverageForIndirectCalls(F, IndirCalls);
390   InjectTraceForCmp(F, CmpTraceTargets);
391   InjectTraceForSwitch(F, SwitchTraceTargets);
392   InjectTraceForDiv(F, DivTraceTargets);
393   InjectTraceForGep(F, GepTraceTargets);
394   return true;
395 }
396 void SanitizerCoverageModule::CreateFunctionGuardArray(size_t NumGuards,
397                                                        Function &F) {
398   if (!Options.TracePCGuard) return;
399   HasSancovGuardsSection = true;
400   ArrayType *ArrayOfInt32Ty = ArrayType::get(Int32Ty, NumGuards);
401   FunctionGuardArray = new GlobalVariable(
402       *CurModule, ArrayOfInt32Ty, false, GlobalVariable::PrivateLinkage,
403       Constant::getNullValue(ArrayOfInt32Ty), "__sancov_gen_");
404   if (auto Comdat = F.getComdat())
405     FunctionGuardArray->setComdat(Comdat);
406   FunctionGuardArray->setSection(getSanCovTracePCGuardSection());
407 }
408
409 bool SanitizerCoverageModule::InjectCoverage(Function &F,
410                                              ArrayRef<BasicBlock *> AllBlocks) {
411   if (AllBlocks.empty()) return false;
412   switch (Options.CoverageType) {
413   case SanitizerCoverageOptions::SCK_None:
414     return false;
415   case SanitizerCoverageOptions::SCK_Function:
416     CreateFunctionGuardArray(1, F);
417     InjectCoverageAtBlock(F, F.getEntryBlock(), 0);
418     return true;
419   default: {
420     CreateFunctionGuardArray(AllBlocks.size(), F);
421     for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
422       InjectCoverageAtBlock(F, *AllBlocks[i], i);
423     return true;
424   }
425   }
426 }
427
428 // On every indirect call we call a run-time function
429 // __sanitizer_cov_indir_call* with two parameters:
430 //   - callee address,
431 //   - global cache array that contains CacheSize pointers (zero-initialized).
432 //     The cache is used to speed up recording the caller-callee pairs.
433 // The address of the caller is passed implicitly via caller PC.
434 // CacheSize is encoded in the name of the run-time function.
435 void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
436     Function &F, ArrayRef<Instruction *> IndirCalls) {
437   if (IndirCalls.empty())
438     return;
439   assert(Options.TracePC || Options.TracePCGuard);
440   for (auto I : IndirCalls) {
441     IRBuilder<> IRB(I);
442     CallSite CS(I);
443     Value *Callee = CS.getCalledValue();
444     if (isa<InlineAsm>(Callee))
445       continue;
446     IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
447   }
448 }
449
450 // For every switch statement we insert a call:
451 // __sanitizer_cov_trace_switch(CondValue,
452 //      {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
453
454 void SanitizerCoverageModule::InjectTraceForSwitch(
455     Function &, ArrayRef<Instruction *> SwitchTraceTargets) {
456   for (auto I : SwitchTraceTargets) {
457     if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
458       IRBuilder<> IRB(I);
459       SmallVector<Constant *, 16> Initializers;
460       Value *Cond = SI->getCondition();
461       if (Cond->getType()->getScalarSizeInBits() >
462           Int64Ty->getScalarSizeInBits())
463         continue;
464       Initializers.push_back(ConstantInt::get(Int64Ty, SI->getNumCases()));
465       Initializers.push_back(
466           ConstantInt::get(Int64Ty, Cond->getType()->getScalarSizeInBits()));
467       if (Cond->getType()->getScalarSizeInBits() <
468           Int64Ty->getScalarSizeInBits())
469         Cond = IRB.CreateIntCast(Cond, Int64Ty, false);
470       for (auto It : SI->cases()) {
471         Constant *C = It.getCaseValue();
472         if (C->getType()->getScalarSizeInBits() <
473             Int64Ty->getScalarSizeInBits())
474           C = ConstantExpr::getCast(CastInst::ZExt, It.getCaseValue(), Int64Ty);
475         Initializers.push_back(C);
476       }
477       std::sort(Initializers.begin() + 2, Initializers.end(),
478                 [](const Constant *A, const Constant *B) {
479                   return cast<ConstantInt>(A)->getLimitedValue() <
480                          cast<ConstantInt>(B)->getLimitedValue();
481                 });
482       ArrayType *ArrayOfInt64Ty = ArrayType::get(Int64Ty, Initializers.size());
483       GlobalVariable *GV = new GlobalVariable(
484           *CurModule, ArrayOfInt64Ty, false, GlobalVariable::InternalLinkage,
485           ConstantArray::get(ArrayOfInt64Ty, Initializers),
486           "__sancov_gen_cov_switch_values");
487       IRB.CreateCall(SanCovTraceSwitchFunction,
488                      {Cond, IRB.CreatePointerCast(GV, Int64PtrTy)});
489     }
490   }
491 }
492
493 void SanitizerCoverageModule::InjectTraceForDiv(
494     Function &, ArrayRef<BinaryOperator *> DivTraceTargets) {
495   for (auto BO : DivTraceTargets) {
496     IRBuilder<> IRB(BO);
497     Value *A1 = BO->getOperand(1);
498     if (isa<ConstantInt>(A1)) continue;
499     if (!A1->getType()->isIntegerTy())
500       continue;
501     uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType());
502     int CallbackIdx = TypeSize == 32 ? 0 :
503         TypeSize == 64 ? 1 : -1;
504     if (CallbackIdx < 0) continue;
505     auto Ty = Type::getIntNTy(*C, TypeSize);
506     IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
507                    {IRB.CreateIntCast(A1, Ty, true)});
508   }
509 }
510
511 void SanitizerCoverageModule::InjectTraceForGep(
512     Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) {
513   for (auto GEP : GepTraceTargets) {
514     IRBuilder<> IRB(GEP);
515     for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I)
516       if (!isa<ConstantInt>(*I) && (*I)->getType()->isIntegerTy())
517         IRB.CreateCall(SanCovTraceGepFunction,
518                        {IRB.CreateIntCast(*I, IntptrTy, true)});
519   }
520 }
521
522 void SanitizerCoverageModule::InjectTraceForCmp(
523     Function &, ArrayRef<Instruction *> CmpTraceTargets) {
524   for (auto I : CmpTraceTargets) {
525     if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
526       IRBuilder<> IRB(ICMP);
527       Value *A0 = ICMP->getOperand(0);
528       Value *A1 = ICMP->getOperand(1);
529       if (!A0->getType()->isIntegerTy())
530         continue;
531       uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
532       int CallbackIdx = TypeSize == 8 ? 0 :
533                         TypeSize == 16 ? 1 :
534                         TypeSize == 32 ? 2 :
535                         TypeSize == 64 ? 3 : -1;
536       if (CallbackIdx < 0) continue;
537       // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
538       auto Ty = Type::getIntNTy(*C, TypeSize);
539       IRB.CreateCall(
540           SanCovTraceCmpFunction[CallbackIdx],
541           {IRB.CreateIntCast(A0, Ty, true), IRB.CreateIntCast(A1, Ty, true)});
542     }
543   }
544 }
545
546 void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
547                                                     size_t Idx) {
548   BasicBlock::iterator IP = BB.getFirstInsertionPt();
549   bool IsEntryBB = &BB == &F.getEntryBlock();
550   DebugLoc EntryLoc;
551   if (IsEntryBB) {
552     if (auto SP = F.getSubprogram())
553       EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
554     // Keep static allocas and llvm.localescape calls in the entry block.  Even
555     // if we aren't splitting the block, it's nice for allocas to be before
556     // calls.
557     IP = PrepareToSplitEntryBlock(BB, IP);
558   } else {
559     EntryLoc = IP->getDebugLoc();
560   }
561
562   IRBuilder<> IRB(&*IP);
563   IRB.SetCurrentDebugLocation(EntryLoc);
564   if (Options.TracePC) {
565     IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC.
566     IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
567   } else {
568     assert(Options.TracePCGuard);
569     auto GuardPtr = IRB.CreateIntToPtr(
570         IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
571                       ConstantInt::get(IntptrTy, Idx * 4)),
572         Int32PtrTy);
573     IRB.CreateCall(SanCovTracePCGuard, GuardPtr);
574     IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
575   }
576 }
577
578 StringRef SanitizerCoverageModule::getSanCovTracePCGuardSection() const {
579   if (TargetTriple.getObjectFormat() == Triple::COFF)
580     return ".SCOV$M";
581   if (TargetTriple.isOSBinFormatMachO())
582     return "__DATA,__sancov_guards";
583   return "__sancov_guards";
584 }
585
586 StringRef SanitizerCoverageModule::getSanCovTracePCGuardSectionStart() const {
587   if (TargetTriple.isOSBinFormatMachO())
588     return "\1section$start$__DATA$__sancov_guards";
589   return "__start___sancov_guards";
590 }
591
592 StringRef SanitizerCoverageModule::getSanCovTracePCGuardSectionEnd() const {
593   if (TargetTriple.isOSBinFormatMachO())
594     return "\1section$end$__DATA$__sancov_guards";
595   return "__stop___sancov_guards";
596 }
597
598
599 char SanitizerCoverageModule::ID = 0;
600 INITIALIZE_PASS_BEGIN(SanitizerCoverageModule, "sancov",
601                       "SanitizerCoverage: TODO."
602                       "ModulePass",
603                       false, false)
604 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
605 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
606 INITIALIZE_PASS_END(SanitizerCoverageModule, "sancov",
607                     "SanitizerCoverage: TODO."
608                     "ModulePass",
609                     false, false)
610 ModulePass *llvm::createSanitizerCoverageModulePass(
611     const SanitizerCoverageOptions &Options) {
612   return new SanitizerCoverageModule(Options);
613 }