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