1 //===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Coverage instrumentation done on LLVM IR level, works with Sanitizers.
12 //===----------------------------------------------------------------------===//
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/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
<GlobalVariable
*, GlobalVariable
*>
215 CreateSecStartEnd(Module
&M
, const char *Section
, Type
*Ty
);
217 void SetNoSanitizeMetadata(Instruction
*I
) {
218 I
->setMetadata(I
->getModule()->getMDKindID("nosanitize"),
219 MDNode::get(*C
, None
));
222 Comdat
*GetOrCreateFunctionComdat(Function
&F
);
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 Function
*SanCovTracePCIndir
;
228 Function
*SanCovTracePC
, *SanCovTracePCGuard
;
229 Function
*SanCovTraceCmpFunction
[4];
230 Function
*SanCovTraceConstCmpFunction
[4];
231 Function
*SanCovTraceDivFunction
[2];
232 Function
*SanCovTraceGepFunction
;
233 Function
*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
;
255 std::pair
<GlobalVariable
*, GlobalVariable
*>
256 SanitizerCoverageModule::CreateSecStartEnd(Module
&M
, const char *Section
,
258 GlobalVariable
*SecStart
=
259 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
, nullptr,
260 getSectionStart(Section
));
261 SecStart
->setVisibility(GlobalValue::HiddenVisibility
);
262 GlobalVariable
*SecEnd
=
263 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
,
264 nullptr, getSectionEnd(Section
));
265 SecEnd
->setVisibility(GlobalValue::HiddenVisibility
);
267 return std::make_pair(SecStart
, SecEnd
);
271 Function
*SanitizerCoverageModule::CreateInitCallsForSections(
272 Module
&M
, const char *InitFunctionName
, Type
*Ty
,
273 const char *Section
) {
274 IRBuilder
<> IRB(M
.getContext());
275 auto SecStartEnd
= CreateSecStartEnd(M
, Section
, Ty
);
276 auto SecStart
= SecStartEnd
.first
;
277 auto SecEnd
= SecStartEnd
.second
;
279 Value
*SecStartPtr
= nullptr;
280 // Account for the fact that on windows-msvc __start_* symbols actually
281 // point to a uint64_t before the start of the array.
282 if (TargetTriple
.getObjectFormat() == Triple::COFF
) {
283 auto SecStartI8Ptr
= IRB
.CreatePointerCast(SecStart
, Int8PtrTy
);
284 auto GEP
= IRB
.CreateGEP(SecStartI8Ptr
,
285 ConstantInt::get(IntptrTy
, sizeof(uint64_t)));
286 SecStartPtr
= IRB
.CreatePointerCast(GEP
, Ty
);
288 SecStartPtr
= IRB
.CreatePointerCast(SecStart
, Ty
);
290 std::tie(CtorFunc
, std::ignore
) = createSanitizerCtorAndInitFunctions(
291 M
, SanCovModuleCtorName
, InitFunctionName
, {Ty
, Ty
},
292 {SecStartPtr
, IRB
.CreatePointerCast(SecEnd
, Ty
)});
294 if (TargetTriple
.supportsCOMDAT()) {
295 // Use comdat to dedup CtorFunc.
296 CtorFunc
->setComdat(M
.getOrInsertComdat(SanCovModuleCtorName
));
297 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
, CtorFunc
);
299 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
);
304 bool SanitizerCoverageModule::runOnModule(Module
&M
) {
305 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_None
)
307 C
= &(M
.getContext());
308 DL
= &M
.getDataLayout();
310 CurModuleUniqueId
= getUniqueModuleId(CurModule
);
311 TargetTriple
= Triple(M
.getTargetTriple());
312 FunctionGuardArray
= nullptr;
313 Function8bitCounterArray
= nullptr;
314 FunctionPCsArray
= nullptr;
315 IntptrTy
= Type::getIntNTy(*C
, DL
->getPointerSizeInBits());
316 IntptrPtrTy
= PointerType::getUnqual(IntptrTy
);
317 Type
*VoidTy
= Type::getVoidTy(*C
);
319 Int64PtrTy
= PointerType::getUnqual(IRB
.getInt64Ty());
320 Int32PtrTy
= PointerType::getUnqual(IRB
.getInt32Ty());
321 Int8PtrTy
= PointerType::getUnqual(IRB
.getInt8Ty());
322 Int64Ty
= IRB
.getInt64Ty();
323 Int32Ty
= IRB
.getInt32Ty();
324 Int16Ty
= IRB
.getInt16Ty();
325 Int8Ty
= IRB
.getInt8Ty();
327 SanCovTracePCIndir
= checkSanitizerInterfaceFunction(
328 M
.getOrInsertFunction(SanCovTracePCIndirName
, VoidTy
, IntptrTy
));
329 SanCovTraceCmpFunction
[0] =
330 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
331 SanCovTraceCmp1
, VoidTy
, IRB
.getInt8Ty(), IRB
.getInt8Ty()));
332 SanCovTraceCmpFunction
[1] = checkSanitizerInterfaceFunction(
333 M
.getOrInsertFunction(SanCovTraceCmp2
, VoidTy
, IRB
.getInt16Ty(),
335 SanCovTraceCmpFunction
[2] = checkSanitizerInterfaceFunction(
336 M
.getOrInsertFunction(SanCovTraceCmp4
, VoidTy
, IRB
.getInt32Ty(),
338 SanCovTraceCmpFunction
[3] =
339 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
340 SanCovTraceCmp8
, VoidTy
, Int64Ty
, Int64Ty
));
342 SanCovTraceConstCmpFunction
[0] =
343 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
344 SanCovTraceConstCmp1
, VoidTy
, Int8Ty
, Int8Ty
));
345 SanCovTraceConstCmpFunction
[1] =
346 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
347 SanCovTraceConstCmp2
, VoidTy
, Int16Ty
, Int16Ty
));
348 SanCovTraceConstCmpFunction
[2] =
349 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
350 SanCovTraceConstCmp4
, VoidTy
, Int32Ty
, Int32Ty
));
351 SanCovTraceConstCmpFunction
[3] =
352 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
353 SanCovTraceConstCmp8
, VoidTy
, Int64Ty
, Int64Ty
));
355 SanCovTraceDivFunction
[0] =
356 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
357 SanCovTraceDiv4
, VoidTy
, IRB
.getInt32Ty()));
358 SanCovTraceDivFunction
[1] =
359 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
360 SanCovTraceDiv8
, VoidTy
, Int64Ty
));
361 SanCovTraceGepFunction
=
362 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
363 SanCovTraceGep
, VoidTy
, IntptrTy
));
364 SanCovTraceSwitchFunction
=
365 checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
366 SanCovTraceSwitchName
, VoidTy
, Int64Ty
, Int64PtrTy
));
368 Constant
*SanCovLowestStackConstant
=
369 M
.getOrInsertGlobal(SanCovLowestStackName
, IntptrTy
);
370 SanCovLowestStack
= cast
<GlobalVariable
>(SanCovLowestStackConstant
);
371 SanCovLowestStack
->setThreadLocalMode(
372 GlobalValue::ThreadLocalMode::InitialExecTLSModel
);
373 if (Options
.StackDepth
&& !SanCovLowestStack
->isDeclaration())
374 SanCovLowestStack
->setInitializer(Constant::getAllOnesValue(IntptrTy
));
376 // Make sure smaller parameters are zero-extended to i64 as required by the
378 if (TargetTriple
.getArch() == Triple::x86_64
) {
379 for (int i
= 0; i
< 3; i
++) {
380 SanCovTraceCmpFunction
[i
]->addParamAttr(0, Attribute::ZExt
);
381 SanCovTraceCmpFunction
[i
]->addParamAttr(1, Attribute::ZExt
);
382 SanCovTraceConstCmpFunction
[i
]->addParamAttr(0, Attribute::ZExt
);
383 SanCovTraceConstCmpFunction
[i
]->addParamAttr(1, Attribute::ZExt
);
385 SanCovTraceDivFunction
[0]->addParamAttr(0, Attribute::ZExt
);
389 // We insert an empty inline asm after cov callbacks to avoid callback merge.
390 EmptyAsm
= InlineAsm::get(FunctionType::get(IRB
.getVoidTy(), false),
391 StringRef(""), StringRef(""),
392 /*hasSideEffects=*/true);
394 SanCovTracePC
= checkSanitizerInterfaceFunction(
395 M
.getOrInsertFunction(SanCovTracePCName
, VoidTy
));
396 SanCovTracePCGuard
= checkSanitizerInterfaceFunction(M
.getOrInsertFunction(
397 SanCovTracePCGuardName
, VoidTy
, Int32PtrTy
));
402 Function
*Ctor
= nullptr;
404 if (FunctionGuardArray
)
405 Ctor
= CreateInitCallsForSections(M
, SanCovTracePCGuardInitName
, Int32PtrTy
,
406 SanCovGuardsSectionName
);
407 if (Function8bitCounterArray
)
408 Ctor
= CreateInitCallsForSections(M
, SanCov8bitCountersInitName
, Int8PtrTy
,
409 SanCovCountersSectionName
);
410 if (Ctor
&& Options
.PCTable
) {
411 auto SecStartEnd
= CreateSecStartEnd(M
, SanCovPCsSectionName
, IntptrPtrTy
);
412 Function
*InitFunction
= declareSanitizerInitFunction(
413 M
, SanCovPCsInitName
, {IntptrPtrTy
, IntptrPtrTy
});
414 IRBuilder
<> IRBCtor(Ctor
->getEntryBlock().getTerminator());
415 Value
*SecStartPtr
= nullptr;
416 // Account for the fact that on windows-msvc __start_pc_table actually
417 // points to a uint64_t before the start of the PC table.
418 if (TargetTriple
.getObjectFormat() == Triple::COFF
) {
419 auto SecStartI8Ptr
= IRB
.CreatePointerCast(SecStartEnd
.first
, Int8PtrTy
);
420 auto GEP
= IRB
.CreateGEP(SecStartI8Ptr
,
421 ConstantInt::get(IntptrTy
, sizeof(uint64_t)));
422 SecStartPtr
= IRB
.CreatePointerCast(GEP
, IntptrPtrTy
);
424 SecStartPtr
= IRB
.CreatePointerCast(SecStartEnd
.first
, IntptrPtrTy
);
428 {SecStartPtr
, IRB
.CreatePointerCast(SecStartEnd
.second
, IntptrPtrTy
)});
430 // We don't reference these arrays directly in any of our runtime functions,
431 // so we need to prevent them from being dead stripped.
432 if (TargetTriple
.isOSBinFormatMachO())
433 appendToUsed(M
, GlobalsToAppendToUsed
);
434 appendToCompilerUsed(M
, GlobalsToAppendToCompilerUsed
);
438 // True if block has successors and it dominates all of them.
439 static bool isFullDominator(const BasicBlock
*BB
, const DominatorTree
*DT
) {
440 if (succ_begin(BB
) == succ_end(BB
))
443 for (const BasicBlock
*SUCC
: make_range(succ_begin(BB
), succ_end(BB
))) {
444 if (!DT
->dominates(BB
, SUCC
))
451 // True if block has predecessors and it postdominates all of them.
452 static bool isFullPostDominator(const BasicBlock
*BB
,
453 const PostDominatorTree
*PDT
) {
454 if (pred_begin(BB
) == pred_end(BB
))
457 for (const BasicBlock
*PRED
: make_range(pred_begin(BB
), pred_end(BB
))) {
458 if (!PDT
->dominates(BB
, PRED
))
465 static bool shouldInstrumentBlock(const Function
&F
, const BasicBlock
*BB
,
466 const DominatorTree
*DT
,
467 const PostDominatorTree
*PDT
,
468 const SanitizerCoverageOptions
&Options
) {
469 // Don't insert coverage for unreachable blocks: we will never call
470 // __sanitizer_cov() for them, so counting them in
471 // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
472 // percentage. Also, unreachable instructions frequently have no debug
474 if (isa
<UnreachableInst
>(BB
->getTerminator()))
477 // Don't insert coverage into blocks without a valid insertion point
478 // (catchswitch blocks).
479 if (BB
->getFirstInsertionPt() == BB
->end())
482 if (Options
.NoPrune
|| &F
.getEntryBlock() == BB
)
485 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_Function
&&
486 &F
.getEntryBlock() != BB
)
489 // Do not instrument full dominators, or full post-dominators with multiple
491 return !isFullDominator(BB
, DT
)
492 && !(isFullPostDominator(BB
, PDT
) && !BB
->getSinglePredecessor());
495 bool SanitizerCoverageModule::runOnFunction(Function
&F
) {
498 if (F
.getName().find(".module_ctor") != std::string::npos
)
499 return false; // Should not instrument sanitizer init functions.
500 if (F
.getName().startswith("__sanitizer_"))
501 return false; // Don't instrument __sanitizer_* callbacks.
502 // Don't touch available_externally functions, their actual body is elewhere.
503 if (F
.getLinkage() == GlobalValue::AvailableExternallyLinkage
)
505 // Don't instrument MSVC CRT configuration helpers. They may run before normal
507 if (F
.getName() == "__local_stdio_printf_options" ||
508 F
.getName() == "__local_stdio_scanf_options")
510 if (isa
<UnreachableInst
>(F
.getEntryBlock().getTerminator()))
512 // Don't instrument functions using SEH for now. Splitting basic blocks like
513 // we do for coverage breaks WinEHPrepare.
514 // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
515 if (F
.hasPersonalityFn() &&
516 isAsynchronousEHPersonality(classifyEHPersonality(F
.getPersonalityFn())))
518 if (Options
.CoverageType
>= SanitizerCoverageOptions::SCK_Edge
)
519 SplitAllCriticalEdges(F
);
520 SmallVector
<Instruction
*, 8> IndirCalls
;
521 SmallVector
<BasicBlock
*, 16> BlocksToInstrument
;
522 SmallVector
<Instruction
*, 8> CmpTraceTargets
;
523 SmallVector
<Instruction
*, 8> SwitchTraceTargets
;
524 SmallVector
<BinaryOperator
*, 8> DivTraceTargets
;
525 SmallVector
<GetElementPtrInst
*, 8> GepTraceTargets
;
527 const DominatorTree
*DT
=
528 &getAnalysis
<DominatorTreeWrapperPass
>(F
).getDomTree();
529 const PostDominatorTree
*PDT
=
530 &getAnalysis
<PostDominatorTreeWrapperPass
>(F
).getPostDomTree();
531 bool IsLeafFunc
= true;
534 if (shouldInstrumentBlock(F
, &BB
, DT
, PDT
, Options
))
535 BlocksToInstrument
.push_back(&BB
);
536 for (auto &Inst
: BB
) {
537 if (Options
.IndirectCalls
) {
539 if (CS
&& !CS
.getCalledFunction())
540 IndirCalls
.push_back(&Inst
);
542 if (Options
.TraceCmp
) {
543 if (isa
<ICmpInst
>(&Inst
))
544 CmpTraceTargets
.push_back(&Inst
);
545 if (isa
<SwitchInst
>(&Inst
))
546 SwitchTraceTargets
.push_back(&Inst
);
548 if (Options
.TraceDiv
)
549 if (BinaryOperator
*BO
= dyn_cast
<BinaryOperator
>(&Inst
))
550 if (BO
->getOpcode() == Instruction::SDiv
||
551 BO
->getOpcode() == Instruction::UDiv
)
552 DivTraceTargets
.push_back(BO
);
553 if (Options
.TraceGep
)
554 if (GetElementPtrInst
*GEP
= dyn_cast
<GetElementPtrInst
>(&Inst
))
555 GepTraceTargets
.push_back(GEP
);
556 if (Options
.StackDepth
)
557 if (isa
<InvokeInst
>(Inst
) ||
558 (isa
<CallInst
>(Inst
) && !isa
<IntrinsicInst
>(Inst
)))
563 InjectCoverage(F
, BlocksToInstrument
, IsLeafFunc
);
564 InjectCoverageForIndirectCalls(F
, IndirCalls
);
565 InjectTraceForCmp(F
, CmpTraceTargets
);
566 InjectTraceForSwitch(F
, SwitchTraceTargets
);
567 InjectTraceForDiv(F
, DivTraceTargets
);
568 InjectTraceForGep(F
, GepTraceTargets
);
572 Comdat
*SanitizerCoverageModule::GetOrCreateFunctionComdat(Function
&F
) {
573 if (auto Comdat
= F
.getComdat()) return Comdat
;
574 if (!TargetTriple
.isOSBinFormatELF()) return nullptr;
576 std::string Name
= F
.getName();
577 if (F
.hasLocalLinkage()) {
578 if (CurModuleUniqueId
.empty()) return nullptr;
579 Name
+= CurModuleUniqueId
;
581 auto Comdat
= CurModule
->getOrInsertComdat(Name
);
586 GlobalVariable
*SanitizerCoverageModule::CreateFunctionLocalArrayInSection(
587 size_t NumElements
, Function
&F
, Type
*Ty
, const char *Section
) {
588 ArrayType
*ArrayTy
= ArrayType::get(Ty
, NumElements
);
589 auto Array
= new GlobalVariable(
590 *CurModule
, ArrayTy
, false, GlobalVariable::PrivateLinkage
,
591 Constant::getNullValue(ArrayTy
), "__sancov_gen_");
592 if (auto Comdat
= GetOrCreateFunctionComdat(F
))
593 Array
->setComdat(Comdat
);
594 Array
->setSection(getSectionName(Section
));
595 Array
->setAlignment(Ty
->isPointerTy() ? DL
->getPointerSize()
596 : Ty
->getPrimitiveSizeInBits() / 8);
597 GlobalsToAppendToCompilerUsed
.push_back(Array
);
598 MDNode
*MD
= MDNode::get(F
.getContext(), ValueAsMetadata::get(&F
));
599 Array
->addMetadata(LLVMContext::MD_associated
, *MD
);
605 SanitizerCoverageModule::CreatePCArray(Function
&F
,
606 ArrayRef
<BasicBlock
*> AllBlocks
) {
607 size_t N
= AllBlocks
.size();
609 SmallVector
<Constant
*, 32> PCs
;
610 IRBuilder
<> IRB(&*F
.getEntryBlock().getFirstInsertionPt());
611 for (size_t i
= 0; i
< N
; i
++) {
612 if (&F
.getEntryBlock() == AllBlocks
[i
]) {
613 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(&F
, IntptrPtrTy
));
614 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
615 ConstantInt::get(IntptrTy
, 1), IntptrPtrTy
));
617 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(
618 BlockAddress::get(AllBlocks
[i
]), IntptrPtrTy
));
619 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
620 ConstantInt::get(IntptrTy
, 0), IntptrPtrTy
));
623 auto *PCArray
= CreateFunctionLocalArrayInSection(N
* 2, F
, IntptrPtrTy
,
624 SanCovPCsSectionName
);
625 PCArray
->setInitializer(
626 ConstantArray::get(ArrayType::get(IntptrPtrTy
, N
* 2), PCs
));
627 PCArray
->setConstant(true);
632 void SanitizerCoverageModule::CreateFunctionLocalArrays(
633 Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
) {
634 if (Options
.TracePCGuard
) {
635 FunctionGuardArray
= CreateFunctionLocalArrayInSection(
636 AllBlocks
.size(), F
, Int32Ty
, SanCovGuardsSectionName
);
637 GlobalsToAppendToUsed
.push_back(FunctionGuardArray
);
639 if (Options
.Inline8bitCounters
)
640 Function8bitCounterArray
= CreateFunctionLocalArrayInSection(
641 AllBlocks
.size(), F
, Int8Ty
, SanCovCountersSectionName
);
643 FunctionPCsArray
= CreatePCArray(F
, AllBlocks
);
646 bool SanitizerCoverageModule::InjectCoverage(Function
&F
,
647 ArrayRef
<BasicBlock
*> AllBlocks
,
649 if (AllBlocks
.empty()) return false;
650 CreateFunctionLocalArrays(F
, AllBlocks
);
651 for (size_t i
= 0, N
= AllBlocks
.size(); i
< N
; i
++)
652 InjectCoverageAtBlock(F
, *AllBlocks
[i
], i
, IsLeafFunc
);
656 // On every indirect call we call a run-time function
657 // __sanitizer_cov_indir_call* with two parameters:
659 // - global cache array that contains CacheSize pointers (zero-initialized).
660 // The cache is used to speed up recording the caller-callee pairs.
661 // The address of the caller is passed implicitly via caller PC.
662 // CacheSize is encoded in the name of the run-time function.
663 void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
664 Function
&F
, ArrayRef
<Instruction
*> IndirCalls
) {
665 if (IndirCalls
.empty())
667 assert(Options
.TracePC
|| Options
.TracePCGuard
|| Options
.Inline8bitCounters
);
668 for (auto I
: IndirCalls
) {
671 Value
*Callee
= CS
.getCalledValue();
672 if (isa
<InlineAsm
>(Callee
))
674 IRB
.CreateCall(SanCovTracePCIndir
, IRB
.CreatePointerCast(Callee
, IntptrTy
));
678 // For every switch statement we insert a call:
679 // __sanitizer_cov_trace_switch(CondValue,
680 // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
682 void SanitizerCoverageModule::InjectTraceForSwitch(
683 Function
&, ArrayRef
<Instruction
*> SwitchTraceTargets
) {
684 for (auto I
: SwitchTraceTargets
) {
685 if (SwitchInst
*SI
= dyn_cast
<SwitchInst
>(I
)) {
687 SmallVector
<Constant
*, 16> Initializers
;
688 Value
*Cond
= SI
->getCondition();
689 if (Cond
->getType()->getScalarSizeInBits() >
690 Int64Ty
->getScalarSizeInBits())
692 Initializers
.push_back(ConstantInt::get(Int64Ty
, SI
->getNumCases()));
693 Initializers
.push_back(
694 ConstantInt::get(Int64Ty
, Cond
->getType()->getScalarSizeInBits()));
695 if (Cond
->getType()->getScalarSizeInBits() <
696 Int64Ty
->getScalarSizeInBits())
697 Cond
= IRB
.CreateIntCast(Cond
, Int64Ty
, false);
698 for (auto It
: SI
->cases()) {
699 Constant
*C
= It
.getCaseValue();
700 if (C
->getType()->getScalarSizeInBits() <
701 Int64Ty
->getScalarSizeInBits())
702 C
= ConstantExpr::getCast(CastInst::ZExt
, It
.getCaseValue(), Int64Ty
);
703 Initializers
.push_back(C
);
705 llvm::sort(Initializers
.begin() + 2, Initializers
.end(),
706 [](const Constant
*A
, const Constant
*B
) {
707 return cast
<ConstantInt
>(A
)->getLimitedValue() <
708 cast
<ConstantInt
>(B
)->getLimitedValue();
710 ArrayType
*ArrayOfInt64Ty
= ArrayType::get(Int64Ty
, Initializers
.size());
711 GlobalVariable
*GV
= new GlobalVariable(
712 *CurModule
, ArrayOfInt64Ty
, false, GlobalVariable::InternalLinkage
,
713 ConstantArray::get(ArrayOfInt64Ty
, Initializers
),
714 "__sancov_gen_cov_switch_values");
715 IRB
.CreateCall(SanCovTraceSwitchFunction
,
716 {Cond
, IRB
.CreatePointerCast(GV
, Int64PtrTy
)});
721 void SanitizerCoverageModule::InjectTraceForDiv(
722 Function
&, ArrayRef
<BinaryOperator
*> DivTraceTargets
) {
723 for (auto BO
: DivTraceTargets
) {
725 Value
*A1
= BO
->getOperand(1);
726 if (isa
<ConstantInt
>(A1
)) continue;
727 if (!A1
->getType()->isIntegerTy())
729 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A1
->getType());
730 int CallbackIdx
= TypeSize
== 32 ? 0 :
731 TypeSize
== 64 ? 1 : -1;
732 if (CallbackIdx
< 0) continue;
733 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
734 IRB
.CreateCall(SanCovTraceDivFunction
[CallbackIdx
],
735 {IRB
.CreateIntCast(A1
, Ty
, true)});
739 void SanitizerCoverageModule::InjectTraceForGep(
740 Function
&, ArrayRef
<GetElementPtrInst
*> GepTraceTargets
) {
741 for (auto GEP
: GepTraceTargets
) {
742 IRBuilder
<> IRB(GEP
);
743 for (auto I
= GEP
->idx_begin(); I
!= GEP
->idx_end(); ++I
)
744 if (!isa
<ConstantInt
>(*I
) && (*I
)->getType()->isIntegerTy())
745 IRB
.CreateCall(SanCovTraceGepFunction
,
746 {IRB
.CreateIntCast(*I
, IntptrTy
, true)});
750 void SanitizerCoverageModule::InjectTraceForCmp(
751 Function
&, ArrayRef
<Instruction
*> CmpTraceTargets
) {
752 for (auto I
: CmpTraceTargets
) {
753 if (ICmpInst
*ICMP
= dyn_cast
<ICmpInst
>(I
)) {
754 IRBuilder
<> IRB(ICMP
);
755 Value
*A0
= ICMP
->getOperand(0);
756 Value
*A1
= ICMP
->getOperand(1);
757 if (!A0
->getType()->isIntegerTy())
759 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A0
->getType());
760 int CallbackIdx
= TypeSize
== 8 ? 0 :
763 TypeSize
== 64 ? 3 : -1;
764 if (CallbackIdx
< 0) continue;
765 // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
766 auto CallbackFunc
= SanCovTraceCmpFunction
[CallbackIdx
];
767 bool FirstIsConst
= isa
<ConstantInt
>(A0
);
768 bool SecondIsConst
= isa
<ConstantInt
>(A1
);
769 // If both are const, then we don't need such a comparison.
770 if (FirstIsConst
&& SecondIsConst
) continue;
771 // If only one is const, then make it the first callback argument.
772 if (FirstIsConst
|| SecondIsConst
) {
773 CallbackFunc
= SanCovTraceConstCmpFunction
[CallbackIdx
];
778 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
779 IRB
.CreateCall(CallbackFunc
, {IRB
.CreateIntCast(A0
, Ty
, true),
780 IRB
.CreateIntCast(A1
, Ty
, true)});
785 void SanitizerCoverageModule::InjectCoverageAtBlock(Function
&F
, BasicBlock
&BB
,
788 BasicBlock::iterator IP
= BB
.getFirstInsertionPt();
789 bool IsEntryBB
= &BB
== &F
.getEntryBlock();
792 if (auto SP
= F
.getSubprogram())
793 EntryLoc
= DebugLoc::get(SP
->getScopeLine(), 0, SP
);
794 // Keep static allocas and llvm.localescape calls in the entry block. Even
795 // if we aren't splitting the block, it's nice for allocas to be before
797 IP
= PrepareToSplitEntryBlock(BB
, IP
);
799 EntryLoc
= IP
->getDebugLoc();
802 IRBuilder
<> IRB(&*IP
);
803 IRB
.SetCurrentDebugLocation(EntryLoc
);
804 if (Options
.TracePC
) {
805 IRB
.CreateCall(SanCovTracePC
); // gets the PC using GET_CALLER_PC.
806 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
808 if (Options
.TracePCGuard
) {
809 auto GuardPtr
= IRB
.CreateIntToPtr(
810 IRB
.CreateAdd(IRB
.CreatePointerCast(FunctionGuardArray
, IntptrTy
),
811 ConstantInt::get(IntptrTy
, Idx
* 4)),
813 IRB
.CreateCall(SanCovTracePCGuard
, GuardPtr
);
814 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
816 if (Options
.Inline8bitCounters
) {
817 auto CounterPtr
= IRB
.CreateGEP(
818 Function8bitCounterArray
,
819 {ConstantInt::get(IntptrTy
, 0), ConstantInt::get(IntptrTy
, Idx
)});
820 auto Load
= IRB
.CreateLoad(CounterPtr
);
821 auto Inc
= IRB
.CreateAdd(Load
, ConstantInt::get(Int8Ty
, 1));
822 auto Store
= IRB
.CreateStore(Inc
, CounterPtr
);
823 SetNoSanitizeMetadata(Load
);
824 SetNoSanitizeMetadata(Store
);
826 if (Options
.StackDepth
&& IsEntryBB
&& !IsLeafFunc
) {
827 // Check stack depth. If it's the deepest so far, record it.
828 Function
*GetFrameAddr
=
829 Intrinsic::getDeclaration(F
.getParent(), Intrinsic::frameaddress
);
831 IRB
.CreateCall(GetFrameAddr
, {Constant::getNullValue(Int32Ty
)});
832 auto FrameAddrInt
= IRB
.CreatePtrToInt(FrameAddrPtr
, IntptrTy
);
833 auto LowestStack
= IRB
.CreateLoad(SanCovLowestStack
);
834 auto IsStackLower
= IRB
.CreateICmpULT(FrameAddrInt
, LowestStack
);
835 auto ThenTerm
= SplitBlockAndInsertIfThen(IsStackLower
, &*IP
, false);
836 IRBuilder
<> ThenIRB(ThenTerm
);
837 auto Store
= ThenIRB
.CreateStore(FrameAddrInt
, SanCovLowestStack
);
838 SetNoSanitizeMetadata(LowestStack
);
839 SetNoSanitizeMetadata(Store
);
844 SanitizerCoverageModule::getSectionName(const std::string
&Section
) const {
845 if (TargetTriple
.getObjectFormat() == Triple::COFF
) {
846 if (Section
== SanCovCountersSectionName
)
848 if (Section
== SanCovPCsSectionName
)
850 return ".SCOV$GM"; // For SanCovGuardsSectionName.
852 if (TargetTriple
.isOSBinFormatMachO())
853 return "__DATA,__" + Section
;
854 return "__" + Section
;
858 SanitizerCoverageModule::getSectionStart(const std::string
&Section
) const {
859 if (TargetTriple
.isOSBinFormatMachO())
860 return "\1section$start$__DATA$__" + Section
;
861 return "__start___" + Section
;
865 SanitizerCoverageModule::getSectionEnd(const std::string
&Section
) const {
866 if (TargetTriple
.isOSBinFormatMachO())
867 return "\1section$end$__DATA$__" + Section
;
868 return "__stop___" + Section
;
872 char SanitizerCoverageModule::ID
= 0;
873 INITIALIZE_PASS_BEGIN(SanitizerCoverageModule
, "sancov",
874 "SanitizerCoverage: TODO."
877 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass
)
878 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass
)
879 INITIALIZE_PASS_END(SanitizerCoverageModule
, "sancov",
880 "SanitizerCoverage: TODO."
883 ModulePass
*llvm::createSanitizerCoverageModulePass(
884 const SanitizerCoverageOptions
&Options
) {
885 return new SanitizerCoverageModule(Options
);