1 //===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===//
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
7 //===----------------------------------------------------------------------===//
9 // Coverage instrumentation done on LLVM IR level, works with Sanitizers.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/Analysis/EHPersonalities.h"
16 #include "llvm/Analysis/PostDominators.h"
17 #include "llvm/IR/CFG.h"
18 #include "llvm/IR/CallSite.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/Support/CommandLine.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include "llvm/Transforms/Instrumentation.h"
38 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
39 #include "llvm/Transforms/Utils/ModuleUtils.h"
43 #define DEBUG_TYPE "sancov"
45 static const char *const SanCovTracePCIndirName
=
46 "__sanitizer_cov_trace_pc_indir";
47 static const char *const SanCovTracePCName
= "__sanitizer_cov_trace_pc";
48 static const char *const SanCovTraceCmp1
= "__sanitizer_cov_trace_cmp1";
49 static const char *const SanCovTraceCmp2
= "__sanitizer_cov_trace_cmp2";
50 static const char *const SanCovTraceCmp4
= "__sanitizer_cov_trace_cmp4";
51 static const char *const SanCovTraceCmp8
= "__sanitizer_cov_trace_cmp8";
52 static const char *const SanCovTraceConstCmp1
=
53 "__sanitizer_cov_trace_const_cmp1";
54 static const char *const SanCovTraceConstCmp2
=
55 "__sanitizer_cov_trace_const_cmp2";
56 static const char *const SanCovTraceConstCmp4
=
57 "__sanitizer_cov_trace_const_cmp4";
58 static const char *const SanCovTraceConstCmp8
=
59 "__sanitizer_cov_trace_const_cmp8";
60 static const char *const SanCovTraceDiv4
= "__sanitizer_cov_trace_div4";
61 static const char *const SanCovTraceDiv8
= "__sanitizer_cov_trace_div8";
62 static const char *const SanCovTraceGep
= "__sanitizer_cov_trace_gep";
63 static const char *const SanCovTraceSwitchName
= "__sanitizer_cov_trace_switch";
64 static const char *const SanCovModuleCtorName
= "sancov.module_ctor";
65 static const uint64_t SanCtorAndDtorPriority
= 2;
67 static const char *const SanCovTracePCGuardName
=
68 "__sanitizer_cov_trace_pc_guard";
69 static const char *const SanCovTracePCGuardInitName
=
70 "__sanitizer_cov_trace_pc_guard_init";
71 static const char *const SanCov8bitCountersInitName
=
72 "__sanitizer_cov_8bit_counters_init";
73 static const char *const SanCovPCsInitName
= "__sanitizer_cov_pcs_init";
75 static const char *const SanCovGuardsSectionName
= "sancov_guards";
76 static const char *const SanCovCountersSectionName
= "sancov_cntrs";
77 static const char *const SanCovPCsSectionName
= "sancov_pcs";
79 static const char *const SanCovLowestStackName
= "__sancov_lowest_stack";
81 static cl::opt
<int> ClCoverageLevel(
82 "sanitizer-coverage-level",
83 cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
84 "3: all blocks and critical edges"),
85 cl::Hidden
, cl::init(0));
87 static cl::opt
<bool> ClTracePC("sanitizer-coverage-trace-pc",
88 cl::desc("Experimental pc tracing"), cl::Hidden
,
91 static cl::opt
<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
92 cl::desc("pc tracing with a guard"),
93 cl::Hidden
, cl::init(false));
95 // If true, we create a global variable that contains PCs of all instrumented
96 // BBs, put this global into a named section, and pass this section's bounds
97 // to __sanitizer_cov_pcs_init.
98 // This way the coverage instrumentation does not need to acquire the PCs
99 // at run-time. Works with trace-pc-guard and inline-8bit-counters.
100 static cl::opt
<bool> ClCreatePCTable("sanitizer-coverage-pc-table",
101 cl::desc("create a static PC table"),
102 cl::Hidden
, cl::init(false));
105 ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters",
106 cl::desc("increments 8-bit counter for every edge"),
107 cl::Hidden
, cl::init(false));
110 ClCMPTracing("sanitizer-coverage-trace-compares",
111 cl::desc("Tracing of CMP and similar instructions"),
112 cl::Hidden
, cl::init(false));
114 static cl::opt
<bool> ClDIVTracing("sanitizer-coverage-trace-divs",
115 cl::desc("Tracing of DIV instructions"),
116 cl::Hidden
, cl::init(false));
118 static cl::opt
<bool> ClGEPTracing("sanitizer-coverage-trace-geps",
119 cl::desc("Tracing of GEP instructions"),
120 cl::Hidden
, cl::init(false));
123 ClPruneBlocks("sanitizer-coverage-prune-blocks",
124 cl::desc("Reduce the number of instrumented blocks"),
125 cl::Hidden
, cl::init(true));
127 static cl::opt
<bool> ClStackDepth("sanitizer-coverage-stack-depth",
128 cl::desc("max stack depth tracing"),
129 cl::Hidden
, cl::init(false));
133 SanitizerCoverageOptions
getOptions(int LegacyCoverageLevel
) {
134 SanitizerCoverageOptions Res
;
135 switch (LegacyCoverageLevel
) {
137 Res
.CoverageType
= SanitizerCoverageOptions::SCK_None
;
140 Res
.CoverageType
= SanitizerCoverageOptions::SCK_Function
;
143 Res
.CoverageType
= SanitizerCoverageOptions::SCK_BB
;
146 Res
.CoverageType
= SanitizerCoverageOptions::SCK_Edge
;
149 Res
.CoverageType
= SanitizerCoverageOptions::SCK_Edge
;
150 Res
.IndirectCalls
= true;
156 SanitizerCoverageOptions
OverrideFromCL(SanitizerCoverageOptions Options
) {
157 // Sets CoverageType and IndirectCalls.
158 SanitizerCoverageOptions CLOpts
= getOptions(ClCoverageLevel
);
159 Options
.CoverageType
= std::max(Options
.CoverageType
, CLOpts
.CoverageType
);
160 Options
.IndirectCalls
|= CLOpts
.IndirectCalls
;
161 Options
.TraceCmp
|= ClCMPTracing
;
162 Options
.TraceDiv
|= ClDIVTracing
;
163 Options
.TraceGep
|= ClGEPTracing
;
164 Options
.TracePC
|= ClTracePC
;
165 Options
.TracePCGuard
|= ClTracePCGuard
;
166 Options
.Inline8bitCounters
|= ClInline8bitCounters
;
167 Options
.PCTable
|= ClCreatePCTable
;
168 Options
.NoPrune
|= !ClPruneBlocks
;
169 Options
.StackDepth
|= ClStackDepth
;
170 if (!Options
.TracePCGuard
&& !Options
.TracePC
&&
171 !Options
.Inline8bitCounters
&& !Options
.StackDepth
)
172 Options
.TracePCGuard
= true; // TracePCGuard is default.
176 class SanitizerCoverageModule
: public ModulePass
{
178 SanitizerCoverageModule(
179 const SanitizerCoverageOptions
&Options
= SanitizerCoverageOptions())
180 : ModulePass(ID
), Options(OverrideFromCL(Options
)) {
181 initializeSanitizerCoverageModulePass(*PassRegistry::getPassRegistry());
183 bool runOnModule(Module
&M
) override
;
184 bool runOnFunction(Function
&F
);
185 static char ID
; // Pass identification, replacement for typeid
186 StringRef
getPassName() const override
{ return "SanitizerCoverageModule"; }
188 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
189 AU
.addRequired
<DominatorTreeWrapperPass
>();
190 AU
.addRequired
<PostDominatorTreeWrapperPass
>();
194 void InjectCoverageForIndirectCalls(Function
&F
,
195 ArrayRef
<Instruction
*> IndirCalls
);
196 void InjectTraceForCmp(Function
&F
, ArrayRef
<Instruction
*> CmpTraceTargets
);
197 void InjectTraceForDiv(Function
&F
,
198 ArrayRef
<BinaryOperator
*> DivTraceTargets
);
199 void InjectTraceForGep(Function
&F
,
200 ArrayRef
<GetElementPtrInst
*> GepTraceTargets
);
201 void InjectTraceForSwitch(Function
&F
,
202 ArrayRef
<Instruction
*> SwitchTraceTargets
);
203 bool InjectCoverage(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
,
204 bool IsLeafFunc
= true);
205 GlobalVariable
*CreateFunctionLocalArrayInSection(size_t NumElements
,
206 Function
&F
, Type
*Ty
,
207 const char *Section
);
208 GlobalVariable
*CreatePCArray(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
);
209 void CreateFunctionLocalArrays(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
);
210 void InjectCoverageAtBlock(Function
&F
, BasicBlock
&BB
, size_t Idx
,
211 bool IsLeafFunc
= true);
212 Function
*CreateInitCallsForSections(Module
&M
, const char *InitFunctionName
,
213 Type
*Ty
, const char *Section
);
214 std::pair
<Value
*, Value
*> CreateSecStartEnd(Module
&M
, const char *Section
,
217 void SetNoSanitizeMetadata(Instruction
*I
) {
218 I
->setMetadata(I
->getModule()->getMDKindID("nosanitize"),
219 MDNode::get(*C
, None
));
222 std::string
getSectionName(const std::string
&Section
) const;
223 std::string
getSectionStart(const std::string
&Section
) const;
224 std::string
getSectionEnd(const std::string
&Section
) const;
225 FunctionCallee SanCovTracePCIndir
;
226 FunctionCallee SanCovTracePC
, SanCovTracePCGuard
;
227 FunctionCallee SanCovTraceCmpFunction
[4];
228 FunctionCallee SanCovTraceConstCmpFunction
[4];
229 FunctionCallee SanCovTraceDivFunction
[2];
230 FunctionCallee SanCovTraceGepFunction
;
231 FunctionCallee SanCovTraceSwitchFunction
;
232 GlobalVariable
*SanCovLowestStack
;
234 Type
*IntptrTy
, *IntptrPtrTy
, *Int64Ty
, *Int64PtrTy
, *Int32Ty
, *Int32PtrTy
,
235 *Int16Ty
, *Int8Ty
, *Int8PtrTy
;
237 std::string CurModuleUniqueId
;
240 const DataLayout
*DL
;
242 GlobalVariable
*FunctionGuardArray
; // for trace-pc-guard.
243 GlobalVariable
*Function8bitCounterArray
; // for inline-8bit-counters.
244 GlobalVariable
*FunctionPCsArray
; // for pc-table.
245 SmallVector
<GlobalValue
*, 20> GlobalsToAppendToUsed
;
246 SmallVector
<GlobalValue
*, 20> GlobalsToAppendToCompilerUsed
;
248 SanitizerCoverageOptions Options
;
253 std::pair
<Value
*, Value
*>
254 SanitizerCoverageModule::CreateSecStartEnd(Module
&M
, const char *Section
,
256 GlobalVariable
*SecStart
=
257 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
, nullptr,
258 getSectionStart(Section
));
259 SecStart
->setVisibility(GlobalValue::HiddenVisibility
);
260 GlobalVariable
*SecEnd
=
261 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
,
262 nullptr, getSectionEnd(Section
));
263 SecEnd
->setVisibility(GlobalValue::HiddenVisibility
);
264 IRBuilder
<> IRB(M
.getContext());
265 Value
*SecEndPtr
= IRB
.CreatePointerCast(SecEnd
, Ty
);
266 if (!TargetTriple
.isOSBinFormatCOFF())
267 return std::make_pair(IRB
.CreatePointerCast(SecStart
, Ty
), SecEndPtr
);
269 // Account for the fact that on windows-msvc __start_* symbols actually
270 // point to a uint64_t before the start of the array.
271 auto SecStartI8Ptr
= IRB
.CreatePointerCast(SecStart
, Int8PtrTy
);
272 auto GEP
= IRB
.CreateGEP(Int8Ty
, SecStartI8Ptr
,
273 ConstantInt::get(IntptrTy
, sizeof(uint64_t)));
274 return std::make_pair(IRB
.CreatePointerCast(GEP
, Ty
), SecEndPtr
);
277 Function
*SanitizerCoverageModule::CreateInitCallsForSections(
278 Module
&M
, const char *InitFunctionName
, Type
*Ty
,
279 const char *Section
) {
280 auto SecStartEnd
= CreateSecStartEnd(M
, Section
, Ty
);
281 auto SecStart
= SecStartEnd
.first
;
282 auto SecEnd
= SecStartEnd
.second
;
284 std::tie(CtorFunc
, std::ignore
) = createSanitizerCtorAndInitFunctions(
285 M
, SanCovModuleCtorName
, InitFunctionName
, {Ty
, Ty
}, {SecStart
, SecEnd
});
287 if (TargetTriple
.supportsCOMDAT()) {
288 // Use comdat to dedup CtorFunc.
289 CtorFunc
->setComdat(M
.getOrInsertComdat(SanCovModuleCtorName
));
290 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
, CtorFunc
);
292 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
);
295 if (TargetTriple
.isOSBinFormatCOFF()) {
296 // In COFF files, if the contructors are set as COMDAT (they are because
297 // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced
298 // functions and data) is used, the constructors get stripped. To prevent
299 // this, give the constructors weak ODR linkage and ensure the linker knows
300 // to include the sancov constructor. This way the linker can deduplicate
301 // the constructors but always leave one copy.
302 CtorFunc
->setLinkage(GlobalValue::WeakODRLinkage
);
303 appendToUsed(M
, CtorFunc
);
308 bool SanitizerCoverageModule::runOnModule(Module
&M
) {
309 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_None
)
311 C
= &(M
.getContext());
312 DL
= &M
.getDataLayout();
314 CurModuleUniqueId
= getUniqueModuleId(CurModule
);
315 TargetTriple
= Triple(M
.getTargetTriple());
316 FunctionGuardArray
= nullptr;
317 Function8bitCounterArray
= nullptr;
318 FunctionPCsArray
= nullptr;
319 IntptrTy
= Type::getIntNTy(*C
, DL
->getPointerSizeInBits());
320 IntptrPtrTy
= PointerType::getUnqual(IntptrTy
);
321 Type
*VoidTy
= Type::getVoidTy(*C
);
323 Int64PtrTy
= PointerType::getUnqual(IRB
.getInt64Ty());
324 Int32PtrTy
= PointerType::getUnqual(IRB
.getInt32Ty());
325 Int8PtrTy
= PointerType::getUnqual(IRB
.getInt8Ty());
326 Int64Ty
= IRB
.getInt64Ty();
327 Int32Ty
= IRB
.getInt32Ty();
328 Int16Ty
= IRB
.getInt16Ty();
329 Int8Ty
= IRB
.getInt8Ty();
332 M
.getOrInsertFunction(SanCovTracePCIndirName
, VoidTy
, IntptrTy
);
333 // Make sure smaller parameters are zero-extended to i64 as required by the
335 AttributeList SanCovTraceCmpZeroExtAL
;
336 if (TargetTriple
.getArch() == Triple::x86_64
) {
337 SanCovTraceCmpZeroExtAL
=
338 SanCovTraceCmpZeroExtAL
.addParamAttribute(*C
, 0, Attribute::ZExt
);
339 SanCovTraceCmpZeroExtAL
=
340 SanCovTraceCmpZeroExtAL
.addParamAttribute(*C
, 1, Attribute::ZExt
);
343 SanCovTraceCmpFunction
[0] =
344 M
.getOrInsertFunction(SanCovTraceCmp1
, SanCovTraceCmpZeroExtAL
, VoidTy
,
345 IRB
.getInt8Ty(), IRB
.getInt8Ty());
346 SanCovTraceCmpFunction
[1] =
347 M
.getOrInsertFunction(SanCovTraceCmp2
, SanCovTraceCmpZeroExtAL
, VoidTy
,
348 IRB
.getInt16Ty(), IRB
.getInt16Ty());
349 SanCovTraceCmpFunction
[2] =
350 M
.getOrInsertFunction(SanCovTraceCmp4
, SanCovTraceCmpZeroExtAL
, VoidTy
,
351 IRB
.getInt32Ty(), IRB
.getInt32Ty());
352 SanCovTraceCmpFunction
[3] =
353 M
.getOrInsertFunction(SanCovTraceCmp8
, VoidTy
, Int64Ty
, Int64Ty
);
355 SanCovTraceConstCmpFunction
[0] = M
.getOrInsertFunction(
356 SanCovTraceConstCmp1
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int8Ty
, Int8Ty
);
357 SanCovTraceConstCmpFunction
[1] = M
.getOrInsertFunction(
358 SanCovTraceConstCmp2
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int16Ty
, Int16Ty
);
359 SanCovTraceConstCmpFunction
[2] = M
.getOrInsertFunction(
360 SanCovTraceConstCmp4
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int32Ty
, Int32Ty
);
361 SanCovTraceConstCmpFunction
[3] =
362 M
.getOrInsertFunction(SanCovTraceConstCmp8
, VoidTy
, Int64Ty
, Int64Ty
);
366 if (TargetTriple
.getArch() == Triple::x86_64
)
367 AL
= AL
.addParamAttribute(*C
, 0, Attribute::ZExt
);
368 SanCovTraceDivFunction
[0] =
369 M
.getOrInsertFunction(SanCovTraceDiv4
, AL
, VoidTy
, IRB
.getInt32Ty());
371 SanCovTraceDivFunction
[1] =
372 M
.getOrInsertFunction(SanCovTraceDiv8
, VoidTy
, Int64Ty
);
373 SanCovTraceGepFunction
=
374 M
.getOrInsertFunction(SanCovTraceGep
, VoidTy
, IntptrTy
);
375 SanCovTraceSwitchFunction
=
376 M
.getOrInsertFunction(SanCovTraceSwitchName
, VoidTy
, Int64Ty
, Int64PtrTy
);
378 Constant
*SanCovLowestStackConstant
=
379 M
.getOrInsertGlobal(SanCovLowestStackName
, IntptrTy
);
380 SanCovLowestStack
= dyn_cast
<GlobalVariable
>(SanCovLowestStackConstant
);
381 if (!SanCovLowestStack
) {
382 C
->emitError(StringRef("'") + SanCovLowestStackName
+
383 "' should not be declared by the user");
386 SanCovLowestStack
->setThreadLocalMode(
387 GlobalValue::ThreadLocalMode::InitialExecTLSModel
);
388 if (Options
.StackDepth
&& !SanCovLowestStack
->isDeclaration())
389 SanCovLowestStack
->setInitializer(Constant::getAllOnesValue(IntptrTy
));
391 // We insert an empty inline asm after cov callbacks to avoid callback merge.
392 EmptyAsm
= InlineAsm::get(FunctionType::get(IRB
.getVoidTy(), false),
393 StringRef(""), StringRef(""),
394 /*hasSideEffects=*/true);
396 SanCovTracePC
= M
.getOrInsertFunction(SanCovTracePCName
, VoidTy
);
398 M
.getOrInsertFunction(SanCovTracePCGuardName
, VoidTy
, Int32PtrTy
);
403 Function
*Ctor
= nullptr;
405 if (FunctionGuardArray
)
406 Ctor
= CreateInitCallsForSections(M
, SanCovTracePCGuardInitName
, Int32PtrTy
,
407 SanCovGuardsSectionName
);
408 if (Function8bitCounterArray
)
409 Ctor
= CreateInitCallsForSections(M
, SanCov8bitCountersInitName
, Int8PtrTy
,
410 SanCovCountersSectionName
);
411 if (Ctor
&& Options
.PCTable
) {
412 auto SecStartEnd
= CreateSecStartEnd(M
, SanCovPCsSectionName
, IntptrPtrTy
);
413 FunctionCallee InitFunction
= declareSanitizerInitFunction(
414 M
, SanCovPCsInitName
, {IntptrPtrTy
, IntptrPtrTy
});
415 IRBuilder
<> IRBCtor(Ctor
->getEntryBlock().getTerminator());
416 IRBCtor
.CreateCall(InitFunction
, {SecStartEnd
.first
, SecStartEnd
.second
});
418 // We don't reference these arrays directly in any of our runtime functions,
419 // so we need to prevent them from being dead stripped.
420 if (TargetTriple
.isOSBinFormatMachO())
421 appendToUsed(M
, GlobalsToAppendToUsed
);
422 appendToCompilerUsed(M
, GlobalsToAppendToCompilerUsed
);
426 // True if block has successors and it dominates all of them.
427 static bool isFullDominator(const BasicBlock
*BB
, const DominatorTree
*DT
) {
428 if (succ_begin(BB
) == succ_end(BB
))
431 for (const BasicBlock
*SUCC
: make_range(succ_begin(BB
), succ_end(BB
))) {
432 if (!DT
->dominates(BB
, SUCC
))
439 // True if block has predecessors and it postdominates all of them.
440 static bool isFullPostDominator(const BasicBlock
*BB
,
441 const PostDominatorTree
*PDT
) {
442 if (pred_begin(BB
) == pred_end(BB
))
445 for (const BasicBlock
*PRED
: make_range(pred_begin(BB
), pred_end(BB
))) {
446 if (!PDT
->dominates(BB
, PRED
))
453 static bool shouldInstrumentBlock(const Function
&F
, const BasicBlock
*BB
,
454 const DominatorTree
*DT
,
455 const PostDominatorTree
*PDT
,
456 const SanitizerCoverageOptions
&Options
) {
457 // Don't insert coverage for unreachable blocks: we will never call
458 // __sanitizer_cov() for them, so counting them in
459 // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
460 // percentage. Also, unreachable instructions frequently have no debug
462 if (isa
<UnreachableInst
>(BB
->getTerminator()))
465 // Don't insert coverage into blocks without a valid insertion point
466 // (catchswitch blocks).
467 if (BB
->getFirstInsertionPt() == BB
->end())
470 if (Options
.NoPrune
|| &F
.getEntryBlock() == BB
)
473 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_Function
&&
474 &F
.getEntryBlock() != BB
)
477 // Do not instrument full dominators, or full post-dominators with multiple
479 return !isFullDominator(BB
, DT
)
480 && !(isFullPostDominator(BB
, PDT
) && !BB
->getSinglePredecessor());
484 // Returns true iff From->To is a backedge.
485 // A twist here is that we treat From->To as a backedge if
486 // * To dominates From or
487 // * To->UniqueSuccessor dominates From
488 static bool IsBackEdge(BasicBlock
*From
, BasicBlock
*To
,
489 const DominatorTree
*DT
) {
490 if (DT
->dominates(To
, From
))
492 if (auto Next
= To
->getUniqueSuccessor())
493 if (DT
->dominates(Next
, From
))
498 // Prunes uninteresting Cmp instrumentation:
499 // * CMP instructions that feed into loop backedge branch.
501 // Note that Cmp pruning is controlled by the same flag as the
503 static bool IsInterestingCmp(ICmpInst
*CMP
, const DominatorTree
*DT
,
504 const SanitizerCoverageOptions
&Options
) {
505 if (!Options
.NoPrune
)
506 if (CMP
->hasOneUse())
507 if (auto BR
= dyn_cast
<BranchInst
>(CMP
->user_back()))
508 for (BasicBlock
*B
: BR
->successors())
509 if (IsBackEdge(BR
->getParent(), B
, DT
))
514 bool SanitizerCoverageModule::runOnFunction(Function
&F
) {
517 if (F
.getName().find(".module_ctor") != std::string::npos
)
518 return false; // Should not instrument sanitizer init functions.
519 if (F
.getName().startswith("__sanitizer_"))
520 return false; // Don't instrument __sanitizer_* callbacks.
521 // Don't touch available_externally functions, their actual body is elewhere.
522 if (F
.getLinkage() == GlobalValue::AvailableExternallyLinkage
)
524 // Don't instrument MSVC CRT configuration helpers. They may run before normal
526 if (F
.getName() == "__local_stdio_printf_options" ||
527 F
.getName() == "__local_stdio_scanf_options")
529 if (isa
<UnreachableInst
>(F
.getEntryBlock().getTerminator()))
531 // Don't instrument functions using SEH for now. Splitting basic blocks like
532 // we do for coverage breaks WinEHPrepare.
533 // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
534 if (F
.hasPersonalityFn() &&
535 isAsynchronousEHPersonality(classifyEHPersonality(F
.getPersonalityFn())))
537 if (Options
.CoverageType
>= SanitizerCoverageOptions::SCK_Edge
)
538 SplitAllCriticalEdges(F
);
539 SmallVector
<Instruction
*, 8> IndirCalls
;
540 SmallVector
<BasicBlock
*, 16> BlocksToInstrument
;
541 SmallVector
<Instruction
*, 8> CmpTraceTargets
;
542 SmallVector
<Instruction
*, 8> SwitchTraceTargets
;
543 SmallVector
<BinaryOperator
*, 8> DivTraceTargets
;
544 SmallVector
<GetElementPtrInst
*, 8> GepTraceTargets
;
546 const DominatorTree
*DT
=
547 &getAnalysis
<DominatorTreeWrapperPass
>(F
).getDomTree();
548 const PostDominatorTree
*PDT
=
549 &getAnalysis
<PostDominatorTreeWrapperPass
>(F
).getPostDomTree();
550 bool IsLeafFunc
= true;
553 if (shouldInstrumentBlock(F
, &BB
, DT
, PDT
, Options
))
554 BlocksToInstrument
.push_back(&BB
);
555 for (auto &Inst
: BB
) {
556 if (Options
.IndirectCalls
) {
558 if (CS
&& !CS
.getCalledFunction())
559 IndirCalls
.push_back(&Inst
);
561 if (Options
.TraceCmp
) {
562 if (ICmpInst
*CMP
= dyn_cast
<ICmpInst
>(&Inst
))
563 if (IsInterestingCmp(CMP
, DT
, Options
))
564 CmpTraceTargets
.push_back(&Inst
);
565 if (isa
<SwitchInst
>(&Inst
))
566 SwitchTraceTargets
.push_back(&Inst
);
568 if (Options
.TraceDiv
)
569 if (BinaryOperator
*BO
= dyn_cast
<BinaryOperator
>(&Inst
))
570 if (BO
->getOpcode() == Instruction::SDiv
||
571 BO
->getOpcode() == Instruction::UDiv
)
572 DivTraceTargets
.push_back(BO
);
573 if (Options
.TraceGep
)
574 if (GetElementPtrInst
*GEP
= dyn_cast
<GetElementPtrInst
>(&Inst
))
575 GepTraceTargets
.push_back(GEP
);
576 if (Options
.StackDepth
)
577 if (isa
<InvokeInst
>(Inst
) ||
578 (isa
<CallInst
>(Inst
) && !isa
<IntrinsicInst
>(Inst
)))
583 InjectCoverage(F
, BlocksToInstrument
, IsLeafFunc
);
584 InjectCoverageForIndirectCalls(F
, IndirCalls
);
585 InjectTraceForCmp(F
, CmpTraceTargets
);
586 InjectTraceForSwitch(F
, SwitchTraceTargets
);
587 InjectTraceForDiv(F
, DivTraceTargets
);
588 InjectTraceForGep(F
, GepTraceTargets
);
592 GlobalVariable
*SanitizerCoverageModule::CreateFunctionLocalArrayInSection(
593 size_t NumElements
, Function
&F
, Type
*Ty
, const char *Section
) {
594 ArrayType
*ArrayTy
= ArrayType::get(Ty
, NumElements
);
595 auto Array
= new GlobalVariable(
596 *CurModule
, ArrayTy
, false, GlobalVariable::PrivateLinkage
,
597 Constant::getNullValue(ArrayTy
), "__sancov_gen_");
599 if (TargetTriple
.supportsCOMDAT() && !F
.isInterposable())
601 GetOrCreateFunctionComdat(F
, TargetTriple
, CurModuleUniqueId
))
602 Array
->setComdat(Comdat
);
603 Array
->setSection(getSectionName(Section
));
604 Array
->setAlignment(Ty
->isPointerTy() ? DL
->getPointerSize()
605 : Ty
->getPrimitiveSizeInBits() / 8);
606 GlobalsToAppendToUsed
.push_back(Array
);
607 GlobalsToAppendToCompilerUsed
.push_back(Array
);
608 MDNode
*MD
= MDNode::get(F
.getContext(), ValueAsMetadata::get(&F
));
609 Array
->addMetadata(LLVMContext::MD_associated
, *MD
);
615 SanitizerCoverageModule::CreatePCArray(Function
&F
,
616 ArrayRef
<BasicBlock
*> AllBlocks
) {
617 size_t N
= AllBlocks
.size();
619 SmallVector
<Constant
*, 32> PCs
;
620 IRBuilder
<> IRB(&*F
.getEntryBlock().getFirstInsertionPt());
621 for (size_t i
= 0; i
< N
; i
++) {
622 if (&F
.getEntryBlock() == AllBlocks
[i
]) {
623 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(&F
, IntptrPtrTy
));
624 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
625 ConstantInt::get(IntptrTy
, 1), IntptrPtrTy
));
627 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(
628 BlockAddress::get(AllBlocks
[i
]), IntptrPtrTy
));
629 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
630 ConstantInt::get(IntptrTy
, 0), IntptrPtrTy
));
633 auto *PCArray
= CreateFunctionLocalArrayInSection(N
* 2, F
, IntptrPtrTy
,
634 SanCovPCsSectionName
);
635 PCArray
->setInitializer(
636 ConstantArray::get(ArrayType::get(IntptrPtrTy
, N
* 2), PCs
));
637 PCArray
->setConstant(true);
642 void SanitizerCoverageModule::CreateFunctionLocalArrays(
643 Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
) {
644 if (Options
.TracePCGuard
)
645 FunctionGuardArray
= CreateFunctionLocalArrayInSection(
646 AllBlocks
.size(), F
, Int32Ty
, SanCovGuardsSectionName
);
648 if (Options
.Inline8bitCounters
)
649 Function8bitCounterArray
= CreateFunctionLocalArrayInSection(
650 AllBlocks
.size(), F
, Int8Ty
, SanCovCountersSectionName
);
653 FunctionPCsArray
= CreatePCArray(F
, AllBlocks
);
656 bool SanitizerCoverageModule::InjectCoverage(Function
&F
,
657 ArrayRef
<BasicBlock
*> AllBlocks
,
659 if (AllBlocks
.empty()) return false;
660 CreateFunctionLocalArrays(F
, AllBlocks
);
661 for (size_t i
= 0, N
= AllBlocks
.size(); i
< N
; i
++)
662 InjectCoverageAtBlock(F
, *AllBlocks
[i
], i
, IsLeafFunc
);
666 // On every indirect call we call a run-time function
667 // __sanitizer_cov_indir_call* with two parameters:
669 // - global cache array that contains CacheSize pointers (zero-initialized).
670 // The cache is used to speed up recording the caller-callee pairs.
671 // The address of the caller is passed implicitly via caller PC.
672 // CacheSize is encoded in the name of the run-time function.
673 void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
674 Function
&F
, ArrayRef
<Instruction
*> IndirCalls
) {
675 if (IndirCalls
.empty())
677 assert(Options
.TracePC
|| Options
.TracePCGuard
|| Options
.Inline8bitCounters
);
678 for (auto I
: IndirCalls
) {
681 Value
*Callee
= CS
.getCalledValue();
682 if (isa
<InlineAsm
>(Callee
))
684 IRB
.CreateCall(SanCovTracePCIndir
, IRB
.CreatePointerCast(Callee
, IntptrTy
));
688 // For every switch statement we insert a call:
689 // __sanitizer_cov_trace_switch(CondValue,
690 // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
692 void SanitizerCoverageModule::InjectTraceForSwitch(
693 Function
&, ArrayRef
<Instruction
*> SwitchTraceTargets
) {
694 for (auto I
: SwitchTraceTargets
) {
695 if (SwitchInst
*SI
= dyn_cast
<SwitchInst
>(I
)) {
697 SmallVector
<Constant
*, 16> Initializers
;
698 Value
*Cond
= SI
->getCondition();
699 if (Cond
->getType()->getScalarSizeInBits() >
700 Int64Ty
->getScalarSizeInBits())
702 Initializers
.push_back(ConstantInt::get(Int64Ty
, SI
->getNumCases()));
703 Initializers
.push_back(
704 ConstantInt::get(Int64Ty
, Cond
->getType()->getScalarSizeInBits()));
705 if (Cond
->getType()->getScalarSizeInBits() <
706 Int64Ty
->getScalarSizeInBits())
707 Cond
= IRB
.CreateIntCast(Cond
, Int64Ty
, false);
708 for (auto It
: SI
->cases()) {
709 Constant
*C
= It
.getCaseValue();
710 if (C
->getType()->getScalarSizeInBits() <
711 Int64Ty
->getScalarSizeInBits())
712 C
= ConstantExpr::getCast(CastInst::ZExt
, It
.getCaseValue(), Int64Ty
);
713 Initializers
.push_back(C
);
715 llvm::sort(Initializers
.begin() + 2, Initializers
.end(),
716 [](const Constant
*A
, const Constant
*B
) {
717 return cast
<ConstantInt
>(A
)->getLimitedValue() <
718 cast
<ConstantInt
>(B
)->getLimitedValue();
720 ArrayType
*ArrayOfInt64Ty
= ArrayType::get(Int64Ty
, Initializers
.size());
721 GlobalVariable
*GV
= new GlobalVariable(
722 *CurModule
, ArrayOfInt64Ty
, false, GlobalVariable::InternalLinkage
,
723 ConstantArray::get(ArrayOfInt64Ty
, Initializers
),
724 "__sancov_gen_cov_switch_values");
725 IRB
.CreateCall(SanCovTraceSwitchFunction
,
726 {Cond
, IRB
.CreatePointerCast(GV
, Int64PtrTy
)});
731 void SanitizerCoverageModule::InjectTraceForDiv(
732 Function
&, ArrayRef
<BinaryOperator
*> DivTraceTargets
) {
733 for (auto BO
: DivTraceTargets
) {
735 Value
*A1
= BO
->getOperand(1);
736 if (isa
<ConstantInt
>(A1
)) continue;
737 if (!A1
->getType()->isIntegerTy())
739 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A1
->getType());
740 int CallbackIdx
= TypeSize
== 32 ? 0 :
741 TypeSize
== 64 ? 1 : -1;
742 if (CallbackIdx
< 0) continue;
743 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
744 IRB
.CreateCall(SanCovTraceDivFunction
[CallbackIdx
],
745 {IRB
.CreateIntCast(A1
, Ty
, true)});
749 void SanitizerCoverageModule::InjectTraceForGep(
750 Function
&, ArrayRef
<GetElementPtrInst
*> GepTraceTargets
) {
751 for (auto GEP
: GepTraceTargets
) {
752 IRBuilder
<> IRB(GEP
);
753 for (auto I
= GEP
->idx_begin(); I
!= GEP
->idx_end(); ++I
)
754 if (!isa
<ConstantInt
>(*I
) && (*I
)->getType()->isIntegerTy())
755 IRB
.CreateCall(SanCovTraceGepFunction
,
756 {IRB
.CreateIntCast(*I
, IntptrTy
, true)});
760 void SanitizerCoverageModule::InjectTraceForCmp(
761 Function
&, ArrayRef
<Instruction
*> CmpTraceTargets
) {
762 for (auto I
: CmpTraceTargets
) {
763 if (ICmpInst
*ICMP
= dyn_cast
<ICmpInst
>(I
)) {
764 IRBuilder
<> IRB(ICMP
);
765 Value
*A0
= ICMP
->getOperand(0);
766 Value
*A1
= ICMP
->getOperand(1);
767 if (!A0
->getType()->isIntegerTy())
769 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A0
->getType());
770 int CallbackIdx
= TypeSize
== 8 ? 0 :
773 TypeSize
== 64 ? 3 : -1;
774 if (CallbackIdx
< 0) continue;
775 // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
776 auto CallbackFunc
= SanCovTraceCmpFunction
[CallbackIdx
];
777 bool FirstIsConst
= isa
<ConstantInt
>(A0
);
778 bool SecondIsConst
= isa
<ConstantInt
>(A1
);
779 // If both are const, then we don't need such a comparison.
780 if (FirstIsConst
&& SecondIsConst
) continue;
781 // If only one is const, then make it the first callback argument.
782 if (FirstIsConst
|| SecondIsConst
) {
783 CallbackFunc
= SanCovTraceConstCmpFunction
[CallbackIdx
];
788 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
789 IRB
.CreateCall(CallbackFunc
, {IRB
.CreateIntCast(A0
, Ty
, true),
790 IRB
.CreateIntCast(A1
, Ty
, true)});
795 void SanitizerCoverageModule::InjectCoverageAtBlock(Function
&F
, BasicBlock
&BB
,
798 BasicBlock::iterator IP
= BB
.getFirstInsertionPt();
799 bool IsEntryBB
= &BB
== &F
.getEntryBlock();
802 if (auto SP
= F
.getSubprogram())
803 EntryLoc
= DebugLoc::get(SP
->getScopeLine(), 0, SP
);
804 // Keep static allocas and llvm.localescape calls in the entry block. Even
805 // if we aren't splitting the block, it's nice for allocas to be before
807 IP
= PrepareToSplitEntryBlock(BB
, IP
);
809 EntryLoc
= IP
->getDebugLoc();
812 IRBuilder
<> IRB(&*IP
);
813 IRB
.SetCurrentDebugLocation(EntryLoc
);
814 if (Options
.TracePC
) {
815 IRB
.CreateCall(SanCovTracePC
); // gets the PC using GET_CALLER_PC.
816 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
818 if (Options
.TracePCGuard
) {
819 auto GuardPtr
= IRB
.CreateIntToPtr(
820 IRB
.CreateAdd(IRB
.CreatePointerCast(FunctionGuardArray
, IntptrTy
),
821 ConstantInt::get(IntptrTy
, Idx
* 4)),
823 IRB
.CreateCall(SanCovTracePCGuard
, GuardPtr
);
824 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
826 if (Options
.Inline8bitCounters
) {
827 auto CounterPtr
= IRB
.CreateGEP(
828 Function8bitCounterArray
->getValueType(), Function8bitCounterArray
,
829 {ConstantInt::get(IntptrTy
, 0), ConstantInt::get(IntptrTy
, Idx
)});
830 auto Load
= IRB
.CreateLoad(Int8Ty
, CounterPtr
);
831 auto Inc
= IRB
.CreateAdd(Load
, ConstantInt::get(Int8Ty
, 1));
832 auto Store
= IRB
.CreateStore(Inc
, CounterPtr
);
833 SetNoSanitizeMetadata(Load
);
834 SetNoSanitizeMetadata(Store
);
836 if (Options
.StackDepth
&& IsEntryBB
&& !IsLeafFunc
) {
837 // Check stack depth. If it's the deepest so far, record it.
838 Function
*GetFrameAddr
=
839 Intrinsic::getDeclaration(F
.getParent(), Intrinsic::frameaddress
);
841 IRB
.CreateCall(GetFrameAddr
, {Constant::getNullValue(Int32Ty
)});
842 auto FrameAddrInt
= IRB
.CreatePtrToInt(FrameAddrPtr
, IntptrTy
);
843 auto LowestStack
= IRB
.CreateLoad(IntptrTy
, SanCovLowestStack
);
844 auto IsStackLower
= IRB
.CreateICmpULT(FrameAddrInt
, LowestStack
);
845 auto ThenTerm
= SplitBlockAndInsertIfThen(IsStackLower
, &*IP
, false);
846 IRBuilder
<> ThenIRB(ThenTerm
);
847 auto Store
= ThenIRB
.CreateStore(FrameAddrInt
, SanCovLowestStack
);
848 SetNoSanitizeMetadata(LowestStack
);
849 SetNoSanitizeMetadata(Store
);
854 SanitizerCoverageModule::getSectionName(const std::string
&Section
) const {
855 if (TargetTriple
.isOSBinFormatCOFF()) {
856 if (Section
== SanCovCountersSectionName
)
858 if (Section
== SanCovPCsSectionName
)
860 return ".SCOV$GM"; // For SanCovGuardsSectionName.
862 if (TargetTriple
.isOSBinFormatMachO())
863 return "__DATA,__" + Section
;
864 return "__" + Section
;
868 SanitizerCoverageModule::getSectionStart(const std::string
&Section
) const {
869 if (TargetTriple
.isOSBinFormatMachO())
870 return "\1section$start$__DATA$__" + Section
;
871 return "__start___" + Section
;
875 SanitizerCoverageModule::getSectionEnd(const std::string
&Section
) const {
876 if (TargetTriple
.isOSBinFormatMachO())
877 return "\1section$end$__DATA$__" + Section
;
878 return "__stop___" + Section
;
882 char SanitizerCoverageModule::ID
= 0;
883 INITIALIZE_PASS_BEGIN(SanitizerCoverageModule
, "sancov",
884 "SanitizerCoverage: TODO."
887 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass
)
888 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass
)
889 INITIALIZE_PASS_END(SanitizerCoverageModule
, "sancov",
890 "SanitizerCoverage: TODO."
893 ModulePass
*llvm::createSanitizerCoverageModulePass(
894 const SanitizerCoverageOptions
&Options
) {
895 return new SanitizerCoverageModule(Options
);