From 36c46b9579df3e123950ae89d3973442ba73ab4f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 13 Sep 2022 10:52:55 +0200 Subject: Fix LLVM 15 build By removing ModuleSanitizerCoverageLegacyPass, which is completely unused. There was some confusing between the initialization function for the upstream sancov pass and AFLs own implementation. --- instrumentation/SanitizerCoveragePCGUARD.so.cc | 74 -------------------------- 1 file changed, 74 deletions(-) diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index faad0bf6..ef2d3b9c 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -209,57 +209,6 @@ class ModuleSanitizerCoverageAFL }; -class ModuleSanitizerCoverageLegacyPass : public ModulePass { - - public: - ModuleSanitizerCoverageLegacyPass( - const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) - : ModulePass(ID), Options(Options) { - - initializeModuleSanitizerCoverageLegacyPassPass( - *PassRegistry::getPassRegistry()); - - } - - bool runOnModule(Module &M) override { - - ModuleSanitizerCoverageAFL ModuleSancov(Options); - auto DTCallback = [this](Function &F) -> const DominatorTree * { - - return &this->getAnalysis(F).getDomTree(); - - }; - - auto PDTCallback = [this](Function &F) -> const PostDominatorTree * { - - return &this->getAnalysis(F) - .getPostDomTree(); - - }; - - return ModuleSancov.instrumentModule(M, DTCallback, PDTCallback); - - } - - /*static*/ char ID; // Pass identification, replacement for typeid - StringRef getPassName() const override { - - return "ModuleSanitizerCoverage"; - - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - - AU.addRequired(); - AU.addRequired(); - - } - - private: - SanitizerCoverageOptions Options; - -}; - } // namespace #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ @@ -1530,26 +1479,3 @@ std::string ModuleSanitizerCoverageAFL::getSectionEnd( } -#if 0 - -char ModuleSanitizerCoverageLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", - "Pass for instrumenting coverage on functions", false, - false) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) -INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov", - "Pass for instrumenting coverage on functions", false, - false) -ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( - const SanitizerCoverageOptions &Options, - const std::vector &AllowlistFiles, - const std::vector &BlocklistFiles) { - - return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles, - BlocklistFiles); - -} - -#endif - -- cgit 1.4.1 From 9b6ad933cdee7243fffcb722440b878760da1b5d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 14 Sep 2022 10:12:42 +0200 Subject: Allow building LTO component with LLVM 15 --- GNUmakefile.llvm | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index 83330ddc..c37c4a51 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -86,12 +86,6 @@ ifeq "$(LLVM_TOO_OLD)" "1" $(shell sleep 1) endif -ifeq "$(LLVM_MAJOR)" "15" - $(info [!] llvm_mode detected llvm 15, which is currently broken for LTO plugins.) - LLVM_LTO = 0 - LLVM_HAVE_LTO = 0 -endif - ifeq "$(LLVM_HAVE_LTO)" "1" $(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation) LLVM_LTO = 1 @@ -99,7 +93,7 @@ ifeq "$(LLVM_HAVE_LTO)" "1" endif ifeq "$(LLVM_LTO)" "0" - $(info [+] llvm_mode detected llvm < 11 or llvm 15, afl-lto LTO will not be build.) + $(info [+] llvm_mode detected llvm < 11, afl-lto LTO will not be build.) endif ifeq "$(LLVM_APPLE_XCODE)" "1" -- cgit 1.4.1 From 5452d4652b14bbb311057bb09b0345669491bfac Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 14 Sep 2022 10:34:22 +0200 Subject: Fix naming clash between AFL's sancov LTO pass and upstream sancov pass There was some confusion here due to name reuse. The initializeModuleSanitizerCoverageLegacyPassPass() function was actually calling the initialization of the upstream pass (which no longer supports legacy PM and thus fails to build on LLVM 15). The intention was to call the LTO initialization here. Fix this by renaming symbols to avoid collision. --- instrumentation/SanitizerCoverageLTO.so.cc | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 721bc487..fb447354 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -111,6 +111,12 @@ static cl::opt ClPruneBlocks( cl::desc("Reduce the number of instrumented blocks"), cl::Hidden, cl::init(true)); +namespace llvm { + +void initializeModuleSanitizerCoverageLTOLegacyPassPass(PassRegistry &PB); + +} + namespace { SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) { @@ -255,13 +261,13 @@ class ModuleSanitizerCoverageLTO }; -class ModuleSanitizerCoverageLegacyPass : public ModulePass { +class ModuleSanitizerCoverageLTOLegacyPass : public ModulePass { public: static char ID; StringRef getPassName() const override { - return "sancov"; + return "sancov-lto"; } @@ -272,11 +278,11 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { } - ModuleSanitizerCoverageLegacyPass( + ModuleSanitizerCoverageLTOLegacyPass( const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : ModulePass(ID), Options(Options) { - initializeModuleSanitizerCoverageLegacyPassPass( + initializeModuleSanitizerCoverageLTOLegacyPassPass( *PassRegistry::getPassRegistry()); } @@ -1750,30 +1756,21 @@ std::string ModuleSanitizerCoverageLTO::getSectionName( } -char ModuleSanitizerCoverageLegacyPass::ID = 0; +char ModuleSanitizerCoverageLTOLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", +INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLTOLegacyPass, "sancov-lto", "Pass for instrumenting coverage on functions", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) -INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov", +INITIALIZE_PASS_END(ModuleSanitizerCoverageLTOLegacyPass, "sancov-lto", "Pass for instrumenting coverage on functions", false, false) -ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( - const SanitizerCoverageOptions &Options, - const std::vector &AllowlistFiles, - const std::vector &BlocklistFiles) { - - return new ModuleSanitizerCoverageLegacyPass(Options); - -} - static void registerLTOPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { - auto p = new ModuleSanitizerCoverageLegacyPass(); + auto p = new ModuleSanitizerCoverageLTOLegacyPass(); PM.add(p); } -- cgit 1.4.1 From b27a4a3689983390bbfc48c1bd1ba04e1b1aa935 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 14 Sep 2022 11:34:29 +0200 Subject: Fix loading and registeration of LTO pass for new pass manager --- instrumentation/SanitizerCoverageLTO.so.cc | 5 ++++- src/afl-cc.c | 12 +++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index fb447354..231151f5 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -324,8 +324,11 @@ llvmGetPassPluginInfo() { #if LLVM_VERSION_MAJOR <= 13 using OptimizationLevel = typename PassBuilder::OptimizationLevel; #endif - // PB.registerFullLinkTimeOptimizationLastEPCallback( +#if LLVM_VERSION_MAJOR >= 15 + PB.registerFullLinkTimeOptimizationLastEPCallback( +#else PB.registerOptimizerLastEPCallback( +#endif [](ModulePassManager &MPM, OptimizationLevel OL) { MPM.addPass(ModuleSanitizerCoverageLTO()); diff --git a/src/afl-cc.c b/src/afl-cc.c index c0449e64..5e7a9c9e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -666,15 +666,21 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif free(ld_path); -#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13 +#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15 + // The NewPM implementation only works fully since LLVM 15. + cc_params[cc_par_cnt++] = + alloc_printf("-Wl,--load-pass-plugin=%s/SanitizerCoverageLTO.so", obj_path); +#elif defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13 cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path); #else cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path); #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; } else { -- cgit 1.4.1