diff options
author | Leonard Chan <leonardchan@google.com> | 2019-09-04 20:30:29 +0000 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2019-09-04 20:30:29 +0000 |
commit | eca01b031d44da54239d9956ba0acc7cf2f7798b (patch) | |
tree | 2ff56b11f8d7c54de8a6d19e9e61153ad68fabaf /llvm/lib | |
parent | 40e3760472eae18919f4be8906869701db8f8f03 (diff) | |
download | bcm5719-llvm-eca01b031d44da54239d9956ba0acc7cf2f7798b.tar.gz bcm5719-llvm-eca01b031d44da54239d9956ba0acc7cf2f7798b.zip |
[NewPM][Sancov] Make Sancov a Module Pass instead of 2 Passes
This patch merges the sancov module and funciton passes into one module pass.
The reason for this is because we ran into an out of memory error when
attempting to run asan fuzzer on some protobufs (pc.cc files). I traced the OOM
error to the destructor of SanitizerCoverage where we only call
appendTo[Compiler]Used which calls appendToUsedList. I'm not sure where precisely
in appendToUsedList causes the OOM, but I am able to confirm that it's calling
this function *repeatedly* that causes the OOM. (I hacked sancov a bit such that
I can still create and destroy a new sancov on every function run, but only call
appendToUsedList after all functions in the module have finished. This passes, but
when I make it such that appendToUsedList is called on every sancov destruction,
we hit OOM.)
I don't think the OOM is from just adding to the SmallSet and SmallVector inside
appendToUsedList since in either case for a given module, they'll have the same
max size. I suspect that when the existing llvm.compiler.used global is erased,
the memory behind it isn't freed. I could be wrong on this though.
This patch works around the OOM issue by just calling appendToUsedList at the
end of every module run instead of function run. The same amount of constants
still get added to llvm.compiler.used, abd we make the pass usage and logic
simpler by not having any inter-pass dependencies.
Differential Revision: https://reviews.llvm.org/D66988
llvm-svn: 370971
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/Instrumentation.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp | 356 |
3 files changed, 130 insertions, 229 deletions
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index f3ce6282e0a..905d3464ae9 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -246,7 +246,6 @@ FUNCTION_PASS("kasan", AddressSanitizerPass(true, false, false)) FUNCTION_PASS("msan", MemorySanitizerPass({})) FUNCTION_PASS("kmsan", MemorySanitizerPass({0, false, /*Kernel=*/true})) FUNCTION_PASS("tsan", ThreadSanitizerPass()) -FUNCTION_PASS("sancov-func", SanitizerCoveragePass()) #undef FUNCTION_PASS #ifndef FUNCTION_PASS_WITH_PARAMS diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp index 64bf5147661..3a63cda60b3 100644 --- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -116,7 +116,7 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) { initializeMemorySanitizerLegacyPassPass(Registry); initializeHWAddressSanitizerLegacyPassPass(Registry); initializeThreadSanitizerLegacyPassPass(Registry); - initializeSanitizerCoverageLegacyPassPass(Registry); + initializeModuleSanitizerCoverageLegacyPassPass(Registry); initializeDataFlowSanitizerPass(Registry); } diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index ef8c3acadc3..f09081314eb 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -177,168 +177,21 @@ SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) { return Options; } -bool canInstrumentWithSancov(const Function &F) { - if (F.empty()) - return false; - if (F.getName().find(".module_ctor") != std::string::npos) - return false; // Should not instrument sanitizer init functions. - if (F.getName().startswith("__sanitizer_")) - return false; // Don't instrument __sanitizer_* callbacks. - // Don't touch available_externally functions, their actual body is elewhere. - if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) - return false; - // Don't instrument MSVC CRT configuration helpers. They may run before normal - // initialization. - if (F.getName() == "__local_stdio_printf_options" || - F.getName() == "__local_stdio_scanf_options") - return false; - if (isa<UnreachableInst>(F.getEntryBlock().getTerminator())) - return false; - // Don't instrument functions using SEH for now. Splitting basic blocks like - // we do for coverage breaks WinEHPrepare. - // FIXME: Remove this when SEH no longer uses landingpad pattern matching. - if (F.hasPersonalityFn() && - isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) - return false; - return true; -} - -std::string getSectionStartImpl(const Triple &TargetTriple, - const std::string &Section) { - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$start$__DATA$__" + Section; - return "__start___" + Section; -} +using DomTreeCallback = function_ref<const DominatorTree *(Function &F)>; +using PostDomTreeCallback = + function_ref<const PostDominatorTree *(Function &F)>; -std::string getSectionEndImpl(const Triple &TargetTriple, - const std::string &Section) { - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$end$__DATA$__" + Section; - return "__stop___" + Section; -} - -/// This is a class for instrumenting the module to add calls to initializing -/// the trace PC guards and 8bit counter globals. This should only be done -/// though if there is at least one function that can be instrumented with -/// Sancov. class ModuleSanitizerCoverage { public: - ModuleSanitizerCoverage(const SanitizerCoverageOptions &Options) + ModuleSanitizerCoverage( + const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : Options(OverrideFromCL(Options)) {} - - bool instrumentModule(Module &M) { - if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) - return false; - - Function *Ctor = nullptr; - LLVMContext *C = &(M.getContext()); - const DataLayout *DL = &M.getDataLayout(); - TargetTriple = Triple(M.getTargetTriple()); - IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits()); - Type *IntptrPtrTy = PointerType::getUnqual(IntptrTy); - IRBuilder<> IRB(*C); - Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); - Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty()); - Int8Ty = IRB.getInt8Ty(); - - // Check that the __sancov_lowest_stack marker does not already exist. - Constant *SanCovLowestStackConstant = - M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy); - GlobalVariable *SanCovLowestStack = - dyn_cast<GlobalVariable>(SanCovLowestStackConstant); - if (!SanCovLowestStack) { - C->emitError(StringRef("'") + SanCovLowestStackName + - "' should not be declared by the user"); - return true; - } - - // We want to emit guard init calls if the module contains a function that - // we can instrument with SanitizerCoverage. We ignore any functions that - // were inserted by SanitizerCoverage and get the result from the analysis - // that checks for a valid function that the analysis may have run over. - if (!llvm::any_of( - M, [](const Function &F) { return canInstrumentWithSancov(F); })) - return false; - - // Emit the init calls. - if (Options.TracePCGuard) - Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName, - SanCovTracePCGuardInitName, Int32PtrTy, - SanCovGuardsSectionName); - if (Options.Inline8bitCounters) - Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName, - SanCov8bitCountersInitName, Int8PtrTy, - SanCovCountersSectionName); - if (Ctor && Options.PCTable) { - auto SecStartEnd = - CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy); - FunctionCallee InitFunction = declareSanitizerInitFunction( - M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy}); - IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator()); - IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second}); - } - return Ctor; - } - -private: - Function *CreateInitCallsForSections(Module &M, const char *CtorName, - const char *InitFunctionName, Type *Ty, - const char *Section); - std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char *Section, - Type *Ty); - std::string getSectionStart(const std::string &Section) const { - return getSectionStartImpl(TargetTriple, Section); - } - std::string getSectionEnd(const std::string &Section) const { - return getSectionEndImpl(TargetTriple, Section); - } - - SanitizerCoverageOptions Options; - Triple TargetTriple; - Type *IntptrTy, *Int8PtrTy, *Int8Ty; -}; - -class ModuleSanitizerCoverageLegacyPass : public ModulePass { -public: - static char ID; - - ModuleSanitizerCoverageLegacyPass( - SanitizerCoverageOptions Options = SanitizerCoverageOptions()) - : ModulePass(ID), Options(Options) { - initializeModuleSanitizerCoverageLegacyPassPass( - *PassRegistry::getPassRegistry()); - } - - bool runOnModule(Module &M) override { - ModuleSanitizerCoverage ModuleSancov(Options); - return ModuleSancov.instrumentModule(M); - }; - - StringRef getPassName() const override { - return "ModuleSanitizerCoverageLegacyPass"; - } - -private: - SanitizerCoverageOptions Options; -}; - -char ModuleSanitizerCoverageLegacyPass::ID = 0; - -class SanitizerCoverage { -public: - SanitizerCoverage(Function &F, const SanitizerCoverageOptions &Options) - : CurModule(F.getParent()), Options(OverrideFromCL(Options)) { - initializeModule(*F.getParent()); - } - - ~SanitizerCoverage() { finalizeModule(*CurModule); } - - bool instrumentFunction(Function &F, const DominatorTree *DT, - const PostDominatorTree *PDT); + bool instrumentModule(Module &M, DomTreeCallback DTCallback, + PostDomTreeCallback PDTCallback); private: - void initializeModule(Module &M); - void finalizeModule(Module &M); + void instrumentFunction(Function &F, DomTreeCallback DTCallback, + PostDomTreeCallback PDTCallback); void InjectCoverageForIndirectCalls(Function &F, ArrayRef<Instruction *> IndirCalls); void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets); @@ -357,6 +210,11 @@ private: void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks); void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx, bool IsLeafFunc = true); + Function *CreateInitCallsForSections(Module &M, const char *CtorName, + const char *InitFunctionName, Type *Ty, + const char *Section); + std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char *Section, + Type *Ty); void SetNoSanitizeMetadata(Instruction *I) { I->setMetadata(I->getModule()->getMDKindID("nosanitize"), @@ -392,33 +250,30 @@ private: SanitizerCoverageOptions Options; }; -class SanitizerCoverageLegacyPass : public FunctionPass { +class ModuleSanitizerCoverageLegacyPass : public ModulePass { public: - static char ID; // Pass identification, replacement for typeid - - SanitizerCoverageLegacyPass( - SanitizerCoverageOptions Options = SanitizerCoverageOptions()) - : FunctionPass(ID), Options(Options) { - initializeSanitizerCoverageLegacyPassPass(*PassRegistry::getPassRegistry()); + ModuleSanitizerCoverageLegacyPass( + const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) + : ModulePass(ID), Options(Options) { + initializeModuleSanitizerCoverageLegacyPassPass( + *PassRegistry::getPassRegistry()); } - - bool runOnFunction(Function &F) override { - const DominatorTree *DT = - &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - const PostDominatorTree *PDT = - &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree(); - SanitizerCoverage Sancov(F, Options); - return Sancov.instrumentFunction(F, DT, PDT); + bool runOnModule(Module &M) override { + ModuleSanitizerCoverage ModuleSancov(Options); + auto DTCallback = [this](Function &F) -> const DominatorTree * { + return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); + }; + auto PDTCallback = [this](Function &F) -> const PostDominatorTree * { + return &this->getAnalysis<PostDominatorTreeWrapperPass>(F) + .getPostDomTree(); + }; + return ModuleSancov.instrumentModule(M, DTCallback, PDTCallback); } - StringRef getPassName() const override { - return "SanitizerCoverageLegacyPass"; - } + static char ID; // Pass identification, replacement for typeid + StringRef getPassName() const override { return "ModuleSanitizerCoverage"; } void getAnalysisUsage(AnalysisUsage &AU) const override { - // Make the module sancov pass required by this pass so that it runs when - // -sancov is passed. - AU.addRequired<ModuleSanitizerCoverageLegacyPass>(); AU.addRequired<DominatorTreeWrapperPass>(); AU.addRequired<PostDominatorTreeWrapperPass>(); } @@ -429,20 +284,17 @@ private: } // namespace -PreservedAnalyses SanitizerCoveragePass::run(Function &F, - FunctionAnalysisManager &AM) { - const DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F); - const PostDominatorTree *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F); - SanitizerCoverage Sancov(F, Options); - if (Sancov.instrumentFunction(F, DT, PDT)) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); -} - PreservedAnalyses ModuleSanitizerCoveragePass::run(Module &M, - ModuleAnalysisManager &AM) { + ModuleAnalysisManager &MAM) { ModuleSanitizerCoverage ModuleSancov(Options); - if (ModuleSancov.instrumentModule(M)) + auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); + auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { + return &FAM.getResult<DominatorTreeAnalysis>(F); + }; + auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * { + return &FAM.getResult<PostDominatorTreeAnalysis>(F); + }; + if (ModuleSancov.instrumentModule(M, DTCallback, PDTCallback)) return PreservedAnalyses::none(); return PreservedAnalyses::all(); } @@ -458,7 +310,6 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section, new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr, getSectionEnd(Section)); SecEnd->setVisibility(GlobalValue::HiddenVisibility); - IRBuilder<> IRB(M.getContext()); Value *SecEndPtr = IRB.CreatePointerCast(SecEnd, Ty); if (!TargetTriple.isOSBinFormatCOFF()) @@ -504,11 +355,13 @@ Function *ModuleSanitizerCoverage::CreateInitCallsForSections( return CtorFunc; } -void SanitizerCoverage::initializeModule(Module &M) { +bool ModuleSanitizerCoverage::instrumentModule( + Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) - return; + return false; C = &(M.getContext()); DL = &M.getDataLayout(); + CurModule = &M; CurModuleUniqueId = getUniqueModuleId(CurModule); TargetTriple = Triple(M.getTargetTriple()); FunctionGuardArray = nullptr; @@ -576,6 +429,11 @@ void SanitizerCoverage::initializeModule(Module &M) { Constant *SanCovLowestStackConstant = M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy); SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant); + if (!SanCovLowestStack) { + C->emitError(StringRef("'") + SanCovLowestStackName + + "' should not be declared by the user"); + return true; + } SanCovLowestStack->setThreadLocalMode( GlobalValue::ThreadLocalMode::InitialExecTLSModel); if (Options.StackDepth && !SanCovLowestStack->isDeclaration()) @@ -589,14 +447,33 @@ void SanitizerCoverage::initializeModule(Module &M) { SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy); SanCovTracePCGuard = M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy); -} -void SanitizerCoverage::finalizeModule(Module &M) { + for (auto &F : M) + instrumentFunction(F, DTCallback, PDTCallback); + + Function *Ctor = nullptr; + + if (FunctionGuardArray) + Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName, + SanCovTracePCGuardInitName, Int32PtrTy, + SanCovGuardsSectionName); + if (Function8bitCounterArray) + Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName, + SanCov8bitCountersInitName, Int8PtrTy, + SanCovCountersSectionName); + if (Ctor && Options.PCTable) { + auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy); + FunctionCallee InitFunction = declareSanitizerInitFunction( + M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy}); + IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator()); + IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second}); + } // We don't reference these arrays directly in any of our runtime functions, // so we need to prevent them from being dead stripped. if (TargetTriple.isOSBinFormatMachO()) appendToUsed(M, GlobalsToAppendToUsed); appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed); + return true; } // True if block has successors and it dominates all of them. @@ -687,12 +564,30 @@ static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, return true; } -bool SanitizerCoverage::instrumentFunction(Function &F, const DominatorTree *DT, - const PostDominatorTree *PDT) { - if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) - return false; - if (!canInstrumentWithSancov(F)) - return false; +void ModuleSanitizerCoverage::instrumentFunction( + Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { + if (F.empty()) + return; + if (F.getName().find(".module_ctor") != std::string::npos) + return; // Should not instrument sanitizer init functions. + if (F.getName().startswith("__sanitizer_")) + return; // Don't instrument __sanitizer_* callbacks. + // Don't touch available_externally functions, their actual body is elewhere. + if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) + return; + // Don't instrument MSVC CRT configuration helpers. They may run before normal + // initialization. + if (F.getName() == "__local_stdio_printf_options" || + F.getName() == "__local_stdio_scanf_options") + return; + if (isa<UnreachableInst>(F.getEntryBlock().getTerminator())) + return; + // Don't instrument functions using SEH for now. Splitting basic blocks like + // we do for coverage breaks WinEHPrepare. + // FIXME: Remove this when SEH no longer uses landingpad pattern matching. + if (F.hasPersonalityFn() && + isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) + return; if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests()); SmallVector<Instruction *, 8> IndirCalls; @@ -702,6 +597,8 @@ bool SanitizerCoverage::instrumentFunction(Function &F, const DominatorTree *DT, SmallVector<BinaryOperator *, 8> DivTraceTargets; SmallVector<GetElementPtrInst *, 8> GepTraceTargets; + const DominatorTree *DT = DTCallback(F); + const PostDominatorTree *PDT = PDTCallback(F); bool IsLeafFunc = true; for (auto &BB : F) { @@ -741,10 +638,9 @@ bool SanitizerCoverage::instrumentFunction(Function &F, const DominatorTree *DT, InjectTraceForSwitch(F, SwitchTraceTargets); InjectTraceForDiv(F, DivTraceTargets); InjectTraceForGep(F, GepTraceTargets); - return true; } -GlobalVariable *SanitizerCoverage::CreateFunctionLocalArrayInSection( +GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( size_t NumElements, Function &F, Type *Ty, const char *Section) { ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); auto Array = new GlobalVariable( @@ -767,8 +663,8 @@ GlobalVariable *SanitizerCoverage::CreateFunctionLocalArrayInSection( } GlobalVariable * -SanitizerCoverage::CreatePCArray(Function &F, - ArrayRef<BasicBlock *> AllBlocks) { +ModuleSanitizerCoverage::CreatePCArray(Function &F, + ArrayRef<BasicBlock *> AllBlocks) { size_t N = AllBlocks.size(); assert(N); SmallVector<Constant *, 32> PCs; @@ -794,7 +690,7 @@ SanitizerCoverage::CreatePCArray(Function &F, return PCArray; } -void SanitizerCoverage::CreateFunctionLocalArrays( +void ModuleSanitizerCoverage::CreateFunctionLocalArrays( Function &F, ArrayRef<BasicBlock *> AllBlocks) { if (Options.TracePCGuard) FunctionGuardArray = CreateFunctionLocalArrayInSection( @@ -808,9 +704,9 @@ void SanitizerCoverage::CreateFunctionLocalArrays( FunctionPCsArray = CreatePCArray(F, AllBlocks); } -bool SanitizerCoverage::InjectCoverage(Function &F, - ArrayRef<BasicBlock *> AllBlocks, - bool IsLeafFunc) { +bool ModuleSanitizerCoverage::InjectCoverage(Function &F, + ArrayRef<BasicBlock *> AllBlocks, + bool IsLeafFunc) { if (AllBlocks.empty()) return false; CreateFunctionLocalArrays(F, AllBlocks); for (size_t i = 0, N = AllBlocks.size(); i < N; i++) @@ -825,7 +721,7 @@ bool SanitizerCoverage::InjectCoverage(Function &F, // The cache is used to speed up recording the caller-callee pairs. // The address of the caller is passed implicitly via caller PC. // CacheSize is encoded in the name of the run-time function. -void SanitizerCoverage::InjectCoverageForIndirectCalls( +void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( Function &F, ArrayRef<Instruction *> IndirCalls) { if (IndirCalls.empty()) return; @@ -844,7 +740,7 @@ void SanitizerCoverage::InjectCoverageForIndirectCalls( // __sanitizer_cov_trace_switch(CondValue, // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... }) -void SanitizerCoverage::InjectTraceForSwitch( +void ModuleSanitizerCoverage::InjectTraceForSwitch( Function &, ArrayRef<Instruction *> SwitchTraceTargets) { for (auto I : SwitchTraceTargets) { if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) { @@ -883,7 +779,7 @@ void SanitizerCoverage::InjectTraceForSwitch( } } -void SanitizerCoverage::InjectTraceForDiv( +void ModuleSanitizerCoverage::InjectTraceForDiv( Function &, ArrayRef<BinaryOperator *> DivTraceTargets) { for (auto BO : DivTraceTargets) { IRBuilder<> IRB(BO); @@ -901,7 +797,7 @@ void SanitizerCoverage::InjectTraceForDiv( } } -void SanitizerCoverage::InjectTraceForGep( +void ModuleSanitizerCoverage::InjectTraceForGep( Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) { for (auto GEP : GepTraceTargets) { IRBuilder<> IRB(GEP); @@ -912,7 +808,7 @@ void SanitizerCoverage::InjectTraceForGep( } } -void SanitizerCoverage::InjectTraceForCmp( +void ModuleSanitizerCoverage::InjectTraceForCmp( Function &, ArrayRef<Instruction *> CmpTraceTargets) { for (auto I : CmpTraceTargets) { if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) { @@ -947,8 +843,9 @@ void SanitizerCoverage::InjectTraceForCmp( } } -void SanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, - size_t Idx, bool IsLeafFunc) { +void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, + size_t Idx, + bool IsLeafFunc) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc; @@ -1007,7 +904,7 @@ void SanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } std::string -SanitizerCoverage::getSectionName(const std::string &Section) const { +ModuleSanitizerCoverage::getSectionName(const std::string &Section) const { if (TargetTriple.isOSBinFormatCOFF()) { if (Section == SanCovCountersSectionName) return ".SCOV$CM"; @@ -1020,24 +917,29 @@ SanitizerCoverage::getSectionName(const std::string &Section) const { return "__" + Section; } -INITIALIZE_PASS(ModuleSanitizerCoverageLegacyPass, "module-sancov", - "Pass for inserting sancov top-level initialization calls", - false, false) +std::string +ModuleSanitizerCoverage::getSectionStart(const std::string &Section) const { + if (TargetTriple.isOSBinFormatMachO()) + return "\1section$start$__DATA$__" + Section; + return "__start___" + Section; +} + +std::string +ModuleSanitizerCoverage::getSectionEnd(const std::string &Section) const { + if (TargetTriple.isOSBinFormatMachO()) + return "\1section$end$__DATA$__" + Section; + return "__stop___" + Section; +} -char SanitizerCoverageLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(SanitizerCoverageLegacyPass, "sancov", +char ModuleSanitizerCoverageLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) -INITIALIZE_PASS_DEPENDENCY(ModuleSanitizerCoverageLegacyPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) -INITIALIZE_PASS_END(SanitizerCoverageLegacyPass, "sancov", +INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) -FunctionPass *llvm::createSanitizerCoverageLegacyPassPass( - const SanitizerCoverageOptions &Options) { - return new SanitizerCoverageLegacyPass(Options); -} ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( const SanitizerCoverageOptions &Options) { return new ModuleSanitizerCoverageLegacyPass(Options); |