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/Transforms/Instrumentation/SanitizerCoverage.h"
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/Constant.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/DebugInfo.h"
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/GlobalVariable.h"
26 #include "llvm/IR/IRBuilder.h"
27 #include "llvm/IR/InlineAsm.h"
28 #include "llvm/IR/IntrinsicInst.h"
29 #include "llvm/IR/Intrinsics.h"
30 #include "llvm/IR/LLVMContext.h"
31 #include "llvm/IR/MDBuilder.h"
32 #include "llvm/IR/Mangler.h"
33 #include "llvm/IR/Module.h"
34 #include "llvm/IR/Type.h"
35 #include "llvm/Support/CommandLine.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/raw_ostream.h"
38 #include "llvm/Transforms/Instrumentation.h"
39 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
40 #include "llvm/Transforms/Utils/ModuleUtils.h"
44 #define DEBUG_TYPE "sancov"
46 static const char *const SanCovTracePCIndirName
=
47 "__sanitizer_cov_trace_pc_indir";
48 static const char *const SanCovTracePCName
= "__sanitizer_cov_trace_pc";
49 static const char *const SanCovTraceCmp1
= "__sanitizer_cov_trace_cmp1";
50 static const char *const SanCovTraceCmp2
= "__sanitizer_cov_trace_cmp2";
51 static const char *const SanCovTraceCmp4
= "__sanitizer_cov_trace_cmp4";
52 static const char *const SanCovTraceCmp8
= "__sanitizer_cov_trace_cmp8";
53 static const char *const SanCovTraceConstCmp1
=
54 "__sanitizer_cov_trace_const_cmp1";
55 static const char *const SanCovTraceConstCmp2
=
56 "__sanitizer_cov_trace_const_cmp2";
57 static const char *const SanCovTraceConstCmp4
=
58 "__sanitizer_cov_trace_const_cmp4";
59 static const char *const SanCovTraceConstCmp8
=
60 "__sanitizer_cov_trace_const_cmp8";
61 static const char *const SanCovTraceDiv4
= "__sanitizer_cov_trace_div4";
62 static const char *const SanCovTraceDiv8
= "__sanitizer_cov_trace_div8";
63 static const char *const SanCovTraceGep
= "__sanitizer_cov_trace_gep";
64 static const char *const SanCovTraceSwitchName
= "__sanitizer_cov_trace_switch";
65 static const char *const SanCovModuleCtorTracePcGuardName
=
66 "sancov.module_ctor_trace_pc_guard";
67 static const char *const SanCovModuleCtor8bitCountersName
=
68 "sancov.module_ctor_8bit_counters";
69 static const uint64_t SanCtorAndDtorPriority
= 2;
71 static const char *const SanCovTracePCGuardName
=
72 "__sanitizer_cov_trace_pc_guard";
73 static const char *const SanCovTracePCGuardInitName
=
74 "__sanitizer_cov_trace_pc_guard_init";
75 static const char *const SanCov8bitCountersInitName
=
76 "__sanitizer_cov_8bit_counters_init";
77 static const char *const SanCovPCsInitName
= "__sanitizer_cov_pcs_init";
79 static const char *const SanCovGuardsSectionName
= "sancov_guards";
80 static const char *const SanCovCountersSectionName
= "sancov_cntrs";
81 static const char *const SanCovPCsSectionName
= "sancov_pcs";
83 static const char *const SanCovLowestStackName
= "__sancov_lowest_stack";
85 static cl::opt
<int> ClCoverageLevel(
86 "sanitizer-coverage-level",
87 cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
88 "3: all blocks and critical edges"),
89 cl::Hidden
, cl::init(0));
91 static cl::opt
<bool> ClTracePC("sanitizer-coverage-trace-pc",
92 cl::desc("Experimental pc tracing"), cl::Hidden
,
95 static cl::opt
<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
96 cl::desc("pc tracing with a guard"),
97 cl::Hidden
, cl::init(false));
99 // If true, we create a global variable that contains PCs of all instrumented
100 // BBs, put this global into a named section, and pass this section's bounds
101 // to __sanitizer_cov_pcs_init.
102 // This way the coverage instrumentation does not need to acquire the PCs
103 // at run-time. Works with trace-pc-guard and inline-8bit-counters.
104 static cl::opt
<bool> ClCreatePCTable("sanitizer-coverage-pc-table",
105 cl::desc("create a static PC table"),
106 cl::Hidden
, cl::init(false));
109 ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters",
110 cl::desc("increments 8-bit counter for every edge"),
111 cl::Hidden
, cl::init(false));
114 ClCMPTracing("sanitizer-coverage-trace-compares",
115 cl::desc("Tracing of CMP and similar instructions"),
116 cl::Hidden
, cl::init(false));
118 static cl::opt
<bool> ClDIVTracing("sanitizer-coverage-trace-divs",
119 cl::desc("Tracing of DIV instructions"),
120 cl::Hidden
, cl::init(false));
122 static cl::opt
<bool> ClGEPTracing("sanitizer-coverage-trace-geps",
123 cl::desc("Tracing of GEP instructions"),
124 cl::Hidden
, cl::init(false));
127 ClPruneBlocks("sanitizer-coverage-prune-blocks",
128 cl::desc("Reduce the number of instrumented blocks"),
129 cl::Hidden
, cl::init(true));
131 static cl::opt
<bool> ClStackDepth("sanitizer-coverage-stack-depth",
132 cl::desc("max stack depth tracing"),
133 cl::Hidden
, cl::init(false));
137 SanitizerCoverageOptions
getOptions(int LegacyCoverageLevel
) {
138 SanitizerCoverageOptions Res
;
139 switch (LegacyCoverageLevel
) {
141 Res
.CoverageType
= SanitizerCoverageOptions::SCK_None
;
144 Res
.CoverageType
= SanitizerCoverageOptions::SCK_Function
;
147 Res
.CoverageType
= SanitizerCoverageOptions::SCK_BB
;
150 Res
.CoverageType
= SanitizerCoverageOptions::SCK_Edge
;
153 Res
.CoverageType
= SanitizerCoverageOptions::SCK_Edge
;
154 Res
.IndirectCalls
= true;
160 SanitizerCoverageOptions
OverrideFromCL(SanitizerCoverageOptions Options
) {
161 // Sets CoverageType and IndirectCalls.
162 SanitizerCoverageOptions CLOpts
= getOptions(ClCoverageLevel
);
163 Options
.CoverageType
= std::max(Options
.CoverageType
, CLOpts
.CoverageType
);
164 Options
.IndirectCalls
|= CLOpts
.IndirectCalls
;
165 Options
.TraceCmp
|= ClCMPTracing
;
166 Options
.TraceDiv
|= ClDIVTracing
;
167 Options
.TraceGep
|= ClGEPTracing
;
168 Options
.TracePC
|= ClTracePC
;
169 Options
.TracePCGuard
|= ClTracePCGuard
;
170 Options
.Inline8bitCounters
|= ClInline8bitCounters
;
171 Options
.PCTable
|= ClCreatePCTable
;
172 Options
.NoPrune
|= !ClPruneBlocks
;
173 Options
.StackDepth
|= ClStackDepth
;
174 if (!Options
.TracePCGuard
&& !Options
.TracePC
&&
175 !Options
.Inline8bitCounters
&& !Options
.StackDepth
)
176 Options
.TracePCGuard
= true; // TracePCGuard is default.
180 using DomTreeCallback
= function_ref
<const DominatorTree
*(Function
&F
)>;
181 using PostDomTreeCallback
=
182 function_ref
<const PostDominatorTree
*(Function
&F
)>;
184 class ModuleSanitizerCoverage
{
186 ModuleSanitizerCoverage(
187 const SanitizerCoverageOptions
&Options
= SanitizerCoverageOptions())
188 : Options(OverrideFromCL(Options
)) {}
189 bool instrumentModule(Module
&M
, DomTreeCallback DTCallback
,
190 PostDomTreeCallback PDTCallback
);
193 void instrumentFunction(Function
&F
, DomTreeCallback DTCallback
,
194 PostDomTreeCallback PDTCallback
);
195 void InjectCoverageForIndirectCalls(Function
&F
,
196 ArrayRef
<Instruction
*> IndirCalls
);
197 void InjectTraceForCmp(Function
&F
, ArrayRef
<Instruction
*> CmpTraceTargets
);
198 void InjectTraceForDiv(Function
&F
,
199 ArrayRef
<BinaryOperator
*> DivTraceTargets
);
200 void InjectTraceForGep(Function
&F
,
201 ArrayRef
<GetElementPtrInst
*> GepTraceTargets
);
202 void InjectTraceForSwitch(Function
&F
,
203 ArrayRef
<Instruction
*> SwitchTraceTargets
);
204 bool InjectCoverage(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
,
205 bool IsLeafFunc
= true);
206 GlobalVariable
*CreateFunctionLocalArrayInSection(size_t NumElements
,
207 Function
&F
, Type
*Ty
,
208 const char *Section
);
209 GlobalVariable
*CreatePCArray(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
);
210 void CreateFunctionLocalArrays(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
);
211 void InjectCoverageAtBlock(Function
&F
, BasicBlock
&BB
, size_t Idx
,
212 bool IsLeafFunc
= true);
213 Function
*CreateInitCallsForSections(Module
&M
, const char *CtorName
,
214 const char *InitFunctionName
, Type
*Ty
,
215 const char *Section
);
216 std::pair
<Value
*, Value
*> CreateSecStartEnd(Module
&M
, const char *Section
,
219 void SetNoSanitizeMetadata(Instruction
*I
) {
220 I
->setMetadata(I
->getModule()->getMDKindID("nosanitize"),
221 MDNode::get(*C
, None
));
224 std::string
getSectionName(const std::string
&Section
) const;
225 std::string
getSectionStart(const std::string
&Section
) const;
226 std::string
getSectionEnd(const std::string
&Section
) const;
227 FunctionCallee SanCovTracePCIndir
;
228 FunctionCallee SanCovTracePC
, SanCovTracePCGuard
;
229 FunctionCallee SanCovTraceCmpFunction
[4];
230 FunctionCallee SanCovTraceConstCmpFunction
[4];
231 FunctionCallee SanCovTraceDivFunction
[2];
232 FunctionCallee SanCovTraceGepFunction
;
233 FunctionCallee SanCovTraceSwitchFunction
;
234 GlobalVariable
*SanCovLowestStack
;
236 Type
*IntptrTy
, *IntptrPtrTy
, *Int64Ty
, *Int64PtrTy
, *Int32Ty
, *Int32PtrTy
,
237 *Int16Ty
, *Int8Ty
, *Int8PtrTy
;
239 std::string CurModuleUniqueId
;
242 const DataLayout
*DL
;
244 GlobalVariable
*FunctionGuardArray
; // for trace-pc-guard.
245 GlobalVariable
*Function8bitCounterArray
; // for inline-8bit-counters.
246 GlobalVariable
*FunctionPCsArray
; // for pc-table.
247 SmallVector
<GlobalValue
*, 20> GlobalsToAppendToUsed
;
248 SmallVector
<GlobalValue
*, 20> GlobalsToAppendToCompilerUsed
;
250 SanitizerCoverageOptions Options
;
253 class ModuleSanitizerCoverageLegacyPass
: public ModulePass
{
255 ModuleSanitizerCoverageLegacyPass(
256 const SanitizerCoverageOptions
&Options
= SanitizerCoverageOptions())
257 : ModulePass(ID
), Options(Options
) {
258 initializeModuleSanitizerCoverageLegacyPassPass(
259 *PassRegistry::getPassRegistry());
261 bool runOnModule(Module
&M
) override
{
262 ModuleSanitizerCoverage
ModuleSancov(Options
);
263 auto DTCallback
= [this](Function
&F
) -> const DominatorTree
* {
264 return &this->getAnalysis
<DominatorTreeWrapperPass
>(F
).getDomTree();
266 auto PDTCallback
= [this](Function
&F
) -> const PostDominatorTree
* {
267 return &this->getAnalysis
<PostDominatorTreeWrapperPass
>(F
)
270 return ModuleSancov
.instrumentModule(M
, DTCallback
, PDTCallback
);
273 static char ID
; // Pass identification, replacement for typeid
274 StringRef
getPassName() const override
{ return "ModuleSanitizerCoverage"; }
276 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
277 AU
.addRequired
<DominatorTreeWrapperPass
>();
278 AU
.addRequired
<PostDominatorTreeWrapperPass
>();
282 SanitizerCoverageOptions Options
;
287 PreservedAnalyses
ModuleSanitizerCoveragePass::run(Module
&M
,
288 ModuleAnalysisManager
&MAM
) {
289 ModuleSanitizerCoverage
ModuleSancov(Options
);
290 auto &FAM
= MAM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
291 auto DTCallback
= [&FAM
](Function
&F
) -> const DominatorTree
* {
292 return &FAM
.getResult
<DominatorTreeAnalysis
>(F
);
294 auto PDTCallback
= [&FAM
](Function
&F
) -> const PostDominatorTree
* {
295 return &FAM
.getResult
<PostDominatorTreeAnalysis
>(F
);
297 if (ModuleSancov
.instrumentModule(M
, DTCallback
, PDTCallback
))
298 return PreservedAnalyses::none();
299 return PreservedAnalyses::all();
302 std::pair
<Value
*, Value
*>
303 ModuleSanitizerCoverage::CreateSecStartEnd(Module
&M
, const char *Section
,
305 GlobalVariable
*SecStart
=
306 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
, nullptr,
307 getSectionStart(Section
));
308 SecStart
->setVisibility(GlobalValue::HiddenVisibility
);
309 GlobalVariable
*SecEnd
=
310 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
,
311 nullptr, getSectionEnd(Section
));
312 SecEnd
->setVisibility(GlobalValue::HiddenVisibility
);
313 IRBuilder
<> IRB(M
.getContext());
314 Value
*SecEndPtr
= IRB
.CreatePointerCast(SecEnd
, Ty
);
315 if (!TargetTriple
.isOSBinFormatCOFF())
316 return std::make_pair(IRB
.CreatePointerCast(SecStart
, Ty
), SecEndPtr
);
318 // Account for the fact that on windows-msvc __start_* symbols actually
319 // point to a uint64_t before the start of the array.
320 auto SecStartI8Ptr
= IRB
.CreatePointerCast(SecStart
, Int8PtrTy
);
321 auto GEP
= IRB
.CreateGEP(Int8Ty
, SecStartI8Ptr
,
322 ConstantInt::get(IntptrTy
, sizeof(uint64_t)));
323 return std::make_pair(IRB
.CreatePointerCast(GEP
, Ty
), SecEndPtr
);
326 Function
*ModuleSanitizerCoverage::CreateInitCallsForSections(
327 Module
&M
, const char *CtorName
, const char *InitFunctionName
, Type
*Ty
,
328 const char *Section
) {
329 auto SecStartEnd
= CreateSecStartEnd(M
, Section
, Ty
);
330 auto SecStart
= SecStartEnd
.first
;
331 auto SecEnd
= SecStartEnd
.second
;
333 std::tie(CtorFunc
, std::ignore
) = createSanitizerCtorAndInitFunctions(
334 M
, CtorName
, InitFunctionName
, {Ty
, Ty
}, {SecStart
, SecEnd
});
335 assert(CtorFunc
->getName() == CtorName
);
337 if (TargetTriple
.supportsCOMDAT()) {
338 // Use comdat to dedup CtorFunc.
339 CtorFunc
->setComdat(M
.getOrInsertComdat(CtorName
));
340 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
, CtorFunc
);
342 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
);
345 if (TargetTriple
.isOSBinFormatCOFF()) {
346 // In COFF files, if the contructors are set as COMDAT (they are because
347 // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced
348 // functions and data) is used, the constructors get stripped. To prevent
349 // this, give the constructors weak ODR linkage and ensure the linker knows
350 // to include the sancov constructor. This way the linker can deduplicate
351 // the constructors but always leave one copy.
352 CtorFunc
->setLinkage(GlobalValue::WeakODRLinkage
);
353 appendToUsed(M
, CtorFunc
);
358 bool ModuleSanitizerCoverage::instrumentModule(
359 Module
&M
, DomTreeCallback DTCallback
, PostDomTreeCallback PDTCallback
) {
360 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_None
)
362 C
= &(M
.getContext());
363 DL
= &M
.getDataLayout();
365 CurModuleUniqueId
= getUniqueModuleId(CurModule
);
366 TargetTriple
= Triple(M
.getTargetTriple());
367 FunctionGuardArray
= nullptr;
368 Function8bitCounterArray
= nullptr;
369 FunctionPCsArray
= nullptr;
370 IntptrTy
= Type::getIntNTy(*C
, DL
->getPointerSizeInBits());
371 IntptrPtrTy
= PointerType::getUnqual(IntptrTy
);
372 Type
*VoidTy
= Type::getVoidTy(*C
);
374 Int64PtrTy
= PointerType::getUnqual(IRB
.getInt64Ty());
375 Int32PtrTy
= PointerType::getUnqual(IRB
.getInt32Ty());
376 Int8PtrTy
= PointerType::getUnqual(IRB
.getInt8Ty());
377 Int64Ty
= IRB
.getInt64Ty();
378 Int32Ty
= IRB
.getInt32Ty();
379 Int16Ty
= IRB
.getInt16Ty();
380 Int8Ty
= IRB
.getInt8Ty();
383 M
.getOrInsertFunction(SanCovTracePCIndirName
, VoidTy
, IntptrTy
);
384 // Make sure smaller parameters are zero-extended to i64 as required by the
386 AttributeList SanCovTraceCmpZeroExtAL
;
387 if (TargetTriple
.getArch() == Triple::x86_64
) {
388 SanCovTraceCmpZeroExtAL
=
389 SanCovTraceCmpZeroExtAL
.addParamAttribute(*C
, 0, Attribute::ZExt
);
390 SanCovTraceCmpZeroExtAL
=
391 SanCovTraceCmpZeroExtAL
.addParamAttribute(*C
, 1, Attribute::ZExt
);
394 SanCovTraceCmpFunction
[0] =
395 M
.getOrInsertFunction(SanCovTraceCmp1
, SanCovTraceCmpZeroExtAL
, VoidTy
,
396 IRB
.getInt8Ty(), IRB
.getInt8Ty());
397 SanCovTraceCmpFunction
[1] =
398 M
.getOrInsertFunction(SanCovTraceCmp2
, SanCovTraceCmpZeroExtAL
, VoidTy
,
399 IRB
.getInt16Ty(), IRB
.getInt16Ty());
400 SanCovTraceCmpFunction
[2] =
401 M
.getOrInsertFunction(SanCovTraceCmp4
, SanCovTraceCmpZeroExtAL
, VoidTy
,
402 IRB
.getInt32Ty(), IRB
.getInt32Ty());
403 SanCovTraceCmpFunction
[3] =
404 M
.getOrInsertFunction(SanCovTraceCmp8
, VoidTy
, Int64Ty
, Int64Ty
);
406 SanCovTraceConstCmpFunction
[0] = M
.getOrInsertFunction(
407 SanCovTraceConstCmp1
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int8Ty
, Int8Ty
);
408 SanCovTraceConstCmpFunction
[1] = M
.getOrInsertFunction(
409 SanCovTraceConstCmp2
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int16Ty
, Int16Ty
);
410 SanCovTraceConstCmpFunction
[2] = M
.getOrInsertFunction(
411 SanCovTraceConstCmp4
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int32Ty
, Int32Ty
);
412 SanCovTraceConstCmpFunction
[3] =
413 M
.getOrInsertFunction(SanCovTraceConstCmp8
, VoidTy
, Int64Ty
, Int64Ty
);
417 if (TargetTriple
.getArch() == Triple::x86_64
)
418 AL
= AL
.addParamAttribute(*C
, 0, Attribute::ZExt
);
419 SanCovTraceDivFunction
[0] =
420 M
.getOrInsertFunction(SanCovTraceDiv4
, AL
, VoidTy
, IRB
.getInt32Ty());
422 SanCovTraceDivFunction
[1] =
423 M
.getOrInsertFunction(SanCovTraceDiv8
, VoidTy
, Int64Ty
);
424 SanCovTraceGepFunction
=
425 M
.getOrInsertFunction(SanCovTraceGep
, VoidTy
, IntptrTy
);
426 SanCovTraceSwitchFunction
=
427 M
.getOrInsertFunction(SanCovTraceSwitchName
, VoidTy
, Int64Ty
, Int64PtrTy
);
429 Constant
*SanCovLowestStackConstant
=
430 M
.getOrInsertGlobal(SanCovLowestStackName
, IntptrTy
);
431 SanCovLowestStack
= dyn_cast
<GlobalVariable
>(SanCovLowestStackConstant
);
432 if (!SanCovLowestStack
) {
433 C
->emitError(StringRef("'") + SanCovLowestStackName
+
434 "' should not be declared by the user");
437 SanCovLowestStack
->setThreadLocalMode(
438 GlobalValue::ThreadLocalMode::InitialExecTLSModel
);
439 if (Options
.StackDepth
&& !SanCovLowestStack
->isDeclaration())
440 SanCovLowestStack
->setInitializer(Constant::getAllOnesValue(IntptrTy
));
442 // We insert an empty inline asm after cov callbacks to avoid callback merge.
443 EmptyAsm
= InlineAsm::get(FunctionType::get(IRB
.getVoidTy(), false),
444 StringRef(""), StringRef(""),
445 /*hasSideEffects=*/true);
447 SanCovTracePC
= M
.getOrInsertFunction(SanCovTracePCName
, VoidTy
);
449 M
.getOrInsertFunction(SanCovTracePCGuardName
, VoidTy
, Int32PtrTy
);
452 instrumentFunction(F
, DTCallback
, PDTCallback
);
454 Function
*Ctor
= nullptr;
456 if (FunctionGuardArray
)
457 Ctor
= CreateInitCallsForSections(M
, SanCovModuleCtorTracePcGuardName
,
458 SanCovTracePCGuardInitName
, Int32PtrTy
,
459 SanCovGuardsSectionName
);
460 if (Function8bitCounterArray
)
461 Ctor
= CreateInitCallsForSections(M
, SanCovModuleCtor8bitCountersName
,
462 SanCov8bitCountersInitName
, Int8PtrTy
,
463 SanCovCountersSectionName
);
464 if (Ctor
&& Options
.PCTable
) {
465 auto SecStartEnd
= CreateSecStartEnd(M
, SanCovPCsSectionName
, IntptrPtrTy
);
466 FunctionCallee InitFunction
= declareSanitizerInitFunction(
467 M
, SanCovPCsInitName
, {IntptrPtrTy
, IntptrPtrTy
});
468 IRBuilder
<> IRBCtor(Ctor
->getEntryBlock().getTerminator());
469 IRBCtor
.CreateCall(InitFunction
, {SecStartEnd
.first
, SecStartEnd
.second
});
471 // We don't reference these arrays directly in any of our runtime functions,
472 // so we need to prevent them from being dead stripped.
473 if (TargetTriple
.isOSBinFormatMachO())
474 appendToUsed(M
, GlobalsToAppendToUsed
);
475 appendToCompilerUsed(M
, GlobalsToAppendToCompilerUsed
);
479 // True if block has successors and it dominates all of them.
480 static bool isFullDominator(const BasicBlock
*BB
, const DominatorTree
*DT
) {
481 if (succ_begin(BB
) == succ_end(BB
))
484 for (const BasicBlock
*SUCC
: make_range(succ_begin(BB
), succ_end(BB
))) {
485 if (!DT
->dominates(BB
, SUCC
))
492 // True if block has predecessors and it postdominates all of them.
493 static bool isFullPostDominator(const BasicBlock
*BB
,
494 const PostDominatorTree
*PDT
) {
495 if (pred_begin(BB
) == pred_end(BB
))
498 for (const BasicBlock
*PRED
: make_range(pred_begin(BB
), pred_end(BB
))) {
499 if (!PDT
->dominates(BB
, PRED
))
506 static bool shouldInstrumentBlock(const Function
&F
, const BasicBlock
*BB
,
507 const DominatorTree
*DT
,
508 const PostDominatorTree
*PDT
,
509 const SanitizerCoverageOptions
&Options
) {
510 // Don't insert coverage for blocks containing nothing but unreachable: we
511 // will never call __sanitizer_cov() for them, so counting them in
512 // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
513 // percentage. Also, unreachable instructions frequently have no debug
515 if (isa
<UnreachableInst
>(BB
->getFirstNonPHIOrDbgOrLifetime()))
518 // Don't insert coverage into blocks without a valid insertion point
519 // (catchswitch blocks).
520 if (BB
->getFirstInsertionPt() == BB
->end())
523 if (Options
.NoPrune
|| &F
.getEntryBlock() == BB
)
526 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_Function
&&
527 &F
.getEntryBlock() != BB
)
530 // Do not instrument full dominators, or full post-dominators with multiple
532 return !isFullDominator(BB
, DT
)
533 && !(isFullPostDominator(BB
, PDT
) && !BB
->getSinglePredecessor());
537 // Returns true iff From->To is a backedge.
538 // A twist here is that we treat From->To as a backedge if
539 // * To dominates From or
540 // * To->UniqueSuccessor dominates From
541 static bool IsBackEdge(BasicBlock
*From
, BasicBlock
*To
,
542 const DominatorTree
*DT
) {
543 if (DT
->dominates(To
, From
))
545 if (auto Next
= To
->getUniqueSuccessor())
546 if (DT
->dominates(Next
, From
))
551 // Prunes uninteresting Cmp instrumentation:
552 // * CMP instructions that feed into loop backedge branch.
554 // Note that Cmp pruning is controlled by the same flag as the
556 static bool IsInterestingCmp(ICmpInst
*CMP
, const DominatorTree
*DT
,
557 const SanitizerCoverageOptions
&Options
) {
558 if (!Options
.NoPrune
)
559 if (CMP
->hasOneUse())
560 if (auto BR
= dyn_cast
<BranchInst
>(CMP
->user_back()))
561 for (BasicBlock
*B
: BR
->successors())
562 if (IsBackEdge(BR
->getParent(), B
, DT
))
567 void ModuleSanitizerCoverage::instrumentFunction(
568 Function
&F
, DomTreeCallback DTCallback
, PostDomTreeCallback PDTCallback
) {
571 if (F
.getName().find(".module_ctor") != std::string::npos
)
572 return; // Should not instrument sanitizer init functions.
573 if (F
.getName().startswith("__sanitizer_"))
574 return; // Don't instrument __sanitizer_* callbacks.
575 // Don't touch available_externally functions, their actual body is elewhere.
576 if (F
.getLinkage() == GlobalValue::AvailableExternallyLinkage
)
578 // Don't instrument MSVC CRT configuration helpers. They may run before normal
580 if (F
.getName() == "__local_stdio_printf_options" ||
581 F
.getName() == "__local_stdio_scanf_options")
583 if (isa
<UnreachableInst
>(F
.getEntryBlock().getTerminator()))
585 // Don't instrument functions using SEH for now. Splitting basic blocks like
586 // we do for coverage breaks WinEHPrepare.
587 // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
588 if (F
.hasPersonalityFn() &&
589 isAsynchronousEHPersonality(classifyEHPersonality(F
.getPersonalityFn())))
591 if (Options
.CoverageType
>= SanitizerCoverageOptions::SCK_Edge
)
592 SplitAllCriticalEdges(F
, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
593 SmallVector
<Instruction
*, 8> IndirCalls
;
594 SmallVector
<BasicBlock
*, 16> BlocksToInstrument
;
595 SmallVector
<Instruction
*, 8> CmpTraceTargets
;
596 SmallVector
<Instruction
*, 8> SwitchTraceTargets
;
597 SmallVector
<BinaryOperator
*, 8> DivTraceTargets
;
598 SmallVector
<GetElementPtrInst
*, 8> GepTraceTargets
;
600 const DominatorTree
*DT
= DTCallback(F
);
601 const PostDominatorTree
*PDT
= PDTCallback(F
);
602 bool IsLeafFunc
= true;
605 if (shouldInstrumentBlock(F
, &BB
, DT
, PDT
, Options
))
606 BlocksToInstrument
.push_back(&BB
);
607 for (auto &Inst
: BB
) {
608 if (Options
.IndirectCalls
) {
610 if (CS
&& !CS
.getCalledFunction())
611 IndirCalls
.push_back(&Inst
);
613 if (Options
.TraceCmp
) {
614 if (ICmpInst
*CMP
= dyn_cast
<ICmpInst
>(&Inst
))
615 if (IsInterestingCmp(CMP
, DT
, Options
))
616 CmpTraceTargets
.push_back(&Inst
);
617 if (isa
<SwitchInst
>(&Inst
))
618 SwitchTraceTargets
.push_back(&Inst
);
620 if (Options
.TraceDiv
)
621 if (BinaryOperator
*BO
= dyn_cast
<BinaryOperator
>(&Inst
))
622 if (BO
->getOpcode() == Instruction::SDiv
||
623 BO
->getOpcode() == Instruction::UDiv
)
624 DivTraceTargets
.push_back(BO
);
625 if (Options
.TraceGep
)
626 if (GetElementPtrInst
*GEP
= dyn_cast
<GetElementPtrInst
>(&Inst
))
627 GepTraceTargets
.push_back(GEP
);
628 if (Options
.StackDepth
)
629 if (isa
<InvokeInst
>(Inst
) ||
630 (isa
<CallInst
>(Inst
) && !isa
<IntrinsicInst
>(Inst
)))
635 InjectCoverage(F
, BlocksToInstrument
, IsLeafFunc
);
636 InjectCoverageForIndirectCalls(F
, IndirCalls
);
637 InjectTraceForCmp(F
, CmpTraceTargets
);
638 InjectTraceForSwitch(F
, SwitchTraceTargets
);
639 InjectTraceForDiv(F
, DivTraceTargets
);
640 InjectTraceForGep(F
, GepTraceTargets
);
643 GlobalVariable
*ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
644 size_t NumElements
, Function
&F
, Type
*Ty
, const char *Section
) {
645 ArrayType
*ArrayTy
= ArrayType::get(Ty
, NumElements
);
646 auto Array
= new GlobalVariable(
647 *CurModule
, ArrayTy
, false, GlobalVariable::PrivateLinkage
,
648 Constant::getNullValue(ArrayTy
), "__sancov_gen_");
650 if (TargetTriple
.supportsCOMDAT() && !F
.isInterposable())
652 GetOrCreateFunctionComdat(F
, TargetTriple
, CurModuleUniqueId
))
653 Array
->setComdat(Comdat
);
654 Array
->setSection(getSectionName(Section
));
655 Array
->setAlignment(Align(Ty
->isPointerTy()
656 ? DL
->getPointerSize()
657 : Ty
->getPrimitiveSizeInBits() / 8));
658 GlobalsToAppendToUsed
.push_back(Array
);
659 GlobalsToAppendToCompilerUsed
.push_back(Array
);
660 MDNode
*MD
= MDNode::get(F
.getContext(), ValueAsMetadata::get(&F
));
661 Array
->addMetadata(LLVMContext::MD_associated
, *MD
);
667 ModuleSanitizerCoverage::CreatePCArray(Function
&F
,
668 ArrayRef
<BasicBlock
*> AllBlocks
) {
669 size_t N
= AllBlocks
.size();
671 SmallVector
<Constant
*, 32> PCs
;
672 IRBuilder
<> IRB(&*F
.getEntryBlock().getFirstInsertionPt());
673 for (size_t i
= 0; i
< N
; i
++) {
674 if (&F
.getEntryBlock() == AllBlocks
[i
]) {
675 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(&F
, IntptrPtrTy
));
676 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
677 ConstantInt::get(IntptrTy
, 1), IntptrPtrTy
));
679 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(
680 BlockAddress::get(AllBlocks
[i
]), IntptrPtrTy
));
681 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
682 ConstantInt::get(IntptrTy
, 0), IntptrPtrTy
));
685 auto *PCArray
= CreateFunctionLocalArrayInSection(N
* 2, F
, IntptrPtrTy
,
686 SanCovPCsSectionName
);
687 PCArray
->setInitializer(
688 ConstantArray::get(ArrayType::get(IntptrPtrTy
, N
* 2), PCs
));
689 PCArray
->setConstant(true);
694 void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
695 Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
) {
696 if (Options
.TracePCGuard
)
697 FunctionGuardArray
= CreateFunctionLocalArrayInSection(
698 AllBlocks
.size(), F
, Int32Ty
, SanCovGuardsSectionName
);
700 if (Options
.Inline8bitCounters
)
701 Function8bitCounterArray
= CreateFunctionLocalArrayInSection(
702 AllBlocks
.size(), F
, Int8Ty
, SanCovCountersSectionName
);
705 FunctionPCsArray
= CreatePCArray(F
, AllBlocks
);
708 bool ModuleSanitizerCoverage::InjectCoverage(Function
&F
,
709 ArrayRef
<BasicBlock
*> AllBlocks
,
711 if (AllBlocks
.empty()) return false;
712 CreateFunctionLocalArrays(F
, AllBlocks
);
713 for (size_t i
= 0, N
= AllBlocks
.size(); i
< N
; i
++)
714 InjectCoverageAtBlock(F
, *AllBlocks
[i
], i
, IsLeafFunc
);
718 // On every indirect call we call a run-time function
719 // __sanitizer_cov_indir_call* with two parameters:
721 // - global cache array that contains CacheSize pointers (zero-initialized).
722 // The cache is used to speed up recording the caller-callee pairs.
723 // The address of the caller is passed implicitly via caller PC.
724 // CacheSize is encoded in the name of the run-time function.
725 void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
726 Function
&F
, ArrayRef
<Instruction
*> IndirCalls
) {
727 if (IndirCalls
.empty())
729 assert(Options
.TracePC
|| Options
.TracePCGuard
|| Options
.Inline8bitCounters
);
730 for (auto I
: IndirCalls
) {
733 Value
*Callee
= CS
.getCalledValue();
734 if (isa
<InlineAsm
>(Callee
))
736 IRB
.CreateCall(SanCovTracePCIndir
, IRB
.CreatePointerCast(Callee
, IntptrTy
));
740 // For every switch statement we insert a call:
741 // __sanitizer_cov_trace_switch(CondValue,
742 // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
744 void ModuleSanitizerCoverage::InjectTraceForSwitch(
745 Function
&, ArrayRef
<Instruction
*> SwitchTraceTargets
) {
746 for (auto I
: SwitchTraceTargets
) {
747 if (SwitchInst
*SI
= dyn_cast
<SwitchInst
>(I
)) {
749 SmallVector
<Constant
*, 16> Initializers
;
750 Value
*Cond
= SI
->getCondition();
751 if (Cond
->getType()->getScalarSizeInBits() >
752 Int64Ty
->getScalarSizeInBits())
754 Initializers
.push_back(ConstantInt::get(Int64Ty
, SI
->getNumCases()));
755 Initializers
.push_back(
756 ConstantInt::get(Int64Ty
, Cond
->getType()->getScalarSizeInBits()));
757 if (Cond
->getType()->getScalarSizeInBits() <
758 Int64Ty
->getScalarSizeInBits())
759 Cond
= IRB
.CreateIntCast(Cond
, Int64Ty
, false);
760 for (auto It
: SI
->cases()) {
761 Constant
*C
= It
.getCaseValue();
762 if (C
->getType()->getScalarSizeInBits() <
763 Int64Ty
->getScalarSizeInBits())
764 C
= ConstantExpr::getCast(CastInst::ZExt
, It
.getCaseValue(), Int64Ty
);
765 Initializers
.push_back(C
);
767 llvm::sort(Initializers
.begin() + 2, Initializers
.end(),
768 [](const Constant
*A
, const Constant
*B
) {
769 return cast
<ConstantInt
>(A
)->getLimitedValue() <
770 cast
<ConstantInt
>(B
)->getLimitedValue();
772 ArrayType
*ArrayOfInt64Ty
= ArrayType::get(Int64Ty
, Initializers
.size());
773 GlobalVariable
*GV
= new GlobalVariable(
774 *CurModule
, ArrayOfInt64Ty
, false, GlobalVariable::InternalLinkage
,
775 ConstantArray::get(ArrayOfInt64Ty
, Initializers
),
776 "__sancov_gen_cov_switch_values");
777 IRB
.CreateCall(SanCovTraceSwitchFunction
,
778 {Cond
, IRB
.CreatePointerCast(GV
, Int64PtrTy
)});
783 void ModuleSanitizerCoverage::InjectTraceForDiv(
784 Function
&, ArrayRef
<BinaryOperator
*> DivTraceTargets
) {
785 for (auto BO
: DivTraceTargets
) {
787 Value
*A1
= BO
->getOperand(1);
788 if (isa
<ConstantInt
>(A1
)) continue;
789 if (!A1
->getType()->isIntegerTy())
791 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A1
->getType());
792 int CallbackIdx
= TypeSize
== 32 ? 0 :
793 TypeSize
== 64 ? 1 : -1;
794 if (CallbackIdx
< 0) continue;
795 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
796 IRB
.CreateCall(SanCovTraceDivFunction
[CallbackIdx
],
797 {IRB
.CreateIntCast(A1
, Ty
, true)});
801 void ModuleSanitizerCoverage::InjectTraceForGep(
802 Function
&, ArrayRef
<GetElementPtrInst
*> GepTraceTargets
) {
803 for (auto GEP
: GepTraceTargets
) {
804 IRBuilder
<> IRB(GEP
);
805 for (auto I
= GEP
->idx_begin(); I
!= GEP
->idx_end(); ++I
)
806 if (!isa
<ConstantInt
>(*I
) && (*I
)->getType()->isIntegerTy())
807 IRB
.CreateCall(SanCovTraceGepFunction
,
808 {IRB
.CreateIntCast(*I
, IntptrTy
, true)});
812 void ModuleSanitizerCoverage::InjectTraceForCmp(
813 Function
&, ArrayRef
<Instruction
*> CmpTraceTargets
) {
814 for (auto I
: CmpTraceTargets
) {
815 if (ICmpInst
*ICMP
= dyn_cast
<ICmpInst
>(I
)) {
816 IRBuilder
<> IRB(ICMP
);
817 Value
*A0
= ICMP
->getOperand(0);
818 Value
*A1
= ICMP
->getOperand(1);
819 if (!A0
->getType()->isIntegerTy())
821 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A0
->getType());
822 int CallbackIdx
= TypeSize
== 8 ? 0 :
825 TypeSize
== 64 ? 3 : -1;
826 if (CallbackIdx
< 0) continue;
827 // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
828 auto CallbackFunc
= SanCovTraceCmpFunction
[CallbackIdx
];
829 bool FirstIsConst
= isa
<ConstantInt
>(A0
);
830 bool SecondIsConst
= isa
<ConstantInt
>(A1
);
831 // If both are const, then we don't need such a comparison.
832 if (FirstIsConst
&& SecondIsConst
) continue;
833 // If only one is const, then make it the first callback argument.
834 if (FirstIsConst
|| SecondIsConst
) {
835 CallbackFunc
= SanCovTraceConstCmpFunction
[CallbackIdx
];
840 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
841 IRB
.CreateCall(CallbackFunc
, {IRB
.CreateIntCast(A0
, Ty
, true),
842 IRB
.CreateIntCast(A1
, Ty
, true)});
847 void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function
&F
, BasicBlock
&BB
,
850 BasicBlock::iterator IP
= BB
.getFirstInsertionPt();
851 bool IsEntryBB
= &BB
== &F
.getEntryBlock();
854 if (auto SP
= F
.getSubprogram())
855 EntryLoc
= DebugLoc::get(SP
->getScopeLine(), 0, SP
);
856 // Keep static allocas and llvm.localescape calls in the entry block. Even
857 // if we aren't splitting the block, it's nice for allocas to be before
859 IP
= PrepareToSplitEntryBlock(BB
, IP
);
861 EntryLoc
= IP
->getDebugLoc();
864 IRBuilder
<> IRB(&*IP
);
865 IRB
.SetCurrentDebugLocation(EntryLoc
);
866 if (Options
.TracePC
) {
867 IRB
.CreateCall(SanCovTracePC
); // gets the PC using GET_CALLER_PC.
868 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
870 if (Options
.TracePCGuard
) {
871 auto GuardPtr
= IRB
.CreateIntToPtr(
872 IRB
.CreateAdd(IRB
.CreatePointerCast(FunctionGuardArray
, IntptrTy
),
873 ConstantInt::get(IntptrTy
, Idx
* 4)),
875 IRB
.CreateCall(SanCovTracePCGuard
, GuardPtr
);
876 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
878 if (Options
.Inline8bitCounters
) {
879 auto CounterPtr
= IRB
.CreateGEP(
880 Function8bitCounterArray
->getValueType(), Function8bitCounterArray
,
881 {ConstantInt::get(IntptrTy
, 0), ConstantInt::get(IntptrTy
, Idx
)});
882 auto Load
= IRB
.CreateLoad(Int8Ty
, CounterPtr
);
883 auto Inc
= IRB
.CreateAdd(Load
, ConstantInt::get(Int8Ty
, 1));
884 auto Store
= IRB
.CreateStore(Inc
, CounterPtr
);
885 SetNoSanitizeMetadata(Load
);
886 SetNoSanitizeMetadata(Store
);
888 if (Options
.StackDepth
&& IsEntryBB
&& !IsLeafFunc
) {
889 // Check stack depth. If it's the deepest so far, record it.
890 Module
*M
= F
.getParent();
891 Function
*GetFrameAddr
= Intrinsic::getDeclaration(
892 M
, Intrinsic::frameaddress
,
893 IRB
.getInt8PtrTy(M
->getDataLayout().getAllocaAddrSpace()));
895 IRB
.CreateCall(GetFrameAddr
, {Constant::getNullValue(Int32Ty
)});
896 auto FrameAddrInt
= IRB
.CreatePtrToInt(FrameAddrPtr
, IntptrTy
);
897 auto LowestStack
= IRB
.CreateLoad(IntptrTy
, SanCovLowestStack
);
898 auto IsStackLower
= IRB
.CreateICmpULT(FrameAddrInt
, LowestStack
);
899 auto ThenTerm
= SplitBlockAndInsertIfThen(IsStackLower
, &*IP
, false);
900 IRBuilder
<> ThenIRB(ThenTerm
);
901 auto Store
= ThenIRB
.CreateStore(FrameAddrInt
, SanCovLowestStack
);
902 SetNoSanitizeMetadata(LowestStack
);
903 SetNoSanitizeMetadata(Store
);
908 ModuleSanitizerCoverage::getSectionName(const std::string
&Section
) const {
909 if (TargetTriple
.isOSBinFormatCOFF()) {
910 if (Section
== SanCovCountersSectionName
)
912 if (Section
== SanCovPCsSectionName
)
914 return ".SCOV$GM"; // For SanCovGuardsSectionName.
916 if (TargetTriple
.isOSBinFormatMachO())
917 return "__DATA,__" + Section
;
918 return "__" + Section
;
922 ModuleSanitizerCoverage::getSectionStart(const std::string
&Section
) const {
923 if (TargetTriple
.isOSBinFormatMachO())
924 return "\1section$start$__DATA$__" + Section
;
925 return "__start___" + Section
;
929 ModuleSanitizerCoverage::getSectionEnd(const std::string
&Section
) const {
930 if (TargetTriple
.isOSBinFormatMachO())
931 return "\1section$end$__DATA$__" + Section
;
932 return "__stop___" + Section
;
935 char ModuleSanitizerCoverageLegacyPass::ID
= 0;
936 INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass
, "sancov",
937 "Pass for instrumenting coverage on functions", false,
939 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass
)
940 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass
)
941 INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass
, "sancov",
942 "Pass for instrumenting coverage on functions", false,
944 ModulePass
*llvm::createModuleSanitizerCoverageLegacyPassPass(
945 const SanitizerCoverageOptions
&Options
) {
946 return new ModuleSanitizerCoverageLegacyPass(Options
);