diff options
author | van Hauser <vh@thc.org> | 2021-11-03 21:55:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-03 21:55:21 +0100 |
commit | f5535e348d37460daa4c6ea43063b451aa83d9cc (patch) | |
tree | 2339a99aa53f604cbe77b0dc88882f29ec9a6bf6 /instrumentation | |
parent | 25c947cd5ae93cb865081f9259255b4fdb3ca3ba (diff) | |
parent | 9278f27d749bcf0852ba2629caa319375c9a60e4 (diff) | |
download | afl++-f5535e348d37460daa4c6ea43063b451aa83d9cc.tar.gz |
Merge pull request #1142 from AFLplusplus/dev
Dev
Diffstat (limited to 'instrumentation')
-rw-r--r-- | instrumentation/SanitizerCoverageLTO.so.cc | 183 | ||||
-rw-r--r-- | instrumentation/SanitizerCoveragePCGUARD.so.cc | 306 | ||||
-rw-r--r-- | instrumentation/afl-llvm-dict2file.so.cc | 7 | ||||
-rw-r--r-- | instrumentation/afl-llvm-lto-instrumentation.so.cc | 15 | ||||
-rw-r--r-- | instrumentation/afl-llvm-lto-instrumentlist.so.cc | 7 | ||||
-rw-r--r-- | instrumentation/cmplog-instructions-pass.cc | 213 | ||||
-rw-r--r-- | instrumentation/split-compares-pass.so.cc | 10 |
7 files changed, 634 insertions, 107 deletions
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 960eb783..ee8c317e 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -235,6 +235,8 @@ class ModuleSanitizerCoverage { uint32_t autodictionary = 1; uint32_t inst = 0; uint32_t afl_global_id = 0; + uint32_t unhandled = 0; + uint32_t select_cnt = 0; uint64_t map_addr = 0; const char * skip_nozero = NULL; const char * use_threadsafe_counters = nullptr; @@ -447,8 +449,7 @@ bool ModuleSanitizerCoverage::instrumentModule( if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) { dFile.open(ptr, std::ofstream::out | std::ofstream::app); - if (dFile.is_open()) - WARNF("Cannot access document file %s", ptr); + if (dFile.is_open()) WARNF("Cannot access document file %s", ptr); } @@ -1041,8 +1042,7 @@ bool ModuleSanitizerCoverage::instrumentModule( M, Int64Tyi, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr"); ConstantInt *MapAddr = ConstantInt::get(Int64Tyi, map_addr); StoreInst * StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed); - StoreMapAddr->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(Ctx, None)); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreMapAddr); } @@ -1050,15 +1050,14 @@ bool ModuleSanitizerCoverage::instrumentModule( uint32_t write_loc = afl_global_id; - if (afl_global_id % 8) write_loc = (((afl_global_id + 8) >> 3) << 3); + write_loc = (((afl_global_id + 8) >> 3) << 3); GlobalVariable *AFLFinalLoc = new GlobalVariable(M, Int32Tyi, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc"); ConstantInt *const_loc = ConstantInt::get(Int32Tyi, write_loc); StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc); - StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(Ctx, None)); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreFinalLoc); } @@ -1084,7 +1083,7 @@ bool ModuleSanitizerCoverage::instrumentModule( if (count) { - auto ptrhld = std::unique_ptr<char []>(new char[memlen + count]); + auto ptrhld = std::unique_ptr<char[]>(new char[memlen + count]); count = 0; @@ -1106,8 +1105,7 @@ bool ModuleSanitizerCoverage::instrumentModule( 0, "__afl_dictionary_len"); ConstantInt *const_len = ConstantInt::get(Int32Tyi, offset); StoreInst *StoreDictLen = IRB.CreateStore(const_len, AFLDictionaryLen); - StoreDictLen->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(Ctx, None)); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDictLen); ArrayType *ArrayTy = ArrayType::get(IntegerType::get(Ctx, 8), offset); GlobalVariable *AFLInternalDictionary = new GlobalVariable( @@ -1127,8 +1125,7 @@ bool ModuleSanitizerCoverage::instrumentModule( Value *AFLDictPtr = IRB.CreatePointerCast(AFLDictOff, PointerType::get(Int8Tyi, 0)); StoreInst *StoreDict = IRB.CreateStore(AFLDictPtr, AFLDictionary); - StoreDict->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(Ctx, None)); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDict); } @@ -1151,9 +1148,9 @@ bool ModuleSanitizerCoverage::instrumentModule( getenv("AFL_USE_MSAN") ? ", MSAN" : "", getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); - OKF("Instrumented %u locations with no collisions (on average %llu " - "collisions would be in afl-gcc/vanilla AFL) (%s mode).", - inst, calculateCollisions(inst), modeline); + OKF("Instrumented %u locations (%u selects) without collisions (%llu " + "collisions have been avoided) (%s mode).", + inst, select_cnt, calculateCollisions(inst), modeline); } @@ -1275,6 +1272,7 @@ void ModuleSanitizerCoverage::instrumentFunction( const DominatorTree * DT = DTCallback(F); const PostDominatorTree *PDT = PDTCallback(F); bool IsLeafFunc = true; + uint32_t skip_next = 0, local_selects = 0; for (auto &BB : F) { @@ -1292,6 +1290,148 @@ void ModuleSanitizerCoverage::instrumentFunction( Value *val = ConstantInt::get(Int32Ty, ++afl_global_id); callInst->setOperand(1, val); + ++inst; + + } + + SelectInst *selectInst = nullptr; + + /* + std::string errMsg; + raw_string_ostream os(errMsg); + IN.print(os); + fprintf(stderr, "X(%u): %s\n", skip_next, os.str().c_str()); + */ + if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN))) { + + uint32_t vector_cnt = 0; + Value * condition = selectInst->getCondition(); + Value * result; + auto t = condition->getType(); + IRBuilder<> IRB(selectInst->getNextNode()); + + ++select_cnt; + + if (t->getTypeID() == llvm::Type::IntegerTyID) { + + Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id); + Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id); + result = IRB.CreateSelect(condition, val1, val2); + skip_next = 1; + inst += 2; + + } else + +#if LLVM_VERSION_MAJOR > 13 + if (t->getTypeID() == llvm::Type::FixedVectorTyID) { + + FixedVectorType *tt = dyn_cast<FixedVectorType>(t); + if (tt) { + + uint32_t elements = tt->getElementCount().getFixedValue(); + vector_cnt = elements; + inst += vector_cnt * 2; + if (elements) { + + FixedVectorType *GuardPtr1 = + FixedVectorType::get(Int32Ty, elements); + FixedVectorType *GuardPtr2 = + FixedVectorType::get(Int32Ty, elements); + Value *x, *y; + + Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id); + Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id); + x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0); + y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0); + + for (uint64_t i = 1; i < elements; i++) { + + val1 = ConstantInt::get(Int32Ty, ++afl_global_id); + val2 = ConstantInt::get(Int32Ty, ++afl_global_id); + x = IRB.CreateInsertElement(GuardPtr1, val1, i); + y = IRB.CreateInsertElement(GuardPtr2, val2, i); + + } + + result = IRB.CreateSelect(condition, x, y); + skip_next = 1; + + } + + } + + } else + +#endif + { + + unhandled++; + continue; + + } + + local_selects++; + uint32_t vector_cur = 0; + /* Load SHM pointer */ + LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + + while (1) { + + /* Get CurLoc */ + Value *MapPtrIdx = nullptr; + + /* Load counter for CurLoc */ + if (!vector_cnt) { + + MapPtrIdx = IRB.CreateGEP(MapPtr, result); + + } else { + + auto element = IRB.CreateExtractElement(result, vector_cur++); + MapPtrIdx = IRB.CreateGEP(MapPtr, element); + + } + + if (use_threadsafe_counters) { + + IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One, +#if LLVM_VERSION_MAJOR >= 13 + llvm::MaybeAlign(1), +#endif + llvm::AtomicOrdering::Monotonic); + + } else { + + LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + + /* Update bitmap */ + + Value *Incr = IRB.CreateAdd(Counter, One); + + if (skip_nozero == NULL) { + + auto cf = IRB.CreateICmpEQ(Incr, Zero); + auto carry = IRB.CreateZExt(cf, Int8Ty); + Incr = IRB.CreateAdd(Incr, carry); + + } + + auto nosan = IRB.CreateStore(Incr, MapPtrIdx); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan); + + } + + if (!vector_cnt || vector_cnt == vector_cur) { break; } + + } + + skip_next = 1; + + } else { + + skip_next = 0; } @@ -1502,7 +1642,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, unsigned long long int moduleID = (((unsigned long long int)(rand() & 0xffffffff)) << 32) | getpid(); - dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str() << " edgeID=" << afl_global_id << "\n"; + dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str() + << " edgeID=" << afl_global_id << "\n"; } @@ -1521,8 +1662,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); - MapPtr->setMetadata(Mo->getMDKindID("nosanitize"), - MDNode::get(*Ct, None)); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc); } @@ -1539,8 +1679,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); - Counter->setMetadata(Mo->getMDKindID("nosanitize"), - MDNode::get(*Ct, None)); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); Value *Incr = IRB.CreateAdd(Counter, One); @@ -1552,8 +1691,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } - IRB.CreateStore(Incr, MapPtrIdx) - ->setMetadata(Mo->getMDKindID("nosanitize"), MDNode::get(*Ct, None)); + auto nosan = IRB.CreateStore(Incr, MapPtrIdx); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan); } diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 48ad2d02..be3f4f49 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -203,7 +203,7 @@ class ModuleSanitizerCoverage { SanitizerCoverageOptions Options; - uint32_t instr = 0; + uint32_t instr = 0, selects = 0, unhandled = 0; GlobalVariable *AFLMapPtr = NULL; ConstantInt * One = NULL; ConstantInt * Zero = NULL; @@ -553,8 +553,9 @@ bool ModuleSanitizerCoverage::instrumentModule( getenv("AFL_USE_MSAN") ? ", MSAN" : "", getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); - OKF("Instrumented %u locations with no collisions (%s mode).", instr, - modeline); + OKF("Instrumented %u locations with no collisions (%s mode) of which are " + "%u handled and %u unhandled selects.", + instr, modeline, selects, unhandled); } @@ -833,9 +834,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, ArrayRef<BasicBlock *> AllBlocks, bool IsLeafFunc) { - if (AllBlocks.empty()) return false; + uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0; - uint32_t special = 0; for (auto &BB : F) { for (auto &IN : BB) { @@ -850,9 +850,37 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, StringRef FuncName = Callee->getName(); if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue; - uint32_t id = 1 + instr + (uint32_t)AllBlocks.size() + special++; - Value * val = ConstantInt::get(Int32Ty, id); - callInst->setOperand(1, val); + cnt_cov++; + + } + + SelectInst *selectInst = nullptr; + + if ((selectInst = dyn_cast<SelectInst>(&IN))) { + + Value *c = selectInst->getCondition(); + auto t = c->getType(); + if (t->getTypeID() == llvm::Type::IntegerTyID) { + + cnt_sel++; + cnt_sel_inc += 2; + + } + +#if LLVM__MAJOR > 11 + else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { + + FixedVectorType *tt = dyn_cast<FixedVectorType>(t); + if (tt) { + + cnt_sel++; + cnt_sel_inc += tt->getElementCount().getFixedValue(); + + } + + } + +#endif } @@ -860,11 +888,256 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } - CreateFunctionLocalArrays(F, AllBlocks, special); - for (size_t i = 0, N = AllBlocks.size(); i < N; i++) - InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc); + /* Create PCGUARD array */ + CreateFunctionLocalArrays(F, AllBlocks, cnt_cov + cnt_sel_inc); + selects += cnt_sel; + + uint32_t special = 0, local_selects = 0, skip_next = 0; + + for (auto &BB : F) { + + for (auto &IN : BB) { + + CallInst *callInst = nullptr; + + /* + std::string errMsg; + raw_string_ostream os(errMsg); + IN.print(os); + fprintf(stderr, "X: %s\n", os.str().c_str()); + */ + if ((callInst = dyn_cast<CallInst>(&IN))) { + + Function *Callee = callInst->getCalledFunction(); + if (!Callee) continue; + if (callInst->getCallingConv() != llvm::CallingConv::C) continue; + StringRef FuncName = Callee->getName(); + if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue; + + IRBuilder<> IRB(callInst); + + Value *GuardPtr = IRB.CreateIntToPtr( + IRB.CreateAdd( + IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), + ConstantInt::get(IntptrTy, (++special + AllBlocks.size()) * 4)), + Int32PtrTy); + + LoadInst *Idx = IRB.CreateLoad(GuardPtr); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(Idx); + + callInst->setOperand(1, Idx); + + } + + SelectInst *selectInst = nullptr; + + if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN))) { + + uint32_t vector_cnt = 0; + Value * condition = selectInst->getCondition(); + Value * result; + auto t = condition->getType(); + IRBuilder<> IRB(selectInst->getNextNode()); + + if (t->getTypeID() == llvm::Type::IntegerTyID) { + + 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(condition, GuardPtr1, GuardPtr2); + + } else + +#if LLVM_VERSION_MAJOR > 13 + if (t->getTypeID() == llvm::Type::FixedVectorTyID) { + + FixedVectorType *tt = dyn_cast<FixedVectorType>(t); + if (tt) { + + uint32_t elements = tt->getElementCount().getFixedValue(); + vector_cnt = elements; + if (elements) { + + FixedVectorType *GuardPtr1 = + FixedVectorType::get(Int32PtrTy, elements); + FixedVectorType *GuardPtr2 = + FixedVectorType::get(Int32PtrTy, elements); + Value *x, *y; + + Value *val1 = IRB.CreateIntToPtr( + IRB.CreateAdd( + IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), + ConstantInt::get( + IntptrTy, + (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), + Int32PtrTy); + x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0); + + Value *val2 = IRB.CreateIntToPtr( + IRB.CreateAdd( + IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), + ConstantInt::get( + IntptrTy, + (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), + Int32PtrTy); + y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0); + + for (uint64_t i = 1; i < elements; i++) { + + val1 = IRB.CreateIntToPtr( + IRB.CreateAdd( + IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), + ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects + + AllBlocks.size()) * + 4)), + Int32PtrTy); + x = IRB.CreateInsertElement(x, val1, i); + + val2 = IRB.CreateIntToPtr( + IRB.CreateAdd( + IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), + ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects + + AllBlocks.size()) * + 4)), + Int32PtrTy); + y = IRB.CreateInsertElement(y, val2, i); + + } + + /* + std::string errMsg; + raw_string_ostream os(errMsg); + x->print(os); + fprintf(stderr, "X: %s\n", os.str().c_str()); + */ + result = IRB.CreateSelect(condition, x, y); + + } + + } + + } else + +#endif + { + + unhandled++; + continue; + + } + + local_selects++; + uint32_t vector_cur = 0; - instr += special; + /* Load SHM pointer */ + + LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + + /* + std::string errMsg; + raw_string_ostream os(errMsg); + result->print(os); + fprintf(stderr, "X: %s\n", os.str().c_str()); + */ + + while (1) { + + /* Get CurLoc */ + LoadInst *CurLoc = nullptr; + Value * MapPtrIdx = nullptr; + + /* Load counter for CurLoc */ + if (!vector_cnt) { + + CurLoc = IRB.CreateLoad(result); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); + MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc); + + } else { + + auto element = IRB.CreateExtractElement(result, vector_cur++); + auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy); + auto elementld = IRB.CreateLoad(elementptr); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(elementld); + MapPtrIdx = IRB.CreateGEP(MapPtr, elementld); + + } + + if (use_threadsafe_counters) { + + IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One, +#if LLVM_VERSION_MAJOR >= 13 + llvm::MaybeAlign(1), +#endif + llvm::AtomicOrdering::Monotonic); + + } else { + + LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + + /* Update bitmap */ + + Value *Incr = IRB.CreateAdd(Counter, One); + + if (skip_nozero == NULL) { + + auto cf = IRB.CreateICmpEQ(Incr, Zero); + auto carry = IRB.CreateZExt(cf, Int8Ty); + Incr = IRB.CreateAdd(Incr, carry); + + } + + StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx); + + } + + if (!vector_cnt) { + + vector_cnt = 2; + break; + + } else if (vector_cnt == vector_cur) { + + break; + + } + + } + + skip_next = 1; + instr += vector_cnt; + + } else { + + skip_next = 0; + + } + + } + + } + + if (AllBlocks.empty() && !special && !local_selects) return false; + + if (!AllBlocks.empty()) + for (size_t i = 0, N = AllBlocks.size(); i < N; i++) + InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc); return true; @@ -881,8 +1154,6 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( Function &F, ArrayRef<Instruction *> IndirCalls) { if (IndirCalls.empty()) return; - assert(Options.TracePC || Options.TracePCGuard || - Options.Inline8bitCounters /*|| Options.InlineBoolFlag*/); for (auto I : IndirCalls) { IRBuilder<> IRB(I); @@ -1062,10 +1333,12 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, Int32PtrTy); LoadInst *CurLoc = IRB.CreateLoad(GuardPtr); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); /* Load SHM pointer */ LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); /* Load counter for CurLoc */ @@ -1082,6 +1355,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + /* Update bitmap */ Value *Incr = IRB.CreateAdd(Counter, One); @@ -1094,7 +1369,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } - IRB.CreateStore(Incr, MapPtrIdx); + StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); + ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx); } diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index c4ad1783..0a3e74b9 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -65,8 +65,10 @@ using namespace llvm; namespace { class AFLdict2filePass : public ModulePass { + std::ofstream of; - void dict2file(u8 *, u32); + void dict2file(u8 *, u32); + public: static char ID; @@ -147,8 +149,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { FATAL("AFL_LLVM_DICT2FILE is not set to an absolute path: %s", ptr); of.open(ptr, std::ofstream::out | std::ofstream::app); - if (!of.is_open()) - PFATAL("Could not open/create %s.", ptr); + if (!of.is_open()) PFATAL("Could not open/create %s.", ptr); /* Instrument all the things! */ diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index 73e41f60..c2f61d34 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -138,8 +138,7 @@ bool AFLLTOPass::runOnModule(Module &M) { if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) { dFile.open(ptr, std::ofstream::out | std::ofstream::app); - if (!dFile.is_open()) - WARNF("Cannot access document file %s", ptr); + if (!dFile.is_open()) WARNF("Cannot access document file %s", ptr); } @@ -244,8 +243,14 @@ bool AFLLTOPass::runOnModule(Module &M) { // the instrument file list check AttributeList Attrs = F.getAttributes(); +#if LLVM_VERSION_MAJOR < 14 if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) { +#else + if (Attrs.hasFnAttr(StringRef("skipinstrument"))) { + +#endif + if (debug) fprintf(stderr, "DEBUG: Function %s is not in a source file that was specified " @@ -848,7 +853,9 @@ bool AFLLTOPass::runOnModule(Module &M) { if (dFile.is_open()) { - dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str() << " edgeID=" << afl_global_id << "\n"; + dFile << "ModuleID=" << moduleID + << " Function=" << F.getName().str() + << " edgeID=" << afl_global_id << "\n"; } @@ -1015,7 +1022,7 @@ bool AFLLTOPass::runOnModule(Module &M) { if (count) { - auto ptrhld = std::unique_ptr<char []>(new char[memlen + count]); + auto ptrhld = std::unique_ptr<char[]>(new char[memlen + count]); count = 0; diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc index 416dbb88..ee2e5dd3 100644 --- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc @@ -116,10 +116,15 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) { auto & Ctx = F.getContext(); AttributeList Attrs = F.getAttributes(); - AttrBuilder NewAttrs; +#if LLVM_VERSION_MAJOR < 14 + AttrBuilder NewAttrs; NewAttrs.addAttribute("skipinstrument"); F.setAttributes( Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs)); +#else + AttributeList NewAttrs = Attrs.addFnAttribute(Ctx, "skipinstrument"); + F.setAttributes(NewAttrs); +#endif } diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 0562c5b2..01a8a637 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -274,14 +274,15 @@ bool CmpLogInstructions::hookInstrs(Module &M) { Value *op0 = selectcmpInst->getOperand(0); Value *op1 = selectcmpInst->getOperand(1); + Value *op0_saved = op0, *op1_saved = op1; + auto ty0 = op0->getType(); + auto ty1 = op1->getType(); - IntegerType * intTyOp0 = NULL; - IntegerType * intTyOp1 = NULL; - unsigned max_size = 0, cast_size = 0; - unsigned char attr = 0; - std::vector<Value *> args; - - CmpInst *cmpInst = dyn_cast<CmpInst>(selectcmpInst); + IntegerType *intTyOp0 = NULL; + IntegerType *intTyOp1 = NULL; + unsigned max_size = 0, cast_size = 0; + unsigned attr = 0, vector_cnt = 0; + CmpInst * cmpInst = dyn_cast<CmpInst>(selectcmpInst); if (!cmpInst) { continue; } @@ -327,7 +328,23 @@ bool CmpLogInstructions::hookInstrs(Module &M) { if (selectcmpInst->getOpcode() == Instruction::FCmp) { - auto ty0 = op0->getType(); + if (ty0->isVectorTy()) { + + VectorType *tt = dyn_cast<VectorType>(ty0); + if (!tt) { + + fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n"); + continue; + + } + +#if LLVM_MAJOR > 11 + vector_cnt = tt->getElementCount().getFixedValue(); + ty0 = tt->getElementType(); +#endif + + } + if (ty0->isHalfTy() #if LLVM_VERSION_MAJOR >= 11 || ty0->isBFloatTy() @@ -342,13 +359,35 @@ bool CmpLogInstructions::hookInstrs(Module &M) { max_size = 80; else if (ty0->isFP128Ty() || ty0->isPPC_FP128Ty()) max_size = 128; +#if LLVM_MAJOR > 11 + else if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) + fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n", + ty0->getTypeID()); +#endif attr += 8; } else { - intTyOp0 = dyn_cast<IntegerType>(op0->getType()); - intTyOp1 = dyn_cast<IntegerType>(op1->getType()); + if (ty0->isVectorTy()) { + +#if LLVM_MAJOR > 11 + VectorType *tt = dyn_cast<VectorType>(ty0); + if (!tt) { + + fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n"); + continue; + + } + + vector_cnt = tt->getElementCount().getFixedValue(); + ty1 = ty0 = tt->getElementType(); +#endif + + } + + intTyOp0 = dyn_cast<IntegerType>(ty0); + intTyOp1 = dyn_cast<IntegerType>(ty1); if (intTyOp0 && intTyOp1) { @@ -356,11 +395,28 @@ bool CmpLogInstructions::hookInstrs(Module &M) { ? intTyOp0->getBitWidth() : intTyOp1->getBitWidth(); + } else { + +#if LLVM_MAJOR > 11 + if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) { + + fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u\n", + ty0->getTypeID()); + + } + +#endif + } } - if (!max_size || max_size < 16) { continue; } + if (!max_size || max_size < 16) { + + // fprintf(stderr, "too small\n"); + continue; + + } if (max_size % 8) { max_size = (((max_size / 8) + 1) * 8); } @@ -393,67 +449,110 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } - // errs() << "[CMPLOG] cmp " << *cmpInst << "(in function " << - // cmpInst->getFunction()->getName() << ")\n"; + uint64_t cur = 0, last_val0 = 0, last_val1 = 0, cur_val; - // first bitcast to integer type of the same bitsize as the original - // type (this is a nop, if already integer) - Value *op0_i = IRB.CreateBitCast( - op0, IntegerType::get(C, op0->getType()->getPrimitiveSizeInBits())); - // then create a int cast, which does zext, trunc or bitcast. In our case - // usually zext to the next larger supported type (this is a nop if - // already the right type) - Value *V0 = - IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false); - args.push_back(V0); - Value *op1_i = IRB.CreateBitCast( - op1, IntegerType::get(C, op1->getType()->getPrimitiveSizeInBits())); - Value *V1 = - IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false); - args.push_back(V1); + while (1) { - // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " << *V1 - // << "\n"; + std::vector<Value *> args; + uint32_t skip = 0; - ConstantInt *attribute = ConstantInt::get(Int8Ty, attr); - args.push_back(attribute); + if (vector_cnt) { - if (cast_size != max_size) { + op0 = IRB.CreateExtractElement(op0_saved, cur); + op1 = IRB.CreateExtractElement(op1_saved, cur); + ConstantInt *i0 = dyn_cast<ConstantInt>(op0); + ConstantInt *i1 = dyn_cast<ConstantInt>(op1); + if (i0 && i0->uge(0xffffffffffffffff) == false) { - ConstantInt *bitsize = ConstantInt::get(Int8Ty, (max_size / 8) - 1); - args.push_back(bitsize); + cur_val = i0->getZExtValue(); + if (last_val0 && last_val0 == cur_val) { skip = 1; } + last_val0 = cur_val; - } + } - // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n", - // max_size, cast_size, attr); + if (i1 && i1->uge(0xffffffffffffffff) == false) { - switch (cast_size) { + cur_val = i1->getZExtValue(); + if (last_val1 && last_val1 == cur_val) { skip = 1; } + last_val1 = cur_val; - case 8: - IRB.CreateCall(cmplogHookIns1, args); - break; - case 16: - IRB.CreateCall(cmplogHookIns2, args); - break; - case 32: - IRB.CreateCall(cmplogHookIns4, args); - break; - case 64: - IRB.CreateCall(cmplogHookIns8, args); - break; - case 128: - if (max_size == 128) { + } + + } + + if (!skip) { + + // errs() << "[CMPLOG] cmp " << *cmpInst << "(in function " << + // cmpInst->getFunction()->getName() << ")\n"; + + // first bitcast to integer type of the same bitsize as the original + // type (this is a nop, if already integer) + Value *op0_i = IRB.CreateBitCast( + op0, IntegerType::get(C, ty0->getPrimitiveSizeInBits())); + // then create a int cast, which does zext, trunc or bitcast. In our + // case usually zext to the next larger supported type (this is a nop + // if already the right type) + Value *V0 = + IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false); + args.push_back(V0); + Value *op1_i = IRB.CreateBitCast( + op1, IntegerType::get(C, ty1->getPrimitiveSizeInBits())); + Value *V1 = + IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false); + args.push_back(V1); - IRB.CreateCall(cmplogHookIns16, args); + // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " << + // *V1 + // << "\n"; - } else { + ConstantInt *attribute = ConstantInt::get(Int8Ty, attr); + args.push_back(attribute); - IRB.CreateCall(cmplogHookInsN, args); + if (cast_size != max_size) { + + ConstantInt *bitsize = ConstantInt::get(Int8Ty, (max_size / 8) - 1); + args.push_back(bitsize); } - break; + // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n", + // max_size, cast_size, attr); + + switch (cast_size) { + + case 8: + IRB.CreateCall(cmplogHookIns1, args); + break; + case 16: + IRB.CreateCall(cmplogHookIns2, args); + break; + case 32: + IRB.CreateCall(cmplogHookIns4, args); + break; + case 64: + IRB.CreateCall(cmplogHookIns8, args); + break; + case 128: + if (max_size == 128) { + + IRB.CreateCall(cmplogHookIns16, args); + + } else { + + IRB.CreateCall(cmplogHookInsN, args); + + } + + break; + + } + + } + + /* else fprintf(stderr, "skipped\n"); */ + + ++cur; + if (cur >= vector_cnt) { break; } } diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 13f45b69..e63be98c 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -578,16 +578,16 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M, /* dependent on the cmp of the high parts go to the end or go on with * the comparison */ - auto term = bb->getTerminator(); - BranchInst *br = nullptr; + auto term = bb->getTerminator(); + if (pred == CmpInst::ICMP_EQ) { - br = BranchInst::Create(cmp_low_bb, end_bb, icmp_high, bb); + BranchInst::Create(cmp_low_bb, end_bb, icmp_high, bb); } else { - /* CmpInst::ICMP_NE */ - br = BranchInst::Create(end_bb, cmp_low_bb, icmp_high, bb); + // CmpInst::ICMP_NE + BranchInst::Create(end_bb, cmp_low_bb, icmp_high, bb); } |