about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rw-r--r--GNUmakefile.gcc_plugin4
-rw-r--r--GNUmakefile.llvm14
-rw-r--r--TODO_LLVM10
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc177
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc67
-rw-r--r--instrumentation/cmplog-instructions-pass.cc82
-rw-r--r--instrumentation/cmplog-routines-pass.cc73
-rw-r--r--instrumentation/cmplog-switches-pass.cc102
-rw-r--r--src/afl-cc.c44
-rw-r--r--src/afl-ld-lto.c5
11 files changed, 424 insertions, 156 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 6444ecb8..d31c52da 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -566,7 +566,7 @@ all_done: test_build
 
 .PHONY: clean
 clean:
-	rm -rf $(PROGS) afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM
+	rm -rf $(PROGS) afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM lib*.a
 	-$(MAKE) -f GNUmakefile.llvm clean
 	-$(MAKE) -f GNUmakefile.gcc_plugin clean
 	-$(MAKE) -C utils/libdislocator clean
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 63b22017..e21203ae 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -135,11 +135,11 @@ afl-common.o: ./src/afl-common.c
 
 ./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c
 	@printf "[*] Building 32-bit variant of the runtime (-m32)... "
-	@$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi
+	@$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
 
 ./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c
 	@printf "[*] Building 64-bit variant of the runtime (-m64)... "
-	@$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi
+	@$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
 
 ./afl-gcc-pass.so: instrumentation/afl-gcc-pass.so.cc | test_deps
 	$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index f1de28a4..a8f019c6 100644
--- a/GNUmakefile.llvm
+++ b/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) -Wdeprecated -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
+	-$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-with-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
@@ -447,11 +447,11 @@ document:
 
 ./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c
 	@printf "[*] Building 32-bit variant of the runtime (-m32)... "
-	@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi
+	@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
 
 ./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c
 	@printf "[*] Building 64-bit variant of the runtime (-m64)... "
-	@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi
+	@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
 
 .PHONY: test_build
 test_build: $(PROGS)
@@ -474,11 +474,11 @@ install: all
 	@install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)
 	@if [ -f ./afl-cc ]; then set -e; install -m 755 ./afl-cc $${DESTDIR}$(BIN_PATH); ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-c++; fi
 	@rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt*.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt*.o
-	@if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o ;fi
+	@if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-compiler-rt.o ;fi
 	@if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi
 	@if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi
-	@if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o ;fi
-	@if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o ; fi
+	@if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-compiler-rt-32.o ;fi
+	@if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-compiler-rt-64.o ; fi
 	@if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi
 	@if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi
 	@if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi
@@ -520,4 +520,4 @@ endif
 .PHONY: clean
 clean:
 	rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo
-	rm -f $(PROGS) afl-common.o ./afl-c++ ./afl-lto ./afl-lto++ ./afl-clang-lto* ./afl-clang-fast* ./afl-clang*.8 ./ld ./afl-ld ./afl-llvm-rt*.o instrumentation/*.o
+	rm -f $(PROGS) afl-common.o ./afl-c++ ./afl-lto ./afl-lto++ ./afl-clang-lto* ./afl-clang-fast* ./afl-clang*.8 ./ld ./afl-ld ./afl-compiler-rt*.o ./afl-llvm-rt*.o instrumentation/*.o
diff --git a/TODO_LLVM b/TODO_LLVM
new file mode 100644
index 00000000..3dea8cca
--- /dev/null
+++ b/TODO_LLVM
@@ -0,0 +1,10 @@
+with LLVM 14: only new pass manager
+up to LLVM 13: only old pass manager
+
+These do not work yet with the new pass manager:
+cmplog-instructions-pass.so
+compare-transform-pass.so
+afl-llvm-dict2file.so
+afl-llvm-lto-instrumentlist.so
+SanitizerCoverageLTO.so
+SanitizerCoveragePCGUARD.so
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 48bb5a2c..e234cf57 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -37,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"
@@ -124,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);
 
@@ -216,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(
@@ -234,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();
@@ -257,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";
 
@@ -274,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 * {
 
@@ -309,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(
@@ -333,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) {
 
@@ -374,7 +375,7 @@ Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
 
 }
 
-bool ModuleSanitizerCoverage::instrumentModule(
+bool ModuleSanitizerCoverageAFL::instrumentModule(
     Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
 
   setvbuf(stdout, NULL, _IONBF, 0);
@@ -657,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;
@@ -743,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);
@@ -779,7 +780,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
 
 }
 
-GlobalVariable *ModuleSanitizerCoverage::CreatePCArray(
+GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray(
     Function &F, ArrayRef<BasicBlock *> AllBlocks) {
 
   size_t N = AllBlocks.size();
@@ -815,7 +816,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray(
 
 }
 
-void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
+void ModuleSanitizerCoverageAFL::CreateFunctionLocalArrays(
     Function &F, ArrayRef<BasicBlock *> AllBlocks, uint32_t special) {
 
   if (Options.TracePCGuard)
@@ -834,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;
 
@@ -939,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);
 
@@ -1061,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;
@@ -1080,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 {
@@ -1088,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);
 
           }
@@ -1104,7 +1104,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function &             F,
           } else {
 
             LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
-            ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter);
+            ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter);
 
             /* Update bitmap */
 
@@ -1119,7 +1119,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function &             F,
             }
 
             StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx);
-            ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx);
+            ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx);
 
           }
 
@@ -1166,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;
@@ -1186,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) {
@@ -1237,7 +1237,7 @@ void ModuleSanitizerCoverage::InjectTraceForSwitch(
 
 }
 
-void ModuleSanitizerCoverage::InjectTraceForDiv(
+void ModuleSanitizerCoverageAFL::InjectTraceForDiv(
     Function &, ArrayRef<BinaryOperator *> DivTraceTargets) {
 
   for (auto BO : DivTraceTargets) {
@@ -1257,7 +1257,7 @@ void ModuleSanitizerCoverage::InjectTraceForDiv(
 
 }
 
-void ModuleSanitizerCoverage::InjectTraceForGep(
+void ModuleSanitizerCoverageAFL::InjectTraceForGep(
     Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) {
 
   for (auto GEP : GepTraceTargets) {
@@ -1272,7 +1272,7 @@ void ModuleSanitizerCoverage::InjectTraceForGep(
 
 }
 
-void ModuleSanitizerCoverage::InjectTraceForCmp(
+void ModuleSanitizerCoverageAFL::InjectTraceForCmp(
     Function &, ArrayRef<Instruction *> CmpTraceTargets) {
 
   for (auto I : CmpTraceTargets) {
@@ -1314,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();
@@ -1349,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 */
 
@@ -1371,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 */
 
@@ -1386,7 +1387,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
       }
 
       StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx);
-      ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx);
+      ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx);
 
     }
 
@@ -1451,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()) {
@@ -1468,7 +1469,7 @@ std::string ModuleSanitizerCoverage::getSectionName(
 
 }
 
-std::string ModuleSanitizerCoverage::getSectionStart(
+std::string ModuleSanitizerCoverageAFL::getSectionStart(
     const std::string &Section) const {
 
   if (TargetTriple.isOSBinFormatMachO())
@@ -1477,7 +1478,7 @@ std::string ModuleSanitizerCoverage::getSectionStart(
 
 }
 
-std::string ModuleSanitizerCoverage::getSectionEnd(
+std::string ModuleSanitizerCoverageAFL::getSectionEnd(
     const std::string &Section) const {
 
   if (TargetTriple.isOSBinFormatMachO())
@@ -1486,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)
@@ -1496,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 94dc6984..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;
@@ -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/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 310f5585..85dec437 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -32,10 +32,20 @@
 #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 +65,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 +86,26 @@ class CmpLogInstructions : public ModulePass {
 
   }
 
-  bool runOnModule(Module &M) override;
+#endif
 
-#if LLVM_VERSION_MAJOR >= 4
+#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
   StringRef getPassName() const override {
 
-#else
+  #else
   const char *getPassName() const override {
 
-#endif
+  #endif
     return "cmplog instructions";
 
   }
 
+#endif
+
  private:
   bool hookInstrs(Module &M);
 
@@ -85,8 +113,32 @@ 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, "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 +665,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 +681,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 +704,9 @@ 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/src/afl-cc.c b/src/afl-cc.c
index bacd9de9..051e4910 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -462,12 +462,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       } 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/split-switches-pass.so", obj_path);
+#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] =
             alloc_printf("%s/split-switches-pass.so", obj_path);
-
+#endif
+        
       }
 
     }
@@ -482,12 +488,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       } 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);
+#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] =
             alloc_printf("%s/compare-transform-pass.so", obj_path);
-
+#endif
+        
       }
 
     }
@@ -548,10 +560,10 @@ 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";
-#endif
+//#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";
+//#endif
 
     if (lto_mode && !have_c) {
 
@@ -576,6 +588,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       free(ld_path);
 
       cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
+#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15
+      cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager";
+#endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
       cc_params[cc_par_cnt++] = lto_flag;
@@ -601,11 +616,17 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
         } 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/SanitizerCoveragePCGUARD.so", obj_path);
+    #else
           cc_params[cc_par_cnt++] = "-Xclang";
           cc_params[cc_par_cnt++] = "-load";
           cc_params[cc_par_cnt++] = "-Xclang";
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path);
+    #endif
 
         }
 
@@ -653,6 +674,14 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       } else {
 
+#if LLVM_MAJOR >= 11
+        cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+        cc_params[cc_par_cnt++] = alloc_printf(
+            "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path);
+        cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+        cc_params[cc_par_cnt++] = alloc_printf(
+            "-fpass-plugin=%s/cmplog-routines-pass.so", obj_path);
+#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
@@ -664,7 +693,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] =
             alloc_printf("%s/cmplog-routines-pass.so", obj_path);
-
+#endif
+        
       }
 
     }
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index 9b58125f..5797def8 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -86,7 +86,7 @@ static void edit_params(int argc, char **argv) {
     for (i = 1; i < (u32)argc; i++) {
 
       if (strstr(argv[i], "/afl-llvm-rt-lto.o") != NULL) rt_lto_present = 1;
-      if (strstr(argv[i], "/afl-llvm-rt.o") != NULL) rt_present = 1;
+      if (strstr(argv[i], "/afl-compiler-rt.o") != NULL) rt_present = 1;
       if (strstr(argv[i], "/afl-llvm-lto-instr") != NULL) inst_present = 1;
 
     }
@@ -237,7 +237,8 @@ static void edit_params(int argc, char **argv) {
       }
 
       if (!rt_present)
-        ld_params[ld_param_cnt++] = alloc_printf("%s/afl-llvm-rt.o", afl_path);
+        ld_params[ld_param_cnt++] =
+            alloc_printf("%s/afl-compiler-rt.o", afl_path);
       if (!rt_lto_present)
         ld_params[ld_param_cnt++] =
             alloc_printf("%s/afl-llvm-rt-lto.o", afl_path);