mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
[sanitizer] experimental tracing for cmp instructions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232873 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
995f4f8fd1
commit
a1ea57a185
@ -59,6 +59,7 @@ static const char *const kSanCovWithCheckName = "__sanitizer_cov_with_check";
|
|||||||
static const char *const kSanCovIndirCallName = "__sanitizer_cov_indir_call16";
|
static const char *const kSanCovIndirCallName = "__sanitizer_cov_indir_call16";
|
||||||
static const char *const kSanCovTraceEnter = "__sanitizer_cov_trace_func_enter";
|
static const char *const kSanCovTraceEnter = "__sanitizer_cov_trace_func_enter";
|
||||||
static const char *const kSanCovTraceBB = "__sanitizer_cov_trace_basic_block";
|
static const char *const kSanCovTraceBB = "__sanitizer_cov_trace_basic_block";
|
||||||
|
static const char *const kSanCovTraceCmp = "__sanitizer_cov_trace_cmp";
|
||||||
static const char *const kSanCovModuleCtorName = "sancov.module_ctor";
|
static const char *const kSanCovModuleCtorName = "sancov.module_ctor";
|
||||||
static const uint64_t kSanCtorAndDtorPriority = 2;
|
static const uint64_t kSanCtorAndDtorPriority = 2;
|
||||||
|
|
||||||
@ -80,6 +81,12 @@ static cl::opt<bool>
|
|||||||
"callbacks at every basic block"),
|
"callbacks at every basic block"),
|
||||||
cl::Hidden, cl::init(false));
|
cl::Hidden, cl::init(false));
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
ClExperimentalCMPTracing("sanitizer-coverage-experimental-trace-compares",
|
||||||
|
cl::desc("Experimental tracing of CMP and similar "
|
||||||
|
"instructions"),
|
||||||
|
cl::Hidden, cl::init(false));
|
||||||
|
|
||||||
// Experimental 8-bit counters used as an additional search heuristic during
|
// Experimental 8-bit counters used as an additional search heuristic during
|
||||||
// coverage-guided fuzzing.
|
// coverage-guided fuzzing.
|
||||||
// The counters are not thread-friendly:
|
// The counters are not thread-friendly:
|
||||||
@ -107,8 +114,8 @@ class SanitizerCoverageModule : public ModulePass {
|
|||||||
private:
|
private:
|
||||||
void InjectCoverageForIndirectCalls(Function &F,
|
void InjectCoverageForIndirectCalls(Function &F,
|
||||||
ArrayRef<Instruction *> IndirCalls);
|
ArrayRef<Instruction *> IndirCalls);
|
||||||
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
|
void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
|
||||||
ArrayRef<Instruction *> IndirCalls);
|
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks);
|
||||||
void SetNoSanitizeMetada(Instruction *I);
|
void SetNoSanitizeMetada(Instruction *I);
|
||||||
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls);
|
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls);
|
||||||
unsigned NumberOfInstrumentedBlocks() {
|
unsigned NumberOfInstrumentedBlocks() {
|
||||||
@ -119,9 +126,11 @@ class SanitizerCoverageModule : public ModulePass {
|
|||||||
Function *SanCovIndirCallFunction;
|
Function *SanCovIndirCallFunction;
|
||||||
Function *SanCovModuleInit;
|
Function *SanCovModuleInit;
|
||||||
Function *SanCovTraceEnter, *SanCovTraceBB;
|
Function *SanCovTraceEnter, *SanCovTraceBB;
|
||||||
|
Function *SanCovTraceCmpFunction;
|
||||||
InlineAsm *EmptyAsm;
|
InlineAsm *EmptyAsm;
|
||||||
Type *IntptrTy;
|
Type *IntptrTy, *Int64Ty;
|
||||||
LLVMContext *C;
|
LLVMContext *C;
|
||||||
|
const DataLayout *DL;
|
||||||
|
|
||||||
GlobalVariable *GuardArray;
|
GlobalVariable *GuardArray;
|
||||||
GlobalVariable *EightBitCounterArray;
|
GlobalVariable *EightBitCounterArray;
|
||||||
@ -144,12 +153,13 @@ static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
|
|||||||
bool SanitizerCoverageModule::runOnModule(Module &M) {
|
bool SanitizerCoverageModule::runOnModule(Module &M) {
|
||||||
if (!CoverageLevel) return false;
|
if (!CoverageLevel) return false;
|
||||||
C = &(M.getContext());
|
C = &(M.getContext());
|
||||||
auto &DL = M.getDataLayout();
|
DL = &M.getDataLayout();
|
||||||
IntptrTy = Type::getIntNTy(*C, DL.getPointerSizeInBits());
|
IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
|
||||||
Type *VoidTy = Type::getVoidTy(*C);
|
Type *VoidTy = Type::getVoidTy(*C);
|
||||||
IRBuilder<> IRB(*C);
|
IRBuilder<> IRB(*C);
|
||||||
Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
|
Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
|
||||||
Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
|
Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
|
||||||
|
Int64Ty = IRB.getInt64Ty();
|
||||||
|
|
||||||
Function *CtorFunc =
|
Function *CtorFunc =
|
||||||
Function::Create(FunctionType::get(VoidTy, false),
|
Function::Create(FunctionType::get(VoidTy, false),
|
||||||
@ -163,6 +173,9 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
|||||||
M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
|
M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
|
||||||
SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
|
SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
|
||||||
kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
|
kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
|
||||||
|
SanCovTraceCmpFunction = checkInterfaceFunction(M.getOrInsertFunction(
|
||||||
|
kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr));
|
||||||
|
|
||||||
SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction(
|
SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction(
|
||||||
kSanCovModuleInitName, Type::getVoidTy(*C), Int32PtrTy, IntptrTy,
|
kSanCovModuleInitName, Type::getVoidTy(*C), Int32PtrTy, IntptrTy,
|
||||||
Int8PtrTy, Int8PtrTy, nullptr));
|
Int8PtrTy, Int8PtrTy, nullptr));
|
||||||
@ -252,23 +265,28 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
|
|||||||
SplitAllCriticalEdges(F);
|
SplitAllCriticalEdges(F);
|
||||||
SmallVector<Instruction*, 8> IndirCalls;
|
SmallVector<Instruction*, 8> IndirCalls;
|
||||||
SmallVector<BasicBlock*, 16> AllBlocks;
|
SmallVector<BasicBlock*, 16> AllBlocks;
|
||||||
|
SmallVector<Instruction*, 8> CmpTraceTargets;
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
AllBlocks.push_back(&BB);
|
AllBlocks.push_back(&BB);
|
||||||
if (CoverageLevel >= 4)
|
for (auto &Inst : BB) {
|
||||||
for (auto &Inst : BB) {
|
if (CoverageLevel >= 4) {
|
||||||
CallSite CS(&Inst);
|
CallSite CS(&Inst);
|
||||||
if (CS && !CS.getCalledFunction())
|
if (CS && !CS.getCalledFunction())
|
||||||
IndirCalls.push_back(&Inst);
|
IndirCalls.push_back(&Inst);
|
||||||
}
|
}
|
||||||
|
if (ClExperimentalCMPTracing)
|
||||||
|
if (isa<ICmpInst>(&Inst))
|
||||||
|
CmpTraceTargets.push_back(&Inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
InjectCoverage(F, AllBlocks, IndirCalls);
|
InjectCoverage(F, AllBlocks);
|
||||||
|
InjectCoverageForIndirectCalls(F, IndirCalls);
|
||||||
|
InjectTraceForCmp(F, CmpTraceTargets);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool SanitizerCoverageModule::InjectCoverage(Function &F,
|
||||||
SanitizerCoverageModule::InjectCoverage(Function &F,
|
ArrayRef<BasicBlock *> AllBlocks) {
|
||||||
ArrayRef<BasicBlock *> AllBlocks,
|
|
||||||
ArrayRef<Instruction *> IndirCalls) {
|
|
||||||
if (!CoverageLevel) return false;
|
if (!CoverageLevel) return false;
|
||||||
|
|
||||||
if (CoverageLevel == 1) {
|
if (CoverageLevel == 1) {
|
||||||
@ -278,7 +296,6 @@ SanitizerCoverageModule::InjectCoverage(Function &F,
|
|||||||
InjectCoverageAtBlock(F, *BB,
|
InjectCoverageAtBlock(F, *BB,
|
||||||
ClCoverageBlockThreshold < AllBlocks.size());
|
ClCoverageBlockThreshold < AllBlocks.size());
|
||||||
}
|
}
|
||||||
InjectCoverageForIndirectCalls(F, IndirCalls);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +327,26 @@ void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SanitizerCoverageModule::InjectTraceForCmp(
|
||||||
|
Function &F, ArrayRef<Instruction *> CmpTraceTargets) {
|
||||||
|
if (!ClExperimentalCMPTracing) return;
|
||||||
|
for (auto I : CmpTraceTargets) {
|
||||||
|
if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
|
||||||
|
IRBuilder<> IRB(ICMP);
|
||||||
|
Value *A0 = ICMP->getOperand(0);
|
||||||
|
Value *A1 = ICMP->getOperand(1);
|
||||||
|
if (!A0->getType()->isIntegerTy()) continue;
|
||||||
|
uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
|
||||||
|
// __sanitizer_cov_indir_call((type_size << 32) | predicate, A0, A1);
|
||||||
|
IRB.CreateCall3(
|
||||||
|
SanCovTraceCmpFunction,
|
||||||
|
ConstantInt::get(Int64Ty, (TypeSize << 32) | ICMP->getPredicate()),
|
||||||
|
IRB.CreateIntCast(A0, Int64Ty, true),
|
||||||
|
IRB.CreateIntCast(A1, Int64Ty, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SanitizerCoverageModule::SetNoSanitizeMetada(Instruction *I) {
|
void SanitizerCoverageModule::SetNoSanitizeMetada(Instruction *I) {
|
||||||
I->setMetadata(
|
I->setMetadata(
|
||||||
I->getParent()->getParent()->getParent()->getMDKindID("nosanitize"),
|
I->getParent()->getParent()->getParent()->getMDKindID("nosanitize"),
|
||||||
|
13
test/Instrumentation/SanitizerCoverage/cmp-tracing.ll
Normal file
13
test/Instrumentation/SanitizerCoverage/cmp-tracing.ll
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
; Test -sanitizer-coverage-experimental-trace-compares=1
|
||||||
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-experimental-trace-compares=1 -S | FileCheck %s --check-prefix=CHECK
|
||||||
|
|
||||||
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
define i32 @foo(i32 %a, i32 %b) #0 {
|
||||||
|
entry:
|
||||||
|
%cmp = icmp slt i32 %a, %b
|
||||||
|
; CHECK: call void @__sanitizer_cov_trace_cmp
|
||||||
|
; CHECK-NEXT: icmp slt i32 %a, %b
|
||||||
|
%conv = zext i1 %cmp to i32
|
||||||
|
ret i32 %conv
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user