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