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 bool canInstrumentWithSancov(const Function
&F
) {
183 if (F
.getName().find(".module_ctor") != std::string::npos
)
184 return false; // Should not instrument sanitizer init functions.
185 if (F
.getName().startswith("__sanitizer_"))
186 return false; // Don't instrument __sanitizer_* callbacks.
187 // Don't touch available_externally functions, their actual body is elewhere.
188 if (F
.getLinkage() == GlobalValue::AvailableExternallyLinkage
)
190 // Don't instrument MSVC CRT configuration helpers. They may run before normal
192 if (F
.getName() == "__local_stdio_printf_options" ||
193 F
.getName() == "__local_stdio_scanf_options")
195 if (isa
<UnreachableInst
>(F
.getEntryBlock().getTerminator()))
197 // Don't instrument functions using SEH for now. Splitting basic blocks like
198 // we do for coverage breaks WinEHPrepare.
199 // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
200 if (F
.hasPersonalityFn() &&
201 isAsynchronousEHPersonality(classifyEHPersonality(F
.getPersonalityFn())))
206 std::string
getSectionStartImpl(const Triple
&TargetTriple
,
207 const std::string
&Section
) {
208 if (TargetTriple
.isOSBinFormatMachO())
209 return "\1section$start$__DATA$__" + Section
;
210 return "__start___" + Section
;
213 std::string
getSectionEndImpl(const Triple
&TargetTriple
,
214 const std::string
&Section
) {
215 if (TargetTriple
.isOSBinFormatMachO())
216 return "\1section$end$__DATA$__" + Section
;
217 return "__stop___" + Section
;
220 /// This is a class for instrumenting the module to add calls to initializing
221 /// the trace PC guards and 8bit counter globals. This should only be done
222 /// though if there is at least one function that can be instrumented with
224 class ModuleSanitizerCoverage
{
226 ModuleSanitizerCoverage(const SanitizerCoverageOptions
&Options
)
227 : Options(OverrideFromCL(Options
)) {}
229 bool instrumentModule(Module
&M
) {
230 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_None
)
233 Function
*Ctor
= nullptr;
234 LLVMContext
*C
= &(M
.getContext());
235 const DataLayout
*DL
= &M
.getDataLayout();
236 TargetTriple
= Triple(M
.getTargetTriple());
237 IntptrTy
= Type::getIntNTy(*C
, DL
->getPointerSizeInBits());
238 Type
*IntptrPtrTy
= PointerType::getUnqual(IntptrTy
);
240 Type
*Int32PtrTy
= PointerType::getUnqual(IRB
.getInt32Ty());
241 Int8PtrTy
= PointerType::getUnqual(IRB
.getInt8Ty());
242 Int8Ty
= IRB
.getInt8Ty();
244 // Check that the __sancov_lowest_stack marker does not already exist.
245 Constant
*SanCovLowestStackConstant
=
246 M
.getOrInsertGlobal(SanCovLowestStackName
, IntptrTy
);
247 GlobalVariable
*SanCovLowestStack
=
248 dyn_cast
<GlobalVariable
>(SanCovLowestStackConstant
);
249 if (!SanCovLowestStack
) {
250 C
->emitError(StringRef("'") + SanCovLowestStackName
+
251 "' should not be declared by the user");
255 // We want to emit guard init calls if the module contains a function that
256 // we can instrument with SanitizerCoverage. We ignore any functions that
257 // were inserted by SanitizerCoverage and get the result from the analysis
258 // that checks for a valid function that the analysis may have run over.
260 M
, [](const Function
&F
) { return canInstrumentWithSancov(F
); }))
263 // Emit the init calls.
264 if (Options
.TracePCGuard
)
265 Ctor
= CreateInitCallsForSections(M
, SanCovModuleCtorTracePcGuardName
,
266 SanCovTracePCGuardInitName
, Int32PtrTy
,
267 SanCovGuardsSectionName
);
268 if (Options
.Inline8bitCounters
)
269 Ctor
= CreateInitCallsForSections(M
, SanCovModuleCtor8bitCountersName
,
270 SanCov8bitCountersInitName
, Int8PtrTy
,
271 SanCovCountersSectionName
);
272 if (Ctor
&& Options
.PCTable
) {
274 CreateSecStartEnd(M
, SanCovPCsSectionName
, IntptrPtrTy
);
275 FunctionCallee InitFunction
= declareSanitizerInitFunction(
276 M
, SanCovPCsInitName
, {IntptrPtrTy
, IntptrPtrTy
});
277 IRBuilder
<> IRBCtor(Ctor
->getEntryBlock().getTerminator());
278 IRBCtor
.CreateCall(InitFunction
, {SecStartEnd
.first
, SecStartEnd
.second
});
284 Function
*CreateInitCallsForSections(Module
&M
, const char *CtorName
,
285 const char *InitFunctionName
, Type
*Ty
,
286 const char *Section
);
287 std::pair
<Value
*, Value
*> CreateSecStartEnd(Module
&M
, const char *Section
,
289 std::string
getSectionStart(const std::string
&Section
) const {
290 return getSectionStartImpl(TargetTriple
, Section
);
292 std::string
getSectionEnd(const std::string
&Section
) const {
293 return getSectionEndImpl(TargetTriple
, Section
);
296 SanitizerCoverageOptions Options
;
298 Type
*IntptrTy
, *Int8PtrTy
, *Int8Ty
;
301 class ModuleSanitizerCoverageLegacyPass
: public ModulePass
{
305 ModuleSanitizerCoverageLegacyPass(
306 SanitizerCoverageOptions Options
= SanitizerCoverageOptions())
307 : ModulePass(ID
), Options(Options
) {
308 initializeModuleSanitizerCoverageLegacyPassPass(
309 *PassRegistry::getPassRegistry());
312 bool runOnModule(Module
&M
) override
{
313 ModuleSanitizerCoverage
ModuleSancov(Options
);
314 return ModuleSancov
.instrumentModule(M
);
317 StringRef
getPassName() const override
{
318 return "ModuleSanitizerCoverageLegacyPass";
322 SanitizerCoverageOptions Options
;
325 char ModuleSanitizerCoverageLegacyPass::ID
= 0;
327 class SanitizerCoverage
{
329 SanitizerCoverage(Function
&F
, const SanitizerCoverageOptions
&Options
)
330 : CurModule(F
.getParent()), Options(OverrideFromCL(Options
)) {
331 initializeModule(*F
.getParent());
334 ~SanitizerCoverage() { finalizeModule(*CurModule
); }
336 bool instrumentFunction(Function
&F
, const DominatorTree
*DT
,
337 const PostDominatorTree
*PDT
);
340 void initializeModule(Module
&M
);
341 void finalizeModule(Module
&M
);
342 void InjectCoverageForIndirectCalls(Function
&F
,
343 ArrayRef
<Instruction
*> IndirCalls
);
344 void InjectTraceForCmp(Function
&F
, ArrayRef
<Instruction
*> CmpTraceTargets
);
345 void InjectTraceForDiv(Function
&F
,
346 ArrayRef
<BinaryOperator
*> DivTraceTargets
);
347 void InjectTraceForGep(Function
&F
,
348 ArrayRef
<GetElementPtrInst
*> GepTraceTargets
);
349 void InjectTraceForSwitch(Function
&F
,
350 ArrayRef
<Instruction
*> SwitchTraceTargets
);
351 bool InjectCoverage(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
,
352 bool IsLeafFunc
= true);
353 GlobalVariable
*CreateFunctionLocalArrayInSection(size_t NumElements
,
354 Function
&F
, Type
*Ty
,
355 const char *Section
);
356 GlobalVariable
*CreatePCArray(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
);
357 void CreateFunctionLocalArrays(Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
);
358 void InjectCoverageAtBlock(Function
&F
, BasicBlock
&BB
, size_t Idx
,
359 bool IsLeafFunc
= true);
361 void SetNoSanitizeMetadata(Instruction
*I
) {
362 I
->setMetadata(I
->getModule()->getMDKindID("nosanitize"),
363 MDNode::get(*C
, None
));
366 std::string
getSectionName(const std::string
&Section
) const;
367 std::string
getSectionStart(const std::string
&Section
) const;
368 std::string
getSectionEnd(const std::string
&Section
) const;
369 FunctionCallee SanCovTracePCIndir
;
370 FunctionCallee SanCovTracePC
, SanCovTracePCGuard
;
371 FunctionCallee SanCovTraceCmpFunction
[4];
372 FunctionCallee SanCovTraceConstCmpFunction
[4];
373 FunctionCallee SanCovTraceDivFunction
[2];
374 FunctionCallee SanCovTraceGepFunction
;
375 FunctionCallee SanCovTraceSwitchFunction
;
376 GlobalVariable
*SanCovLowestStack
;
378 Type
*IntptrTy
, *IntptrPtrTy
, *Int64Ty
, *Int64PtrTy
, *Int32Ty
, *Int32PtrTy
,
379 *Int16Ty
, *Int8Ty
, *Int8PtrTy
;
381 std::string CurModuleUniqueId
;
384 const DataLayout
*DL
;
386 GlobalVariable
*FunctionGuardArray
; // for trace-pc-guard.
387 GlobalVariable
*Function8bitCounterArray
; // for inline-8bit-counters.
388 GlobalVariable
*FunctionPCsArray
; // for pc-table.
389 SmallVector
<GlobalValue
*, 20> GlobalsToAppendToUsed
;
390 SmallVector
<GlobalValue
*, 20> GlobalsToAppendToCompilerUsed
;
392 SanitizerCoverageOptions Options
;
395 class SanitizerCoverageLegacyPass
: public FunctionPass
{
397 static char ID
; // Pass identification, replacement for typeid
399 SanitizerCoverageLegacyPass(
400 SanitizerCoverageOptions Options
= SanitizerCoverageOptions())
401 : FunctionPass(ID
), Options(Options
) {
402 initializeSanitizerCoverageLegacyPassPass(*PassRegistry::getPassRegistry());
405 bool runOnFunction(Function
&F
) override
{
406 const DominatorTree
*DT
=
407 &getAnalysis
<DominatorTreeWrapperPass
>().getDomTree();
408 const PostDominatorTree
*PDT
=
409 &getAnalysis
<PostDominatorTreeWrapperPass
>().getPostDomTree();
410 SanitizerCoverage
Sancov(F
, Options
);
411 return Sancov
.instrumentFunction(F
, DT
, PDT
);
414 StringRef
getPassName() const override
{
415 return "SanitizerCoverageLegacyPass";
418 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
419 // Make the module sancov pass required by this pass so that it runs when
420 // -sancov is passed.
421 AU
.addRequired
<ModuleSanitizerCoverageLegacyPass
>();
422 AU
.addRequired
<DominatorTreeWrapperPass
>();
423 AU
.addRequired
<PostDominatorTreeWrapperPass
>();
427 SanitizerCoverageOptions Options
;
432 PreservedAnalyses
SanitizerCoveragePass::run(Function
&F
,
433 FunctionAnalysisManager
&AM
) {
434 const DominatorTree
*DT
= &AM
.getResult
<DominatorTreeAnalysis
>(F
);
435 const PostDominatorTree
*PDT
= &AM
.getResult
<PostDominatorTreeAnalysis
>(F
);
436 SanitizerCoverage
Sancov(F
, Options
);
437 if (Sancov
.instrumentFunction(F
, DT
, PDT
))
438 return PreservedAnalyses::none();
439 return PreservedAnalyses::all();
442 PreservedAnalyses
ModuleSanitizerCoveragePass::run(Module
&M
,
443 ModuleAnalysisManager
&AM
) {
444 ModuleSanitizerCoverage
ModuleSancov(Options
);
445 if (ModuleSancov
.instrumentModule(M
))
446 return PreservedAnalyses::none();
447 return PreservedAnalyses::all();
450 std::pair
<Value
*, Value
*>
451 ModuleSanitizerCoverage::CreateSecStartEnd(Module
&M
, const char *Section
,
453 GlobalVariable
*SecStart
=
454 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
, nullptr,
455 getSectionStart(Section
));
456 SecStart
->setVisibility(GlobalValue::HiddenVisibility
);
457 GlobalVariable
*SecEnd
=
458 new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
,
459 nullptr, getSectionEnd(Section
));
460 SecEnd
->setVisibility(GlobalValue::HiddenVisibility
);
462 IRBuilder
<> IRB(M
.getContext());
463 Value
*SecEndPtr
= IRB
.CreatePointerCast(SecEnd
, Ty
);
464 if (!TargetTriple
.isOSBinFormatCOFF())
465 return std::make_pair(IRB
.CreatePointerCast(SecStart
, Ty
), SecEndPtr
);
467 // Account for the fact that on windows-msvc __start_* symbols actually
468 // point to a uint64_t before the start of the array.
469 auto SecStartI8Ptr
= IRB
.CreatePointerCast(SecStart
, Int8PtrTy
);
470 auto GEP
= IRB
.CreateGEP(Int8Ty
, SecStartI8Ptr
,
471 ConstantInt::get(IntptrTy
, sizeof(uint64_t)));
472 return std::make_pair(IRB
.CreatePointerCast(GEP
, Ty
), SecEndPtr
);
475 Function
*ModuleSanitizerCoverage::CreateInitCallsForSections(
476 Module
&M
, const char *CtorName
, const char *InitFunctionName
, Type
*Ty
,
477 const char *Section
) {
478 auto SecStartEnd
= CreateSecStartEnd(M
, Section
, Ty
);
479 auto SecStart
= SecStartEnd
.first
;
480 auto SecEnd
= SecStartEnd
.second
;
482 std::tie(CtorFunc
, std::ignore
) = createSanitizerCtorAndInitFunctions(
483 M
, CtorName
, InitFunctionName
, {Ty
, Ty
}, {SecStart
, SecEnd
});
484 assert(CtorFunc
->getName() == CtorName
);
486 if (TargetTriple
.supportsCOMDAT()) {
487 // Use comdat to dedup CtorFunc.
488 CtorFunc
->setComdat(M
.getOrInsertComdat(CtorName
));
489 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
, CtorFunc
);
491 appendToGlobalCtors(M
, CtorFunc
, SanCtorAndDtorPriority
);
494 if (TargetTriple
.isOSBinFormatCOFF()) {
495 // In COFF files, if the contructors are set as COMDAT (they are because
496 // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced
497 // functions and data) is used, the constructors get stripped. To prevent
498 // this, give the constructors weak ODR linkage and ensure the linker knows
499 // to include the sancov constructor. This way the linker can deduplicate
500 // the constructors but always leave one copy.
501 CtorFunc
->setLinkage(GlobalValue::WeakODRLinkage
);
502 appendToUsed(M
, CtorFunc
);
507 void SanitizerCoverage::initializeModule(Module
&M
) {
508 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_None
)
510 C
= &(M
.getContext());
511 DL
= &M
.getDataLayout();
512 CurModuleUniqueId
= getUniqueModuleId(CurModule
);
513 TargetTriple
= Triple(M
.getTargetTriple());
514 FunctionGuardArray
= nullptr;
515 Function8bitCounterArray
= nullptr;
516 FunctionPCsArray
= nullptr;
517 IntptrTy
= Type::getIntNTy(*C
, DL
->getPointerSizeInBits());
518 IntptrPtrTy
= PointerType::getUnqual(IntptrTy
);
519 Type
*VoidTy
= Type::getVoidTy(*C
);
521 Int64PtrTy
= PointerType::getUnqual(IRB
.getInt64Ty());
522 Int32PtrTy
= PointerType::getUnqual(IRB
.getInt32Ty());
523 Int8PtrTy
= PointerType::getUnqual(IRB
.getInt8Ty());
524 Int64Ty
= IRB
.getInt64Ty();
525 Int32Ty
= IRB
.getInt32Ty();
526 Int16Ty
= IRB
.getInt16Ty();
527 Int8Ty
= IRB
.getInt8Ty();
530 M
.getOrInsertFunction(SanCovTracePCIndirName
, VoidTy
, IntptrTy
);
531 // Make sure smaller parameters are zero-extended to i64 as required by the
533 AttributeList SanCovTraceCmpZeroExtAL
;
534 if (TargetTriple
.getArch() == Triple::x86_64
) {
535 SanCovTraceCmpZeroExtAL
=
536 SanCovTraceCmpZeroExtAL
.addParamAttribute(*C
, 0, Attribute::ZExt
);
537 SanCovTraceCmpZeroExtAL
=
538 SanCovTraceCmpZeroExtAL
.addParamAttribute(*C
, 1, Attribute::ZExt
);
541 SanCovTraceCmpFunction
[0] =
542 M
.getOrInsertFunction(SanCovTraceCmp1
, SanCovTraceCmpZeroExtAL
, VoidTy
,
543 IRB
.getInt8Ty(), IRB
.getInt8Ty());
544 SanCovTraceCmpFunction
[1] =
545 M
.getOrInsertFunction(SanCovTraceCmp2
, SanCovTraceCmpZeroExtAL
, VoidTy
,
546 IRB
.getInt16Ty(), IRB
.getInt16Ty());
547 SanCovTraceCmpFunction
[2] =
548 M
.getOrInsertFunction(SanCovTraceCmp4
, SanCovTraceCmpZeroExtAL
, VoidTy
,
549 IRB
.getInt32Ty(), IRB
.getInt32Ty());
550 SanCovTraceCmpFunction
[3] =
551 M
.getOrInsertFunction(SanCovTraceCmp8
, VoidTy
, Int64Ty
, Int64Ty
);
553 SanCovTraceConstCmpFunction
[0] = M
.getOrInsertFunction(
554 SanCovTraceConstCmp1
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int8Ty
, Int8Ty
);
555 SanCovTraceConstCmpFunction
[1] = M
.getOrInsertFunction(
556 SanCovTraceConstCmp2
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int16Ty
, Int16Ty
);
557 SanCovTraceConstCmpFunction
[2] = M
.getOrInsertFunction(
558 SanCovTraceConstCmp4
, SanCovTraceCmpZeroExtAL
, VoidTy
, Int32Ty
, Int32Ty
);
559 SanCovTraceConstCmpFunction
[3] =
560 M
.getOrInsertFunction(SanCovTraceConstCmp8
, VoidTy
, Int64Ty
, Int64Ty
);
564 if (TargetTriple
.getArch() == Triple::x86_64
)
565 AL
= AL
.addParamAttribute(*C
, 0, Attribute::ZExt
);
566 SanCovTraceDivFunction
[0] =
567 M
.getOrInsertFunction(SanCovTraceDiv4
, AL
, VoidTy
, IRB
.getInt32Ty());
569 SanCovTraceDivFunction
[1] =
570 M
.getOrInsertFunction(SanCovTraceDiv8
, VoidTy
, Int64Ty
);
571 SanCovTraceGepFunction
=
572 M
.getOrInsertFunction(SanCovTraceGep
, VoidTy
, IntptrTy
);
573 SanCovTraceSwitchFunction
=
574 M
.getOrInsertFunction(SanCovTraceSwitchName
, VoidTy
, Int64Ty
, Int64PtrTy
);
576 Constant
*SanCovLowestStackConstant
=
577 M
.getOrInsertGlobal(SanCovLowestStackName
, IntptrTy
);
578 SanCovLowestStack
= dyn_cast
<GlobalVariable
>(SanCovLowestStackConstant
);
579 SanCovLowestStack
->setThreadLocalMode(
580 GlobalValue::ThreadLocalMode::InitialExecTLSModel
);
581 if (Options
.StackDepth
&& !SanCovLowestStack
->isDeclaration())
582 SanCovLowestStack
->setInitializer(Constant::getAllOnesValue(IntptrTy
));
584 // We insert an empty inline asm after cov callbacks to avoid callback merge.
585 EmptyAsm
= InlineAsm::get(FunctionType::get(IRB
.getVoidTy(), false),
586 StringRef(""), StringRef(""),
587 /*hasSideEffects=*/true);
589 SanCovTracePC
= M
.getOrInsertFunction(SanCovTracePCName
, VoidTy
);
591 M
.getOrInsertFunction(SanCovTracePCGuardName
, VoidTy
, Int32PtrTy
);
594 void SanitizerCoverage::finalizeModule(Module
&M
) {
595 // We don't reference these arrays directly in any of our runtime functions,
596 // so we need to prevent them from being dead stripped.
597 if (TargetTriple
.isOSBinFormatMachO())
598 appendToUsed(M
, GlobalsToAppendToUsed
);
599 appendToCompilerUsed(M
, GlobalsToAppendToCompilerUsed
);
602 // True if block has successors and it dominates all of them.
603 static bool isFullDominator(const BasicBlock
*BB
, const DominatorTree
*DT
) {
604 if (succ_begin(BB
) == succ_end(BB
))
607 for (const BasicBlock
*SUCC
: make_range(succ_begin(BB
), succ_end(BB
))) {
608 if (!DT
->dominates(BB
, SUCC
))
615 // True if block has predecessors and it postdominates all of them.
616 static bool isFullPostDominator(const BasicBlock
*BB
,
617 const PostDominatorTree
*PDT
) {
618 if (pred_begin(BB
) == pred_end(BB
))
621 for (const BasicBlock
*PRED
: make_range(pred_begin(BB
), pred_end(BB
))) {
622 if (!PDT
->dominates(BB
, PRED
))
629 static bool shouldInstrumentBlock(const Function
&F
, const BasicBlock
*BB
,
630 const DominatorTree
*DT
,
631 const PostDominatorTree
*PDT
,
632 const SanitizerCoverageOptions
&Options
) {
633 // Don't insert coverage for blocks containing nothing but unreachable: we
634 // will never call __sanitizer_cov() for them, so counting them in
635 // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
636 // percentage. Also, unreachable instructions frequently have no debug
638 if (isa
<UnreachableInst
>(BB
->getFirstNonPHIOrDbgOrLifetime()))
641 // Don't insert coverage into blocks without a valid insertion point
642 // (catchswitch blocks).
643 if (BB
->getFirstInsertionPt() == BB
->end())
646 if (Options
.NoPrune
|| &F
.getEntryBlock() == BB
)
649 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_Function
&&
650 &F
.getEntryBlock() != BB
)
653 // Do not instrument full dominators, or full post-dominators with multiple
655 return !isFullDominator(BB
, DT
)
656 && !(isFullPostDominator(BB
, PDT
) && !BB
->getSinglePredecessor());
660 // Returns true iff From->To is a backedge.
661 // A twist here is that we treat From->To as a backedge if
662 // * To dominates From or
663 // * To->UniqueSuccessor dominates From
664 static bool IsBackEdge(BasicBlock
*From
, BasicBlock
*To
,
665 const DominatorTree
*DT
) {
666 if (DT
->dominates(To
, From
))
668 if (auto Next
= To
->getUniqueSuccessor())
669 if (DT
->dominates(Next
, From
))
674 // Prunes uninteresting Cmp instrumentation:
675 // * CMP instructions that feed into loop backedge branch.
677 // Note that Cmp pruning is controlled by the same flag as the
679 static bool IsInterestingCmp(ICmpInst
*CMP
, const DominatorTree
*DT
,
680 const SanitizerCoverageOptions
&Options
) {
681 if (!Options
.NoPrune
)
682 if (CMP
->hasOneUse())
683 if (auto BR
= dyn_cast
<BranchInst
>(CMP
->user_back()))
684 for (BasicBlock
*B
: BR
->successors())
685 if (IsBackEdge(BR
->getParent(), B
, DT
))
690 bool SanitizerCoverage::instrumentFunction(Function
&F
, const DominatorTree
*DT
,
691 const PostDominatorTree
*PDT
) {
692 if (Options
.CoverageType
== SanitizerCoverageOptions::SCK_None
)
694 if (!canInstrumentWithSancov(F
))
696 if (Options
.CoverageType
>= SanitizerCoverageOptions::SCK_Edge
)
697 SplitAllCriticalEdges(F
, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
698 SmallVector
<Instruction
*, 8> IndirCalls
;
699 SmallVector
<BasicBlock
*, 16> BlocksToInstrument
;
700 SmallVector
<Instruction
*, 8> CmpTraceTargets
;
701 SmallVector
<Instruction
*, 8> SwitchTraceTargets
;
702 SmallVector
<BinaryOperator
*, 8> DivTraceTargets
;
703 SmallVector
<GetElementPtrInst
*, 8> GepTraceTargets
;
705 bool IsLeafFunc
= true;
708 if (shouldInstrumentBlock(F
, &BB
, DT
, PDT
, Options
))
709 BlocksToInstrument
.push_back(&BB
);
710 for (auto &Inst
: BB
) {
711 if (Options
.IndirectCalls
) {
713 if (CS
&& !CS
.getCalledFunction())
714 IndirCalls
.push_back(&Inst
);
716 if (Options
.TraceCmp
) {
717 if (ICmpInst
*CMP
= dyn_cast
<ICmpInst
>(&Inst
))
718 if (IsInterestingCmp(CMP
, DT
, Options
))
719 CmpTraceTargets
.push_back(&Inst
);
720 if (isa
<SwitchInst
>(&Inst
))
721 SwitchTraceTargets
.push_back(&Inst
);
723 if (Options
.TraceDiv
)
724 if (BinaryOperator
*BO
= dyn_cast
<BinaryOperator
>(&Inst
))
725 if (BO
->getOpcode() == Instruction::SDiv
||
726 BO
->getOpcode() == Instruction::UDiv
)
727 DivTraceTargets
.push_back(BO
);
728 if (Options
.TraceGep
)
729 if (GetElementPtrInst
*GEP
= dyn_cast
<GetElementPtrInst
>(&Inst
))
730 GepTraceTargets
.push_back(GEP
);
731 if (Options
.StackDepth
)
732 if (isa
<InvokeInst
>(Inst
) ||
733 (isa
<CallInst
>(Inst
) && !isa
<IntrinsicInst
>(Inst
)))
738 InjectCoverage(F
, BlocksToInstrument
, IsLeafFunc
);
739 InjectCoverageForIndirectCalls(F
, IndirCalls
);
740 InjectTraceForCmp(F
, CmpTraceTargets
);
741 InjectTraceForSwitch(F
, SwitchTraceTargets
);
742 InjectTraceForDiv(F
, DivTraceTargets
);
743 InjectTraceForGep(F
, GepTraceTargets
);
747 GlobalVariable
*SanitizerCoverage::CreateFunctionLocalArrayInSection(
748 size_t NumElements
, Function
&F
, Type
*Ty
, const char *Section
) {
749 ArrayType
*ArrayTy
= ArrayType::get(Ty
, NumElements
);
750 auto Array
= new GlobalVariable(
751 *CurModule
, ArrayTy
, false, GlobalVariable::PrivateLinkage
,
752 Constant::getNullValue(ArrayTy
), "__sancov_gen_");
754 if (TargetTriple
.supportsCOMDAT() && !F
.isInterposable())
756 GetOrCreateFunctionComdat(F
, TargetTriple
, CurModuleUniqueId
))
757 Array
->setComdat(Comdat
);
758 Array
->setSection(getSectionName(Section
));
759 Array
->setAlignment(Ty
->isPointerTy() ? DL
->getPointerSize()
760 : Ty
->getPrimitiveSizeInBits() / 8);
761 GlobalsToAppendToUsed
.push_back(Array
);
762 GlobalsToAppendToCompilerUsed
.push_back(Array
);
763 MDNode
*MD
= MDNode::get(F
.getContext(), ValueAsMetadata::get(&F
));
764 Array
->addMetadata(LLVMContext::MD_associated
, *MD
);
770 SanitizerCoverage::CreatePCArray(Function
&F
,
771 ArrayRef
<BasicBlock
*> AllBlocks
) {
772 size_t N
= AllBlocks
.size();
774 SmallVector
<Constant
*, 32> PCs
;
775 IRBuilder
<> IRB(&*F
.getEntryBlock().getFirstInsertionPt());
776 for (size_t i
= 0; i
< N
; i
++) {
777 if (&F
.getEntryBlock() == AllBlocks
[i
]) {
778 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(&F
, IntptrPtrTy
));
779 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
780 ConstantInt::get(IntptrTy
, 1), IntptrPtrTy
));
782 PCs
.push_back((Constant
*)IRB
.CreatePointerCast(
783 BlockAddress::get(AllBlocks
[i
]), IntptrPtrTy
));
784 PCs
.push_back((Constant
*)IRB
.CreateIntToPtr(
785 ConstantInt::get(IntptrTy
, 0), IntptrPtrTy
));
788 auto *PCArray
= CreateFunctionLocalArrayInSection(N
* 2, F
, IntptrPtrTy
,
789 SanCovPCsSectionName
);
790 PCArray
->setInitializer(
791 ConstantArray::get(ArrayType::get(IntptrPtrTy
, N
* 2), PCs
));
792 PCArray
->setConstant(true);
797 void SanitizerCoverage::CreateFunctionLocalArrays(
798 Function
&F
, ArrayRef
<BasicBlock
*> AllBlocks
) {
799 if (Options
.TracePCGuard
)
800 FunctionGuardArray
= CreateFunctionLocalArrayInSection(
801 AllBlocks
.size(), F
, Int32Ty
, SanCovGuardsSectionName
);
803 if (Options
.Inline8bitCounters
)
804 Function8bitCounterArray
= CreateFunctionLocalArrayInSection(
805 AllBlocks
.size(), F
, Int8Ty
, SanCovCountersSectionName
);
808 FunctionPCsArray
= CreatePCArray(F
, AllBlocks
);
811 bool SanitizerCoverage::InjectCoverage(Function
&F
,
812 ArrayRef
<BasicBlock
*> AllBlocks
,
814 if (AllBlocks
.empty()) return false;
815 CreateFunctionLocalArrays(F
, AllBlocks
);
816 for (size_t i
= 0, N
= AllBlocks
.size(); i
< N
; i
++)
817 InjectCoverageAtBlock(F
, *AllBlocks
[i
], i
, IsLeafFunc
);
821 // On every indirect call we call a run-time function
822 // __sanitizer_cov_indir_call* with two parameters:
824 // - global cache array that contains CacheSize pointers (zero-initialized).
825 // The cache is used to speed up recording the caller-callee pairs.
826 // The address of the caller is passed implicitly via caller PC.
827 // CacheSize is encoded in the name of the run-time function.
828 void SanitizerCoverage::InjectCoverageForIndirectCalls(
829 Function
&F
, ArrayRef
<Instruction
*> IndirCalls
) {
830 if (IndirCalls
.empty())
832 assert(Options
.TracePC
|| Options
.TracePCGuard
|| Options
.Inline8bitCounters
);
833 for (auto I
: IndirCalls
) {
836 Value
*Callee
= CS
.getCalledValue();
837 if (isa
<InlineAsm
>(Callee
))
839 IRB
.CreateCall(SanCovTracePCIndir
, IRB
.CreatePointerCast(Callee
, IntptrTy
));
843 // For every switch statement we insert a call:
844 // __sanitizer_cov_trace_switch(CondValue,
845 // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
847 void SanitizerCoverage::InjectTraceForSwitch(
848 Function
&, ArrayRef
<Instruction
*> SwitchTraceTargets
) {
849 for (auto I
: SwitchTraceTargets
) {
850 if (SwitchInst
*SI
= dyn_cast
<SwitchInst
>(I
)) {
852 SmallVector
<Constant
*, 16> Initializers
;
853 Value
*Cond
= SI
->getCondition();
854 if (Cond
->getType()->getScalarSizeInBits() >
855 Int64Ty
->getScalarSizeInBits())
857 Initializers
.push_back(ConstantInt::get(Int64Ty
, SI
->getNumCases()));
858 Initializers
.push_back(
859 ConstantInt::get(Int64Ty
, Cond
->getType()->getScalarSizeInBits()));
860 if (Cond
->getType()->getScalarSizeInBits() <
861 Int64Ty
->getScalarSizeInBits())
862 Cond
= IRB
.CreateIntCast(Cond
, Int64Ty
, false);
863 for (auto It
: SI
->cases()) {
864 Constant
*C
= It
.getCaseValue();
865 if (C
->getType()->getScalarSizeInBits() <
866 Int64Ty
->getScalarSizeInBits())
867 C
= ConstantExpr::getCast(CastInst::ZExt
, It
.getCaseValue(), Int64Ty
);
868 Initializers
.push_back(C
);
870 llvm::sort(Initializers
.begin() + 2, Initializers
.end(),
871 [](const Constant
*A
, const Constant
*B
) {
872 return cast
<ConstantInt
>(A
)->getLimitedValue() <
873 cast
<ConstantInt
>(B
)->getLimitedValue();
875 ArrayType
*ArrayOfInt64Ty
= ArrayType::get(Int64Ty
, Initializers
.size());
876 GlobalVariable
*GV
= new GlobalVariable(
877 *CurModule
, ArrayOfInt64Ty
, false, GlobalVariable::InternalLinkage
,
878 ConstantArray::get(ArrayOfInt64Ty
, Initializers
),
879 "__sancov_gen_cov_switch_values");
880 IRB
.CreateCall(SanCovTraceSwitchFunction
,
881 {Cond
, IRB
.CreatePointerCast(GV
, Int64PtrTy
)});
886 void SanitizerCoverage::InjectTraceForDiv(
887 Function
&, ArrayRef
<BinaryOperator
*> DivTraceTargets
) {
888 for (auto BO
: DivTraceTargets
) {
890 Value
*A1
= BO
->getOperand(1);
891 if (isa
<ConstantInt
>(A1
)) continue;
892 if (!A1
->getType()->isIntegerTy())
894 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A1
->getType());
895 int CallbackIdx
= TypeSize
== 32 ? 0 :
896 TypeSize
== 64 ? 1 : -1;
897 if (CallbackIdx
< 0) continue;
898 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
899 IRB
.CreateCall(SanCovTraceDivFunction
[CallbackIdx
],
900 {IRB
.CreateIntCast(A1
, Ty
, true)});
904 void SanitizerCoverage::InjectTraceForGep(
905 Function
&, ArrayRef
<GetElementPtrInst
*> GepTraceTargets
) {
906 for (auto GEP
: GepTraceTargets
) {
907 IRBuilder
<> IRB(GEP
);
908 for (auto I
= GEP
->idx_begin(); I
!= GEP
->idx_end(); ++I
)
909 if (!isa
<ConstantInt
>(*I
) && (*I
)->getType()->isIntegerTy())
910 IRB
.CreateCall(SanCovTraceGepFunction
,
911 {IRB
.CreateIntCast(*I
, IntptrTy
, true)});
915 void SanitizerCoverage::InjectTraceForCmp(
916 Function
&, ArrayRef
<Instruction
*> CmpTraceTargets
) {
917 for (auto I
: CmpTraceTargets
) {
918 if (ICmpInst
*ICMP
= dyn_cast
<ICmpInst
>(I
)) {
919 IRBuilder
<> IRB(ICMP
);
920 Value
*A0
= ICMP
->getOperand(0);
921 Value
*A1
= ICMP
->getOperand(1);
922 if (!A0
->getType()->isIntegerTy())
924 uint64_t TypeSize
= DL
->getTypeStoreSizeInBits(A0
->getType());
925 int CallbackIdx
= TypeSize
== 8 ? 0 :
928 TypeSize
== 64 ? 3 : -1;
929 if (CallbackIdx
< 0) continue;
930 // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
931 auto CallbackFunc
= SanCovTraceCmpFunction
[CallbackIdx
];
932 bool FirstIsConst
= isa
<ConstantInt
>(A0
);
933 bool SecondIsConst
= isa
<ConstantInt
>(A1
);
934 // If both are const, then we don't need such a comparison.
935 if (FirstIsConst
&& SecondIsConst
) continue;
936 // If only one is const, then make it the first callback argument.
937 if (FirstIsConst
|| SecondIsConst
) {
938 CallbackFunc
= SanCovTraceConstCmpFunction
[CallbackIdx
];
943 auto Ty
= Type::getIntNTy(*C
, TypeSize
);
944 IRB
.CreateCall(CallbackFunc
, {IRB
.CreateIntCast(A0
, Ty
, true),
945 IRB
.CreateIntCast(A1
, Ty
, true)});
950 void SanitizerCoverage::InjectCoverageAtBlock(Function
&F
, BasicBlock
&BB
,
951 size_t Idx
, bool IsLeafFunc
) {
952 BasicBlock::iterator IP
= BB
.getFirstInsertionPt();
953 bool IsEntryBB
= &BB
== &F
.getEntryBlock();
956 if (auto SP
= F
.getSubprogram())
957 EntryLoc
= DebugLoc::get(SP
->getScopeLine(), 0, SP
);
958 // Keep static allocas and llvm.localescape calls in the entry block. Even
959 // if we aren't splitting the block, it's nice for allocas to be before
961 IP
= PrepareToSplitEntryBlock(BB
, IP
);
963 EntryLoc
= IP
->getDebugLoc();
966 IRBuilder
<> IRB(&*IP
);
967 IRB
.SetCurrentDebugLocation(EntryLoc
);
968 if (Options
.TracePC
) {
969 IRB
.CreateCall(SanCovTracePC
); // gets the PC using GET_CALLER_PC.
970 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
972 if (Options
.TracePCGuard
) {
973 auto GuardPtr
= IRB
.CreateIntToPtr(
974 IRB
.CreateAdd(IRB
.CreatePointerCast(FunctionGuardArray
, IntptrTy
),
975 ConstantInt::get(IntptrTy
, Idx
* 4)),
977 IRB
.CreateCall(SanCovTracePCGuard
, GuardPtr
);
978 IRB
.CreateCall(EmptyAsm
, {}); // Avoids callback merge.
980 if (Options
.Inline8bitCounters
) {
981 auto CounterPtr
= IRB
.CreateGEP(
982 Function8bitCounterArray
->getValueType(), Function8bitCounterArray
,
983 {ConstantInt::get(IntptrTy
, 0), ConstantInt::get(IntptrTy
, Idx
)});
984 auto Load
= IRB
.CreateLoad(Int8Ty
, CounterPtr
);
985 auto Inc
= IRB
.CreateAdd(Load
, ConstantInt::get(Int8Ty
, 1));
986 auto Store
= IRB
.CreateStore(Inc
, CounterPtr
);
987 SetNoSanitizeMetadata(Load
);
988 SetNoSanitizeMetadata(Store
);
990 if (Options
.StackDepth
&& IsEntryBB
&& !IsLeafFunc
) {
991 // Check stack depth. If it's the deepest so far, record it.
992 Module
*M
= F
.getParent();
993 Function
*GetFrameAddr
= Intrinsic::getDeclaration(
994 M
, Intrinsic::frameaddress
,
995 IRB
.getInt8PtrTy(M
->getDataLayout().getAllocaAddrSpace()));
997 IRB
.CreateCall(GetFrameAddr
, {Constant::getNullValue(Int32Ty
)});
998 auto FrameAddrInt
= IRB
.CreatePtrToInt(FrameAddrPtr
, IntptrTy
);
999 auto LowestStack
= IRB
.CreateLoad(IntptrTy
, SanCovLowestStack
);
1000 auto IsStackLower
= IRB
.CreateICmpULT(FrameAddrInt
, LowestStack
);
1001 auto ThenTerm
= SplitBlockAndInsertIfThen(IsStackLower
, &*IP
, false);
1002 IRBuilder
<> ThenIRB(ThenTerm
);
1003 auto Store
= ThenIRB
.CreateStore(FrameAddrInt
, SanCovLowestStack
);
1004 SetNoSanitizeMetadata(LowestStack
);
1005 SetNoSanitizeMetadata(Store
);
1010 SanitizerCoverage::getSectionName(const std::string
&Section
) const {
1011 if (TargetTriple
.isOSBinFormatCOFF()) {
1012 if (Section
== SanCovCountersSectionName
)
1014 if (Section
== SanCovPCsSectionName
)
1016 return ".SCOV$GM"; // For SanCovGuardsSectionName.
1018 if (TargetTriple
.isOSBinFormatMachO())
1019 return "__DATA,__" + Section
;
1020 return "__" + Section
;
1024 SanitizerCoverage::getSectionStart(const std::string
&Section
) const {
1025 return getSectionStartImpl(TargetTriple
, Section
);
1028 std::string
SanitizerCoverage::getSectionEnd(const std::string
&Section
) const {
1029 return getSectionEndImpl(TargetTriple
, Section
);
1032 INITIALIZE_PASS(ModuleSanitizerCoverageLegacyPass
, "module-sancov",
1033 "Pass for inserting sancov top-level initialization calls",
1036 char SanitizerCoverageLegacyPass::ID
= 0;
1037 INITIALIZE_PASS_BEGIN(SanitizerCoverageLegacyPass
, "sancov",
1038 "Pass for instrumenting coverage on functions", false,
1040 INITIALIZE_PASS_DEPENDENCY(ModuleSanitizerCoverageLegacyPass
)
1041 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass
)
1042 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass
)
1043 INITIALIZE_PASS_END(SanitizerCoverageLegacyPass
, "sancov",
1044 "Pass for instrumenting coverage on functions", false,
1046 FunctionPass
*llvm::createSanitizerCoverageLegacyPassPass(
1047 const SanitizerCoverageOptions
&Options
) {
1048 return new SanitizerCoverageLegacyPass(Options
);
1050 ModulePass
*llvm::createModuleSanitizerCoverageLegacyPassPass(
1051 const SanitizerCoverageOptions
&Options
) {
1052 return new ModuleSanitizerCoverageLegacyPass(Options
);