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