LLVM  14.0.0git
SanitizerCoverage.cpp
Go to the documentation of this file.
1 //===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===//
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 // Coverage instrumentation done on LLVM IR level, works with Sanitizers.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/IR/CFG.h"
19 #include "llvm/IR/Constant.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/GlobalVariable.h"
25 #include "llvm/IR/IRBuilder.h"
26 #include "llvm/IR/InlineAsm.h"
27 #include "llvm/IR/IntrinsicInst.h"
28 #include "llvm/IR/Intrinsics.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/MDBuilder.h"
31 #include "llvm/IR/Mangler.h"
32 #include "llvm/IR/Module.h"
33 #include "llvm/IR/Type.h"
34 #include "llvm/InitializePasses.h"
36 #include "llvm/Support/Debug.h"
43 
44 using namespace llvm;
45 
46 #define DEBUG_TYPE "sancov"
47 
48 const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir";
49 const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
50 const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1";
51 const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2";
52 const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4";
53 const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8";
54 const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1";
55 const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2";
56 const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4";
57 const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8";
58 const char SanCovLoad1[] = "__sanitizer_cov_load1";
59 const char SanCovLoad2[] = "__sanitizer_cov_load2";
60 const char SanCovLoad4[] = "__sanitizer_cov_load4";
61 const char SanCovLoad8[] = "__sanitizer_cov_load8";
62 const char SanCovLoad16[] = "__sanitizer_cov_load16";
63 const char SanCovStore1[] = "__sanitizer_cov_store1";
64 const char SanCovStore2[] = "__sanitizer_cov_store2";
65 const char SanCovStore4[] = "__sanitizer_cov_store4";
66 const char SanCovStore8[] = "__sanitizer_cov_store8";
67 const char SanCovStore16[] = "__sanitizer_cov_store16";
68 const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4";
69 const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8";
70 const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep";
71 const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch";
73  "sancov.module_ctor_trace_pc_guard";
75  "sancov.module_ctor_8bit_counters";
76 const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag";
78 
79 const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard";
80 const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
81 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
82 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
83 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
84 
85 const char SanCovGuardsSectionName[] = "sancov_guards";
86 const char SanCovCountersSectionName[] = "sancov_cntrs";
87 const char SanCovBoolFlagSectionName[] = "sancov_bools";
88 const char SanCovPCsSectionName[] = "sancov_pcs";
89 
90 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
91 
93  "sanitizer-coverage-level",
94  cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
95  "3: all blocks and critical edges"),
96  cl::Hidden, cl::init(0));
97 
98 static cl::opt<bool> ClTracePC("sanitizer-coverage-trace-pc",
99  cl::desc("Experimental pc tracing"), cl::Hidden,
100  cl::init(false));
101 
102 static cl::opt<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
103  cl::desc("pc tracing with a guard"),
104  cl::Hidden, cl::init(false));
105 
106 // If true, we create a global variable that contains PCs of all instrumented
107 // BBs, put this global into a named section, and pass this section's bounds
108 // to __sanitizer_cov_pcs_init.
109 // This way the coverage instrumentation does not need to acquire the PCs
110 // at run-time. Works with trace-pc-guard, inline-8bit-counters, and
111 // inline-bool-flag.
112 static cl::opt<bool> ClCreatePCTable("sanitizer-coverage-pc-table",
113  cl::desc("create a static PC table"),
114  cl::Hidden, cl::init(false));
115 
116 static cl::opt<bool>
117  ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters",
118  cl::desc("increments 8-bit counter for every edge"),
119  cl::Hidden, cl::init(false));
120 
121 static cl::opt<bool>
122  ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag",
123  cl::desc("sets a boolean flag for every edge"), cl::Hidden,
124  cl::init(false));
125 
126 static cl::opt<bool>
127  ClCMPTracing("sanitizer-coverage-trace-compares",
128  cl::desc("Tracing of CMP and similar instructions"),
129  cl::Hidden, cl::init(false));
130 
131 static cl::opt<bool> ClDIVTracing("sanitizer-coverage-trace-divs",
132  cl::desc("Tracing of DIV instructions"),
133  cl::Hidden, cl::init(false));
134 
135 static cl::opt<bool> ClLoadTracing("sanitizer-coverage-trace-loads",
136  cl::desc("Tracing of load instructions"),
137  cl::Hidden, cl::init(false));
138 
139 static cl::opt<bool> ClStoreTracing("sanitizer-coverage-trace-stores",
140  cl::desc("Tracing of store instructions"),
141  cl::Hidden, cl::init(false));
142 
143 static cl::opt<bool> ClGEPTracing("sanitizer-coverage-trace-geps",
144  cl::desc("Tracing of GEP instructions"),
145  cl::Hidden, cl::init(false));
146 
147 static cl::opt<bool>
148  ClPruneBlocks("sanitizer-coverage-prune-blocks",
149  cl::desc("Reduce the number of instrumented blocks"),
150  cl::Hidden, cl::init(true));
151 
152 static cl::opt<bool> ClStackDepth("sanitizer-coverage-stack-depth",
153  cl::desc("max stack depth tracing"),
154  cl::Hidden, cl::init(false));
155 
156 namespace {
157 
158 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
160  switch (LegacyCoverageLevel) {
161  case 0:
163  break;
164  case 1:
166  break;
167  case 2:
169  break;
170  case 3:
172  break;
173  case 4:
175  Res.IndirectCalls = true;
176  break;
177  }
178  return Res;
179 }
180 
182  // Sets CoverageType and IndirectCalls.
183  SanitizerCoverageOptions CLOpts = getOptions(ClCoverageLevel);
184  Options.CoverageType = std::max(Options.CoverageType, CLOpts.CoverageType);
185  Options.IndirectCalls |= CLOpts.IndirectCalls;
186  Options.TraceCmp |= ClCMPTracing;
187  Options.TraceDiv |= ClDIVTracing;
188  Options.TraceGep |= ClGEPTracing;
189  Options.TracePC |= ClTracePC;
190  Options.TracePCGuard |= ClTracePCGuard;
191  Options.Inline8bitCounters |= ClInline8bitCounters;
192  Options.InlineBoolFlag |= ClInlineBoolFlag;
193  Options.PCTable |= ClCreatePCTable;
194  Options.NoPrune |= !ClPruneBlocks;
195  Options.StackDepth |= ClStackDepth;
196  Options.TraceLoads |= ClLoadTracing;
197  Options.TraceStores |= ClStoreTracing;
198  if (!Options.TracePCGuard && !Options.TracePC &&
199  !Options.Inline8bitCounters && !Options.StackDepth &&
200  !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
201  Options.TracePCGuard = true; // TracePCGuard is default.
202  return Options;
203 }
204 
205 using DomTreeCallback = function_ref<const DominatorTree *(Function &F)>;
206 using PostDomTreeCallback =
208 
209 class ModuleSanitizerCoverage {
210 public:
211  ModuleSanitizerCoverage(
213  const SpecialCaseList *Allowlist = nullptr,
214  const SpecialCaseList *Blocklist = nullptr)
215  : Options(OverrideFromCL(Options)), Allowlist(Allowlist),
216  Blocklist(Blocklist) {}
217  bool instrumentModule(Module &M, DomTreeCallback DTCallback,
218  PostDomTreeCallback PDTCallback);
219 
220 private:
221  void instrumentFunction(Function &F, DomTreeCallback DTCallback,
222  PostDomTreeCallback PDTCallback);
223  void InjectCoverageForIndirectCalls(Function &F,
224  ArrayRef<Instruction *> IndirCalls);
225  void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
226  void InjectTraceForDiv(Function &F,
227  ArrayRef<BinaryOperator *> DivTraceTargets);
228  void InjectTraceForGep(Function &F,
229  ArrayRef<GetElementPtrInst *> GepTraceTargets);
230  void InjectTraceForLoadsAndStores(Function &F, ArrayRef<LoadInst *> Loads,
231  ArrayRef<StoreInst *> Stores);
232  void InjectTraceForSwitch(Function &F,
233  ArrayRef<Instruction *> SwitchTraceTargets);
234  bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
235  bool IsLeafFunc = true);
236  GlobalVariable *CreateFunctionLocalArrayInSection(size_t NumElements,
237  Function &F, Type *Ty,
238  const char *Section);
239  GlobalVariable *CreatePCArray(Function &F, ArrayRef<BasicBlock *> AllBlocks);
240  void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks);
241  void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
242  bool IsLeafFunc = true);
243  Function *CreateInitCallsForSections(Module &M, const char *CtorName,
244  const char *InitFunctionName, Type *Ty,
245  const char *Section);
246  std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char *Section,
247  Type *Ty);
248 
249  void SetNoSanitizeMetadata(Instruction *I) {
250  I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
251  MDNode::get(*C, None));
252  }
253 
254  std::string getSectionName(const std::string &Section) const;
255  std::string getSectionStart(const std::string &Section) const;
256  std::string getSectionEnd(const std::string &Section) const;
257  FunctionCallee SanCovTracePCIndir;
258  FunctionCallee SanCovTracePC, SanCovTracePCGuard;
259  std::array<FunctionCallee, 4> SanCovTraceCmpFunction;
260  std::array<FunctionCallee, 4> SanCovTraceConstCmpFunction;
261  std::array<FunctionCallee, 5> SanCovLoadFunction;
262  std::array<FunctionCallee, 5> SanCovStoreFunction;
263  std::array<FunctionCallee, 2> SanCovTraceDivFunction;
264  FunctionCallee SanCovTraceGepFunction;
265  FunctionCallee SanCovTraceSwitchFunction;
266  GlobalVariable *SanCovLowestStack;
267  Type *Int128PtrTy, *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty,
268  *Int32PtrTy, *Int16PtrTy, *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty,
269  *Int1PtrTy;
270  Module *CurModule;
271  std::string CurModuleUniqueId;
272  Triple TargetTriple;
273  LLVMContext *C;
274  const DataLayout *DL;
275 
276  GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
277  GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters.
278  GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
279  GlobalVariable *FunctionPCsArray; // for pc-table.
280  SmallVector<GlobalValue *, 20> GlobalsToAppendToUsed;
281  SmallVector<GlobalValue *, 20> GlobalsToAppendToCompilerUsed;
282 
284 
285  const SpecialCaseList *Allowlist;
286  const SpecialCaseList *Blocklist;
287 };
288 
289 class ModuleSanitizerCoverageLegacyPass : public ModulePass {
290 public:
291  ModuleSanitizerCoverageLegacyPass(
293  const std::vector<std::string> &AllowlistFiles =
294  std::vector<std::string>(),
295  const std::vector<std::string> &BlocklistFiles =
296  std::vector<std::string>())
298  if (AllowlistFiles.size() > 0)
299  Allowlist = SpecialCaseList::createOrDie(AllowlistFiles,
301  if (BlocklistFiles.size() > 0)
302  Blocklist = SpecialCaseList::createOrDie(BlocklistFiles,
306  }
307  bool runOnModule(Module &M) override {
308  ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(),
309  Blocklist.get());
310  auto DTCallback = [this](Function &F) -> const DominatorTree * {
311  return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
312  };
313  auto PDTCallback = [this](Function &F) -> const PostDominatorTree * {
314  return &this->getAnalysis<PostDominatorTreeWrapperPass>(F)
315  .getPostDomTree();
316  };
317  return ModuleSancov.instrumentModule(M, DTCallback, PDTCallback);
318  }
319 
320  static char ID; // Pass identification, replacement for typeid
321  StringRef getPassName() const override { return "ModuleSanitizerCoverage"; }
322 
323  void getAnalysisUsage(AnalysisUsage &AU) const override {
326  }
327 
328 private:
330 
331  std::unique_ptr<SpecialCaseList> Allowlist;
332  std::unique_ptr<SpecialCaseList> Blocklist;
333 };
334 
335 } // namespace
336 
339  ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(),
340  Blocklist.get());
341  auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
342  auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
344  };
345  auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * {
347  };
348  if (ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
349  return PreservedAnalyses::none();
350  return PreservedAnalyses::all();
351 }
352 
353 std::pair<Value *, Value *>
354 ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
355  Type *Ty) {
356  // Use ExternalWeak so that if all sections are discarded due to section
357  // garbage collection, the linker will not report undefined symbol errors.
358  // Windows defines the start/stop symbols in compiler-rt so no need for
359  // ExternalWeak.
360  GlobalValue::LinkageTypes Linkage = TargetTriple.isOSBinFormatCOFF()
363  GlobalVariable *SecStart =
364  new GlobalVariable(M, Ty, false, Linkage, nullptr,
365  getSectionStart(Section));
367  GlobalVariable *SecEnd =
368  new GlobalVariable(M, Ty, false, Linkage, nullptr,
369  getSectionEnd(Section));
371  IRBuilder<> IRB(M.getContext());
372  if (!TargetTriple.isOSBinFormatCOFF())
373  return std::make_pair(SecStart, SecEnd);
374 
375  // Account for the fact that on windows-msvc __start_* symbols actually
376  // point to a uint64_t before the start of the array.
377  auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy);
378  auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr,
379  ConstantInt::get(IntptrTy, sizeof(uint64_t)));
380  return std::make_pair(IRB.CreatePointerCast(GEP, PointerType::getUnqual(Ty)),
381  SecEnd);
382 }
383 
384 Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
385  Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty,
386  const char *Section) {
387  auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
388  auto SecStart = SecStartEnd.first;
389  auto SecEnd = SecStartEnd.second;
390  Function *CtorFunc;
391  Type *PtrTy = PointerType::getUnqual(Ty);
392  std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
393  M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
394  assert(CtorFunc->getName() == CtorName);
395 
396  if (TargetTriple.supportsCOMDAT()) {
397  // Use comdat to dedup CtorFunc.
398  CtorFunc->setComdat(M.getOrInsertComdat(CtorName));
399  appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc);
400  } else {
402  }
403 
404  if (TargetTriple.isOSBinFormatCOFF()) {
405  // In COFF files, if the contructors are set as COMDAT (they are because
406  // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced
407  // functions and data) is used, the constructors get stripped. To prevent
408  // this, give the constructors weak ODR linkage and ensure the linker knows
409  // to include the sancov constructor. This way the linker can deduplicate
410  // the constructors but always leave one copy.
412  }
413  return CtorFunc;
414 }
415 
416 bool ModuleSanitizerCoverage::instrumentModule(
417  Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
418  if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
419  return false;
420  if (Allowlist &&
421  !Allowlist->inSection("coverage", "src", M.getSourceFileName()))
422  return false;
423  if (Blocklist &&
424  Blocklist->inSection("coverage", "src", M.getSourceFileName()))
425  return false;
426  C = &(M.getContext());
427  DL = &M.getDataLayout();
428  CurModule = &M;
429  CurModuleUniqueId = getUniqueModuleId(CurModule);
430  TargetTriple = Triple(M.getTargetTriple());
431  FunctionGuardArray = nullptr;
432  Function8bitCounterArray = nullptr;
433  FunctionBoolArray = nullptr;
434  FunctionPCsArray = nullptr;
435  IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
436  IntptrPtrTy = PointerType::getUnqual(IntptrTy);
437  Type *VoidTy = Type::getVoidTy(*C);
438  IRBuilder<> IRB(*C);
439  Int128PtrTy = PointerType::getUnqual(IRB.getInt128Ty());
440  Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
441  Int16PtrTy = PointerType::getUnqual(IRB.getInt16Ty());
442  Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
443  Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
444  Int1PtrTy = PointerType::getUnqual(IRB.getInt1Ty());
445  Int64Ty = IRB.getInt64Ty();
446  Int32Ty = IRB.getInt32Ty();
447  Int16Ty = IRB.getInt16Ty();
448  Int8Ty = IRB.getInt8Ty();
449  Int1Ty = IRB.getInt1Ty();
450 
451  SanCovTracePCIndir =
452  M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
453  // Make sure smaller parameters are zero-extended to i64 if required by the
454  // target ABI.
455  AttributeList SanCovTraceCmpZeroExtAL;
456  SanCovTraceCmpZeroExtAL =
457  SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt);
458  SanCovTraceCmpZeroExtAL =
459  SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt);
460 
461  SanCovTraceCmpFunction[0] =
462  M.getOrInsertFunction(SanCovTraceCmp1, SanCovTraceCmpZeroExtAL, VoidTy,
463  IRB.getInt8Ty(), IRB.getInt8Ty());
464  SanCovTraceCmpFunction[1] =
465  M.getOrInsertFunction(SanCovTraceCmp2, SanCovTraceCmpZeroExtAL, VoidTy,
466  IRB.getInt16Ty(), IRB.getInt16Ty());
467  SanCovTraceCmpFunction[2] =
468  M.getOrInsertFunction(SanCovTraceCmp4, SanCovTraceCmpZeroExtAL, VoidTy,
469  IRB.getInt32Ty(), IRB.getInt32Ty());
470  SanCovTraceCmpFunction[3] =
471  M.getOrInsertFunction(SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty);
472 
473  SanCovTraceConstCmpFunction[0] = M.getOrInsertFunction(
474  SanCovTraceConstCmp1, SanCovTraceCmpZeroExtAL, VoidTy, Int8Ty, Int8Ty);
475  SanCovTraceConstCmpFunction[1] = M.getOrInsertFunction(
476  SanCovTraceConstCmp2, SanCovTraceCmpZeroExtAL, VoidTy, Int16Ty, Int16Ty);
477  SanCovTraceConstCmpFunction[2] = M.getOrInsertFunction(
478  SanCovTraceConstCmp4, SanCovTraceCmpZeroExtAL, VoidTy, Int32Ty, Int32Ty);
479  SanCovTraceConstCmpFunction[3] =
480  M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty);
481 
482  // Loads.
483  SanCovLoadFunction[0] = M.getOrInsertFunction(SanCovLoad1, VoidTy, Int8PtrTy);
484  SanCovLoadFunction[1] =
485  M.getOrInsertFunction(SanCovLoad2, VoidTy, Int16PtrTy);
486  SanCovLoadFunction[2] =
487  M.getOrInsertFunction(SanCovLoad4, VoidTy, Int32PtrTy);
488  SanCovLoadFunction[3] =
489  M.getOrInsertFunction(SanCovLoad8, VoidTy, Int64PtrTy);
490  SanCovLoadFunction[4] =
491  M.getOrInsertFunction(SanCovLoad16, VoidTy, Int128PtrTy);
492  // Stores.
493  SanCovStoreFunction[0] =
494  M.getOrInsertFunction(SanCovStore1, VoidTy, Int8PtrTy);
495  SanCovStoreFunction[1] =
496  M.getOrInsertFunction(SanCovStore2, VoidTy, Int16PtrTy);
497  SanCovStoreFunction[2] =
498  M.getOrInsertFunction(SanCovStore4, VoidTy, Int32PtrTy);
499  SanCovStoreFunction[3] =
500  M.getOrInsertFunction(SanCovStore8, VoidTy, Int64PtrTy);
501  SanCovStoreFunction[4] =
502  M.getOrInsertFunction(SanCovStore16, VoidTy, Int128PtrTy);
503 
504  {
506  AL = AL.addParamAttribute(*C, 0, Attribute::ZExt);
507  SanCovTraceDivFunction[0] =
508  M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty());
509  }
510  SanCovTraceDivFunction[1] =
511  M.getOrInsertFunction(SanCovTraceDiv8, VoidTy, Int64Ty);
512  SanCovTraceGepFunction =
513  M.getOrInsertFunction(SanCovTraceGep, VoidTy, IntptrTy);
514  SanCovTraceSwitchFunction =
515  M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy);
516 
517  Constant *SanCovLowestStackConstant =
518  M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
519  SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
520  if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
521  C->emitError(StringRef("'") + SanCovLowestStackName +
522  "' should not be declared by the user");
523  return true;
524  }
525  SanCovLowestStack->setThreadLocalMode(
526  GlobalValue::ThreadLocalMode::InitialExecTLSModel);
527  if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
528  SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy));
529 
530  SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
531  SanCovTracePCGuard =
532  M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy);
533 
534  for (auto &F : M)
535  instrumentFunction(F, DTCallback, PDTCallback);
536 
537  Function *Ctor = nullptr;
538 
539  if (FunctionGuardArray)
540  Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName,
543  if (Function8bitCounterArray)
544  Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName,
547  if (FunctionBoolArray) {
548  Ctor = CreateInitCallsForSections(M, SanCovModuleCtorBoolFlagName,
549  SanCovBoolFlagInitName, Int1Ty,
551  }
552  if (Ctor && Options.PCTable) {
553  auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrTy);
555  M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy});
556  IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
557  IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
558  }
559  appendToUsed(M, GlobalsToAppendToUsed);
560  appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
561  return true;
562 }
563 
564 // True if block has successors and it dominates all of them.
565 static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
566  if (succ_empty(BB))
567  return false;
568 
569  return llvm::all_of(successors(BB), [&](const BasicBlock *SUCC) {
570  return DT->dominates(BB, SUCC);
571  });
572 }
573 
574 // True if block has predecessors and it postdominates all of them.
575 static bool isFullPostDominator(const BasicBlock *BB,
576  const PostDominatorTree *PDT) {
577  if (pred_empty(BB))
578  return false;
579 
580  return llvm::all_of(predecessors(BB), [&](const BasicBlock *PRED) {
581  return PDT->dominates(BB, PRED);
582  });
583 }
584 
585 static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
586  const DominatorTree *DT,
587  const PostDominatorTree *PDT,
589  // Don't insert coverage for blocks containing nothing but unreachable: we
590  // will never call __sanitizer_cov() for them, so counting them in
591  // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
592  // percentage. Also, unreachable instructions frequently have no debug
593  // locations.
594  if (isa<UnreachableInst>(BB->getFirstNonPHIOrDbgOrLifetime()))
595  return false;
596 
597  // Don't insert coverage into blocks without a valid insertion point
598  // (catchswitch blocks).
599  if (BB->getFirstInsertionPt() == BB->end())
600  return false;
601 
602  if (Options.NoPrune || &F.getEntryBlock() == BB)
603  return true;
604 
605  if (Options.CoverageType == SanitizerCoverageOptions::SCK_Function &&
606  &F.getEntryBlock() != BB)
607  return false;
608 
609  // Do not instrument full dominators, or full post-dominators with multiple
610  // predecessors.
611  return !isFullDominator(BB, DT)
612  && !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
613 }
614 
615 
616 // Returns true iff From->To is a backedge.
617 // A twist here is that we treat From->To as a backedge if
618 // * To dominates From or
619 // * To->UniqueSuccessor dominates From
621  const DominatorTree *DT) {
622  if (DT->dominates(To, From))
623  return true;
624  if (auto Next = To->getUniqueSuccessor())
625  if (DT->dominates(Next, From))
626  return true;
627  return false;
628 }
629 
630 // Prunes uninteresting Cmp instrumentation:
631 // * CMP instructions that feed into loop backedge branch.
632 //
633 // Note that Cmp pruning is controlled by the same flag as the
634 // BB pruning.
635 static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
637  if (!Options.NoPrune)
638  if (CMP->hasOneUse())
639  if (auto BR = dyn_cast<BranchInst>(CMP->user_back()))
640  for (BasicBlock *B : BR->successors())
641  if (IsBackEdge(BR->getParent(), B, DT))
642  return false;
643  return true;
644 }
645 
646 void ModuleSanitizerCoverage::instrumentFunction(
647  Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
648  if (F.empty())
649  return;
650  if (F.getName().find(".module_ctor") != std::string::npos)
651  return; // Should not instrument sanitizer init functions.
652  if (F.getName().startswith("__sanitizer_"))
653  return; // Don't instrument __sanitizer_* callbacks.
654  // Don't touch available_externally functions, their actual body is elewhere.
655  if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
656  return;
657  // Don't instrument MSVC CRT configuration helpers. They may run before normal
658  // initialization.
659  if (F.getName() == "__local_stdio_printf_options" ||
660  F.getName() == "__local_stdio_scanf_options")
661  return;
662  if (isa<UnreachableInst>(F.getEntryBlock().getTerminator()))
663  return;
664  // Don't instrument functions using SEH for now. Splitting basic blocks like
665  // we do for coverage breaks WinEHPrepare.
666  // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
667  if (F.hasPersonalityFn() &&
669  return;
670  if (Allowlist && !Allowlist->inSection("coverage", "fun", F.getName()))
671  return;
672  if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName()))
673  return;
674  if (F.hasFnAttribute(Attribute::NoSanitizeCoverage))
675  return;
676  if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
677  SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
679  SmallVector<BasicBlock *, 16> BlocksToInstrument;
680  SmallVector<Instruction *, 8> CmpTraceTargets;
681  SmallVector<Instruction *, 8> SwitchTraceTargets;
682  SmallVector<BinaryOperator *, 8> DivTraceTargets;
683  SmallVector<GetElementPtrInst *, 8> GepTraceTargets;
686 
687  const DominatorTree *DT = DTCallback(F);
688  const PostDominatorTree *PDT = PDTCallback(F);
689  bool IsLeafFunc = true;
690 
691  for (auto &BB : F) {
692  if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
693  BlocksToInstrument.push_back(&BB);
694  for (auto &Inst : BB) {
695  if (Options.IndirectCalls) {
696  CallBase *CB = dyn_cast<CallBase>(&Inst);
697  if (CB && !CB->getCalledFunction())
698  IndirCalls.push_back(&Inst);
699  }
700  if (Options.TraceCmp) {
701  if (ICmpInst *CMP = dyn_cast<ICmpInst>(&Inst))
702  if (IsInterestingCmp(CMP, DT, Options))
703  CmpTraceTargets.push_back(&Inst);
704  if (isa<SwitchInst>(&Inst))
705  SwitchTraceTargets.push_back(&Inst);
706  }
707  if (Options.TraceDiv)
708  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&Inst))
709  if (BO->getOpcode() == Instruction::SDiv ||
710  BO->getOpcode() == Instruction::UDiv)
711  DivTraceTargets.push_back(BO);
712  if (Options.TraceGep)
713  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&Inst))
714  GepTraceTargets.push_back(GEP);
715  if (Options.TraceLoads)
716  if (LoadInst *LI = dyn_cast<LoadInst>(&Inst))
717  Loads.push_back(LI);
718  if (Options.TraceStores)
719  if (StoreInst *SI = dyn_cast<StoreInst>(&Inst))
720  Stores.push_back(SI);
721  if (Options.StackDepth)
722  if (isa<InvokeInst>(Inst) ||
723  (isa<CallInst>(Inst) && !isa<IntrinsicInst>(Inst)))
724  IsLeafFunc = false;
725  }
726  }
727 
728  InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
729  InjectCoverageForIndirectCalls(F, IndirCalls);
730  InjectTraceForCmp(F, CmpTraceTargets);
731  InjectTraceForSwitch(F, SwitchTraceTargets);
732  InjectTraceForDiv(F, DivTraceTargets);
733  InjectTraceForGep(F, GepTraceTargets);
734  InjectTraceForLoadsAndStores(F, Loads, Stores);
735 }
736 
737 GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
738  size_t NumElements, Function &F, Type *Ty, const char *Section) {
739  ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
740  auto Array = new GlobalVariable(
741  *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
742  Constant::getNullValue(ArrayTy), "__sancov_gen_");
743 
744  if (TargetTriple.supportsCOMDAT() &&
745  (TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
746  if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
747  Array->setComdat(Comdat);
748  Array->setSection(getSectionName(Section));
749  Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
750 
751  // sancov_pcs parallels the other metadata section(s). Optimizers (e.g.
752  // GlobalOpt/ConstantMerge) may not discard sancov_pcs and the other
753  // section(s) as a unit, so we conservatively retain all unconditionally in
754  // the compiler.
755  //
756  // With comdat (COFF/ELF), the linker can guarantee the associated sections
757  // will be retained or discarded as a unit, so llvm.compiler.used is
758  // sufficient. Otherwise, conservatively make all of them retained by the
759  // linker.
760  if (Array->hasComdat())
761  GlobalsToAppendToCompilerUsed.push_back(Array);
762  else
763  GlobalsToAppendToUsed.push_back(Array);
764 
765  return Array;
766 }
767 
769 ModuleSanitizerCoverage::CreatePCArray(Function &F,
770  ArrayRef<BasicBlock *> AllBlocks) {
771  size_t N = AllBlocks.size();
772  assert(N);
774  IRBuilder<> IRB(&*F.getEntryBlock().getFirstInsertionPt());
775  for (size_t i = 0; i < N; i++) {
776  if (&F.getEntryBlock() == AllBlocks[i]) {
777  PCs.push_back((Constant *)IRB.CreatePointerCast(&F, IntptrPtrTy));
778  PCs.push_back((Constant *)IRB.CreateIntToPtr(
779  ConstantInt::get(IntptrTy, 1), IntptrPtrTy));
780  } else {
781  PCs.push_back((Constant *)IRB.CreatePointerCast(
782  BlockAddress::get(AllBlocks[i]), IntptrPtrTy));
783  PCs.push_back((Constant *)IRB.CreateIntToPtr(
784  ConstantInt::get(IntptrTy, 0), IntptrPtrTy));
785  }
786  }
787  auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, IntptrPtrTy,
789  PCArray->setInitializer(
790  ConstantArray::get(ArrayType::get(IntptrPtrTy, N * 2), PCs));
791  PCArray->setConstant(true);
792 
793  return PCArray;
794 }
795 
796 void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
797  Function &F, ArrayRef<BasicBlock *> AllBlocks) {
798  if (Options.TracePCGuard)
799  FunctionGuardArray = CreateFunctionLocalArrayInSection(
800  AllBlocks.size(), F, Int32Ty, SanCovGuardsSectionName);
801 
802  if (Options.Inline8bitCounters)
803  Function8bitCounterArray = CreateFunctionLocalArrayInSection(
804  AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName);
805  if (Options.InlineBoolFlag)
806  FunctionBoolArray = CreateFunctionLocalArrayInSection(
807  AllBlocks.size(), F, Int1Ty, SanCovBoolFlagSectionName);
808 
809  if (Options.PCTable)
810  FunctionPCsArray = CreatePCArray(F, AllBlocks);
811 }
812 
813 bool ModuleSanitizerCoverage::InjectCoverage(Function &F,
814  ArrayRef<BasicBlock *> AllBlocks,
815  bool IsLeafFunc) {
816  if (AllBlocks.empty()) return false;
817  CreateFunctionLocalArrays(F, AllBlocks);
818  for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
819  InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
820  return true;
821 }
822 
823 // On every indirect call we call a run-time function
824 // __sanitizer_cov_indir_call* with two parameters:
825 // - callee address,
826 // - global cache array that contains CacheSize pointers (zero-initialized).
827 // The cache is used to speed up recording the caller-callee pairs.
828 // The address of the caller is passed implicitly via caller PC.
829 // CacheSize is encoded in the name of the run-time function.
830 void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
831  Function &F, ArrayRef<Instruction *> IndirCalls) {
832  if (IndirCalls.empty())
833  return;
834  assert(Options.TracePC || Options.TracePCGuard ||
835  Options.Inline8bitCounters || Options.InlineBoolFlag);
836  for (auto I : IndirCalls) {
837  IRBuilder<> IRB(I);
838  CallBase &CB = cast<CallBase>(*I);
839  Value *Callee = CB.getCalledOperand();
840  if (isa<InlineAsm>(Callee))
841  continue;
842  IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
843  }
844 }
845 
846 // For every switch statement we insert a call:
847 // __sanitizer_cov_trace_switch(CondValue,
848 // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
849 
850 void ModuleSanitizerCoverage::InjectTraceForSwitch(
851  Function &, ArrayRef<Instruction *> SwitchTraceTargets) {
852  for (auto I : SwitchTraceTargets) {
853  if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
854  IRBuilder<> IRB(I);
855  SmallVector<Constant *, 16> Initializers;
856  Value *Cond = SI->getCondition();
857  if (Cond->getType()->getScalarSizeInBits() >
858  Int64Ty->getScalarSizeInBits())
859  continue;
860  Initializers.push_back(ConstantInt::get(Int64Ty, SI->getNumCases()));
861  Initializers.push_back(
862  ConstantInt::get(Int64Ty, Cond->getType()->getScalarSizeInBits()));
863  if (Cond->getType()->getScalarSizeInBits() <
864  Int64Ty->getScalarSizeInBits())
865  Cond = IRB.CreateIntCast(Cond, Int64Ty, false);
866  for (auto It : SI->cases()) {
867  Constant *C = It.getCaseValue();
868  if (C->getType()->getScalarSizeInBits() <
869  Int64Ty->getScalarSizeInBits())
870  C = ConstantExpr::getCast(CastInst::ZExt, It.getCaseValue(), Int64Ty);
871  Initializers.push_back(C);
872  }
873  llvm::sort(drop_begin(Initializers, 2),
874  [](const Constant *A, const Constant *B) {
875  return cast<ConstantInt>(A)->getLimitedValue() <
876  cast<ConstantInt>(B)->getLimitedValue();
877  });
878  ArrayType *ArrayOfInt64Ty = ArrayType::get(Int64Ty, Initializers.size());
879  GlobalVariable *GV = new GlobalVariable(
880  *CurModule, ArrayOfInt64Ty, false, GlobalVariable::InternalLinkage,
881  ConstantArray::get(ArrayOfInt64Ty, Initializers),
882  "__sancov_gen_cov_switch_values");
883  IRB.CreateCall(SanCovTraceSwitchFunction,
884  {Cond, IRB.CreatePointerCast(GV, Int64PtrTy)});
885  }
886  }
887 }
888 
889 void ModuleSanitizerCoverage::InjectTraceForDiv(
890  Function &, ArrayRef<BinaryOperator *> DivTraceTargets) {
891  for (auto BO : DivTraceTargets) {
892  IRBuilder<> IRB(BO);
893  Value *A1 = BO->getOperand(1);
894  if (isa<ConstantInt>(A1)) continue;
895  if (!A1->getType()->isIntegerTy())
896  continue;
897  uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType());
898  int CallbackIdx = TypeSize == 32 ? 0 :
899  TypeSize == 64 ? 1 : -1;
900  if (CallbackIdx < 0) continue;
901  auto Ty = Type::getIntNTy(*C, TypeSize);
902  IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
903  {IRB.CreateIntCast(A1, Ty, true)});
904  }
905 }
906 
907 void ModuleSanitizerCoverage::InjectTraceForGep(
908  Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) {
909  for (auto GEP : GepTraceTargets) {
910  IRBuilder<> IRB(GEP);
911  for (Use &Idx : GEP->indices())
912  if (!isa<ConstantInt>(Idx) && Idx->getType()->isIntegerTy())
913  IRB.CreateCall(SanCovTraceGepFunction,
914  {IRB.CreateIntCast(Idx, IntptrTy, true)});
915  }
916 }
917 
918 void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
920  auto CallbackIdx = [&](const Value *Ptr) -> int {
921  auto ElementTy = cast<PointerType>(Ptr->getType())->getElementType();
922  uint64_t TypeSize = DL->getTypeStoreSizeInBits(ElementTy);
923  return TypeSize == 8 ? 0
924  : TypeSize == 16 ? 1
925  : TypeSize == 32 ? 2
926  : TypeSize == 64 ? 3
927  : TypeSize == 128 ? 4
928  : -1;
929  };
930  Type *PointerType[5] = {Int8PtrTy, Int16PtrTy, Int32PtrTy, Int64PtrTy,
931  Int128PtrTy};
932  for (auto LI : Loads) {
933  IRBuilder<> IRB(LI);
934  auto Ptr = LI->getPointerOperand();
935  int Idx = CallbackIdx(Ptr);
936  if (Idx < 0)
937  continue;
938  IRB.CreateCall(SanCovLoadFunction[Idx],
939  IRB.CreatePointerCast(Ptr, PointerType[Idx]));
940  }
941  for (auto SI : Stores) {
942  IRBuilder<> IRB(SI);
943  auto Ptr = SI->getPointerOperand();
944  int Idx = CallbackIdx(Ptr);
945  if (Idx < 0)
946  continue;
947  IRB.CreateCall(SanCovStoreFunction[Idx],
948  IRB.CreatePointerCast(Ptr, PointerType[Idx]));
949  }
950 }
951 
952 void ModuleSanitizerCoverage::InjectTraceForCmp(
953  Function &, ArrayRef<Instruction *> CmpTraceTargets) {
954  for (auto I : CmpTraceTargets) {
955  if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
956  IRBuilder<> IRB(ICMP);
957  Value *A0 = ICMP->getOperand(0);
958  Value *A1 = ICMP->getOperand(1);
959  if (!A0->getType()->isIntegerTy())
960  continue;
961  uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
962  int CallbackIdx = TypeSize == 8 ? 0 :
963  TypeSize == 16 ? 1 :
964  TypeSize == 32 ? 2 :
965  TypeSize == 64 ? 3 : -1;
966  if (CallbackIdx < 0) continue;
967  // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
968  auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
969  bool FirstIsConst = isa<ConstantInt>(A0);
970  bool SecondIsConst = isa<ConstantInt>(A1);
971  // If both are const, then we don't need such a comparison.
972  if (FirstIsConst && SecondIsConst) continue;
973  // If only one is const, then make it the first callback argument.
974  if (FirstIsConst || SecondIsConst) {
975  CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
976  if (SecondIsConst)
977  std::swap(A0, A1);
978  }
979 
980  auto Ty = Type::getIntNTy(*C, TypeSize);
981  IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty, true),
982  IRB.CreateIntCast(A1, Ty, true)});
983  }
984  }
985 }
986 
987 void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
988  size_t Idx,
989  bool IsLeafFunc) {
990  BasicBlock::iterator IP = BB.getFirstInsertionPt();
991  bool IsEntryBB = &BB == &F.getEntryBlock();
992  DebugLoc EntryLoc;
993  if (IsEntryBB) {
994  if (auto SP = F.getSubprogram())
995  EntryLoc = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
996  // Keep static allocas and llvm.localescape calls in the entry block. Even
997  // if we aren't splitting the block, it's nice for allocas to be before
998  // calls.
1000  } else {
1001  EntryLoc = IP->getDebugLoc();
1002  if (!EntryLoc)
1003  if (auto *SP = F.getSubprogram())
1004  EntryLoc = DILocation::get(SP->getContext(), 0, 0, SP);
1005  }
1006 
1007  IRBuilder<> IRB(&*IP);
1008  IRB.SetCurrentDebugLocation(EntryLoc);
1009  if (Options.TracePC) {
1010  IRB.CreateCall(SanCovTracePC)
1011  ->setCannotMerge(); // gets the PC using GET_CALLER_PC.
1012  }
1013  if (Options.TracePCGuard) {
1014  auto GuardPtr = IRB.CreateIntToPtr(
1015  IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
1016  ConstantInt::get(IntptrTy, Idx * 4)),
1017  Int32PtrTy);
1018  IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
1019  }
1020  if (Options.Inline8bitCounters) {
1021  auto CounterPtr = IRB.CreateGEP(
1022  Function8bitCounterArray->getValueType(), Function8bitCounterArray,
1023  {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
1024  auto Load = IRB.CreateLoad(Int8Ty, CounterPtr);
1025  auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
1026  auto Store = IRB.CreateStore(Inc, CounterPtr);
1027  SetNoSanitizeMetadata(Load);
1028  SetNoSanitizeMetadata(Store);
1029  }
1030  if (Options.InlineBoolFlag) {
1031  auto FlagPtr = IRB.CreateGEP(
1032  FunctionBoolArray->getValueType(), FunctionBoolArray,
1033  {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
1034  auto Load = IRB.CreateLoad(Int1Ty, FlagPtr);
1035  auto ThenTerm =
1036  SplitBlockAndInsertIfThen(IRB.CreateIsNull(Load), &*IP, false);
1037  IRBuilder<> ThenIRB(ThenTerm);
1038  auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
1039  SetNoSanitizeMetadata(Load);
1040  SetNoSanitizeMetadata(Store);
1041  }
1042  if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
1043  // Check stack depth. If it's the deepest so far, record it.
1044  Module *M = F.getParent();
1045  Function *GetFrameAddr = Intrinsic::getDeclaration(
1046  M, Intrinsic::frameaddress,
1047  IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace()));
1048  auto FrameAddrPtr =
1049  IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)});
1050  auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
1051  auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack);
1052  auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
1053  auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false);
1054  IRBuilder<> ThenIRB(ThenTerm);
1055  auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
1056  SetNoSanitizeMetadata(LowestStack);
1057  SetNoSanitizeMetadata(Store);
1058  }
1059 }
1060 
1061 std::string
1062 ModuleSanitizerCoverage::getSectionName(const std::string &Section) const {
1063  if (TargetTriple.isOSBinFormatCOFF()) {
1065  return ".SCOV$CM";
1067  return ".SCOV$BM";
1069  return ".SCOVP$M";
1070  return ".SCOV$GM"; // For SanCovGuardsSectionName.
1071  }
1072  if (TargetTriple.isOSBinFormatMachO())
1073  return "__DATA,__" + Section;
1074  return "__" + Section;
1075 }
1076 
1077 std::string
1078 ModuleSanitizerCoverage::getSectionStart(const std::string &Section) const {
1079  if (TargetTriple.isOSBinFormatMachO())
1080  return "\1section$start$__DATA$__" + Section;
1081  return "__start___" + Section;
1082 }
1083 
1084 std::string
1085 ModuleSanitizerCoverage::getSectionEnd(const std::string &Section) const {
1086  if (TargetTriple.isOSBinFormatMachO())
1087  return "\1section$end$__DATA$__" + Section;
1088  return "__stop___" + Section;
1089 }
1090 
1092 INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov",
1093  "Pass for instrumenting coverage on functions", false,
1094  false)
1097 INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov",
1098  "Pass for instrumenting coverage on functions", false,
1099  false)
1102  const std::vector<std::string> &AllowlistFiles,
1103  const std::vector<std::string> &BlocklistFiles) {
1104  return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles,
1105  BlocklistFiles);
1106 }
i
i
Definition: README.txt:29
ClInline8bitCounters
static cl::opt< bool > ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters", cl::desc("increments 8-bit counter for every edge"), cl::Hidden, cl::init(false))
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
llvm::SpecialCaseList
Definition: SpecialCaseList.h:69
Instrumentation.h
llvm::isAsynchronousEHPersonality
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
Definition: EHPersonalities.h:50
Int32Ty
IntegerType * Int32Ty
Definition: NVVMIntrRange.cpp:67
llvm::predecessors
pred_range predecessors(BasicBlock *BB)
Definition: CFG.h:127
llvm::PrepareToSplitEntryBlock
BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB, BasicBlock::iterator IP)
Instrumentation passes often insert conditional checks into entry blocks.
Definition: Instrumentation.cpp:41
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::Type::getInt1Ty
static IntegerType * getInt1Ty(LLVMContext &C)
Definition: Type.cpp:238
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::AArch64CC::AL
@ AL
Definition: AArch64BaseInfo.h:269
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:266
SanCovTraceCmp2
const char SanCovTraceCmp2[]
Definition: SanitizerCoverage.cpp:51
ClGEPTracing
static cl::opt< bool > ClGEPTracing("sanitizer-coverage-trace-geps", cl::desc("Tracing of GEP instructions"), cl::Hidden, cl::init(false))
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
SanCovTracePCName
const char SanCovTracePCName[]
Definition: SanitizerCoverage.cpp:49
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1384
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:90
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::SanitizerCoverageOptions
Definition: Instrumentation.h:152
IntrinsicInst.h
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:783
llvm::SystemZISD::ICMP
@ ICMP
Definition: SystemZISelLowering.h:55
functions
Pass for instrumenting coverage on functions
Definition: SanitizerCoverage.cpp:1098
llvm::GlobalValue::HiddenVisibility
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:64
llvm::Function
Definition: Function.h:62
ClDIVTracing
static cl::opt< bool > ClDIVTracing("sanitizer-coverage-trace-divs", cl::desc("Tracing of DIV instructions"), cl::Hidden, cl::init(false))
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
InlineAsm.h
llvm::AttributeList::addParamAttribute
LLVM_NODISCARD AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const
Add an argument attribute to the list.
Definition: Attributes.h:532
llvm::Function::getEntryBlock
const BasicBlock & getEntryBlock() const
Definition: Function.h:707
llvm::IRBuilder<>
SanCov8bitCountersInitName
const char SanCov8bitCountersInitName[]
Definition: SanitizerCoverage.cpp:81
llvm::GlobalVariable
Definition: GlobalVariable.h:40
SanCovTraceGep
const char SanCovTraceGep[]
Definition: SanitizerCoverage.cpp:70
SanCovModuleCtorBoolFlagName
const char SanCovModuleCtorBoolFlagName[]
Definition: SanitizerCoverage.cpp:76
llvm::DominatorTree
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:151
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::AttributeList
Definition: Attributes.h:398
EHPersonalities.h
SanCovModuleCtor8bitCountersName
const char SanCovModuleCtor8bitCountersName[]
Definition: SanitizerCoverage.cpp:74
SanCovStore16
const char SanCovStore16[]
Definition: SanitizerCoverage.cpp:67
llvm::msgpack::Type::Array
@ Array
ClInlineBoolFlag
static cl::opt< bool > ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag", cl::desc("sets a boolean flag for every edge"), cl::Hidden, cl::init(false))
ClCreatePCTable
static cl::opt< bool > ClCreatePCTable("sanitizer-coverage-pc-table", cl::desc("create a static PC table"), cl::Hidden, cl::init(false))
llvm::GlobalValue::LinkageTypes
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition: GlobalValue.h:47
llvm::ArrayType
Class to represent array types.
Definition: DerivedTypes.h:357
llvm::successors
succ_range successors(Instruction *I)
Definition: CFG.h:262
llvm::succ_empty
bool succ_empty(const Instruction *I)
Definition: CFG.h:256
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
Definition: Type.cpp:239
ClLoadTracing
static cl::opt< bool > ClLoadTracing("sanitizer-coverage-trace-loads", cl::desc("Tracing of load instructions"), cl::Hidden, cl::init(false))
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:241
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
SanCovLowestStackName
const char SanCovLowestStackName[]
Definition: SanitizerCoverage.cpp:90
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1233
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BasicBlock::getUniqueSuccessor
const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
Definition: BasicBlock.cpp:306
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:78
llvm::SanitizerCoverageOptions::SCK_Edge
@ SCK_Edge
Definition: Instrumentation.h:157
llvm::classifyEHPersonality
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Definition: EHPersonalities.cpp:21
llvm::DominatorTree::dominates
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Definition: Dominators.cpp:115
SanCovLoad2
const char SanCovLoad2[]
Definition: SanitizerCoverage.cpp:59
CommandLine.h
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1581
llvm::SanitizerCoverageOptions::CoverageType
enum llvm::SanitizerCoverageOptions::Type CoverageType
SanCovBoolFlagInitName
const char SanCovBoolFlagInitName[]
Definition: SanitizerCoverage.cpp:82
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
PostDominators.h
SanCovTraceCmp4
const char SanCovTraceCmp4[]
Definition: SanitizerCoverage.cpp:52
SanCovStore4
const char SanCovStore4[]
Definition: SanitizerCoverage.cpp:65
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1398
MAM
ModuleAnalysisManager MAM
Definition: PassBuilderBindings.cpp:61
llvm::ModuleSanitizerCoveragePass::run
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Definition: SanitizerCoverage.cpp:337
llvm::PostDominatorTreeWrapperPass
Definition: PostDominators.h:73
SanCovPCsSectionName
const char SanCovPCsSectionName[]
Definition: SanitizerCoverage.cpp:88
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
isFullPostDominator
static bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT)
Definition: SanitizerCoverage.cpp:575
SanCovLoad4
const char SanCovLoad4[]
Definition: SanitizerCoverage.cpp:60
SanCovTraceDiv8
const char SanCovTraceDiv8[]
Definition: SanitizerCoverage.cpp:69
IP
Definition: NVPTXLowerArgs.cpp:166
llvm::CriticalEdgeSplittingOptions
Option class for critical edge splitting.
Definition: BasicBlockUtils.h:143
false
Definition: StackSlotColoring.cpp:142
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::Constant::getAllOnesValue
static Constant * getAllOnesValue(Type *Ty)
Definition: Constants.cpp:405
llvm::Instruction
Definition: Instruction.h:45
ClPruneBlocks
static cl::opt< bool > ClPruneBlocks("sanitizer-coverage-prune-blocks", cl::desc("Reduce the number of instrumented blocks"), cl::Hidden, cl::init(true))
llvm::DominatorTreeWrapperPass
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:287
MDBuilder.h
llvm::appendToCompilerUsed
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
Definition: ModuleUtils.cpp:110
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::initializeModuleSanitizerCoverageLegacyPassPass
void initializeModuleSanitizerCoverageLegacyPassPass(PassRegistry &)
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:925
SanCovGuardsSectionName
const char SanCovGuardsSectionName[]
Definition: SanitizerCoverage.cpp:85
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
llvm::Comdat
Definition: Comdat.h:31
llvm::SanitizerCoverageOptions::SCK_BB
@ SCK_BB
Definition: Instrumentation.h:156
SanCovTraceConstCmp8
const char SanCovTraceConstCmp8[]
Definition: SanitizerCoverage.cpp:57
shouldInstrumentBlock
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, const DominatorTree *DT, const PostDominatorTree *PDT, const SanitizerCoverageOptions &Options)
Definition: SanitizerCoverage.cpp:585
llvm::None
const NoneType None
Definition: None.h:23
SanCovTraceSwitchName
const char SanCovTraceSwitchName[]
Definition: SanitizerCoverage.cpp:71
Type.h
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
CFG.h
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:190
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:168
llvm::cl::opt
Definition: CommandLine.h:1432
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:304
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::vfs::getRealFileSystem
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
Definition: VirtualFileSystem.cpp:354
llvm::PointerType::getUnqual
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:651
llvm::createSanitizerCtorAndInitFunctions
std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function, and calls sanitizer's init function from it.
Definition: ModuleUtils.cpp:136
llvm::ICmpInst
This instruction compares its operands according to the predicate given to the constructor.
Definition: Instructions.h:1203
uint64_t
llvm::SPII::Store
@ Store
Definition: SparcInstrInfo.h:33
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
SanCovBoolFlagSectionName
const char SanCovBoolFlagSectionName[]
Definition: SanitizerCoverage.cpp:87
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
sancov
sancov
Definition: SanitizerCoverage.cpp:1097
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::declareSanitizerInitFunction
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes)
Definition: ModuleUtils.cpp:115
DebugInfo.h
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::GlobalObject::setComdat
void setComdat(Comdat *C)
Definition: GlobalObject.h:125
ClCoverageLevel
static cl::opt< int > ClCoverageLevel("sanitizer-coverage-level", cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, " "3: all blocks and critical edges"), cl::Hidden, cl::init(0))
SanCovStore8
const char SanCovStore8[]
Definition: SanitizerCoverage.cpp:66
llvm::GetElementPtrInst
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:928
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
llvm::appendToUsed
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
Definition: ModuleUtils.cpp:106
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:632
llvm::GlobalValue::setLinkage
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:460
ArrayRef.h
llvm::SpecialCaseList::createOrDie
static std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
Definition: SpecialCaseList.cpp:91
IRBuilder.h
ClTracePC
static cl::opt< bool > ClTracePC("sanitizer-coverage-trace-pc", cl::desc("Experimental pc tracing"), cl::Hidden, cl::init(false))
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SanCovTraceCmp1
const char SanCovTraceCmp1[]
Definition: SanitizerCoverage.cpp:50
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
SI
StandardInstrumentations SI(Debug, VerifyEach)
SanCovTracePCGuardInitName
const char SanCovTracePCGuardInitName[]
Definition: SanitizerCoverage.cpp:80
llvm::ConstantExpr::getCast
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
Definition: Constants.cpp:1988
SanCovModuleCtorTracePcGuardName
const char SanCovModuleCtorTracePcGuardName[]
Definition: SanitizerCoverage.cpp:72
IsInterestingCmp
static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, const SanitizerCoverageOptions &Options)
Definition: SanitizerCoverage.cpp:635
llvm::ArrayType::get
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:640
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
ClCMPTracing
static cl::opt< bool > ClCMPTracing("sanitizer-coverage-trace-compares", cl::desc("Tracing of CMP and similar instructions"), cl::Hidden, cl::init(false))
Mangler.h
SanCovTracePCIndirName
const char SanCovTracePCIndirName[]
Definition: SanitizerCoverage.cpp:48
ClStoreTracing
static cl::opt< bool > ClStoreTracing("sanitizer-coverage-trace-stores", cl::desc("Tracing of store instructions"), cl::Hidden, cl::init(false))
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::BinaryOperator
Definition: InstrTypes.h:190
SanCovLoad1
const char SanCovLoad1[]
Definition: SanitizerCoverage.cpp:58
DataLayout.h
Cond
SmallVector< MachineOperand, 4 > Cond
Definition: BasicBlockSections.cpp:179
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
SanCovTracePCGuardName
const char SanCovTracePCGuardName[]
Definition: SanitizerCoverage.cpp:79
llvm::SanitizerCoverageOptions::SCK_Function
@ SCK_Function
Definition: Instrumentation.h:155
SanitizerCoverage.h
llvm::PostDominatorTree
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
Definition: PostDominators.h:28
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::GlobalValue::WeakODRLinkage
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:53
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::pred_empty
bool pred_empty(const BasicBlock *BB)
Definition: CFG.h:119
ClTracePCGuard
static cl::opt< bool > ClTracePCGuard("sanitizer-coverage-trace-pc-guard", cl::desc("pc tracing with a guard"), cl::Hidden, cl::init(false))
llvm::GlobalValue::AvailableExternallyLinkage
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:49
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
for
this could be done in SelectionDAGISel along with other special for
Definition: README.txt:104
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:175
llvm::BasicBlock::getTerminator
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:152
VirtualFileSystem.h
SanCovLoad16
const char SanCovLoad16[]
Definition: SanitizerCoverage.cpp:62
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:206
SanCovTraceConstCmp1
const char SanCovTraceConstCmp1[]
Definition: SanitizerCoverage.cpp:54
Constant.h
llvm::ConstantInt::getTrue
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:873
std
Definition: BitVector.h:838
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:348
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition: Type.cpp:245
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
llvm::ISD::BR
@ BR
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:937
GlobalVariable.h
llvm::TypeSize
Definition: TypeSize.h:416
llvm::getOrCreateFunctionComdat
Comdat * getOrCreateFunctionComdat(Function &F, Triple &T)
Definition: Instrumentation.cpp:76
Function.h
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1522
SpecialCaseList.h
llvm::getUniqueModuleId
std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
Definition: ModuleUtils.cpp:244
llvm::ConstantArray::get
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1288
isFullDominator
static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT)
Definition: SanitizerCoverage.cpp:565
llvm::SanitizerCoverageOptions::SCK_None
@ SCK_None
Definition: Instrumentation.h:154
llvm::CallBase::getCalledOperand
Value * getCalledOperand() const
Definition: InstrTypes.h:1391
SanCovTraceConstCmp4
const char SanCovTraceConstCmp4[]
Definition: SanitizerCoverage.cpp:56
SanCovTraceCmp8
const char SanCovTraceCmp8[]
Definition: SanitizerCoverage.cpp:53
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::DominatorTreeAnalysis
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:252
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:224
llvm::SplitAllCriticalEdges
unsigned SplitAllCriticalEdges(Function &F, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions())
Loop over all of the edges in the CFG, breaking critical edges as they are found.
Definition: BasicBlockUtils.cpp:765
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
llvm::GlobalValue::PrivateLinkage
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:56
SmallVector.h
Dominators.h
llvm::ARCISD::CMP
@ CMP
Definition: ARCISelLowering.h:40
ModuleUtils.h
N
#define N
llvm::BlockAddress::get
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
Definition: Constants.cpp:1834
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
SanCovTraceDiv4
const char SanCovTraceDiv4[]
Definition: SanitizerCoverage.cpp:68
SanCtorAndDtorPriority
static const uint64_t SanCtorAndDtorPriority
Definition: SanitizerCoverage.cpp:77
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
SanCovTraceConstCmp2
const char SanCovTraceConstCmp2[]
Definition: SanitizerCoverage.cpp:55
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1176
llvm::Type::getInt16Ty
static IntegerType * getInt16Ty(LLVMContext &C)
Definition: Type.cpp:240
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
SanCovPCsInitName
const char SanCovPCsInitName[]
Definition: SanitizerCoverage.cpp:83
llvm::InnerAnalysisManagerProxy
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:940
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:172
llvm::PostDominatorTreeAnalysis
Analysis pass which computes a PostDominatorTree.
Definition: PostDominators.h:47
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
LLVMContext.h
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::SwitchInst
Multiway switch.
Definition: Instructions.h:3245
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::SplitBlockAndInsertIfThen
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights, DominatorTree *DT, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
Definition: BasicBlockUtils.cpp:1439
llvm::appendToGlobalCtors
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
Definition: ModuleUtils.cpp:66
llvm::cl::desc
Definition: CommandLine.h:412
llvm::SanitizerCoverageOptions::IndirectCalls
bool IndirectCalls
Definition: Instrumentation.h:159
llvm::GlobalValue::ExternalWeakLinkage
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition: GlobalValue.h:57
raw_ostream.h
SanCovStore2
const char SanCovStore2[]
Definition: SanitizerCoverage.cpp:64
BasicBlockUtils.h
llvm::PostDominatorTree::dominates
bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
Definition: PostDominators.cpp:54
llvm::GlobalValue::setVisibility
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:235
SanCovStore1
const char SanCovStore1[]
Definition: SanitizerCoverage.cpp:63
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
IsBackEdge
static bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree *DT)
Definition: SanitizerCoverage.cpp:620
Debug.h
SanCovLoad8
const char SanCovLoad8[]
Definition: SanitizerCoverage.cpp:61
llvm::createModuleSanitizerCoverageLegacyPassPass
ModulePass * createModuleSanitizerCoverageLegacyPassPass(const SanitizerCoverageOptions &Options=SanitizerCoverageOptions(), const std::vector< std::string > &AllowlistFiles=std::vector< std::string >(), const std::vector< std::string > &BlocklistFiles=std::vector< std::string >())
Definition: SanitizerCoverage.cpp:1100
SanCovCountersSectionName
const char SanCovCountersSectionName[]
Definition: SanitizerCoverage.cpp:86
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
ClStackDepth
static cl::opt< bool > ClStackDepth("sanitizer-coverage-stack-depth", cl::desc("max stack depth tracing"), cl::Hidden, cl::init(false))