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 13 #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" 14 #include "llvm/ADT/ArrayRef.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/Analysis/GlobalsModRef.h" 17 #include "llvm/Analysis/PostDominators.h" 18 #include "llvm/IR/Constant.h" 19 #include "llvm/IR/Constants.h" 20 #include "llvm/IR/DataLayout.h" 21 #include "llvm/IR/Dominators.h" 22 #include "llvm/IR/EHPersonalities.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/IR/GlobalVariable.h" 25 #include "llvm/IR/IRBuilder.h" 26 #include "llvm/IR/IntrinsicInst.h" 27 #include "llvm/IR/Intrinsics.h" 28 #include "llvm/IR/LLVMContext.h" 29 #include "llvm/IR/MDBuilder.h" 30 #include "llvm/IR/Module.h" 31 #include "llvm/IR/Type.h" 32 #include "llvm/IR/ValueSymbolTable.h" 33 #include "llvm/InitializePasses.h" 34 #include "llvm/Support/CommandLine.h" 35 #include "llvm/Support/SpecialCaseList.h" 36 #include "llvm/Support/VirtualFileSystem.h" 37 #include "llvm/TargetParser/Triple.h" 38 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 39 #include "llvm/Transforms/Utils/ModuleUtils.h" 40 41 using namespace llvm; 42 43 #define DEBUG_TYPE "sancov" 44 45 const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir"; 46 const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc"; 47 const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1"; 48 const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2"; 49 const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4"; 50 const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8"; 51 const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1"; 52 const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2"; 53 const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4"; 54 const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8"; 55 const char SanCovLoad1[] = "__sanitizer_cov_load1"; 56 const char SanCovLoad2[] = "__sanitizer_cov_load2"; 57 const char SanCovLoad4[] = "__sanitizer_cov_load4"; 58 const char SanCovLoad8[] = "__sanitizer_cov_load8"; 59 const char SanCovLoad16[] = "__sanitizer_cov_load16"; 60 const char SanCovStore1[] = "__sanitizer_cov_store1"; 61 const char SanCovStore2[] = "__sanitizer_cov_store2"; 62 const char SanCovStore4[] = "__sanitizer_cov_store4"; 63 const char SanCovStore8[] = "__sanitizer_cov_store8"; 64 const char SanCovStore16[] = "__sanitizer_cov_store16"; 65 const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4"; 66 const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8"; 67 const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep"; 68 const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch"; 69 const char SanCovModuleCtorTracePcGuardName[] = 70 "sancov.module_ctor_trace_pc_guard"; 71 const char SanCovModuleCtor8bitCountersName[] = 72 "sancov.module_ctor_8bit_counters"; 73 const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag"; 74 static const uint64_t SanCtorAndDtorPriority = 2; 75 76 const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard"; 77 const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init"; 78 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init"; 79 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init"; 80 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init"; 81 const char SanCovCFsInitName[] = "__sanitizer_cov_cfs_init"; 82 83 const char SanCovGuardsSectionName[] = "sancov_guards"; 84 const char SanCovCountersSectionName[] = "sancov_cntrs"; 85 const char SanCovBoolFlagSectionName[] = "sancov_bools"; 86 const char SanCovPCsSectionName[] = "sancov_pcs"; 87 const char SanCovCFsSectionName[] = "sancov_cfs"; 88 const char SanCovCallbackGateSectionName[] = "sancov_gate"; 89 90 const char SanCovLowestStackName[] = "__sancov_lowest_stack"; 91 const char SanCovCallbackGateName[] = "__sancov_should_track"; 92 93 static cl::opt<int> ClCoverageLevel( 94 "sanitizer-coverage-level", 95 cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, " 96 "3: all blocks and critical edges"), 97 cl::Hidden); 98 99 static cl::opt<bool> ClTracePC("sanitizer-coverage-trace-pc", 100 cl::desc("Experimental pc tracing"), cl::Hidden); 101 102 static cl::opt<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard", 103 cl::desc("pc tracing with a guard"), 104 cl::Hidden); 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); 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); 120 121 static cl::opt<bool> 122 ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag", 123 cl::desc("sets a boolean flag for every edge"), 124 cl::Hidden); 125 126 static cl::opt<bool> 127 ClCMPTracing("sanitizer-coverage-trace-compares", 128 cl::desc("Tracing of CMP and similar instructions"), 129 cl::Hidden); 130 131 static cl::opt<bool> ClDIVTracing("sanitizer-coverage-trace-divs", 132 cl::desc("Tracing of DIV instructions"), 133 cl::Hidden); 134 135 static cl::opt<bool> ClLoadTracing("sanitizer-coverage-trace-loads", 136 cl::desc("Tracing of load instructions"), 137 cl::Hidden); 138 139 static cl::opt<bool> ClStoreTracing("sanitizer-coverage-trace-stores", 140 cl::desc("Tracing of store instructions"), 141 cl::Hidden); 142 143 static cl::opt<bool> ClGEPTracing("sanitizer-coverage-trace-geps", 144 cl::desc("Tracing of GEP instructions"), 145 cl::Hidden); 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); 155 156 static cl::opt<bool> 157 ClCollectCF("sanitizer-coverage-control-flow", 158 cl::desc("collect control flow for each function"), cl::Hidden); 159 160 static cl::opt<bool> ClGatedCallbacks( 161 "sanitizer-coverage-gated-trace-callbacks", 162 cl::desc("Gate the invocation of the tracing callbacks on a global " 163 "variable. Currently only supported for trace-pc-guard."), 164 cl::Hidden, cl::init(false)); 165 166 namespace { 167 168 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) { 169 SanitizerCoverageOptions Res; 170 switch (LegacyCoverageLevel) { 171 case 0: 172 Res.CoverageType = SanitizerCoverageOptions::SCK_None; 173 break; 174 case 1: 175 Res.CoverageType = SanitizerCoverageOptions::SCK_Function; 176 break; 177 case 2: 178 Res.CoverageType = SanitizerCoverageOptions::SCK_BB; 179 break; 180 case 3: 181 Res.CoverageType = SanitizerCoverageOptions::SCK_Edge; 182 break; 183 case 4: 184 Res.CoverageType = SanitizerCoverageOptions::SCK_Edge; 185 Res.IndirectCalls = true; 186 break; 187 } 188 return Res; 189 } 190 191 SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) { 192 // Sets CoverageType and IndirectCalls. 193 SanitizerCoverageOptions CLOpts = getOptions(ClCoverageLevel); 194 Options.CoverageType = std::max(Options.CoverageType, CLOpts.CoverageType); 195 Options.IndirectCalls |= CLOpts.IndirectCalls; 196 Options.TraceCmp |= ClCMPTracing; 197 Options.TraceDiv |= ClDIVTracing; 198 Options.TraceGep |= ClGEPTracing; 199 Options.TracePC |= ClTracePC; 200 Options.TracePCGuard |= ClTracePCGuard; 201 Options.Inline8bitCounters |= ClInline8bitCounters; 202 Options.InlineBoolFlag |= ClInlineBoolFlag; 203 Options.PCTable |= ClCreatePCTable; 204 Options.NoPrune |= !ClPruneBlocks; 205 Options.StackDepth |= ClStackDepth; 206 Options.TraceLoads |= ClLoadTracing; 207 Options.TraceStores |= ClStoreTracing; 208 Options.GatedCallbacks |= ClGatedCallbacks; 209 if (!Options.TracePCGuard && !Options.TracePC && 210 !Options.Inline8bitCounters && !Options.StackDepth && 211 !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores) 212 Options.TracePCGuard = true; // TracePCGuard is default. 213 Options.CollectControlFlow |= ClCollectCF; 214 return Options; 215 } 216 217 class ModuleSanitizerCoverage { 218 public: 219 using DomTreeCallback = function_ref<const DominatorTree &(Function &F)>; 220 using PostDomTreeCallback = 221 function_ref<const PostDominatorTree &(Function &F)>; 222 223 ModuleSanitizerCoverage(Module &M, DomTreeCallback DTCallback, 224 PostDomTreeCallback PDTCallback, 225 const SanitizerCoverageOptions &Options, 226 const SpecialCaseList *Allowlist, 227 const SpecialCaseList *Blocklist) 228 : M(M), DTCallback(DTCallback), PDTCallback(PDTCallback), 229 Options(Options), Allowlist(Allowlist), Blocklist(Blocklist) {} 230 231 bool instrumentModule(); 232 233 private: 234 void createFunctionControlFlow(Function &F); 235 void instrumentFunction(Function &F); 236 void InjectCoverageForIndirectCalls(Function &F, 237 ArrayRef<Instruction *> IndirCalls); 238 void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets); 239 void InjectTraceForDiv(Function &F, 240 ArrayRef<BinaryOperator *> DivTraceTargets); 241 void InjectTraceForGep(Function &F, 242 ArrayRef<GetElementPtrInst *> GepTraceTargets); 243 void InjectTraceForLoadsAndStores(Function &F, ArrayRef<LoadInst *> Loads, 244 ArrayRef<StoreInst *> Stores); 245 void InjectTraceForSwitch(Function &F, 246 ArrayRef<Instruction *> SwitchTraceTargets); 247 bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks, 248 bool IsLeafFunc = true); 249 GlobalVariable *CreateFunctionLocalArrayInSection(size_t NumElements, 250 Function &F, Type *Ty, 251 const char *Section); 252 GlobalVariable *CreatePCArray(Function &F, ArrayRef<BasicBlock *> AllBlocks); 253 void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks); 254 Value *CreateFunctionLocalGateCmp(IRBuilder<> &IRB); 255 void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx, 256 Value *&FunctionGateCmp, bool IsLeafFunc = true); 257 Function *CreateInitCallsForSections(Module &M, const char *CtorName, 258 const char *InitFunctionName, Type *Ty, 259 const char *Section); 260 std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char *Section, 261 Type *Ty); 262 263 std::string getSectionName(const std::string &Section) const; 264 std::string getSectionStart(const std::string &Section) const; 265 std::string getSectionEnd(const std::string &Section) const; 266 267 Module &M; 268 DomTreeCallback DTCallback; 269 PostDomTreeCallback PDTCallback; 270 271 FunctionCallee SanCovTracePCIndir; 272 FunctionCallee SanCovTracePC, SanCovTracePCGuard; 273 std::array<FunctionCallee, 4> SanCovTraceCmpFunction; 274 std::array<FunctionCallee, 4> SanCovTraceConstCmpFunction; 275 std::array<FunctionCallee, 5> SanCovLoadFunction; 276 std::array<FunctionCallee, 5> SanCovStoreFunction; 277 std::array<FunctionCallee, 2> SanCovTraceDivFunction; 278 FunctionCallee SanCovTraceGepFunction; 279 FunctionCallee SanCovTraceSwitchFunction; 280 GlobalVariable *SanCovLowestStack; 281 GlobalVariable *SanCovCallbackGate; 282 Type *PtrTy, *IntptrTy, *Int64Ty, *Int32Ty, *Int16Ty, *Int8Ty, *Int1Ty; 283 Module *CurModule; 284 std::string CurModuleUniqueId; 285 Triple TargetTriple; 286 LLVMContext *C; 287 const DataLayout *DL; 288 289 GlobalVariable *FunctionGuardArray; // for trace-pc-guard. 290 GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters. 291 GlobalVariable *FunctionBoolArray; // for inline-bool-flag. 292 GlobalVariable *FunctionPCsArray; // for pc-table. 293 GlobalVariable *FunctionCFsArray; // for control flow table 294 SmallVector<GlobalValue *, 20> GlobalsToAppendToUsed; 295 SmallVector<GlobalValue *, 20> GlobalsToAppendToCompilerUsed; 296 297 SanitizerCoverageOptions Options; 298 299 const SpecialCaseList *Allowlist; 300 const SpecialCaseList *Blocklist; 301 }; 302 } // namespace 303 304 PreservedAnalyses SanitizerCoveragePass::run(Module &M, 305 ModuleAnalysisManager &MAM) { 306 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 307 auto DTCallback = [&FAM](Function &F) -> const DominatorTree & { 308 return FAM.getResult<DominatorTreeAnalysis>(F); 309 }; 310 auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree & { 311 return FAM.getResult<PostDominatorTreeAnalysis>(F); 312 }; 313 ModuleSanitizerCoverage ModuleSancov(M, DTCallback, PDTCallback, 314 OverrideFromCL(Options), Allowlist.get(), 315 Blocklist.get()); 316 if (!ModuleSancov.instrumentModule()) 317 return PreservedAnalyses::all(); 318 319 PreservedAnalyses PA = PreservedAnalyses::none(); 320 // GlobalsAA is considered stateless and does not get invalidated unless 321 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers 322 // make changes that require GlobalsAA to be invalidated. 323 PA.abandon<GlobalsAA>(); 324 return PA; 325 } 326 327 std::pair<Value *, Value *> 328 ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section, 329 Type *Ty) { 330 // Use ExternalWeak so that if all sections are discarded due to section 331 // garbage collection, the linker will not report undefined symbol errors. 332 // Windows defines the start/stop symbols in compiler-rt so no need for 333 // ExternalWeak. 334 GlobalValue::LinkageTypes Linkage = TargetTriple.isOSBinFormatCOFF() 335 ? GlobalVariable::ExternalLinkage 336 : GlobalVariable::ExternalWeakLinkage; 337 GlobalVariable *SecStart = 338 new GlobalVariable(M, Ty, false, Linkage, nullptr, 339 getSectionStart(Section)); 340 SecStart->setVisibility(GlobalValue::HiddenVisibility); 341 GlobalVariable *SecEnd = 342 new GlobalVariable(M, Ty, false, Linkage, nullptr, 343 getSectionEnd(Section)); 344 SecEnd->setVisibility(GlobalValue::HiddenVisibility); 345 IRBuilder<> IRB(M.getContext()); 346 if (!TargetTriple.isOSBinFormatCOFF()) 347 return std::make_pair(SecStart, SecEnd); 348 349 // Account for the fact that on windows-msvc __start_* symbols actually 350 // point to a uint64_t before the start of the array. 351 auto GEP = 352 IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); 353 return std::make_pair(GEP, SecEnd); 354 } 355 356 Function *ModuleSanitizerCoverage::CreateInitCallsForSections( 357 Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty, 358 const char *Section) { 359 auto SecStartEnd = CreateSecStartEnd(M, Section, Ty); 360 auto SecStart = SecStartEnd.first; 361 auto SecEnd = SecStartEnd.second; 362 Function *CtorFunc; 363 std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions( 364 M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd}); 365 assert(CtorFunc->getName() == CtorName); 366 367 if (TargetTriple.supportsCOMDAT()) { 368 // Use comdat to dedup CtorFunc. 369 CtorFunc->setComdat(M.getOrInsertComdat(CtorName)); 370 appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc); 371 } else { 372 appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority); 373 } 374 375 if (TargetTriple.isOSBinFormatCOFF()) { 376 // In COFF files, if the contructors are set as COMDAT (they are because 377 // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced 378 // functions and data) is used, the constructors get stripped. To prevent 379 // this, give the constructors weak ODR linkage and ensure the linker knows 380 // to include the sancov constructor. This way the linker can deduplicate 381 // the constructors but always leave one copy. 382 CtorFunc->setLinkage(GlobalValue::WeakODRLinkage); 383 } 384 return CtorFunc; 385 } 386 387 bool ModuleSanitizerCoverage::instrumentModule() { 388 if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) 389 return false; 390 if (Allowlist && 391 !Allowlist->inSection("coverage", "src", M.getSourceFileName())) 392 return false; 393 if (Blocklist && 394 Blocklist->inSection("coverage", "src", M.getSourceFileName())) 395 return false; 396 C = &(M.getContext()); 397 DL = &M.getDataLayout(); 398 CurModule = &M; 399 CurModuleUniqueId = getUniqueModuleId(CurModule); 400 TargetTriple = Triple(M.getTargetTriple()); 401 FunctionGuardArray = nullptr; 402 Function8bitCounterArray = nullptr; 403 FunctionBoolArray = nullptr; 404 FunctionPCsArray = nullptr; 405 FunctionCFsArray = nullptr; 406 IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits()); 407 PtrTy = PointerType::getUnqual(*C); 408 Type *VoidTy = Type::getVoidTy(*C); 409 IRBuilder<> IRB(*C); 410 Int64Ty = IRB.getInt64Ty(); 411 Int32Ty = IRB.getInt32Ty(); 412 Int16Ty = IRB.getInt16Ty(); 413 Int8Ty = IRB.getInt8Ty(); 414 Int1Ty = IRB.getInt1Ty(); 415 416 SanCovTracePCIndir = 417 M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy); 418 // Make sure smaller parameters are zero-extended to i64 if required by the 419 // target ABI. 420 AttributeList SanCovTraceCmpZeroExtAL; 421 SanCovTraceCmpZeroExtAL = 422 SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt); 423 SanCovTraceCmpZeroExtAL = 424 SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt); 425 426 SanCovTraceCmpFunction[0] = 427 M.getOrInsertFunction(SanCovTraceCmp1, SanCovTraceCmpZeroExtAL, VoidTy, 428 IRB.getInt8Ty(), IRB.getInt8Ty()); 429 SanCovTraceCmpFunction[1] = 430 M.getOrInsertFunction(SanCovTraceCmp2, SanCovTraceCmpZeroExtAL, VoidTy, 431 IRB.getInt16Ty(), IRB.getInt16Ty()); 432 SanCovTraceCmpFunction[2] = 433 M.getOrInsertFunction(SanCovTraceCmp4, SanCovTraceCmpZeroExtAL, VoidTy, 434 IRB.getInt32Ty(), IRB.getInt32Ty()); 435 SanCovTraceCmpFunction[3] = 436 M.getOrInsertFunction(SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty); 437 438 SanCovTraceConstCmpFunction[0] = M.getOrInsertFunction( 439 SanCovTraceConstCmp1, SanCovTraceCmpZeroExtAL, VoidTy, Int8Ty, Int8Ty); 440 SanCovTraceConstCmpFunction[1] = M.getOrInsertFunction( 441 SanCovTraceConstCmp2, SanCovTraceCmpZeroExtAL, VoidTy, Int16Ty, Int16Ty); 442 SanCovTraceConstCmpFunction[2] = M.getOrInsertFunction( 443 SanCovTraceConstCmp4, SanCovTraceCmpZeroExtAL, VoidTy, Int32Ty, Int32Ty); 444 SanCovTraceConstCmpFunction[3] = 445 M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty); 446 447 // Loads. 448 SanCovLoadFunction[0] = M.getOrInsertFunction(SanCovLoad1, VoidTy, PtrTy); 449 SanCovLoadFunction[1] = 450 M.getOrInsertFunction(SanCovLoad2, VoidTy, PtrTy); 451 SanCovLoadFunction[2] = 452 M.getOrInsertFunction(SanCovLoad4, VoidTy, PtrTy); 453 SanCovLoadFunction[3] = 454 M.getOrInsertFunction(SanCovLoad8, VoidTy, PtrTy); 455 SanCovLoadFunction[4] = 456 M.getOrInsertFunction(SanCovLoad16, VoidTy, PtrTy); 457 // Stores. 458 SanCovStoreFunction[0] = 459 M.getOrInsertFunction(SanCovStore1, VoidTy, PtrTy); 460 SanCovStoreFunction[1] = 461 M.getOrInsertFunction(SanCovStore2, VoidTy, PtrTy); 462 SanCovStoreFunction[2] = 463 M.getOrInsertFunction(SanCovStore4, VoidTy, PtrTy); 464 SanCovStoreFunction[3] = 465 M.getOrInsertFunction(SanCovStore8, VoidTy, PtrTy); 466 SanCovStoreFunction[4] = 467 M.getOrInsertFunction(SanCovStore16, VoidTy, PtrTy); 468 469 { 470 AttributeList AL; 471 AL = AL.addParamAttribute(*C, 0, Attribute::ZExt); 472 SanCovTraceDivFunction[0] = 473 M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty()); 474 } 475 SanCovTraceDivFunction[1] = 476 M.getOrInsertFunction(SanCovTraceDiv8, VoidTy, Int64Ty); 477 SanCovTraceGepFunction = 478 M.getOrInsertFunction(SanCovTraceGep, VoidTy, IntptrTy); 479 SanCovTraceSwitchFunction = 480 M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, PtrTy); 481 482 Constant *SanCovLowestStackConstant = 483 M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy); 484 SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant); 485 if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) { 486 C->emitError(StringRef("'") + SanCovLowestStackName + 487 "' should not be declared by the user"); 488 return true; 489 } 490 SanCovLowestStack->setThreadLocalMode( 491 GlobalValue::ThreadLocalMode::InitialExecTLSModel); 492 if (Options.StackDepth && !SanCovLowestStack->isDeclaration()) 493 SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy)); 494 495 if (Options.GatedCallbacks) { 496 if (!Options.TracePCGuard) { 497 C->emitError(StringRef("'") + ClGatedCallbacks.ArgStr + 498 "' is only supported with trace-pc-guard"); 499 return true; 500 } 501 502 SanCovCallbackGate = cast<GlobalVariable>( 503 M.getOrInsertGlobal(SanCovCallbackGateName, Int64Ty)); 504 SanCovCallbackGate->setSection( 505 getSectionName(SanCovCallbackGateSectionName)); 506 SanCovCallbackGate->setInitializer(Constant::getNullValue(Int64Ty)); 507 SanCovCallbackGate->setLinkage(GlobalVariable::LinkOnceAnyLinkage); 508 SanCovCallbackGate->setVisibility(GlobalVariable::HiddenVisibility); 509 appendToCompilerUsed(M, SanCovCallbackGate); 510 } 511 512 SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy); 513 SanCovTracePCGuard = 514 M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, PtrTy); 515 516 for (auto &F : M) 517 instrumentFunction(F); 518 519 Function *Ctor = nullptr; 520 521 if (FunctionGuardArray) 522 Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName, 523 SanCovTracePCGuardInitName, Int32Ty, 524 SanCovGuardsSectionName); 525 if (Function8bitCounterArray) 526 Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName, 527 SanCov8bitCountersInitName, Int8Ty, 528 SanCovCountersSectionName); 529 if (FunctionBoolArray) { 530 Ctor = CreateInitCallsForSections(M, SanCovModuleCtorBoolFlagName, 531 SanCovBoolFlagInitName, Int1Ty, 532 SanCovBoolFlagSectionName); 533 } 534 if (Ctor && Options.PCTable) { 535 auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrTy); 536 FunctionCallee InitFunction = declareSanitizerInitFunction( 537 M, SanCovPCsInitName, {PtrTy, PtrTy}); 538 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator()); 539 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second}); 540 } 541 542 if (Ctor && Options.CollectControlFlow) { 543 auto SecStartEnd = CreateSecStartEnd(M, SanCovCFsSectionName, IntptrTy); 544 FunctionCallee InitFunction = declareSanitizerInitFunction( 545 M, SanCovCFsInitName, {PtrTy, PtrTy}); 546 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator()); 547 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second}); 548 } 549 550 appendToUsed(M, GlobalsToAppendToUsed); 551 appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed); 552 return true; 553 } 554 555 // True if block has successors and it dominates all of them. 556 static bool isFullDominator(const BasicBlock *BB, const DominatorTree &DT) { 557 if (succ_empty(BB)) 558 return false; 559 560 return llvm::all_of(successors(BB), [&](const BasicBlock *SUCC) { 561 return DT.dominates(BB, SUCC); 562 }); 563 } 564 565 // True if block has predecessors and it postdominates all of them. 566 static bool isFullPostDominator(const BasicBlock *BB, 567 const PostDominatorTree &PDT) { 568 if (pred_empty(BB)) 569 return false; 570 571 return llvm::all_of(predecessors(BB), [&](const BasicBlock *PRED) { 572 return PDT.dominates(BB, PRED); 573 }); 574 } 575 576 static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, 577 const DominatorTree &DT, 578 const PostDominatorTree &PDT, 579 const SanitizerCoverageOptions &Options) { 580 // Don't insert coverage for blocks containing nothing but unreachable: we 581 // will never call __sanitizer_cov() for them, so counting them in 582 // NumberOfInstrumentedBlocks() might complicate calculation of code coverage 583 // percentage. Also, unreachable instructions frequently have no debug 584 // locations. 585 if (isa<UnreachableInst>(BB->getFirstNonPHIOrDbgOrLifetime())) 586 return false; 587 588 // Don't insert coverage into blocks without a valid insertion point 589 // (catchswitch blocks). 590 if (BB->getFirstInsertionPt() == BB->end()) 591 return false; 592 593 if (Options.NoPrune || &F.getEntryBlock() == BB) 594 return true; 595 596 if (Options.CoverageType == SanitizerCoverageOptions::SCK_Function && 597 &F.getEntryBlock() != BB) 598 return false; 599 600 // Do not instrument full dominators, or full post-dominators with multiple 601 // predecessors. 602 return !isFullDominator(BB, DT) 603 && !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor()); 604 } 605 606 // Returns true iff From->To is a backedge. 607 // A twist here is that we treat From->To as a backedge if 608 // * To dominates From or 609 // * To->UniqueSuccessor dominates From 610 static bool IsBackEdge(BasicBlock *From, BasicBlock *To, 611 const DominatorTree &DT) { 612 if (DT.dominates(To, From)) 613 return true; 614 if (auto Next = To->getUniqueSuccessor()) 615 if (DT.dominates(Next, From)) 616 return true; 617 return false; 618 } 619 620 // Prunes uninteresting Cmp instrumentation: 621 // * CMP instructions that feed into loop backedge branch. 622 // 623 // Note that Cmp pruning is controlled by the same flag as the 624 // BB pruning. 625 static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree &DT, 626 const SanitizerCoverageOptions &Options) { 627 if (!Options.NoPrune) 628 if (CMP->hasOneUse()) 629 if (auto BR = dyn_cast<BranchInst>(CMP->user_back())) 630 for (BasicBlock *B : BR->successors()) 631 if (IsBackEdge(BR->getParent(), B, DT)) 632 return false; 633 return true; 634 } 635 636 void ModuleSanitizerCoverage::instrumentFunction(Function &F) { 637 if (F.empty()) 638 return; 639 if (F.getName().contains(".module_ctor")) 640 return; // Should not instrument sanitizer init functions. 641 if (F.getName().starts_with("__sanitizer_")) 642 return; // Don't instrument __sanitizer_* callbacks. 643 // Don't touch available_externally functions, their actual body is elewhere. 644 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) 645 return; 646 // Don't instrument MSVC CRT configuration helpers. They may run before normal 647 // initialization. 648 if (F.getName() == "__local_stdio_printf_options" || 649 F.getName() == "__local_stdio_scanf_options") 650 return; 651 if (isa<UnreachableInst>(F.getEntryBlock().getTerminator())) 652 return; 653 // Don't instrument functions using SEH for now. Splitting basic blocks like 654 // we do for coverage breaks WinEHPrepare. 655 // FIXME: Remove this when SEH no longer uses landingpad pattern matching. 656 if (F.hasPersonalityFn() && 657 isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) 658 return; 659 if (Allowlist && !Allowlist->inSection("coverage", "fun", F.getName())) 660 return; 661 if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName())) 662 return; 663 // Do not apply any instrumentation for naked functions. 664 if (F.hasFnAttribute(Attribute::Naked)) 665 return; 666 if (F.hasFnAttribute(Attribute::NoSanitizeCoverage)) 667 return; 668 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) 669 return; 670 if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) { 671 SplitAllCriticalEdges( 672 F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests()); 673 } 674 SmallVector<Instruction *, 8> IndirCalls; 675 SmallVector<BasicBlock *, 16> BlocksToInstrument; 676 SmallVector<Instruction *, 8> CmpTraceTargets; 677 SmallVector<Instruction *, 8> SwitchTraceTargets; 678 SmallVector<BinaryOperator *, 8> DivTraceTargets; 679 SmallVector<GetElementPtrInst *, 8> GepTraceTargets; 680 SmallVector<LoadInst *, 8> Loads; 681 SmallVector<StoreInst *, 8> Stores; 682 683 const DominatorTree &DT = DTCallback(F); 684 const PostDominatorTree &PDT = PDTCallback(F); 685 bool IsLeafFunc = true; 686 687 for (auto &BB : F) { 688 if (shouldInstrumentBlock(F, &BB, DT, PDT, Options)) 689 BlocksToInstrument.push_back(&BB); 690 for (auto &Inst : BB) { 691 if (Options.IndirectCalls) { 692 CallBase *CB = dyn_cast<CallBase>(&Inst); 693 if (CB && CB->isIndirectCall()) 694 IndirCalls.push_back(&Inst); 695 } 696 if (Options.TraceCmp) { 697 if (ICmpInst *CMP = dyn_cast<ICmpInst>(&Inst)) 698 if (IsInterestingCmp(CMP, DT, Options)) 699 CmpTraceTargets.push_back(&Inst); 700 if (isa<SwitchInst>(&Inst)) 701 SwitchTraceTargets.push_back(&Inst); 702 } 703 if (Options.TraceDiv) 704 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&Inst)) 705 if (BO->getOpcode() == Instruction::SDiv || 706 BO->getOpcode() == Instruction::UDiv) 707 DivTraceTargets.push_back(BO); 708 if (Options.TraceGep) 709 if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&Inst)) 710 GepTraceTargets.push_back(GEP); 711 if (Options.TraceLoads) 712 if (LoadInst *LI = dyn_cast<LoadInst>(&Inst)) 713 Loads.push_back(LI); 714 if (Options.TraceStores) 715 if (StoreInst *SI = dyn_cast<StoreInst>(&Inst)) 716 Stores.push_back(SI); 717 if (Options.StackDepth) 718 if (isa<InvokeInst>(Inst) || 719 (isa<CallInst>(Inst) && !isa<IntrinsicInst>(Inst))) 720 IsLeafFunc = false; 721 } 722 } 723 724 if (Options.CollectControlFlow) 725 createFunctionControlFlow(F); 726 727 InjectCoverage(F, BlocksToInstrument, IsLeafFunc); 728 InjectCoverageForIndirectCalls(F, IndirCalls); 729 InjectTraceForCmp(F, CmpTraceTargets); 730 InjectTraceForSwitch(F, SwitchTraceTargets); 731 InjectTraceForDiv(F, DivTraceTargets); 732 InjectTraceForGep(F, GepTraceTargets); 733 InjectTraceForLoadsAndStores(F, Loads, Stores); 734 } 735 736 GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( 737 size_t NumElements, Function &F, Type *Ty, const char *Section) { 738 ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); 739 auto Array = new GlobalVariable( 740 *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, 741 Constant::getNullValue(ArrayTy), "__sancov_gen_"); 742 743 if (TargetTriple.supportsCOMDAT() && 744 (TargetTriple.isOSBinFormatELF() || !F.isInterposable())) 745 if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple)) 746 Array->setComdat(Comdat); 747 Array->setSection(getSectionName(Section)); 748 Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedValue())); 749 750 // sancov_pcs parallels the other metadata section(s). Optimizers (e.g. 751 // GlobalOpt/ConstantMerge) may not discard sancov_pcs and the other 752 // section(s) as a unit, so we conservatively retain all unconditionally in 753 // the compiler. 754 // 755 // With comdat (COFF/ELF), the linker can guarantee the associated sections 756 // will be retained or discarded as a unit, so llvm.compiler.used is 757 // sufficient. Otherwise, conservatively make all of them retained by the 758 // linker. 759 if (Array->hasComdat()) 760 GlobalsToAppendToCompilerUsed.push_back(Array); 761 else 762 GlobalsToAppendToUsed.push_back(Array); 763 764 return Array; 765 } 766 767 GlobalVariable * 768 ModuleSanitizerCoverage::CreatePCArray(Function &F, 769 ArrayRef<BasicBlock *> AllBlocks) { 770 size_t N = AllBlocks.size(); 771 assert(N); 772 SmallVector<Constant *, 32> PCs; 773 IRBuilder<> IRB(&*F.getEntryBlock().getFirstInsertionPt()); 774 for (size_t i = 0; i < N; i++) { 775 if (&F.getEntryBlock() == AllBlocks[i]) { 776 PCs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy)); 777 PCs.push_back((Constant *)IRB.CreateIntToPtr( 778 ConstantInt::get(IntptrTy, 1), PtrTy)); 779 } else { 780 PCs.push_back((Constant *)IRB.CreatePointerCast( 781 BlockAddress::get(AllBlocks[i]), PtrTy)); 782 PCs.push_back(Constant::getNullValue(PtrTy)); 783 } 784 } 785 auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, PtrTy, 786 SanCovPCsSectionName); 787 PCArray->setInitializer( 788 ConstantArray::get(ArrayType::get(PtrTy, N * 2), PCs)); 789 PCArray->setConstant(true); 790 791 return PCArray; 792 } 793 794 void ModuleSanitizerCoverage::CreateFunctionLocalArrays( 795 Function &F, ArrayRef<BasicBlock *> AllBlocks) { 796 if (Options.TracePCGuard) 797 FunctionGuardArray = CreateFunctionLocalArrayInSection( 798 AllBlocks.size(), F, Int32Ty, SanCovGuardsSectionName); 799 800 if (Options.Inline8bitCounters) 801 Function8bitCounterArray = CreateFunctionLocalArrayInSection( 802 AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName); 803 if (Options.InlineBoolFlag) 804 FunctionBoolArray = CreateFunctionLocalArrayInSection( 805 AllBlocks.size(), F, Int1Ty, SanCovBoolFlagSectionName); 806 807 if (Options.PCTable) 808 FunctionPCsArray = CreatePCArray(F, AllBlocks); 809 } 810 811 Value *ModuleSanitizerCoverage::CreateFunctionLocalGateCmp(IRBuilder<> &IRB) { 812 auto Load = IRB.CreateLoad(Int64Ty, SanCovCallbackGate); 813 Load->setNoSanitizeMetadata(); 814 auto Cmp = IRB.CreateIsNotNull(Load); 815 Cmp->setName("sancov gate cmp"); 816 return Cmp; 817 } 818 819 bool ModuleSanitizerCoverage::InjectCoverage(Function &F, 820 ArrayRef<BasicBlock *> AllBlocks, 821 bool IsLeafFunc) { 822 if (AllBlocks.empty()) return false; 823 CreateFunctionLocalArrays(F, AllBlocks); 824 Value *FunctionGateCmp = nullptr; 825 for (size_t i = 0, N = AllBlocks.size(); i < N; i++) 826 InjectCoverageAtBlock(F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc); 827 return true; 828 } 829 830 // On every indirect call we call a run-time function 831 // __sanitizer_cov_indir_call* with two parameters: 832 // - callee address, 833 // - global cache array that contains CacheSize pointers (zero-initialized). 834 // The cache is used to speed up recording the caller-callee pairs. 835 // The address of the caller is passed implicitly via caller PC. 836 // CacheSize is encoded in the name of the run-time function. 837 void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( 838 Function &F, ArrayRef<Instruction *> IndirCalls) { 839 if (IndirCalls.empty()) 840 return; 841 assert(Options.TracePC || Options.TracePCGuard || 842 Options.Inline8bitCounters || Options.InlineBoolFlag); 843 for (auto *I : IndirCalls) { 844 InstrumentationIRBuilder IRB(I); 845 CallBase &CB = cast<CallBase>(*I); 846 Value *Callee = CB.getCalledOperand(); 847 if (isa<InlineAsm>(Callee)) 848 continue; 849 IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy)); 850 } 851 } 852 853 // For every switch statement we insert a call: 854 // __sanitizer_cov_trace_switch(CondValue, 855 // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... }) 856 857 void ModuleSanitizerCoverage::InjectTraceForSwitch( 858 Function &, ArrayRef<Instruction *> SwitchTraceTargets) { 859 for (auto *I : SwitchTraceTargets) { 860 if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) { 861 InstrumentationIRBuilder IRB(I); 862 SmallVector<Constant *, 16> Initializers; 863 Value *Cond = SI->getCondition(); 864 if (Cond->getType()->getScalarSizeInBits() > 865 Int64Ty->getScalarSizeInBits()) 866 continue; 867 Initializers.push_back(ConstantInt::get(Int64Ty, SI->getNumCases())); 868 Initializers.push_back( 869 ConstantInt::get(Int64Ty, Cond->getType()->getScalarSizeInBits())); 870 if (Cond->getType()->getScalarSizeInBits() < 871 Int64Ty->getScalarSizeInBits()) 872 Cond = IRB.CreateIntCast(Cond, Int64Ty, false); 873 for (auto It : SI->cases()) { 874 ConstantInt *C = It.getCaseValue(); 875 if (C->getType()->getScalarSizeInBits() < 64) 876 C = ConstantInt::get(C->getContext(), C->getValue().zext(64)); 877 Initializers.push_back(C); 878 } 879 llvm::sort(drop_begin(Initializers, 2), 880 [](const Constant *A, const Constant *B) { 881 return cast<ConstantInt>(A)->getLimitedValue() < 882 cast<ConstantInt>(B)->getLimitedValue(); 883 }); 884 ArrayType *ArrayOfInt64Ty = ArrayType::get(Int64Ty, Initializers.size()); 885 GlobalVariable *GV = new GlobalVariable( 886 *CurModule, ArrayOfInt64Ty, false, GlobalVariable::InternalLinkage, 887 ConstantArray::get(ArrayOfInt64Ty, Initializers), 888 "__sancov_gen_cov_switch_values"); 889 IRB.CreateCall(SanCovTraceSwitchFunction, {Cond, GV}); 890 } 891 } 892 } 893 894 void ModuleSanitizerCoverage::InjectTraceForDiv( 895 Function &, ArrayRef<BinaryOperator *> DivTraceTargets) { 896 for (auto *BO : DivTraceTargets) { 897 InstrumentationIRBuilder IRB(BO); 898 Value *A1 = BO->getOperand(1); 899 if (isa<ConstantInt>(A1)) continue; 900 if (!A1->getType()->isIntegerTy()) 901 continue; 902 uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType()); 903 int CallbackIdx = TypeSize == 32 ? 0 : 904 TypeSize == 64 ? 1 : -1; 905 if (CallbackIdx < 0) continue; 906 auto Ty = Type::getIntNTy(*C, TypeSize); 907 IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx], 908 {IRB.CreateIntCast(A1, Ty, true)}); 909 } 910 } 911 912 void ModuleSanitizerCoverage::InjectTraceForGep( 913 Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) { 914 for (auto *GEP : GepTraceTargets) { 915 InstrumentationIRBuilder IRB(GEP); 916 for (Use &Idx : GEP->indices()) 917 if (!isa<ConstantInt>(Idx) && Idx->getType()->isIntegerTy()) 918 IRB.CreateCall(SanCovTraceGepFunction, 919 {IRB.CreateIntCast(Idx, IntptrTy, true)}); 920 } 921 } 922 923 void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores( 924 Function &, ArrayRef<LoadInst *> Loads, ArrayRef<StoreInst *> Stores) { 925 auto CallbackIdx = [&](Type *ElementTy) -> int { 926 uint64_t TypeSize = DL->getTypeStoreSizeInBits(ElementTy); 927 return TypeSize == 8 ? 0 928 : TypeSize == 16 ? 1 929 : TypeSize == 32 ? 2 930 : TypeSize == 64 ? 3 931 : TypeSize == 128 ? 4 932 : -1; 933 }; 934 for (auto *LI : Loads) { 935 InstrumentationIRBuilder IRB(LI); 936 auto Ptr = LI->getPointerOperand(); 937 int Idx = CallbackIdx(LI->getType()); 938 if (Idx < 0) 939 continue; 940 IRB.CreateCall(SanCovLoadFunction[Idx], Ptr); 941 } 942 for (auto *SI : Stores) { 943 InstrumentationIRBuilder IRB(SI); 944 auto Ptr = SI->getPointerOperand(); 945 int Idx = CallbackIdx(SI->getValueOperand()->getType()); 946 if (Idx < 0) 947 continue; 948 IRB.CreateCall(SanCovStoreFunction[Idx], Ptr); 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 InstrumentationIRBuilder 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 Value *&FunctionGateCmp, 990 bool IsLeafFunc) { 991 BasicBlock::iterator IP = BB.getFirstInsertionPt(); 992 bool IsEntryBB = &BB == &F.getEntryBlock(); 993 DebugLoc EntryLoc; 994 if (IsEntryBB) { 995 if (auto SP = F.getSubprogram()) 996 EntryLoc = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP); 997 // Keep static allocas and llvm.localescape calls in the entry block. Even 998 // if we aren't splitting the block, it's nice for allocas to be before 999 // calls. 1000 IP = PrepareToSplitEntryBlock(BB, IP); 1001 } 1002 1003 InstrumentationIRBuilder IRB(&*IP); 1004 if (EntryLoc) 1005 IRB.SetCurrentDebugLocation(EntryLoc); 1006 if (Options.TracePC) { 1007 IRB.CreateCall(SanCovTracePC) 1008 ->setCannotMerge(); // gets the PC using GET_CALLER_PC. 1009 } 1010 if (Options.TracePCGuard) { 1011 auto GuardPtr = IRB.CreateIntToPtr( 1012 IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), 1013 ConstantInt::get(IntptrTy, Idx * 4)), 1014 PtrTy); 1015 if (Options.GatedCallbacks) { 1016 if (!FunctionGateCmp) { 1017 // Create this in the entry block 1018 assert(IsEntryBB); 1019 FunctionGateCmp = CreateFunctionLocalGateCmp(IRB); 1020 } 1021 // Set the branch weights in order to minimize the price paid when the 1022 // gate is turned off, allowing the default enablement of this 1023 // instrumentation with as little of a performance cost as possible 1024 auto Weights = MDBuilder(*C).createBranchWeights(1, 100000); 1025 auto ThenTerm = 1026 SplitBlockAndInsertIfThen(FunctionGateCmp, &*IP, false, Weights); 1027 IRBuilder<> ThenIRB(ThenTerm); 1028 ThenIRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge(); 1029 } else { 1030 IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge(); 1031 } 1032 } 1033 if (Options.Inline8bitCounters) { 1034 auto CounterPtr = IRB.CreateGEP( 1035 Function8bitCounterArray->getValueType(), Function8bitCounterArray, 1036 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)}); 1037 auto Load = IRB.CreateLoad(Int8Ty, CounterPtr); 1038 auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1)); 1039 auto Store = IRB.CreateStore(Inc, CounterPtr); 1040 Load->setNoSanitizeMetadata(); 1041 Store->setNoSanitizeMetadata(); 1042 } 1043 if (Options.InlineBoolFlag) { 1044 auto FlagPtr = IRB.CreateGEP( 1045 FunctionBoolArray->getValueType(), FunctionBoolArray, 1046 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)}); 1047 auto Load = IRB.CreateLoad(Int1Ty, FlagPtr); 1048 auto ThenTerm = SplitBlockAndInsertIfThen( 1049 IRB.CreateIsNull(Load), &*IP, false, 1050 MDBuilder(IRB.getContext()).createUnlikelyBranchWeights()); 1051 IRBuilder<> ThenIRB(ThenTerm); 1052 auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr); 1053 Load->setNoSanitizeMetadata(); 1054 Store->setNoSanitizeMetadata(); 1055 } 1056 if (Options.StackDepth && IsEntryBB && !IsLeafFunc) { 1057 // Check stack depth. If it's the deepest so far, record it. 1058 Module *M = F.getParent(); 1059 Function *GetFrameAddr = Intrinsic::getOrInsertDeclaration( 1060 M, Intrinsic::frameaddress, 1061 IRB.getPtrTy(M->getDataLayout().getAllocaAddrSpace())); 1062 auto FrameAddrPtr = 1063 IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)}); 1064 auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy); 1065 auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack); 1066 auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack); 1067 auto ThenTerm = SplitBlockAndInsertIfThen( 1068 IsStackLower, &*IP, false, 1069 MDBuilder(IRB.getContext()).createUnlikelyBranchWeights()); 1070 IRBuilder<> ThenIRB(ThenTerm); 1071 auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack); 1072 LowestStack->setNoSanitizeMetadata(); 1073 Store->setNoSanitizeMetadata(); 1074 } 1075 } 1076 1077 std::string 1078 ModuleSanitizerCoverage::getSectionName(const std::string &Section) const { 1079 if (TargetTriple.isOSBinFormatCOFF()) { 1080 if (Section == SanCovCountersSectionName) 1081 return ".SCOV$CM"; 1082 if (Section == SanCovBoolFlagSectionName) 1083 return ".SCOV$BM"; 1084 if (Section == SanCovPCsSectionName) 1085 return ".SCOVP$M"; 1086 return ".SCOV$GM"; // For SanCovGuardsSectionName. 1087 } 1088 if (TargetTriple.isOSBinFormatMachO()) 1089 return "__DATA,__" + Section; 1090 return "__" + Section; 1091 } 1092 1093 std::string 1094 ModuleSanitizerCoverage::getSectionStart(const std::string &Section) const { 1095 if (TargetTriple.isOSBinFormatMachO()) 1096 return "\1section$start$__DATA$__" + Section; 1097 return "__start___" + Section; 1098 } 1099 1100 std::string 1101 ModuleSanitizerCoverage::getSectionEnd(const std::string &Section) const { 1102 if (TargetTriple.isOSBinFormatMachO()) 1103 return "\1section$end$__DATA$__" + Section; 1104 return "__stop___" + Section; 1105 } 1106 1107 void ModuleSanitizerCoverage::createFunctionControlFlow(Function &F) { 1108 SmallVector<Constant *, 32> CFs; 1109 IRBuilder<> IRB(&*F.getEntryBlock().getFirstInsertionPt()); 1110 1111 for (auto &BB : F) { 1112 // blockaddress can not be used on function's entry block. 1113 if (&BB == &F.getEntryBlock()) 1114 CFs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy)); 1115 else 1116 CFs.push_back((Constant *)IRB.CreatePointerCast(BlockAddress::get(&BB), 1117 PtrTy)); 1118 1119 for (auto SuccBB : successors(&BB)) { 1120 assert(SuccBB != &F.getEntryBlock()); 1121 CFs.push_back((Constant *)IRB.CreatePointerCast(BlockAddress::get(SuccBB), 1122 PtrTy)); 1123 } 1124 1125 CFs.push_back((Constant *)Constant::getNullValue(PtrTy)); 1126 1127 for (auto &Inst : BB) { 1128 if (CallBase *CB = dyn_cast<CallBase>(&Inst)) { 1129 if (CB->isIndirectCall()) { 1130 // TODO(navidem): handle indirect calls, for now mark its existence. 1131 CFs.push_back((Constant *)IRB.CreateIntToPtr( 1132 ConstantInt::get(IntptrTy, -1), PtrTy)); 1133 } else { 1134 auto CalledF = CB->getCalledFunction(); 1135 if (CalledF && !CalledF->isIntrinsic()) 1136 CFs.push_back( 1137 (Constant *)IRB.CreatePointerCast(CalledF, PtrTy)); 1138 } 1139 } 1140 } 1141 1142 CFs.push_back((Constant *)Constant::getNullValue(PtrTy)); 1143 } 1144 1145 FunctionCFsArray = CreateFunctionLocalArrayInSection( 1146 CFs.size(), F, PtrTy, SanCovCFsSectionName); 1147 FunctionCFsArray->setInitializer( 1148 ConstantArray::get(ArrayType::get(PtrTy, CFs.size()), CFs)); 1149 FunctionCFsArray->setConstant(true); 1150 } 1151