llvm.org GIT mirror llvm / 50a9486
[SanitizeCoverage] Enable stack-depth coverage for -fsanitize=fuzzer Summary: - Don't sanitize __sancov_lowest_stack. - Don't instrument leaf functions. - Add CoverageStackDepth to Fuzzer and FuzzerNoLink. - Disable stack depth tracking on Mac. Reviewers: vitalybuka, kcc, george.karpenkov Reviewed By: kcc Subscribers: kubamracek, cfe-commits, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D37156 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312026 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Morehouse 2 years ago
2 changed file(s) with 31 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
2424 #include "llvm/IR/GlobalVariable.h"
2525 #include "llvm/IR/IRBuilder.h"
2626 #include "llvm/IR/InlineAsm.h"
27 #include "llvm/IR/IntrinsicInst.h"
2728 #include "llvm/IR/Intrinsics.h"
2829 #include "llvm/IR/LLVMContext.h"
2930 #include "llvm/IR/MDBuilder.h"
199200 ArrayRef GepTraceTargets);
200201 void InjectTraceForSwitch(Function &F,
201202 ArrayRef SwitchTraceTargets);
202 bool InjectCoverage(Function &F, ArrayRef AllBlocks);
203 bool InjectCoverage(Function &F, ArrayRef AllBlocks,
204 bool IsLeafFunc = true);
203205 GlobalVariable *CreateFunctionLocalArrayInSection(size_t NumElements,
204206 Function &F, Type *Ty,
205207 const char *Section);
206208 GlobalVariable *CreatePCArray(Function &F, ArrayRef AllBlocks);
207209 void CreateFunctionLocalArrays(Function &F, ArrayRef AllBlocks);
208 void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx);
210 void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
211 bool IsLeafFunc = true);
209212 Function *CreateInitCallsForSections(Module &M, const char *InitFunctionName,
210213 Type *Ty, const char *Section);
211214 std::pair
490493 &getAnalysis(F).getDomTree();
491494 const PostDominatorTree *PDT =
492495 &getAnalysis(F).getPostDomTree();
496 bool IsLeafFunc = true;
493497
494498 for (auto &BB : F) {
495499 if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
514518 if (Options.TraceGep)
515519 if (GetElementPtrInst *GEP = dyn_cast(&Inst))
516520 GepTraceTargets.push_back(GEP);
517 }
518 }
519
520 InjectCoverage(F, BlocksToInstrument);
521 if (Options.StackDepth)
522 if (isa(Inst) ||
523 (isa(Inst) && !isa(Inst)))
524 IsLeafFunc = false;
525 }
526 }
527
528 InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
521529 InjectCoverageForIndirectCalls(F, IndirCalls);
522530 InjectTraceForCmp(F, CmpTraceTargets);
523531 InjectTraceForSwitch(F, SwitchTraceTargets);
592600 }
593601
594602 bool SanitizerCoverageModule::InjectCoverage(Function &F,
595 ArrayRef AllBlocks) {
603 ArrayRef AllBlocks,
604 bool IsLeafFunc) {
596605 if (AllBlocks.empty()) return false;
597606 CreateFunctionLocalArrays(F, AllBlocks);
598607 for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
599 InjectCoverageAtBlock(F, *AllBlocks[i], i);
608 InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
600609 return true;
601610 }
602611
730739 }
731740
732741 void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
733 size_t Idx) {
742 size_t Idx,
743 bool IsLeafFunc) {
734744 BasicBlock::iterator IP = BB.getFirstInsertionPt();
735745 bool IsEntryBB = &BB == &F.getEntryBlock();
736746 DebugLoc EntryLoc;
769779 SetNoSanitizeMetadata(Load);
770780 SetNoSanitizeMetadata(Store);
771781 }
772 if (Options.StackDepth && IsEntryBB) {
782 if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
773783 // Check stack depth. If it's the deepest so far, record it.
774784 Function *GetFrameAddr =
775785 Intrinsic::getDeclaration(F.getParent(), Intrinsic::frameaddress);
780790 auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
781791 auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false);
782792 IRBuilder<> ThenIRB(ThenTerm);
783 ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
793 auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
794 SetNoSanitizeMetadata(LowestStack);
795 SetNoSanitizeMetadata(Store);
784796 }
785797 }
786798
0 ; This check verifies that stack depth instrumentation works correctly.
11 ; RUN: opt < %s -sancov -sanitizer-coverage-level=1 \
2 ; RUN: -sanitizer-coverage-stack-depth -S | FileCheck %s --enable-var-scope
2 ; RUN: -sanitizer-coverage-stack-depth -S | FileCheck %s
33 ; RUN: opt < %s -sancov -sanitizer-coverage-level=3 \
44 ; RUN: -sanitizer-coverage-stack-depth -sanitizer-coverage-trace-pc-guard \
5 ; RUN: -S | FileCheck %s --enable-var-scope
5 ; RUN: -S | FileCheck %s
66
77 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
88 target triple = "x86_64-unknown-linux-gnu"
1313 define i32 @foo() {
1414 entry:
1515 ; CHECK-LABEL: define i32 @foo
16 ; CHECK: [[framePtr:%[^ \t]+]] = call i8* @llvm.frameaddress(i32 0)
17 ; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[$intType:i[0-9]+]]
18 ; CHECK: [[lowest:%[^ \t]+]] = load [[$intType]], [[$intType]]* @__sancov_lowest_stack
19 ; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowest]]
20 ; CHECK: br i1 [[cmp]], label %[[ifLabel:[^ \t]+]], label
21 ; CHECK:
22 ; CHECK: store [[$intType]] [[frameInt]], [[$intType]]* @__sancov_lowest_stack
16 ; CHECK-NOT: call i8* @llvm.frameaddress(i32 0)
17 ; CHECK-NOT: @__sancov_lowest_stack
2318 ; CHECK: ret i32 7
2419
2520 ret i32 7
2924 entry:
3025 ; CHECK-LABEL: define i32 @bar
3126 ; CHECK: [[framePtr:%[^ \t]+]] = call i8* @llvm.frameaddress(i32 0)
32 ; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[$intType]]
33 ; CHECK: [[lowest:%[^ \t]+]] = load [[$intType]], [[$intType]]* @__sancov_lowest_stack
34 ; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowest]]
27 ; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[intType:i[0-9]+]]
28 ; CHECK: [[lowest:%[^ \t]+]] = load [[intType]], [[intType]]* @__sancov_lowest_stack
29 ; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[intType]] [[frameInt]], [[lowest]]
3530 ; CHECK: br i1 [[cmp]], label %[[ifLabel:[^ \t]+]], label
3631 ; CHECK:
37 ; CHECK: store [[$intType]] [[frameInt]], [[$intType]]* @__sancov_lowest_stack
32 ; CHECK: store [[intType]] [[frameInt]], [[intType]]* @__sancov_lowest_stack
3833 ; CHECK: %call = call i32 @foo()
3934 ; CHECK: ret i32 %call
4035