fix LTO with cmplog and laf
MODIFY
GNUmakefile.llvm
GNUmakefile.llvm
@@ -394,7 +394,7 @@ endif
./SanitizerCoveragePCGUARD.so: instrumentation/SanitizerCoveragePCGUARD.so.cc instrumentation/afl-llvm-common.o | test_deps
ifeq "$(LLVM_10_OK)" "1"
- -$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-with-dtor -Wdeprecated instrumentation/afl-llvm-common.o
+ -$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-dtor -Wdeprecated instrumentation/afl-llvm-common.o
endif
./afl-llvm-lto-instrumentlist.so: instrumentation/afl-llvm-lto-instrumentlist.so.cc instrumentation/afl-llvm-common.o

MODIFY
docs/Changelog.md
docs/Changelog.md
@@ -24,8 +24,6 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
possible in the target (for afl-gcc-fast/afl-clang-fast/
afl-clang-lto)
- afl-cc:
- ! llvm15-dev with LTO and extra features (LAF/CMPLOG etc.) might have
- issues at the moment
- converted all passed to use the new llvm pass manager for llvm 11+
- AFL++ PCGUARD mode is not available for 10.0.1 anymore (11+ only)
- frida_mode:

MODIFY
instrumentation/SanitizerCoverageLTO.so.cc
instrumentation/SanitizerCoverageLTO.so.cc
#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"
#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"
@@ -162,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);
@@ -280,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());
@@ -299,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();
@@ -321,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,
+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 * {
@@ -353,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;
@@ -1045,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);
}
@@ -1060,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);
}
@@ -1108,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(
@@ -1128,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);
}
@@ -1235,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;
@@ -1390,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) {
@@ -1420,7 +1393,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
} else {
LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
- ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter);
/* Update bitmap */
@@ -1435,7 +1408,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
}
auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
- ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan);
}
@@ -1473,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);
@@ -1503,7 +1476,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
}
-GlobalVariable *ModuleSanitizerCoverage::CreatePCArray(
+GlobalVariable *ModuleSanitizerCoverageLTO::CreatePCArray(
Function &F, ArrayRef<BasicBlock *> AllBlocks) {
size_t N = AllBlocks.size();
@@ -1539,7 +1512,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray(
}
-void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
+void ModuleSanitizerCoverageLTO::CreateFunctionLocalArrays(
Function &F, ArrayRef<BasicBlock *> AllBlocks) {
if (Options.TracePCGuard)
@@ -1555,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);
@@ -1603,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;
@@ -1621,7 +1593,8 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
}
-void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
+void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function & F,
+ BasicBlock &BB,
size_t Idx,
bool IsLeafFunc) {
@@ -1678,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);
}
@@ -1695,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);
@@ -1708,7 +1681,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
}
auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
- ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan);
}
@@ -1760,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()) {
@@ -1777,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",
@@ -1815,7 +1767,6 @@ ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
const std::vector<std::string> &BlocklistFiles) {
return new ModuleSanitizerCoverageLegacyPass(Options);
- //, AllowlistFiles, BlocklistFiles);
}

MODIFY
src/afl-cc.c
src/afl-cc.c
@@ -467,13 +467,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
// laf
if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) {
- if (lto_mode && !have_c) {
-
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path);
-
- } else {
-
#if LLVM_MAJOR >= 11 /* use new pass manager */
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
@@ -488,22 +481,13 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- }
-
if (getenv("LAF_TRANSFORM_COMPARES") ||
getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
- if (lto_mode && !have_c) {
-
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/compare-transform-pass.so", obj_path);
-
- } else {
-
#if LLVM_MAJOR >= 11 /* use new pass manager */
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- cc_params[cc_par_cnt++] = alloc_printf(
- "-fpass-plugin=%s/compare-transform-pass.so", obj_path);
+ cc_params[cc_par_cnt++] =
+ alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path);
#else
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
@@ -514,18 +498,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- }
-
if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) {
- if (lto_mode && !have_c) {
-
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/split-compares-pass.so", obj_path);
-
- } else {
-
#if LLVM_MAJOR >= 11 /* use new pass manager */
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
@@ -540,8 +515,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- }
-
// /laf
unsetenv("AFL_LD");
@@ -549,16 +522,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (cmplog_mode) {
- if (lto_mode && !have_c) {
-
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/cmplog-switches-pass.so", obj_path);
-
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path);
-
- } else {
-
cc_params[cc_par_cnt++] = "-fno-inline";
#if LLVM_MAJOR >= 11 /* use new pass manager */
@@ -585,8 +548,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- }
-
//#if LLVM_MAJOR >= 13
// // Use the old pass manager in LLVM 14 which the afl++ passes still
// use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
@@ -614,10 +575,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
#endif
free(ld_path);
- cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
-#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15
+#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13
cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager";
#endif
+
+ cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
cc_params[cc_par_cnt++] =
alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
cc_params[cc_par_cnt++] = lto_flag;
@@ -699,15 +661,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (cmplog_mode) {
- if (lto_mode && !have_c) {
-
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/cmplog-instructions-pass.so", obj_path);
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path);
-
- } else {
-
#if LLVM_MAJOR >= 11
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] = alloc_printf(
@@ -731,8 +684,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- }
-
// cc_params[cc_par_cnt++] = "-Qunused-arguments";
if (lto_mode && argc > 1) {

MODIFY
src/afl-fuzz-run.c
src/afl-fuzz-run.c
@@ -232,7 +232,8 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
memcpy(afl->fsrv.shmem_fuzz, mem, skip_at);
- memcpy(afl->fsrv.shmem_fuzz + skip_at, mem + skip_at + skip_len, tail_len);
+ memcpy(afl->fsrv.shmem_fuzz + skip_at, mem + skip_at + skip_len,
+ tail_len);
}

fix LTO with cmplog and laf