mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-13 18:48:08 +00:00
try different intrumentation strategy
This commit is contained in:
@ -782,11 +782,13 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
if (AllBlocks.empty()) return false;
|
if (AllBlocks.empty()) return false;
|
||||||
|
|
||||||
uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0, cnt_hidden_sel = 0,
|
uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0, cnt_hidden_sel = 0,
|
||||||
cnt_hidden_sel_inc = 0;
|
cnt_hidden_sel_inc = 0, skip_blocks = 0;
|
||||||
static uint32_t first = 1;
|
static uint32_t first = 1;
|
||||||
|
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
|
|
||||||
|
bool block_is_instrumented = false;
|
||||||
|
|
||||||
for (auto &IN : BB) {
|
for (auto &IN : BB) {
|
||||||
|
|
||||||
CallInst *callInst = nullptr;
|
CallInst *callInst = nullptr;
|
||||||
@ -800,11 +802,11 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
if (!FuncName.compare(StringRef("dlopen")) ||
|
if (!FuncName.compare(StringRef("dlopen")) ||
|
||||||
!FuncName.compare(StringRef("_dlopen"))) {
|
!FuncName.compare(StringRef("_dlopen"))) {
|
||||||
|
|
||||||
fprintf(stderr,
|
WARNF(
|
||||||
"WARNING: dlopen() detected. To have coverage for a library "
|
"dlopen() detected. To have coverage for a library that your "
|
||||||
"that your target dlopen()'s this must either happen before "
|
"target dlopen()'s this must either happen before __AFL_INIT() "
|
||||||
"__AFL_INIT() or you must use AFL_PRELOAD to preload all "
|
"or you must use AFL_PRELOAD to preload all dlopen()'ed "
|
||||||
"dlopen()'ed libraries!\n");
|
"libraries!\n");
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -812,16 +814,52 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
if (!FuncName.compare(StringRef("__afl_coverage_interesting"))) {
|
if (!FuncName.compare(StringRef("__afl_coverage_interesting"))) {
|
||||||
|
|
||||||
cnt_cov++;
|
cnt_cov++;
|
||||||
|
block_is_instrumented = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectInst *selectInst = nullptr;
|
bool instrumentInst = false;
|
||||||
|
|
||||||
|
if (isa<FCmpInst>(&IN) || isa<ICmpInst>(&IN) || isa<SelectInst>(&IN) ||
|
||||||
|
isa<PHINode>(&IN)) {
|
||||||
|
|
||||||
|
bool usedInBranch = false;
|
||||||
|
|
||||||
|
for (auto *U : IN.users()) {
|
||||||
|
|
||||||
|
if (isa<BranchInst>(U)) {
|
||||||
|
|
||||||
|
usedInBranch = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usedInBranch) {
|
||||||
|
|
||||||
|
// errs() << "Instrument! " << *(&IN) << "\n";
|
||||||
|
instrumentInst = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instrumentInst) {
|
||||||
|
|
||||||
|
block_is_instrumented = true;
|
||||||
|
SelectInst *selectInst;
|
||||||
|
PHINode *phiInst;
|
||||||
// errs() << "IN: " << *(&IN) << "\n";
|
// errs() << "IN: " << *(&IN) << "\n";
|
||||||
|
|
||||||
if ((selectInst = dyn_cast<SelectInst>(&IN))) {
|
if ((phiInst = dyn_cast<PHINode>(&IN))) {
|
||||||
|
|
||||||
|
cnt_hidden_sel++;
|
||||||
|
cnt_hidden_sel_inc += phiInst->getNumIncomingValues();
|
||||||
|
|
||||||
|
} else if ((selectInst = dyn_cast<SelectInst>(&IN))) {
|
||||||
|
|
||||||
Value *c = selectInst->getCondition();
|
Value *c = selectInst->getCondition();
|
||||||
auto t = c->getType();
|
auto t = c->getType();
|
||||||
@ -830,89 +868,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
cnt_sel++;
|
cnt_sel++;
|
||||||
cnt_sel_inc += 2;
|
cnt_sel_inc += 2;
|
||||||
|
|
||||||
Value *trueVal = selectInst->getTrueValue();
|
} else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
|
||||||
Value *falseVal = selectInst->getFalseValue();
|
|
||||||
BasicBlock *bb = selectInst->getParent();
|
|
||||||
|
|
||||||
auto isFromICmpInSameBB = [bb](Value *v) -> bool {
|
|
||||||
|
|
||||||
std::function<bool(Value *)> traceBack = [&](Value *val) -> bool {
|
|
||||||
|
|
||||||
if (auto *inst = dyn_cast<Instruction>(val)) {
|
|
||||||
|
|
||||||
if (inst->getParent() != bb) return false;
|
|
||||||
|
|
||||||
if (isa<ICmpInst>(inst)) {
|
|
||||||
|
|
||||||
// errs() << "FOUND: " << *inst << "\n";
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isa<SelectInst>(inst) || inst == &bb->front()) return false;
|
|
||||||
|
|
||||||
// If operands are all constants or loads, stop
|
|
||||||
bool allTerminating = true;
|
|
||||||
for (Use &U : inst->operands()) {
|
|
||||||
|
|
||||||
if (!isa<Constant>(U) && !isa<LoadInst>(U)) {
|
|
||||||
|
|
||||||
allTerminating = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allTerminating) return false;
|
|
||||||
|
|
||||||
// Recurse on variable operands
|
|
||||||
for (Use &U : inst->operands()) {
|
|
||||||
|
|
||||||
if (!isa<Constant>(U) && !isa<LoadInst>(U)) {
|
|
||||||
|
|
||||||
if (traceBack(U.get())) return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return traceBack(v);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isFromICmpInSameBB(trueVal)) {
|
|
||||||
|
|
||||||
cnt_hidden_sel++;
|
|
||||||
cnt_hidden_sel_inc += 2;
|
|
||||||
// errs() << "TRUEVAL: " << *selectInst << " |>| " << *c << " | "
|
|
||||||
// << *trueVal << " | " << *falseVal << "\n";
|
|
||||||
|
|
||||||
} // else
|
|
||||||
|
|
||||||
// errs() << "truenot: " << *trueVal << "\n";
|
|
||||||
|
|
||||||
if (isFromICmpInSameBB(falseVal)) {
|
|
||||||
|
|
||||||
cnt_hidden_sel++;
|
|
||||||
cnt_hidden_sel_inc += 2;
|
|
||||||
|
|
||||||
// errs() << "FALSEVAL: " << *selectInst << " |>| " << *c << " | "
|
|
||||||
// << *trueVal << " | " << *falseVal << "\n";
|
|
||||||
|
|
||||||
} // else
|
|
||||||
|
|
||||||
// errs() << "falsenot: " << *falseVal << "\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
|
|
||||||
|
|
||||||
FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
|
FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
|
||||||
if (tt) {
|
if (tt) {
|
||||||
@ -922,27 +878,70 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (!be_quiet) {
|
||||||
|
|
||||||
|
WARNF("unknown select ID type: %u\n", t->getTypeID());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cnt_hidden_sel++;
|
||||||
|
cnt_hidden_sel_inc += 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateFunctionLocalArrays(F, AllBlocks,
|
if (block_is_instrumented && &BB != &BB.getParent()->getEntryBlock()) {
|
||||||
first + cnt_cov + cnt_sel_inc + cnt_hidden_sel_inc);
|
|
||||||
|
Instruction *instr = &*BB.begin();
|
||||||
|
LLVMContext &Ctx = BB.getContext();
|
||||||
|
MDNode *md = MDNode::get(Ctx, MDString::get(Ctx, "skipinstrument"));
|
||||||
|
instr->setMetadata("tag", md);
|
||||||
|
skip_blocks++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t xtra = 0;
|
||||||
|
if (skip_blocks < first + cnt_cov + cnt_sel_inc + cnt_hidden_sel_inc) {
|
||||||
|
|
||||||
|
xtra = first + cnt_cov + cnt_sel_inc + cnt_hidden_sel_inc - skip_blocks;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateFunctionLocalArrays(F, AllBlocks, xtra);
|
||||||
|
|
||||||
|
if (!FunctionGuardArray) {
|
||||||
|
|
||||||
|
WARNF(
|
||||||
|
"SANCOV: FunctionGuardArray is NULL, failed to emit instrumentation.");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (first) { first = 0; }
|
if (first) { first = 0; }
|
||||||
selects += cnt_sel;
|
selects += cnt_sel;
|
||||||
hidden += cnt_hidden_sel;
|
hidden += cnt_hidden_sel;
|
||||||
|
|
||||||
uint32_t special = 0, local_selects = 0, skip_next = 0;
|
uint32_t special = 0, local_selects = 0, skip_select = 0, skip_icmp = 0,
|
||||||
|
skip_phi = 0;
|
||||||
|
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
|
|
||||||
|
// errs() << *(&BB) << "\n";
|
||||||
|
|
||||||
for (auto &IN : BB) {
|
for (auto &IN : BB) {
|
||||||
|
|
||||||
|
// errs() << *(&IN) << "\n";
|
||||||
CallInst *callInst = nullptr;
|
CallInst *callInst = nullptr;
|
||||||
|
|
||||||
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
||||||
@ -960,15 +959,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
IRBuilder<> IRB(callInst);
|
IRBuilder<> IRB(callInst);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!FunctionGuardArray) {
|
|
||||||
|
|
||||||
fprintf(stderr,
|
|
||||||
"SANCOV: FunctionGuardArray is NULL, failed to emit "
|
|
||||||
"instrumentation.");
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *GuardPtr = IRB.CreateIntToPtr(
|
Value *GuardPtr = IRB.CreateIntToPtr(
|
||||||
IRB.CreateAdd(
|
IRB.CreateAdd(
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
@ -982,31 +972,146 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectInst *selectInst = nullptr;
|
bool instrumentInst = false;
|
||||||
|
|
||||||
if (skip_next) {
|
if (isa<FCmpInst>(&IN) || isa<ICmpInst>(&IN) || isa<SelectInst>(&IN) ||
|
||||||
|
isa<PHINode>(&IN)) {
|
||||||
|
|
||||||
skip_next--;
|
bool usedInBranch = false;
|
||||||
|
|
||||||
} else if ((selectInst = dyn_cast<SelectInst>(&IN))) {
|
for (auto *U : IN.users()) {
|
||||||
|
|
||||||
|
if (isa<BranchInst>(U)) {
|
||||||
|
|
||||||
|
usedInBranch = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usedInBranch) {
|
||||||
|
|
||||||
|
// errs() << "Instrument! " << *(&IN) << "\n";
|
||||||
|
instrumentInst = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instrumentInst) {
|
||||||
|
|
||||||
|
Value *result = nullptr;
|
||||||
uint32_t vector_cnt = 0;
|
uint32_t vector_cnt = 0;
|
||||||
Value *condition = selectInst->getCondition();
|
SelectInst *selectInst;
|
||||||
Value *result;
|
ICmpInst *icmp;
|
||||||
auto t = condition->getType();
|
FCmpInst *fcmp;
|
||||||
IRBuilder<> IRB(selectInst->getNextNode());
|
PHINode *phi = nullptr, *newPhi = nullptr;
|
||||||
|
IRBuilder<> IRB(IN.getNextNode());
|
||||||
|
|
||||||
if (t->getTypeID() == llvm::Type::IntegerTyID) {
|
if ((icmp = dyn_cast<ICmpInst>(&IN))) {
|
||||||
|
|
||||||
if (!FunctionGuardArray) {
|
if (skip_icmp) {
|
||||||
|
|
||||||
fprintf(stderr,
|
skip_icmp--;
|
||||||
"SANCOV: FunctionGuardArray is NULL, failed to emit "
|
|
||||||
"instrumentation.");
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto res = icmp;
|
||||||
|
auto GuardPtr1 = IRB.CreateIntToPtr(
|
||||||
|
IRB.CreateAdd(
|
||||||
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
|
ConstantInt::get(
|
||||||
|
IntptrTy,
|
||||||
|
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
||||||
|
Int32PtrTy);
|
||||||
|
|
||||||
|
auto GuardPtr2 = IRB.CreateIntToPtr(
|
||||||
|
IRB.CreateAdd(
|
||||||
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
|
ConstantInt::get(
|
||||||
|
IntptrTy,
|
||||||
|
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
||||||
|
Int32PtrTy);
|
||||||
|
|
||||||
|
result = IRB.CreateSelect(res, GuardPtr1, GuardPtr2);
|
||||||
|
skip_select = 1;
|
||||||
|
// fprintf(stderr, "Icmp!\n");
|
||||||
|
|
||||||
|
} else if ((fcmp = dyn_cast<FCmpInst>(&IN))) {
|
||||||
|
|
||||||
|
auto res = fcmp;
|
||||||
|
auto GuardPtr1 = IRB.CreateIntToPtr(
|
||||||
|
IRB.CreateAdd(
|
||||||
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
|
ConstantInt::get(
|
||||||
|
IntptrTy,
|
||||||
|
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
||||||
|
Int32PtrTy);
|
||||||
|
|
||||||
|
auto GuardPtr2 = IRB.CreateIntToPtr(
|
||||||
|
IRB.CreateAdd(
|
||||||
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
|
ConstantInt::get(
|
||||||
|
IntptrTy,
|
||||||
|
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
||||||
|
Int32PtrTy);
|
||||||
|
|
||||||
|
result = IRB.CreateSelect(res, GuardPtr1, GuardPtr2);
|
||||||
|
skip_select = 1;
|
||||||
|
// fprintf(stderr, "Fcmp!\n");
|
||||||
|
|
||||||
|
} else if ((phi = dyn_cast<PHINode>(&IN))) {
|
||||||
|
|
||||||
|
if (skip_phi) {
|
||||||
|
|
||||||
|
skip_phi = 0;
|
||||||
|
// errs() << "SKIP: " << *(&IN) << "\n";
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// errs() << "-->PHI: " << *(&IN) << "\n";
|
||||||
|
// continue;
|
||||||
|
Instruction *insertBefore = &*phi->getParent()->getFirstInsertionPt();
|
||||||
|
newPhi = PHINode::Create(Int32PtrTy, 0, "", insertBefore);
|
||||||
|
BasicBlock *phiBlock = phi->getParent();
|
||||||
|
|
||||||
|
for (BasicBlock *pred : predecessors(phiBlock)) {
|
||||||
|
|
||||||
|
IRBuilder<> predBuilder(pred->getTerminator());
|
||||||
|
|
||||||
|
Value *ptr = predBuilder.CreateInBoundsGEP(
|
||||||
|
FunctionGuardArray->getValueType(), FunctionGuardArray,
|
||||||
|
ConstantInt::get(
|
||||||
|
IntptrTy, (cnt_cov + local_selects++ + AllBlocks.size())));
|
||||||
|
newPhi->addIncoming(ptr, pred);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
result = newPhi;
|
||||||
|
skip_phi = 1;
|
||||||
|
// fprintf(stderr, "Phi!\n");
|
||||||
|
|
||||||
|
} else if ((selectInst = dyn_cast<SelectInst>(&IN))) {
|
||||||
|
|
||||||
|
if (skip_select) {
|
||||||
|
|
||||||
|
skip_select = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// fprintf(stderr, "Select!\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *condition = selectInst->getCondition();
|
||||||
|
auto t = condition->getType();
|
||||||
|
|
||||||
|
if (t->getTypeID() == llvm::Type::IntegerTyID) {
|
||||||
|
|
||||||
auto GuardPtr1 = IRB.CreateIntToPtr(
|
auto GuardPtr1 = IRB.CreateIntToPtr(
|
||||||
IRB.CreateAdd(
|
IRB.CreateAdd(
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
@ -1024,104 +1129,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
Int32PtrTy);
|
Int32PtrTy);
|
||||||
|
|
||||||
result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2);
|
result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2);
|
||||||
|
skip_select = 1;
|
||||||
Value *trueVal = selectInst->getTrueValue();
|
|
||||||
Value *falseVal = selectInst->getFalseValue();
|
|
||||||
BasicBlock *bb = selectInst->getParent();
|
|
||||||
|
|
||||||
auto isFromICmpInSameBB = [bb](Value *v) -> bool {
|
|
||||||
|
|
||||||
std::function<bool(Value *)> traceBack = [&](Value *val) -> bool {
|
|
||||||
|
|
||||||
if (auto *inst = dyn_cast<Instruction>(val)) {
|
|
||||||
|
|
||||||
if (inst->getParent() != bb) return false;
|
|
||||||
|
|
||||||
if (isa<ICmpInst>(inst)) return true;
|
|
||||||
|
|
||||||
if (isa<SelectInst>(inst) || inst == &bb->front()) return false;
|
|
||||||
|
|
||||||
// If operands are all constants or loads, stop
|
|
||||||
bool allTerminating = true;
|
|
||||||
for (Use &U : inst->operands()) {
|
|
||||||
|
|
||||||
if (!isa<Constant>(U) && !isa<LoadInst>(U)) {
|
|
||||||
|
|
||||||
allTerminating = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allTerminating) return false;
|
|
||||||
|
|
||||||
// Recurse on variable operands
|
|
||||||
for (Use &U : inst->operands()) {
|
|
||||||
|
|
||||||
if (!isa<Constant>(U) && !isa<LoadInst>(U)) {
|
|
||||||
|
|
||||||
if (traceBack(U.get())) return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return traceBack(v);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isFromICmpInSameBB(trueVal)) {
|
|
||||||
|
|
||||||
auto GuardPtr1 = IRB.CreateIntToPtr(
|
|
||||||
IRB.CreateAdd(
|
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
|
||||||
ConstantInt::get(
|
|
||||||
IntptrTy,
|
|
||||||
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
|
||||||
Int32PtrTy);
|
|
||||||
|
|
||||||
auto GuardPtr2 = IRB.CreateIntToPtr(
|
|
||||||
IRB.CreateAdd(
|
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
|
||||||
ConstantInt::get(
|
|
||||||
IntptrTy,
|
|
||||||
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
|
||||||
Int32PtrTy);
|
|
||||||
|
|
||||||
result = IRB.CreateSelect(trueVal, GuardPtr1, GuardPtr2);
|
|
||||||
skip_next++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFromICmpInSameBB(falseVal)) {
|
|
||||||
|
|
||||||
auto GuardPtr1 = IRB.CreateIntToPtr(
|
|
||||||
IRB.CreateAdd(
|
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
|
||||||
ConstantInt::get(
|
|
||||||
IntptrTy,
|
|
||||||
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
|
||||||
Int32PtrTy);
|
|
||||||
|
|
||||||
auto GuardPtr2 = IRB.CreateIntToPtr(
|
|
||||||
IRB.CreateAdd(
|
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
|
||||||
ConstantInt::get(
|
|
||||||
IntptrTy,
|
|
||||||
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
|
||||||
Int32PtrTy);
|
|
||||||
|
|
||||||
result = IRB.CreateSelect(falseVal, GuardPtr1, GuardPtr2);
|
|
||||||
skip_next++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
} else
|
||||||
|
|
||||||
@ -1129,6 +1137,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
|
if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
|
||||||
|
|
||||||
FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
|
FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
|
||||||
|
|
||||||
if (tt) {
|
if (tt) {
|
||||||
|
|
||||||
uint32_t elements = tt->getElementCount().getFixedValue();
|
uint32_t elements = tt->getElementCount().getFixedValue();
|
||||||
@ -1141,30 +1150,21 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
FixedVectorType::get(Int32PtrTy, elements);
|
FixedVectorType::get(Int32PtrTy, elements);
|
||||||
Value *x, *y;
|
Value *x, *y;
|
||||||
|
|
||||||
if (!FunctionGuardArray) {
|
|
||||||
|
|
||||||
fprintf(stderr,
|
|
||||||
"SANCOV: FunctionGuardArray is NULL, failed to emit "
|
|
||||||
"instrumentation.");
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *val1 = IRB.CreateIntToPtr(
|
Value *val1 = IRB.CreateIntToPtr(
|
||||||
IRB.CreateAdd(
|
IRB.CreateAdd(
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
ConstantInt::get(
|
ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
|
||||||
IntptrTy,
|
AllBlocks.size()) *
|
||||||
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
4)),
|
||||||
Int32PtrTy);
|
Int32PtrTy);
|
||||||
x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
|
x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
|
||||||
|
|
||||||
Value *val2 = IRB.CreateIntToPtr(
|
Value *val2 = IRB.CreateIntToPtr(
|
||||||
IRB.CreateAdd(
|
IRB.CreateAdd(
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
ConstantInt::get(
|
ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
|
||||||
IntptrTy,
|
AllBlocks.size()) *
|
||||||
(cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
|
4)),
|
||||||
Int32PtrTy);
|
Int32PtrTy);
|
||||||
y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
|
y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
|
||||||
|
|
||||||
@ -1173,8 +1173,9 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
val1 = IRB.CreateIntToPtr(
|
val1 = IRB.CreateIntToPtr(
|
||||||
IRB.CreateAdd(
|
IRB.CreateAdd(
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
|
ConstantInt::get(
|
||||||
AllBlocks.size()) *
|
IntptrTy,
|
||||||
|
(cnt_cov + local_selects++ + AllBlocks.size()) *
|
||||||
4)),
|
4)),
|
||||||
Int32PtrTy);
|
Int32PtrTy);
|
||||||
x = IRB.CreateInsertElement(x, val1, i);
|
x = IRB.CreateInsertElement(x, val1, i);
|
||||||
@ -1182,8 +1183,9 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
val2 = IRB.CreateIntToPtr(
|
val2 = IRB.CreateIntToPtr(
|
||||||
IRB.CreateAdd(
|
IRB.CreateAdd(
|
||||||
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
|
||||||
ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
|
ConstantInt::get(
|
||||||
AllBlocks.size()) *
|
IntptrTy,
|
||||||
|
(cnt_cov + local_selects++ + AllBlocks.size()) *
|
||||||
4)),
|
4)),
|
||||||
Int32PtrTy);
|
Int32PtrTy);
|
||||||
y = IRB.CreateInsertElement(y, val2, i);
|
y = IRB.CreateInsertElement(y, val2, i);
|
||||||
@ -1191,6 +1193,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = IRB.CreateSelect(condition, x, y);
|
result = IRB.CreateSelect(condition, x, y);
|
||||||
|
skip_select = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1201,15 +1204,37 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
// fprintf(stderr, "UNHANDLED: %u\n", t->getTypeID());
|
if (!be_quiet) {
|
||||||
|
|
||||||
|
WARNF("Warning: Unhandled ID type: %u\n", t->getTypeID());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
unhandled++;
|
unhandled++;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t vector_cur = 0;
|
uint32_t vector_cur = 0;
|
||||||
|
|
||||||
/* Load SHM pointer */
|
/* Load SHM pointer */
|
||||||
|
if (newPhi) {
|
||||||
|
|
||||||
|
auto *inst = dyn_cast<Instruction>(result);
|
||||||
|
PHINode *nphi;
|
||||||
|
|
||||||
|
while ((nphi = dyn_cast<PHINode>(inst))) {
|
||||||
|
|
||||||
|
// fprintf(stderr, "NEXT!\n");
|
||||||
|
inst = inst->getNextNode();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IRB.SetInsertPoint(inst);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
LoadInst *MapPtr =
|
LoadInst *MapPtr =
|
||||||
IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
|
IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
|
||||||
@ -1260,6 +1285,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
auto cf = IRB.CreateICmpEQ(Incr, Zero);
|
auto cf = IRB.CreateICmpEQ(Incr, Zero);
|
||||||
auto carry = IRB.CreateZExt(cf, Int8Ty);
|
auto carry = IRB.CreateZExt(cf, Int8Ty);
|
||||||
Incr = IRB.CreateAdd(Incr, carry);
|
Incr = IRB.CreateAdd(Incr, carry);
|
||||||
|
skip_icmp++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,13 +1307,8 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_next++;
|
|
||||||
instr += vector_cnt;
|
instr += vector_cnt;
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
skip_next = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1296,9 +1317,27 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
|||||||
|
|
||||||
if (AllBlocks.empty() && !special && !local_selects) return false;
|
if (AllBlocks.empty() && !special && !local_selects) return false;
|
||||||
|
|
||||||
if (!AllBlocks.empty())
|
uint32_t skipped = 0;
|
||||||
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
|
|
||||||
InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
|
if (!AllBlocks.empty()) {
|
||||||
|
|
||||||
|
for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
|
||||||
|
|
||||||
|
auto instr = AllBlocks[i]->begin();
|
||||||
|
if (instr->getMetadata("skipinstrument")) {
|
||||||
|
|
||||||
|
skipped++;
|
||||||
|
// fprintf(stderr, "Skipped!\n");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
InjectCoverageAtBlock(F, *AllBlocks[i], i - skipped, IsLeafFunc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user