diff options
Diffstat (limited to 'instrumentation')
-rw-r--r-- | instrumentation/SanitizerCoverageLTO.so.cc | 168 | ||||
-rw-r--r-- | instrumentation/SanitizerCoveragePCGUARD.so.cc | 178 | ||||
-rw-r--r-- | instrumentation/afl-llvm-dict2file.so.cc | 71 | ||||
-rw-r--r-- | instrumentation/afl-llvm-lto-instrumentlist.so.cc | 50 | ||||
-rw-r--r-- | instrumentation/afl-llvm-pass.so.cc | 95 | ||||
-rw-r--r-- | instrumentation/cmplog-instructions-pass.cc | 78 | ||||
-rw-r--r-- | instrumentation/cmplog-routines-pass.cc | 73 | ||||
-rw-r--r-- | instrumentation/cmplog-switches-pass.cc | 102 | ||||
-rw-r--r-- | instrumentation/compare-transform-pass.so.cc | 120 | ||||
-rw-r--r-- | instrumentation/split-compares-pass.so.cc | 132 | ||||
-rw-r--r-- | instrumentation/split-switches-pass.so.cc | 107 |
11 files changed, 879 insertions, 295 deletions
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 6a4a071f..9a48ae6d 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -17,6 +17,7 @@ #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ValueTracking.h" @@ -33,7 +34,6 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Mangler.h" @@ -51,6 +51,9 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/IR/PassManager.h" #include "config.h" #include "debug.h" @@ -161,27 +164,21 @@ using DomTreeCallback = function_ref<const DominatorTree *(Function &F)>; using PostDomTreeCallback = function_ref<const PostDominatorTree *(Function &F)>; -class ModuleSanitizerCoverage { +class ModuleSanitizerCoverageLTO + : public PassInfoMixin<ModuleSanitizerCoverageLTO> { public: - ModuleSanitizerCoverage( + ModuleSanitizerCoverageLTO( const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : Options(OverrideFromCL(Options)) { - /* , - const SpecialCaseList * Allowlist = nullptr, - const SpecialCaseList * Blocklist = nullptr) - , - Allowlist(Allowlist), - Blocklist(Blocklist) { - - */ - } bool instrumentModule(Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback); + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + private: void instrumentFunction(Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback); @@ -279,18 +276,6 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : ModulePass(ID), Options(Options) { - /* , - const std::vector<std::string> &AllowlistFiles = - std::vector<std::string>(), - const std::vector<std::string> &BlocklistFiles = - std::vector<std::string>()) - if (AllowlistFiles.size() > 0) - Allowlist = SpecialCaseList::createOrDie(AllowlistFiles, - *vfs::getRealFileSystem()); - if (BlocklistFiles.size() > 0) - Blocklist = SpecialCaseList::createOrDie(BlocklistFiles, - *vfs::getRealFileSystem()); - */ initializeModuleSanitizerCoverageLegacyPassPass( *PassRegistry::getPassRegistry()); @@ -298,8 +283,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { bool runOnModule(Module &M) override { - ModuleSanitizerCoverage ModuleSancov(Options); - // , Allowlist.get(), Blocklist.get()); + ModuleSanitizerCoverageLTO ModuleSancov(Options); auto DTCallback = [this](Function &F) -> const DominatorTree * { return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); @@ -320,18 +304,36 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { private: SanitizerCoverageOptions Options; - // std::unique_ptr<SpecialCaseList> Allowlist; - // std::unique_ptr<SpecialCaseList> Blocklist; - }; } // namespace -PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, - ModuleAnalysisManager &MAM) { +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "SanitizerCoverageLTO", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + +#if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; +#endif + // PB.registerFullLinkTimeOptimizationLastEPCallback( + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(ModuleSanitizerCoverageLTO()); + + }); + + }}; + +} + +PreservedAnalyses ModuleSanitizerCoverageLTO::run(Module & M, + ModuleAnalysisManager &MAM) { - ModuleSanitizerCoverage ModuleSancov(Options); - // Allowlist.get(), Blocklist.get()); + ModuleSanitizerCoverageLTO ModuleSancov(Options); auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { @@ -352,35 +354,7 @@ PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, } -/* -std::pair<Value *, Value *> ModuleSanitizerCoverage::CreateSecStartEnd( - Module &M, const char *Section, Type *Ty) { - - GlobalVariable *SecStart = - new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr, - getSectionStart(Section)); - SecStart->setVisibility(GlobalValue::HiddenVisibility); - GlobalVariable *SecEnd = - new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr, - getSectionEnd(Section)); - SecEnd->setVisibility(GlobalValue::HiddenVisibility); - IRBuilder<> IRB(M.getContext()); - Value * SecEndPtr = IRB.CreatePointerCast(SecEnd, Ty); - if (!TargetTriple.isOSBinFormatCOFF()) - return std::make_pair(IRB.CreatePointerCast(SecStart, Ty), SecEndPtr); - - // Account for the fact that on windows-msvc __start_* symbols actually - // point to a uint64_t before the start of the array. - auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy); - auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr, - ConstantInt::get(IntptrTy, sizeof(uint64_t))); - return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEndPtr); - -} - -*/ - -bool ModuleSanitizerCoverage::instrumentModule( +bool ModuleSanitizerCoverageLTO::instrumentModule( Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false; @@ -757,7 +731,7 @@ bool ModuleSanitizerCoverage::instrumentModule( if (!HasStr2) { auto *Ptr = dyn_cast<ConstantExpr>(Str2P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { @@ -838,7 +812,7 @@ bool ModuleSanitizerCoverage::instrumentModule( auto Ptr = dyn_cast<ConstantExpr>(Str1P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { @@ -1044,7 +1018,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); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreMapAddr); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreMapAddr); } @@ -1059,7 +1033,7 @@ bool ModuleSanitizerCoverage::instrumentModule( "__afl_final_loc"); ConstantInt *const_loc = ConstantInt::get(Int32Tyi, write_loc); StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreFinalLoc); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreFinalLoc); } @@ -1107,7 +1081,7 @@ bool ModuleSanitizerCoverage::instrumentModule( 0, "__afl_dictionary_len"); ConstantInt *const_len = ConstantInt::get(Int32Tyi, offset); StoreInst *StoreDictLen = IRB.CreateStore(const_len, AFLDictionaryLen); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDictLen); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreDictLen); ArrayType *ArrayTy = ArrayType::get(IntegerType::get(Ctx, 8), offset); GlobalVariable *AFLInternalDictionary = new GlobalVariable( @@ -1127,7 +1101,7 @@ bool ModuleSanitizerCoverage::instrumentModule( Value *AFLDictPtr = IRB.CreatePointerCast(AFLDictOff, PointerType::get(Int8Tyi, 0)); StoreInst *StoreDict = IRB.CreateStore(AFLDictPtr, AFLDictionary); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDict); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreDict); } @@ -1234,7 +1208,7 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, } -void ModuleSanitizerCoverage::instrumentFunction( +void ModuleSanitizerCoverageLTO::instrumentFunction( Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (F.empty()) return; @@ -1389,7 +1363,7 @@ void ModuleSanitizerCoverage::instrumentFunction( /* Load SHM pointer */ LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr); while (1) { @@ -1419,7 +1393,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1434,7 +1408,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } auto nosan = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan); } @@ -1472,7 +1446,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } -GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( +GlobalVariable *ModuleSanitizerCoverageLTO::CreateFunctionLocalArrayInSection( size_t NumElements, Function &F, Type *Ty, const char *Section) { ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); @@ -1502,7 +1476,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( } -GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( +GlobalVariable *ModuleSanitizerCoverageLTO::CreatePCArray( Function &F, ArrayRef<BasicBlock *> AllBlocks) { size_t N = AllBlocks.size(); @@ -1538,7 +1512,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( } -void ModuleSanitizerCoverage::CreateFunctionLocalArrays( +void ModuleSanitizerCoverageLTO::CreateFunctionLocalArrays( Function &F, ArrayRef<BasicBlock *> AllBlocks) { if (Options.TracePCGuard) @@ -1554,9 +1528,8 @@ void ModuleSanitizerCoverage::CreateFunctionLocalArrays( } -bool ModuleSanitizerCoverage::InjectCoverage(Function & F, - ArrayRef<BasicBlock *> AllBlocks, - bool IsLeafFunc) { +bool ModuleSanitizerCoverageLTO::InjectCoverage( + Function &F, ArrayRef<BasicBlock *> AllBlocks, bool IsLeafFunc) { if (AllBlocks.empty()) return false; CreateFunctionLocalArrays(F, AllBlocks); @@ -1602,7 +1575,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, // The cache is used to speed up recording the caller-callee pairs. // The address of the caller is passed implicitly via caller PC. // CacheSize is encoded in the name of the run-time function. -void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( +void ModuleSanitizerCoverageLTO::InjectCoverageForIndirectCalls( Function &F, ArrayRef<Instruction *> IndirCalls) { if (IndirCalls.empty()) return; @@ -1620,9 +1593,10 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( } -void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, - size_t Idx, - bool IsLeafFunc) { +void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function & F, + BasicBlock &BB, + size_t Idx, + bool IsLeafFunc) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); @@ -1677,7 +1651,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr); MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); } @@ -1694,7 +1668,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter); Value *Incr = IRB.CreateAdd(Counter, One); @@ -1707,7 +1681,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } auto nosan = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan); } @@ -1759,7 +1733,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } -std::string ModuleSanitizerCoverage::getSectionName( +std::string ModuleSanitizerCoverageLTO::getSectionName( const std::string &Section) const { if (TargetTriple.isOSBinFormatCOFF()) { @@ -1776,27 +1750,6 @@ std::string ModuleSanitizerCoverage::getSectionName( } -/* -std::string ModuleSanitizerCoverage::getSectionStart( - const std::string &Section) const { - - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$start$__DATA$__" + Section; - return "__start___" + Section; - -} - -std::string ModuleSanitizerCoverage::getSectionEnd( - const std::string &Section) const { - - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$end$__DATA$__" + Section; - return "__stop___" + Section; - -} - -*/ - char ModuleSanitizerCoverageLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", @@ -1814,7 +1767,6 @@ ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( const std::vector<std::string> &BlocklistFiles) { return new ModuleSanitizerCoverageLegacyPass(Options); - //, AllowlistFiles, BlocklistFiles); } diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index e4ffeb50..e234cf57 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -13,6 +13,7 @@ #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/IR/CFG.h" @@ -36,14 +37,14 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/SpecialCaseList.h" -#if LLVM_VERSION_MAJOR >= 11 || \ - (LLVM_VERSION_MAJOR == 10 && LLVM_VERSION_MINOR >= 1) - #include "llvm/Support/VirtualFileSystem.h" -#endif +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/IR/PassManager.h" #include "config.h" #include "debug.h" @@ -123,21 +124,18 @@ using DomTreeCallback = function_ref<const DominatorTree *(Function &F)>; using PostDomTreeCallback = function_ref<const PostDominatorTree *(Function &F)>; -class ModuleSanitizerCoverage { +class ModuleSanitizerCoverageAFL + : public PassInfoMixin<ModuleSanitizerCoverageAFL> { public: - ModuleSanitizerCoverage( - const SanitizerCoverageOptions &Options = SanitizerCoverageOptions() -#if (LLVM_VERSION_MAJOR >= 11) - , - const SpecialCaseList *Allowlist = nullptr, - const SpecialCaseList *Blocklist = nullptr -#endif - ) + ModuleSanitizerCoverageAFL( + const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : Options(OverrideFromCL(Options)) { } + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + bool instrumentModule(Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback); @@ -215,15 +213,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { public: ModuleSanitizerCoverageLegacyPass( - const SanitizerCoverageOptions &Options = SanitizerCoverageOptions() -#if LLVM_VERSION_MAJOR >= 11 - , - const std::vector<std::string> &AllowlistFiles = - std::vector<std::string>(), - const std::vector<std::string> &BlocklistFiles = - std::vector<std::string>() -#endif - ) + const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : ModulePass(ID), Options(Options) { initializeModuleSanitizerCoverageLegacyPassPass( @@ -233,12 +223,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { bool runOnModule(Module &M) override { - ModuleSanitizerCoverage ModuleSancov(Options -#if (LLVM_VERSION_MAJOR >= 11) - , - Allowlist.get(), Blocklist.get() -#endif - ); + ModuleSanitizerCoverageAFL ModuleSancov(Options); auto DTCallback = [this](Function &F) -> const DominatorTree * { return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); @@ -256,8 +241,8 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { } - static char ID; // Pass identification, replacement for typeid - StringRef getPassName() const override { + /*static*/ char ID; // Pass identification, replacement for typeid + StringRef getPassName() const override { return "ModuleSanitizerCoverage"; @@ -273,22 +258,39 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { private: SanitizerCoverageOptions Options; - std::unique_ptr<SpecialCaseList> Allowlist; - std::unique_ptr<SpecialCaseList> Blocklist; - }; } // namespace -PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, - ModuleAnalysisManager &MAM) { +#if 1 + +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(ModuleSanitizerCoverageAFL()); + + }); + + }}; + +} - ModuleSanitizerCoverage ModuleSancov(Options -#if (LLVM_VERSION_MAJOR >= 11) - , - Allowlist.get(), Blocklist.get() #endif - ); + +PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module & M, + ModuleAnalysisManager &MAM) { + + ModuleSanitizerCoverageAFL ModuleSancov(Options); auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { @@ -308,7 +310,7 @@ PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, } -std::pair<Value *, Value *> ModuleSanitizerCoverage::CreateSecStartEnd( +std::pair<Value *, Value *> ModuleSanitizerCoverageAFL::CreateSecStartEnd( Module &M, const char *Section, Type *Ty) { GlobalVariable *SecStart = new GlobalVariable( @@ -332,7 +334,7 @@ std::pair<Value *, Value *> ModuleSanitizerCoverage::CreateSecStartEnd( } -Function *ModuleSanitizerCoverage::CreateInitCallsForSections( +Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections( Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty, const char *Section) { @@ -373,7 +375,7 @@ Function *ModuleSanitizerCoverage::CreateInitCallsForSections( } -bool ModuleSanitizerCoverage::instrumentModule( +bool ModuleSanitizerCoverageAFL::instrumentModule( Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { setvbuf(stdout, NULL, _IONBF, 0); @@ -656,7 +658,7 @@ bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, } -void ModuleSanitizerCoverage::instrumentFunction( +void ModuleSanitizerCoverageAFL::instrumentFunction( Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (F.empty()) return; @@ -742,7 +744,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } -GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( +GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection( size_t NumElements, Function &F, Type *Ty, const char *Section) { ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); @@ -778,7 +780,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( } -GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( +GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray( Function &F, ArrayRef<BasicBlock *> AllBlocks) { size_t N = AllBlocks.size(); @@ -814,7 +816,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( } -void ModuleSanitizerCoverage::CreateFunctionLocalArrays( +void ModuleSanitizerCoverageAFL::CreateFunctionLocalArrays( Function &F, ArrayRef<BasicBlock *> AllBlocks, uint32_t special) { if (Options.TracePCGuard) @@ -833,9 +835,8 @@ void ModuleSanitizerCoverage::CreateFunctionLocalArrays( } -bool ModuleSanitizerCoverage::InjectCoverage(Function & F, - ArrayRef<BasicBlock *> AllBlocks, - bool IsLeafFunc) { +bool ModuleSanitizerCoverageAFL::InjectCoverage( + Function &F, ArrayRef<BasicBlock *> AllBlocks, bool IsLeafFunc) { uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0; @@ -938,7 +939,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, Int32PtrTy); LoadInst *Idx = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Idx); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Idx); callInst->setOperand(1, Idx); @@ -1060,7 +1061,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr); /* std::string errMsg; @@ -1079,7 +1080,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, if (!vector_cnt) { CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), result); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc); MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); } else { @@ -1087,7 +1088,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, auto element = IRB.CreateExtractElement(result, vector_cur++); auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy); auto elementld = IRB.CreateLoad(IRB.getInt32Ty(), elementptr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(elementld); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(elementld); MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, elementld); } @@ -1103,7 +1104,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1118,7 +1119,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx); } @@ -1165,7 +1166,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, // The cache is used to speed up recording the caller-callee pairs. // The address of the caller is passed implicitly via caller PC. // CacheSize is encoded in the name of the run-time function. -void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( +void ModuleSanitizerCoverageAFL::InjectCoverageForIndirectCalls( Function &F, ArrayRef<Instruction *> IndirCalls) { if (IndirCalls.empty()) return; @@ -1185,7 +1186,7 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( // __sanitizer_cov_trace_switch(CondValue, // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... }) -void ModuleSanitizerCoverage::InjectTraceForSwitch( +void ModuleSanitizerCoverageAFL::InjectTraceForSwitch( Function &, ArrayRef<Instruction *> SwitchTraceTargets) { for (auto I : SwitchTraceTargets) { @@ -1236,7 +1237,7 @@ void ModuleSanitizerCoverage::InjectTraceForSwitch( } -void ModuleSanitizerCoverage::InjectTraceForDiv( +void ModuleSanitizerCoverageAFL::InjectTraceForDiv( Function &, ArrayRef<BinaryOperator *> DivTraceTargets) { for (auto BO : DivTraceTargets) { @@ -1256,7 +1257,7 @@ void ModuleSanitizerCoverage::InjectTraceForDiv( } -void ModuleSanitizerCoverage::InjectTraceForGep( +void ModuleSanitizerCoverageAFL::InjectTraceForGep( Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) { for (auto GEP : GepTraceTargets) { @@ -1271,7 +1272,7 @@ void ModuleSanitizerCoverage::InjectTraceForGep( } -void ModuleSanitizerCoverage::InjectTraceForCmp( +void ModuleSanitizerCoverageAFL::InjectTraceForCmp( Function &, ArrayRef<Instruction *> CmpTraceTargets) { for (auto I : CmpTraceTargets) { @@ -1313,9 +1314,10 @@ void ModuleSanitizerCoverage::InjectTraceForCmp( } -void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, - size_t Idx, - bool IsLeafFunc) { +void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function & F, + BasicBlock &BB, + size_t Idx, + bool IsLeafFunc) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); @@ -1348,12 +1350,12 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, Int32PtrTy); LoadInst *CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc); /* Load SHM pointer */ LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr); /* Load counter for CurLoc */ @@ -1370,7 +1372,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1385,7 +1387,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx); } @@ -1450,7 +1452,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } -std::string ModuleSanitizerCoverage::getSectionName( +std::string ModuleSanitizerCoverageAFL::getSectionName( const std::string &Section) const { if (TargetTriple.isOSBinFormatCOFF()) { @@ -1467,7 +1469,7 @@ std::string ModuleSanitizerCoverage::getSectionName( } -std::string ModuleSanitizerCoverage::getSectionStart( +std::string ModuleSanitizerCoverageAFL::getSectionStart( const std::string &Section) const { if (TargetTriple.isOSBinFormatMachO()) @@ -1476,7 +1478,7 @@ std::string ModuleSanitizerCoverage::getSectionStart( } -std::string ModuleSanitizerCoverage::getSectionEnd( +std::string ModuleSanitizerCoverageAFL::getSectionEnd( const std::string &Section) const { if (TargetTriple.isOSBinFormatMachO()) @@ -1485,8 +1487,9 @@ std::string ModuleSanitizerCoverage::getSectionEnd( } -char ModuleSanitizerCoverageLegacyPass::ID = 0; +#if 0 +char ModuleSanitizerCoverageLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) @@ -1495,36 +1498,15 @@ INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) - ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( - const SanitizerCoverageOptions &Options -#if (LLVM_VERSION_MAJOR >= 11) - , + const SanitizerCoverageOptions &Options, const std::vector<std::string> &AllowlistFiles, - const std::vector<std::string> &BlocklistFiles -#endif -) { + const std::vector<std::string> &BlocklistFiles) { - return new ModuleSanitizerCoverageLegacyPass(Options -#if (LLVM_VERSION_MAJOR >= 11) - , - AllowlistFiles, BlocklistFiles -#endif - ); + return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles, + BlocklistFiles); } -void registerPCGUARDPass(const PassManagerBuilder &, - legacy::PassManagerBase &PM) { - - auto p = new ModuleSanitizerCoverageLegacyPass(); - PM.add(p); - -} - -RegisterStandardPasses RegisterCompTransPass( - PassManagerBuilder::EP_OptimizerLast, registerPCGUARDPass); - -RegisterStandardPasses RegisterCompTransPass0( - PassManagerBuilder::EP_EnabledOnOptLevel0, registerPCGUARDPass); +#endif diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 39124660..79cdf491 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -39,7 +39,13 @@ #include "llvm/Config/llvm-config.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" +#endif #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" #include "llvm/IR/DebugInfo.h" @@ -64,6 +70,17 @@ using namespace llvm; namespace { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +class AFLdict2filePass : public PassInfoMixin<AFLdict2filePass> { + + std::ofstream of; + void dict2file(u8 *, u32); + + public: + AFLdict2filePass() { + +#else + class AFLdict2filePass : public ModulePass { std::ofstream of; @@ -74,16 +91,48 @@ class AFLdict2filePass : public ModulePass { AFLdict2filePass() : ModulePass(ID) { +#endif + if (getenv("AFL_DEBUG")) debug = 1; } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else bool runOnModule(Module &M) override; +#endif }; } // namespace +#if LLVM_MAJOR >= 11 +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "AFLdict2filePass", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(AFLdict2filePass()); + + }); + + }}; + +} + +#else +char AFLdict2filePass::ID = 0; +#endif + void AFLdict2filePass::dict2file(u8 *mem, u32 len) { u32 i, j, binary = 0; @@ -123,8 +172,14 @@ void AFLdict2filePass::dict2file(u8 *mem, u32 len) { } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses AFLdict2filePass::run(Module &M, ModuleAnalysisManager &MAM) { + +#else bool AFLdict2filePass::runOnModule(Module &M) { +#endif + DenseMap<Value *, std::string *> valueMap; char * ptr; int found = 0; @@ -435,7 +490,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (!HasStr2) { auto *Ptr = dyn_cast<ConstantExpr>(Str2P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { @@ -519,7 +574,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { auto Ptr = dyn_cast<ConstantExpr>(Str1P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { @@ -658,12 +713,16 @@ bool AFLdict2filePass::runOnModule(Module &M) { } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); + return PA; +#else return true; +#endif } -char AFLdict2filePass::ID = 0; - +#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerAFLdict2filePass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -681,3 +740,5 @@ static RegisterStandardPasses RegisterAFLdict2filePass( static RegisterStandardPasses RegisterAFLdict2filePass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLdict2filePass); +#endif + diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc index 35ba9c5a..70c6b10d 100644 --- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc @@ -43,9 +43,16 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/Pass.h" #include "llvm/Support/Debug.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" +//#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/IR/PassManager.h" #include "llvm/IR/CFG.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #include "afl-llvm-common.h" @@ -53,11 +60,10 @@ using namespace llvm; namespace { -class AFLcheckIfInstrument : public ModulePass { +class AFLcheckIfInstrument : public PassInfoMixin<AFLcheckIfInstrument> { public: - static char ID; - AFLcheckIfInstrument() : ModulePass(ID) { + AFLcheckIfInstrument() { if (getenv("AFL_DEBUG")) debug = 1; @@ -65,12 +71,7 @@ class AFLcheckIfInstrument : public ModulePass { } - bool runOnModule(Module &M) override; - - // StringRef getPassName() const override { - - // return "American Fuzzy Lop Instrumentation"; - // } + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); protected: std::list<std::string> myInstrumentList; @@ -79,9 +80,29 @@ class AFLcheckIfInstrument : public ModulePass { } // namespace -char AFLcheckIfInstrument::ID = 0; +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "AFLcheckIfInstrument", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + +#if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; +#endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(AFLcheckIfInstrument()); + + }); + + }}; -bool AFLcheckIfInstrument::runOnModule(Module &M) { +} + +PreservedAnalyses AFLcheckIfInstrument::run(Module & M, + ModuleAnalysisManager &MAM) { /* Show a banner */ @@ -130,10 +151,12 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) { } - return true; + auto PA = PreservedAnalyses::all(); + return PA; } +#if 0 static void registerAFLcheckIfInstrumentpass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -148,4 +171,5 @@ static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass( static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLcheckIfInstrumentpass); +#endif diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 5246ba08..fde785bd 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -44,13 +44,22 @@ typedef long double max_align_t; #endif -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#include "llvm/Pass.h" +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) @@ -61,6 +70,8 @@ typedef long double max_align_t; #include "llvm/Support/CFG.h" #endif +#include "llvm/IR/IRBuilder.h" + #include "afl-llvm-common.h" #include "llvm-alternative-coverage.h" @@ -68,17 +79,30 @@ using namespace llvm; namespace { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +class AFLCoverage : public PassInfoMixin<AFLCoverage> { + + public: + AFLCoverage() { + +#else class AFLCoverage : public ModulePass { public: static char ID; AFLCoverage() : ModulePass(ID) { +#endif + initInstrumentList(); } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else bool runOnModule(Module &M) override; +#endif protected: uint32_t ngram_size = 0; @@ -92,7 +116,55 @@ class AFLCoverage : public ModulePass { } // namespace +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(AFLCoverage()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef<PipelineElement>) { + + if (Name == "AFLCoverage") { + + MPM.addPass(AFLCoverage()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else + char AFLCoverage::ID = 0; +#endif /* needed up to 3.9.0 */ #if LLVM_VERSION_MAJOR == 3 && \ @@ -118,8 +190,15 @@ uint64_t PowerOf2Ceil(unsigned in) { (LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1) #define AFL_HAVE_VECTOR_INTRINSICS 1 #endif + +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) { + +#else bool AFLCoverage::runOnModule(Module &M) { +#endif + LLVMContext &C = M.getContext(); IntegerType *Int8Ty = IntegerType::getInt8Ty(C); @@ -133,6 +212,10 @@ bool AFLCoverage::runOnModule(Module &M) { u32 rand_seed; unsigned int cur_loc = 0; +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif + /* Setup random() so we get Actually Random(TM) outputs from AFL_R() */ gettimeofday(&tv, &tz); rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); @@ -997,10 +1080,15 @@ bool AFLCoverage::runOnModule(Module &M) { } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + return PA; +#else return true; +#endif } +#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerAFLPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -1013,4 +1101,5 @@ static RegisterStandardPasses RegisterAFLPass( static RegisterStandardPasses RegisterAFLPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass); +#endif diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 310f5585..7c95d9bb 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -28,14 +28,23 @@ #include "llvm/Config/llvm-config.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#if LLVM_MAJOR >= 11 + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) @@ -55,6 +64,17 @@ using namespace llvm; namespace { +#if LLVM_MAJOR >= 11 /* use new pass manager */ +class CmpLogInstructions : public PassInfoMixin<CmpLogInstructions> { + + public: + CmpLogInstructions() { + + initInstrumentList(); + + } + +#else class CmpLogInstructions : public ModulePass { public: @@ -65,19 +85,26 @@ class CmpLogInstructions : public ModulePass { } - bool runOnModule(Module &M) override; +#endif + +#if LLVM_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else + bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + #else const char *getPassName() const override { -#endif + #endif return "cmplog instructions"; } +#endif + private: bool hookInstrs(Module &M); @@ -85,7 +112,31 @@ class CmpLogInstructions : public ModulePass { } // namespace +#if LLVM_MAJOR >= 11 +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "cmploginstructions", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(CmpLogInstructions()); + + }); + + }}; + +} + +#else char CmpLogInstructions::ID = 0; +#endif template <class Iterator> Iterator Unique(Iterator first, Iterator last) { @@ -613,8 +664,15 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } +#if LLVM_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses CmpLogInstructions::run(Module & M, + ModuleAnalysisManager &MAM) { + +#else bool CmpLogInstructions::runOnModule(Module &M) { +#endif + if (getenv("AFL_QUIET") == NULL) printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n"); else @@ -622,10 +680,15 @@ bool CmpLogInstructions::runOnModule(Module &M) { hookInstrs(M); verifyModule(M); +#if LLVM_MAJOR >= 11 /* use new pass manager */ + return PreservedAnalyses::all(); +#else return true; +#endif } +#if LLVM_MAJOR < 11 /* use old pass manager */ static void registerCmpLogInstructionsPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -640,9 +703,10 @@ static RegisterStandardPasses RegisterCmpLogInstructionsPass( static RegisterStandardPasses RegisterCmpLogInstructionsPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogInstructionsPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCmpLogInstructionsPass); + #endif #endif diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc index 2af01a7a..8205cfb0 100644 --- a/instrumentation/cmplog-routines-pass.cc +++ b/instrumentation/cmplog-routines-pass.cc @@ -27,7 +27,14 @@ #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -36,6 +43,7 @@ #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) #include "llvm/IR/Verifier.h" @@ -53,29 +61,43 @@ using namespace llvm; namespace { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +class CmpLogRoutines : public PassInfoMixin<CmpLogRoutines> { + + public: + CmpLogRoutines() { + +#else class CmpLogRoutines : public ModulePass { public: static char ID; CmpLogRoutines() : ModulePass(ID) { +#endif + initInstrumentList(); } - bool runOnModule(Module &M) override; +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else + bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + #else const char *getPassName() const override { -#endif + #endif return "cmplog routines"; } +#endif + private: bool hookRtns(Module &M); @@ -83,7 +105,31 @@ class CmpLogRoutines : public ModulePass { } // namespace +#if LLVM_MAJOR >= 11 +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "cmplogroutines", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(CmpLogRoutines()); + + }); + + }}; + +} + +#else char CmpLogRoutines::ID = 0; +#endif bool CmpLogRoutines::hookRtns(Module &M) { @@ -697,19 +743,33 @@ bool CmpLogRoutines::hookRtns(Module &M) { } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses CmpLogRoutines::run(Module &M, ModuleAnalysisManager &MAM) { + +#else bool CmpLogRoutines::runOnModule(Module &M) { +#endif + if (getenv("AFL_QUIET") == NULL) printf("Running cmplog-routines-pass by andreafioraldi@gmail.com\n"); else be_quiet = 1; hookRtns(M); +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif verifyModule(M); +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + return PA; +#else return true; +#endif } +#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerCmpLogRoutinesPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -724,9 +784,10 @@ static RegisterStandardPasses RegisterCmpLogRoutinesPass( static RegisterStandardPasses RegisterCmpLogRoutinesPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogRoutinesPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterCmpLogRoutinesPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCmpLogRoutinesPass); + #endif #endif diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc index 068650ce..37bf3889 100644 --- a/instrumentation/cmplog-switches-pass.cc +++ b/instrumentation/cmplog-switches-pass.cc @@ -28,7 +28,14 @@ #include "llvm/Config/llvm-config.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -37,6 +44,7 @@ #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) #include "llvm/IR/Verifier.h" @@ -54,29 +62,42 @@ using namespace llvm; namespace { -class CmpLogInstructions : public ModulePass { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +class CmplogSwitches : public PassInfoMixin<CmplogSwitches> { + + public: + CmplogSwitches() { + +#else +class CmplogSwitches : public ModulePass { public: static char ID; - CmpLogInstructions() : ModulePass(ID) { + CmplogSwitches() : ModulePass(ID) { +#endif initInstrumentList(); } - bool runOnModule(Module &M) override; +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else + bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR < 4 + #if LLVM_VERSION_MAJOR < 4 const char *getPassName() const override { -#else + #else StringRef getPassName() const override { -#endif - return "cmplog instructions"; + #endif + return "cmplog switch split"; } +#endif + private: bool hookInstrs(Module &M); @@ -84,7 +105,31 @@ class CmpLogInstructions : public ModulePass { } // namespace -char CmpLogInstructions::ID = 0; +#if LLVM_MAJOR >= 11 +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "cmplogswitches", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(CmplogSwitches()); + + }); + + }}; + +} + +#else +char CmplogSwitches::ID = 0; +#endif template <class Iterator> Iterator Unique(Iterator first, Iterator last) { @@ -101,7 +146,7 @@ Iterator Unique(Iterator first, Iterator last) { } -bool CmpLogInstructions::hookInstrs(Module &M) { +bool CmplogSwitches::hookInstrs(Module &M) { std::vector<SwitchInst *> switches; LLVMContext & C = M.getContext(); @@ -383,36 +428,51 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } -bool CmpLogInstructions::runOnModule(Module &M) { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses CmplogSwitches::run(Module &M, ModuleAnalysisManager &MAM) { + +#else +bool CmplogSwitches::runOnModule(Module &M) { + +#endif if (getenv("AFL_QUIET") == NULL) printf("Running cmplog-switches-pass by andreafioraldi@gmail.com\n"); else be_quiet = 1; hookInstrs(M); +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif verifyModule(M); +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + return PA; +#else return true; +#endif } -static void registerCmpLogInstructionsPass(const PassManagerBuilder &, - legacy::PassManagerBase &PM) { +#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ +static void registerCmplogSwitchesPass(const PassManagerBuilder &, + legacy::PassManagerBase &PM) { - auto p = new CmpLogInstructions(); + auto p = new CmplogSwitches(); PM.add(p); } -static RegisterStandardPasses RegisterCmpLogInstructionsPass( - PassManagerBuilder::EP_OptimizerLast, registerCmpLogInstructionsPass); +static RegisterStandardPasses RegisterCmplogSwitchesPass( + PassManagerBuilder::EP_OptimizerLast, registerCmplogSwitchesPass); -static RegisterStandardPasses RegisterCmpLogInstructionsPass0( - PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogInstructionsPass); +static RegisterStandardPasses RegisterCmplogSwitchesPass0( + PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmplogSwitchesPass); -#if LLVM_VERSION_MAJOR >= 11 -static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO( + #if LLVM_VERSION_MAJOR >= 11 +static RegisterStandardPasses RegisterCmplogSwitchesPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, - registerCmpLogInstructionsPass); + registerCmplogSwitchesPass); + #endif #endif diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index c3a4ee34..34c88735 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -26,14 +26,23 @@ #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) @@ -52,29 +61,46 @@ using namespace llvm; namespace { +#if LLVM_MAJOR >= 11 /* use new pass manager */ +class CompareTransform : public PassInfoMixin<CompareTransform> { + + public: + CompareTransform() { + +#else class CompareTransform : public ModulePass { public: static char ID; CompareTransform() : ModulePass(ID) { +#endif + initInstrumentList(); } - bool runOnModule(Module &M) override; - -#if LLVM_VERSION_MAJOR >= 4 +#if LLVM_MAJOR < 11 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + #else const char *getPassName() const override { -#endif - return "transforms compare functions"; + #endif + + return "cmplog transform"; } +#endif + +#if LLVM_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else + bool runOnModule(Module &M) override; +#endif + private: bool transformCmps(Module &M, const bool processStrcmp, const bool processMemcmp, const bool processStrncmp, @@ -85,7 +111,54 @@ class CompareTransform : public ModulePass { } // namespace +#if LLVM_MAJOR >= 11 /* use new pass manager */ +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "comparetransform", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(CompareTransform()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef<PipelineElement>) { + + if (Name == "comparetransform") { + + MPM.addPass(CompareTransform()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else char CompareTransform::ID = 0; +#endif bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const bool processMemcmp, @@ -103,7 +176,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, #if LLVM_VERSION_MAJOR >= 9 FunctionCallee tolowerFn; #else - Function * tolowerFn; + Function *tolowerFn; #endif { @@ -246,7 +319,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (!(HasStr1 || HasStr2)) { auto *Ptr = dyn_cast<ConstantExpr>(Str2P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { @@ -271,7 +344,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (!HasStr2) { Ptr = dyn_cast<ConstantExpr>(Str1P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { @@ -385,6 +458,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, bool isCaseInsensitive = false; bool needs_null = false; Function * Callee = callInst->getCalledFunction(); + if (Callee) { if (!Callee->getName().compare("memcmp") || @@ -642,8 +716,14 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } +#if LLVM_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) { + +#else bool CompareTransform::runOnModule(Module &M) { +#endif + if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) printf( "Running compare-transform-pass by laf.intel@gmail.com, extended by " @@ -651,13 +731,28 @@ bool CompareTransform::runOnModule(Module &M) { else be_quiet = 1; +#if LLVM_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif + transformCmps(M, true, true, true, true, true); verifyModule(M); +#if LLVM_MAJOR >= 11 /* use new pass manager */ + /* if (modified) { + + PA.abandon<XX_Manager>(); + + }*/ + + return PA; +#else return true; +#endif } +#if LLVM_MAJOR < 11 /* use old pass manager */ static void registerCompTransPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -672,8 +767,9 @@ static RegisterStandardPasses RegisterCompTransPass( static RegisterStandardPasses RegisterCompTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerCompTransPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterCompTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCompTransPass); + #endif #endif diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 0f00fa96..d7bb7aba 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -1,6 +1,7 @@ /* * Copyright 2016 laf-intel * extended for floating point by Heiko Eißfeldt + * adapted to new pass manager by Heiko Eißfeldt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +29,20 @@ #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" + +#if LLVM_MAJOR >= 11 + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/IR/Module.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ @@ -53,27 +64,31 @@ using namespace llvm; namespace { +#if LLVM_MAJOR >= 11 +class SplitComparesTransform : public PassInfoMixin<SplitComparesTransform> { + + public: + // static char ID; + SplitComparesTransform() : enableFPSplit(0) { + +#else class SplitComparesTransform : public ModulePass { public: static char ID; SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) { +#endif + initInstrumentList(); } - bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 - StringRef getPassName() const override { - +#if LLVM_MAJOR >= 11 + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); #else - const char *getPassName() const override { - + bool runOnModule(Module &M) override; #endif - return "AFL_SplitComparesTransform"; - - } private: int enableFPSplit; @@ -162,7 +177,54 @@ class SplitComparesTransform : public ModulePass { } // namespace +#if LLVM_MAJOR >= 11 +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "splitcompares", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(SplitComparesTransform()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef<PipelineElement>) { + + if (Name == "splitcompares") { + + MPM.addPass(SplitComparesTransform()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else char SplitComparesTransform::ID = 0; +#endif /// This function splits FCMP instructions with xGE or xLE predicates into two /// FCMP instructions with predicate xGT or xLT and EQ @@ -1421,8 +1483,15 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } +#if LLVM_MAJOR >= 11 +PreservedAnalyses SplitComparesTransform::run(Module & M, + ModuleAnalysisManager &MAM) { + +#else bool SplitComparesTransform::runOnModule(Module &M) { +#endif + char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW"); if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW"); if (bitw_env) { target_bitwidth = atoi(bitw_env); } @@ -1432,7 +1501,7 @@ bool SplitComparesTransform::runOnModule(Module &M) { if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) { - errs() << "Split-compare-pass by laf.intel@gmail.com, extended by " + errs() << "Split-compare-newpass by laf.intel@gmail.com, extended by " "heiko@hexco.de (splitting icmp to " << target_bitwidth << " bit)\n"; @@ -1444,6 +1513,10 @@ bool SplitComparesTransform::runOnModule(Module &M) { } +#if LLVM_MAJOR >= 11 + auto PA = PreservedAnalyses::all(); +#endif + if (enableFPSplit) { simplifyFPCompares(M); @@ -1473,7 +1546,16 @@ bool SplitComparesTransform::runOnModule(Module &M) { auto op0 = CI->getOperand(0); auto op1 = CI->getOperand(1); - if (!op0 || !op1) { return false; } + if (!op0 || !op1) { + +#if LLVM_MAJOR >= 11 + return PA; +#else + return false; +#endif + + } + auto iTy1 = dyn_cast<IntegerType>(op0->getType()); if (iTy1 && isa<IntegerType>(op1->getType())) { @@ -1522,10 +1604,29 @@ bool SplitComparesTransform::runOnModule(Module &M) { } + if ((isatty(2) && getenv("AFL_QUIET") == NULL) || + getenv("AFL_DEBUG") != NULL) { + + errs() << count << " comparisons found\n"; + + } + +#if LLVM_MAJOR >= 11 + /* if (modified) { + + PA.abandon<XX_Manager>(); + + }*/ + + return PA; +#else return true; +#endif } +#if LLVM_MAJOR < 11 /* use old pass manager */ + static void registerSplitComparesPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -1539,14 +1640,15 @@ static RegisterStandardPasses RegisterSplitComparesPass( static RegisterStandardPasses RegisterSplitComparesTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitComparesPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterSplitComparesTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerSplitComparesPass); -#endif + #endif static RegisterPass<SplitComparesTransform> X("splitcompares", "AFL++ split compares", true /* Only looks at CFG */, true /* Analysis Pass */); +#endif diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc index 9f9e7eca..96e01a8b 100644 --- a/instrumentation/split-switches-pass.so.cc +++ b/instrumentation/split-switches-pass.so.cc @@ -27,14 +27,23 @@ #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ @@ -54,29 +63,42 @@ using namespace llvm; namespace { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +class SplitSwitchesTransform : public PassInfoMixin<SplitSwitchesTransform> { + + public: + SplitSwitchesTransform() { + +#else class SplitSwitchesTransform : public ModulePass { public: static char ID; SplitSwitchesTransform() : ModulePass(ID) { +#endif initInstrumentList(); } - bool runOnModule(Module &M) override; +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else + bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + #else const char *getPassName() const override { -#endif + #endif return "splits switch constructs"; } +#endif + struct CaseExpr { ConstantInt *Val; @@ -103,7 +125,54 @@ class SplitSwitchesTransform : public ModulePass { } // namespace +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "splitswitches", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(SplitSwitchesTransform()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef<PipelineElement>) { + + if (Name == "splitswitches") { + + MPM.addPass(SplitSwitchesTransform()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else char SplitSwitchesTransform::ID = 0; +#endif /* switchConvert - Transform simple list of Cases into list of CaseRange's */ BasicBlock *SplitSwitchesTransform::switchConvert( @@ -413,19 +482,42 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses SplitSwitchesTransform::run(Module & M, + ModuleAnalysisManager &MAM) { + +#else bool SplitSwitchesTransform::runOnModule(Module &M) { +#endif + if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) printf("Running split-switches-pass by laf.intel@gmail.com\n"); else be_quiet = 1; + +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif + splitSwitches(M); verifyModule(M); +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + /* if (modified) { + + PA.abandon<XX_Manager>(); + + }*/ + + return PA; +#else return true; +#endif } +#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerSplitSwitchesTransPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -440,9 +532,10 @@ static RegisterStandardPasses RegisterSplitSwitchesTransPass( static RegisterStandardPasses RegisterSplitSwitchesTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitSwitchesTransPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterSplitSwitchesTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerSplitSwitchesTransPass); + #endif #endif |