llvm.org GIT mirror llvm / 8d56960
[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. Reviewers: vitalybuka, kcc Reviewed By: kcc Subscribers: cfe-commits, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D37156 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311801 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 void CreateFunctionLocalArrays(Function &F, ArrayRef AllBlocks);
207209 void CreatePCArray(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);
582590 }
583591
584592 bool SanitizerCoverageModule::InjectCoverage(Function &F,
585 ArrayRef AllBlocks) {
593 ArrayRef AllBlocks,
594 bool IsLeafFunc) {
586595 if (AllBlocks.empty()) return false;
587596 CreateFunctionLocalArrays(F, AllBlocks);
588597 for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
589 InjectCoverageAtBlock(F, *AllBlocks[i], i);
598 InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
590599 return true;
591600 }
592601
720729 }
721730
722731 void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
723 size_t Idx) {
732 size_t Idx,
733 bool IsLeafFunc) {
724734 BasicBlock::iterator IP = BB.getFirstInsertionPt();
725735 bool IsEntryBB = &BB == &F.getEntryBlock();
726736 DebugLoc EntryLoc;
759769 SetNoSanitizeMetadata(Load);
760770 SetNoSanitizeMetadata(Store);
761771 }
762 if (Options.StackDepth && IsEntryBB) {
772 if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
763773 // Check stack depth. If it's the deepest so far, record it.
764774 Function *GetFrameAddr =
765775 Intrinsic::getDeclaration(F.getParent(), Intrinsic::frameaddress);
770780 auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
771781 auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false);
772782 IRBuilder<> ThenIRB(ThenTerm);
773 ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
783 auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
784 SetNoSanitizeMetadata(LowestStack);
785 SetNoSanitizeMetadata(Store);
774786 }
775787 }
776788
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