about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CITATION.cff2
-rw-r--r--GNUmakefile16
-rw-r--r--GNUmakefile.llvm2
-rw-r--r--README.md4
-rw-r--r--custom_mutators/aflpp/aflpp.c1
-rw-r--r--custom_mutators/aflpp/standalone/aflpp-standalone.c7
-rw-r--r--docs/Changelog.md10
-rw-r--r--docs/fuzzing_in_depth.md2
-rwxr-xr-xfrida_mode/update_frida_version.sh2
-rw-r--r--include/afl-fuzz.h15
-rw-r--r--include/afl-mutations.h5
-rw-r--r--include/afl-record-compat.h4
-rw-r--r--include/config.h2
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc9
-rw-r--r--instrumentation/afl-compiler-rt.o.c7
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc2
-rw-r--r--instrumentation/afl-llvm-pass.so.cc10
-rw-r--r--instrumentation/cmplog-instructions-pass.cc9
-rw-r--r--instrumentation/cmplog-routines-pass.cc12
-rw-r--r--instrumentation/cmplog-switches-pass.cc12
-rw-r--r--instrumentation/compare-transform-pass.so.cc27
-rw-r--r--instrumentation/injection-pass.cc17
-rw-r--r--instrumentation/split-compares-pass.so.cc37
-rw-r--r--instrumentation/split-switches-pass.so.cc17
-rwxr-xr-xqemu_mode/build_qemu_support.sh2
-rw-r--r--src/afl-cc.c7
-rw-r--r--src/afl-common.c46
-rw-r--r--src/afl-forkserver.c7
-rw-r--r--src/afl-fuzz-run.c43
-rw-r--r--src/afl-fuzz-state.c4
-rw-r--r--src/afl-fuzz-stats.c178
-rw-r--r--src/afl-fuzz.c40
-rw-r--r--src/afl-tmin.c34
-rw-r--r--unicorn_mode/helper_scripts/unicorn_dumper_gdb.py10
34 files changed, 403 insertions, 199 deletions
diff --git a/CITATION.cff b/CITATION.cff
index 37a4a174..5ae7211d 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -27,5 +27,5 @@ keywords:
   - qemu
   - llvm
   - unicorn-emulator
-  - securiy
+  - security
 license: AGPL-3.0-or-later
diff --git a/GNUmakefile b/GNUmakefile
index 73fa366f..dee9bbb3 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -52,7 +52,7 @@ endif
 ifdef ASAN_BUILD
   $(info Compiling ASAN version of binaries)
   override CFLAGS += $(ASAN_CFLAGS)
-  LDFLAGS += $(ASAN_LDFLAGS)
+  override LDFLAGS += $(ASAN_LDFLAGS)
 endif
 ifdef UBSAN_BUILD
   $(info Compiling UBSAN version of binaries)
@@ -106,22 +106,22 @@ ifneq "$(SYS)" "Darwin"
  #  SPECIAL_PERFORMANCE += -march=native
  #endif
  #ifndef DEBUG
- #  CFLAGS_OPT += -D_FORTIFY_SOURCE=1
+ #  override CFLAGS_OPT += -D_FORTIFY_SOURCE=1
  #endif
 else
   # On some odd MacOS system configurations, the Xcode sdk path is not set correctly
   SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib
-  LDFLAGS += $(SDK_LD)
+  override LDFLAGS += $(SDK_LD)
 endif
 
 COMPILER_TYPE=$(shell $(CC) --version|grep "Free Software Foundation")
 ifneq "$(COMPILER_TYPE)" ""
   #$(info gcc is being used)
-  CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
+  override CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
 endif
 
 ifeq "$(SYS)" "SunOS"
-  LDFLAGS = -lkstat -lrt -lsocket -lnsl
+  override LDFLAGS = -lkstat -lrt -lsocket -lnsl
 endif
 
 ifdef STATIC
@@ -131,8 +131,8 @@ ifdef STATIC
   PYFLAGS=
   PYTHON_INCLUDE = /
 
-  CFLAGS_OPT += -static
-  LDFLAGS += -lm -lpthread -lz -lutil
+  override CFLAGS_OPT += -static
+  override LDFLAGS += -lm -lpthread -lz -lutil
 endif
 
 ifdef PROFILING
@@ -759,7 +759,7 @@ endif
 	@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md"
 	@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
 ifneq "$(SYS)" "Darwin"
-	test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
+	@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
 endif
 ifeq "$(SYS)" "Linux"
 ifndef NO_NYX
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index ec8fefe4..98ae461c 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -44,7 +44,7 @@ endif
 
 LLVMVER  = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' )
 LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
-LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
+LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' | sed 's/rc.*//' )
 LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-8]\.' && echo 1 || echo 0 )
 LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[8-9]|^2[0-9]' && echo 1 || echo 0 )
 LLVM_TOO_OLD = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[1-9]\.|^1[012]\.' && echo 1 || echo 0 )
diff --git a/README.md b/README.md
index f15089c2..2583407e 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
 
 <img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
 
-Release version: [4.10c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.20c](https://github.com/AFLplusplus/AFLplusplus/releases)
 
-GitHub version: 4.20a
+GitHub version: 4.20c
 
 Repository:
 [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c
index e15d0391..0b236f76 100644
--- a/custom_mutators/aflpp/aflpp.c
+++ b/custom_mutators/aflpp/aflpp.c
@@ -1,3 +1,4 @@
+#include "afl-fuzz.h"
 #include "afl-mutations.h"
 
 typedef struct my_mutator {
diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c
index 361feaba..3a2cbc2f 100644
--- a/custom_mutators/aflpp/standalone/aflpp-standalone.c
+++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c
@@ -1,9 +1,6 @@
+#include "afl-fuzz.h"
 #include "afl-mutations.h"
 
-s8  interesting_8[] = {INTERESTING_8};
-s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
-s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
-
 typedef struct my_mutator {
 
   afl_state_t *afl;
@@ -155,7 +152,7 @@ int main(int argc, char *argv[]) {
     return -1;
   }
 
-  if (verbose) fprintf(stderr, "Mutation output length: %zu\n", outlen);
+  if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
 
   if (fwrite(outbuf, 1, outlen, out) != outlen) {
     fprintf(stderr, "Warning: incomplete write.\n");
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 51f8dc4f..2428d63f 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,12 +3,12 @@
   This is the list of all noteworthy changes made in every public
   release of the tool. See README.md for the general instruction manual.
 
-### Version ++4.20a (dev)
+### Version ++4.20c (release)
   ! A new forkserver communication model is now introduced. afl-fuzz is
     backward compatible to old compiled targets if they are not built
     for CMPLOG/Redqueen, but new compiled targets will not work with
     old afl-fuzz versions!
-  ! Recompiled all targets that are instrumented for CMPLOG/Redqueen!
+  ! Recompile all targets that are instrumented for CMPLOG/Redqueen!
   - AFL++ now supports up to 4 billion coverage edges, up from 6 million.
   - New compile option: `make PERFORMANCE=1` - this will enable special
     CPU dependent optimizations that make everything more performant - but
@@ -23,16 +23,20 @@
     - workround for a bug with MOpt -L when used with -M - in the future
       we will either remove or rewrite MOpt.
     - fix for `-t xxx+` feature
-    - -e extension option now saves the queue items crashes etc. with the
+    - -e extension option now saves the queue items, crashes, etc. with the
       extension too
+    - fixes for trimmming, correct -V time and reading stats on resume by eqv
+      thanks a lot!
   - afl-cc:
     - added collision free caller instrumentation to LTO mode. activate with
       `AFL_LLVM_LTO_CALLER=1`. You can set a max depth to go through single
       block functions with `AFL_LLVM_LTO_CALLER_DEPTH` (default 0)
+    - fixes for COMPCOV/LAF and most other modules
     - fix for GCC_PLUGIN cmplog that broke on std::strings
   - afl-whatsup:
     - now also displays current average speed
     - small bugfixes
+  - Fixes for aflpp custom mutator and standalone tool
   - Minor edits to afl-persistent-config
   - Prevent temporary files being left behind on aborted afl-whatsup
   - More CPU benchmarks added to benchmark/
diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md
index 6a217641..82437807 100644
--- a/docs/fuzzing_in_depth.md
+++ b/docs/fuzzing_in_depth.md
@@ -958,7 +958,7 @@ too long for your overall available fuzz run time.
    campaign but not good for short CI runs.
 
 How this can look like can, e.g., be seen at AFL++'s setup in Google's
-[oss-fuzz](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_afl)
+[previous oss-fuzz version](https://github.com/google/oss-fuzz/blob/3e2c5312417d1a6f9564472f3df1fd27759b289d/infra/base-images/base-builder/compile_afl)
 and
 [clusterfuzz](https://github.com/google/clusterfuzz/blob/master/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py).
 
diff --git a/frida_mode/update_frida_version.sh b/frida_mode/update_frida_version.sh
index 18243fbb..2fafbf2f 100755
--- a/frida_mode/update_frida_version.sh
+++ b/frida_mode/update_frida_version.sh
@@ -2,7 +2,7 @@
 test -n "$1" && { echo This script has no options. It updates the referenced Frida version in GNUmakefile to the most current one. ; exit 1 ; }
 
 OLD=$(grep -E '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}')
-NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep -E 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//')
+NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep 'Frida\ [0-9.]*'|head -n 1|sed 's/.*Frida\ //'| sed 's/<\/h2>//')
 
 echo Current set version: $OLD
 echo Newest available version: $NEW
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index be86910e..c813ae7e 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -5,9 +5,9 @@
    Originally written by Michal Zalewski
 
    Now maintained by Marc Heuse <mh@mh-sec.de>,
-                     Heiko Eißfeldt <heiko.eissfeldt@hexco.de>,
-                     Andrea Fioraldi <andreafioraldi@gmail.com>,
-                     Dominik Maier <mail@dmnk.co>
+                     Dominik Maier <mail@dmnk.co>,
+                     Andrea Fioraldi <andreafioraldi@gmail.com>, and
+                     Heiko Eissfeldt <heiko.eissfeldt@hexco.de>
 
    Copyright 2016, 2017 Google Inc. All rights reserved.
    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
@@ -648,7 +648,10 @@ typedef struct afl_state {
       longest_find_time,                /* Longest time taken for a find    */
       exit_on_time,                     /* Delay to exit if no new paths    */
       sync_time,                        /* Sync time (ms)                   */
-      switch_fuzz_mode;                 /* auto or fixed fuzz mode          */
+      switch_fuzz_mode,                 /* auto or fixed fuzz mode          */
+      calibration_time_us,              /* Time spend on calibration        */
+      sync_time_us,                     /* Time spend on sync               */
+      trim_time_us;                     /* Time spend on trimming           */
 
   u32 slowest_exec_ms,                  /* Slowest testcase non hang in ms  */
       subseq_tmouts;                    /* Number of timeouts in a row      */
@@ -1215,6 +1218,10 @@ void show_stats_normal(afl_state_t *);
 void show_stats_pizza(afl_state_t *);
 void show_init_stats(afl_state_t *);
 
+void update_calibration_time(afl_state_t *afl, u64 *time);
+void update_trim_time(afl_state_t *afl, u64 *time);
+void update_sync_time(afl_state_t *afl, u64 *time);
+
 /* StatsD */
 
 void statsd_setup_format(afl_state_t *afl);
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 75e66484..79cf7c6a 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -30,10 +30,13 @@
 
 #include <stdbool.h>
 #include <inttypes.h>
-#include "afl-fuzz.h"
 
 #define MUT_STRATEGY_ARRAY_SIZE 256
 
+s8  interesting_8[] = {INTERESTING_8};
+s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
+s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
+
 enum {
 
   /* 00 */ MUT_FLIPBIT,
diff --git a/include/afl-record-compat.h b/include/afl-record-compat.h
index 2c79595d..3e5d60e3 100644
--- a/include/afl-record-compat.h
+++ b/include/afl-record-compat.h
@@ -28,7 +28,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
   static unsigned short int inited = 0;
   char                      tcase[PATH_MAX];
 
-  if (is_replay_record) {
+  if (is_replay_record && cycle_cnt) {
 
     if (!inited) {
 
@@ -59,7 +59,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
 
   }
 
-  return --cycle_cnt;
+  return cycle_cnt--;
 
 }
 
diff --git a/include/config.h b/include/config.h
index 31d66b14..3ea059ff 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
 /* Version string: */
 
 // c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.20a"
+#define VERSION "++4.20c"
 
 /******************************************************
  *                                                    *
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 43c6ca40..4518c1c7 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -341,7 +341,7 @@ llvmGetPassPluginInfo() {
             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
 #endif
 #if LLVM_VERSION_MAJOR >= 15
-            PB.registerFullLinkTimeOptimizationLastEPCallback(
+            PB.registerFullLinkTimeOptimizationEarlyEPCallback(
 #else
             PB.registerOptimizerLastEPCallback(
 #endif
@@ -1304,7 +1304,12 @@ u32 countCallers(Function *F) {
 
   for (auto *U : F->users()) {
 
-    if (auto *CI = dyn_cast<CallInst>(U)) { ++callers; }
+    if (auto *CI = dyn_cast<CallInst>(U)) {
+
+      ++callers;
+      (void)(CI);
+
+    }
 
   }
 
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index aa58e8de..e450dc45 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1617,7 +1617,7 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
 
       }
 
-      if (pc_filter) {
+      if (pc_filter && !mod_info->next) {
 
         char PcDescr[1024];
         // This function is a part of the sanitizer run-time.
@@ -1644,7 +1644,8 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
 
       }
 
-      if (__afl_filter_pcs && strstr(mod_info->name, __afl_filter_pcs_module)) {
+      if (__afl_filter_pcs && !mod_info->next &&
+          strstr(mod_info->name, __afl_filter_pcs_module)) {
 
         u32 result_index;
         if (locate_in_pcs(PC, &result_index)) {
@@ -1669,7 +1670,7 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
 
     }
 
-    mod_info->mapped = 1;
+    if (__afl_pcmap_ptr) { mod_info->mapped = 1; }
 
     if (__afl_debug) {
 
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index ac497b5b..b93f61f0 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -746,7 +746,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
   auto PA = PreservedAnalyses::all();
   return PA;
 #else
-  return true;
+  return false;
 #endif
 
 }
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index 62f5023d..75b8532b 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -128,7 +128,11 @@ llvmGetPassPluginInfo() {
     #if LLVM_VERSION_MAJOR <= 13
             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
     #endif
+    #if LLVM_VERSION_MAJOR >= 16
+            PB.registerOptimizerEarlyEPCallback(
+    #else
             PB.registerOptimizerLastEPCallback(
+    #endif
                 [](ModulePassManager &MPM, OptimizationLevel OL) {
 
                   MPM.addPass(AFLCoverage());
@@ -212,10 +216,6 @@ 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();
@@ -1081,7 +1081,7 @@ bool AFLCoverage::runOnModule(Module &M) {
   }
 
 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
-  return PA;
+  return PreservedAnalyses();
 #else
   return true;
 #endif
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index dc60221e..fe5c2926 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -680,13 +680,16 @@ bool CmpLogInstructions::runOnModule(Module &M) {
     printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n");
   else
     be_quiet = 1;
-  hookInstrs(M);
+  bool ret = hookInstrs(M);
   verifyModule(M);
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
-  return PreservedAnalyses::all();
+  if (ret == false)
+    return PreservedAnalyses::all();
+  else
+    return PreservedAnalyses();
 #else
-  return true;
+  return ret;
 #endif
 
 }
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 78317d5d..560bd73b 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -758,16 +758,16 @@ bool CmpLogRoutines::runOnModule(Module &M) {
     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
+  bool ret = hookRtns(M);
   verifyModule(M);
 
 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
-  return PA;
+  if (ret == false)
+    return PreservedAnalyses::all();
+  else
+    return PreservedAnalyses();
 #else
-  return true;
+  return ret;
 #endif
 
 }
diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc
index 3e05c13d..2b87ea8c 100644
--- a/instrumentation/cmplog-switches-pass.cc
+++ b/instrumentation/cmplog-switches-pass.cc
@@ -442,16 +442,16 @@ bool CmplogSwitches::runOnModule(Module &M) {
     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
+  bool ret = hookInstrs(M);
   verifyModule(M);
 
 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
-  return PA;
+  if (ret == false)
+    return PreservedAnalyses::all();
+  else
+    return PreservedAnalyses();
 #else
-  return true;
+  return ret;
 #endif
 
 }
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index b0d6355a..f8ba9de5 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -89,7 +89,7 @@ class CompareTransform : public ModulePass {
 
   #endif
 
-    return "cmplog transform";
+    return "compcov transform";
 
   }
 
@@ -123,7 +123,11 @@ llvmGetPassPluginInfo() {
     #if LLVM_VERSION_MAJOR <= 13
             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
     #endif
+    #if LLVM_VERSION_MAJOR >= 16
+            PB.registerOptimizerEarlyEPCallback(
+    #else
             PB.registerOptimizerLastEPCallback(
+    #endif
                 [](ModulePassManager &MPM, OptimizationLevel OL) {
 
                   MPM.addPass(CompareTransform());
@@ -746,6 +750,8 @@ bool CompareTransform::runOnModule(Module &M) {
 
 #endif
 
+  bool ret = false;
+
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
     printf(
         "Running compare-transform-pass by laf.intel@gmail.com, extended by "
@@ -753,11 +759,7 @@ 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);
+  if (transformCmps(M, true, true, true, true, true) == true) ret = true;
   verifyModule(M);
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
@@ -767,9 +769,18 @@ bool CompareTransform::runOnModule(Module &M) {
                    
                        }*/
 
-  return PA;
+  if (ret == true) {
+
+    return PreservedAnalyses();
+
+  } else {
+
+    return PreservedAnalyses::all();
+
+  }
+
 #else
-  return true;
+  return ret;
 #endif
 
 }
diff --git a/instrumentation/injection-pass.cc b/instrumentation/injection-pass.cc
index 2280208b..47ddabd9 100644
--- a/instrumentation/injection-pass.cc
+++ b/instrumentation/injection-pass.cc
@@ -204,6 +204,8 @@ bool InjectionRoutines::hookRtns(Module &M) {
   Function *FuncPtr;
 #endif
 
+  bool ret = false;
+
   /* iterate over all functions, bbs and instruction and add suitable calls */
   for (auto &F : M) {
 
@@ -281,6 +283,7 @@ bool InjectionRoutines::hookRtns(Module &M) {
 
             IRBuilder<> IRB(callInst->getParent());
             IRB.SetInsertPoint(callInst);
+            ret = true;
 
             Value *parameter = callInst->getArgOperand(param);
 
@@ -299,7 +302,7 @@ bool InjectionRoutines::hookRtns(Module &M) {
 
   }
 
-  return true;
+  return ret;
 
 }
 
@@ -328,16 +331,16 @@ bool InjectionRoutines::runOnModule(Module &M) {
   if (getenv("AFL_LLVM_INJECTIONS_LDAP")) { doLDAP = true; }
   if (getenv("AFL_LLVM_INJECTIONS_XSS")) { doXSS = true; }
 
-  hookRtns(M);
-#if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
-  auto PA = PreservedAnalyses::all();
-#endif
+  bool ret = hookRtns(M);
   verifyModule(M);
 
 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
-  return PA;
+  if (ret == false)
+    return PreservedAnalyses::all();
+  else
+    return PreservedAnalyses();
 #else
-  return true;
+  return ret;
 #endif
 
 }
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 144025fb..421a7c39 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -189,7 +189,11 @@ llvmGetPassPluginInfo() {
     #if LLVM_VERSION_MAJOR <= 13
             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
     #endif
+    #if LLVM_VERSION_MAJOR >= 16
+            PB.registerOptimizerEarlyEPCallback(
+    #else
             PB.registerOptimizerLastEPCallback(
+    #endif
                 [](ModulePassManager &MPM, OptimizationLevel OL) {
 
                   MPM.addPass(SplitComparesTransform());
@@ -935,7 +939,7 @@ size_t SplitComparesTransform::nextPowerOfTwo(size_t in) {
 /* splits fcmps into two nested fcmps with sign compare and the rest */
 size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
-  size_t count = 0;
+  size_t counts = 0;
 
   LLVMContext &C = M.getContext();
 
@@ -951,7 +955,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
   } else {
 
-    return count;
+    return counts;
 
   }
 
@@ -1004,7 +1008,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
   }
 
-  if (!fcomps.size()) { return count; }
+  if (!fcomps.size()) { return counts; }
 
   IntegerType *Int1Ty = IntegerType::getInt1Ty(C);
 
@@ -1690,11 +1694,11 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 #else
     ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN);
 #endif
-    ++count;
+    ++counts;
 
   }
 
-  return count;
+  return counts;
 
 }
 
@@ -1743,10 +1747,6 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
   }
 
-#if LLVM_MAJOR >= 11
-  auto PA = PreservedAnalyses::all();
-#endif
-
   if (enableFPSplit) {
 
     simplifyFPCompares(M);
@@ -1778,15 +1778,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
             auto op0 = CI->getOperand(0);
             auto op1 = CI->getOperand(1);
-            if (!op0 || !op1) {
-
-#if LLVM_MAJOR >= 11
-              return PA;
-#else
-              return false;
-#endif
-
-            }
+            if (!op0 || !op1) { continue; }
 
             auto iTy1 = dyn_cast<IntegerType>(op0->getType());
             if (iTy1 && isa<IntegerType>(op1->getType())) {
@@ -1814,6 +1806,8 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
   }
 
+  bool ret = count == 0 ? false : true;
+
   bool brokenDebug = false;
   if (verifyModule(M, &errs()
 #if LLVM_VERSION_MAJOR >= 4 || \
@@ -1852,9 +1846,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
     }*/
 
-  return PA;
+  if (ret == false)
+    return PreservedAnalyses::all();
+  else
+    return PreservedAnalyses();
 #else
-  return true;
+  return ret;
 #endif
 
 }
diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc
index e3dfea0d..aa552a42 100644
--- a/instrumentation/split-switches-pass.so.cc
+++ b/instrumentation/split-switches-pass.so.cc
@@ -137,7 +137,11 @@ llvmGetPassPluginInfo() {
     #if LLVM_VERSION_MAJOR <= 13
             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
     #endif
+    #if LLVM_VERSION_MAJOR >= 16
+            PB.registerOptimizerEarlyEPCallback(
+    #else
             PB.registerOptimizerLastEPCallback(
+    #endif
                 [](ModulePassManager &MPM, OptimizationLevel OL) {
 
                   MPM.addPass(SplitSwitchesTransform());
@@ -516,11 +520,7 @@ bool SplitSwitchesTransform::runOnModule(Module &M) {
   else
     be_quiet = 1;
 
-#if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
-  auto PA = PreservedAnalyses::all();
-#endif
-
-  splitSwitches(M);
+  bool ret = splitSwitches(M);
   verifyModule(M);
 
 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
@@ -530,9 +530,12 @@ bool SplitSwitchesTransform::runOnModule(Module &M) {
                            
                                }*/
 
-  return PA;
+  if (ret == false)
+    return PreservedAnalyses::all();
+  else
+    return PreservedAnalyses();
 #else
-  return true;
+  return ret;
 #endif
 
 }
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index 45019cc8..ecc90ef5 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -215,8 +215,10 @@ if [ "$STATIC" = "1" ]; then
   echo Building STATIC binary
 
   # static PIE causes https://github.com/AFLplusplus/AFLplusplus/issues/892
+  # plugin support requires dynamic linking
   QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
     --static --disable-pie \
+    --disable-plugins \
     --extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \
     "
 
diff --git a/src/afl-cc.c b/src/afl-cc.c
index faa46103..45fd398b 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1369,6 +1369,13 @@ void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) {
 
   }
 
+  if (getenv("AFL_LLVM_DICT2FILE") &&
+      (getenv("AFL_LLVM_LAF_SPLIT_SWITCHES") ||
+       getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
+       getenv("AFL_LLVM_LAF_SPLIT_FLOATS") ||
+       getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")))
+    FATAL("AFL_LLVM_DICT2FILE is incompatible with AFL_LLVM_LAF_*");
+
   aflcc->cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG") ||
                        getenv("AFL_GCC_CMPLOG");
 
diff --git a/src/afl-common.c b/src/afl-common.c
index 87003b03..6d915b00 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -34,6 +34,7 @@
 #endif
 #include <string.h>
 #include <strings.h>
+#include <time.h>
 #include <math.h>
 #include <sys/mman.h>
 
@@ -58,6 +59,27 @@ u8  last_intr = 0;
   #define AFL_PATH "/usr/local/lib/afl/"
 #endif
 
+/* - Some BSD (i.e.: FreeBSD) offer the FAST clock source as
+ *   equivalent to Linux COARSE clock source. Aliasing COARSE to
+ *   FAST on such systems when COARSE is not already defined.
+ * - macOS has no support of CLOCK_MONOTONIC_COARSE clock type.
+ */
+#if defined(OS_DARWIN) || defined(OS_SUNOS) || defined(__APPLE__) || \
+    defined(__sun) || defined(__NetBSD__)
+  #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
+#elif defined(OS_FREEBSD)
+  #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST
+#endif
+
+/* Convert seconds to milliseconds. */
+#define SEC_TO_MS(sec) ((sec) * 1000)
+/* Convert seconds to microseconds. */
+#define SEC_TO_US(sec) ((sec) * 1000000)
+/* Convert nanoseconds to milliseconds. */
+#define NS_TO_MS(ns) ((ns) / 1000000)
+/* Convert nanoseconds to microseconds. */
+#define NS_TO_US(ns) ((ns) / 1000)
+
 void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle,
                  size_t needlelen) {
 
@@ -974,12 +996,16 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) {
 
 inline u64 get_cur_time(void) {
 
-  struct timeval  tv;
-  struct timezone tz;
+  struct timespec ts;
+  int             rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+  if (rc == -1) {
 
-  gettimeofday(&tv, &tz);
+    PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno,
+           strerror(errno));
 
-  return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
+  }
+
+  return SEC_TO_MS((uint64_t)ts.tv_sec) + NS_TO_MS((uint64_t)ts.tv_nsec);
 
 }
 
@@ -987,12 +1013,16 @@ inline u64 get_cur_time(void) {
 
 u64 get_cur_time_us(void) {
 
-  struct timeval  tv;
-  struct timezone tz;
+  struct timespec ts;
+  int             rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+  if (rc == -1) {
 
-  gettimeofday(&tv, &tz);
+    PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno,
+           strerror(errno));
+
+  }
 
-  return (tv.tv_sec * 1000000ULL) + tv.tv_usec;
+  return SEC_TO_US((uint64_t)ts.tv_sec) + NS_TO_US((uint64_t)ts.tv_nsec);
 
 }
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index cf5c511e..f28a2a64 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -1111,8 +1111,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
       }
 
-      if ((status & FS_NEW_OPT_SHDMEM_FUZZ) && fsrv->add_extra_func &&
-          !ignore_autodict) {
+      if (status & FS_NEW_OPT_SHDMEM_FUZZ) {
 
         if (fsrv->support_shmem_fuzz) {
 
@@ -1129,7 +1128,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
       }
 
-      if ((status & FS_NEW_OPT_AUTODICT)) {
+      if (status & FS_NEW_OPT_AUTODICT) {
 
         // even if we do not need the dictionary we have to read it
 
@@ -1875,7 +1874,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
      territory. */
 
 #ifdef __linux__
-  if (!fsrv->nyx_mode) {
+  if (likely(!fsrv->nyx_mode)) {
 
     memset(fsrv->trace_bits, 0, fsrv->map_size);
     MEM_BARRIER();
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index d764952c..edcddc8e 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -409,6 +409,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
   u32 use_tmout = afl->fsrv.exec_tmout;
   u8 *old_sn = afl->stage_name;
 
+  u64 calibration_start_us = get_cur_time_us();
   if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; }
 
   /* Be a bit more generous about timeouts when resuming sessions, or when
@@ -504,6 +505,10 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
 
     fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
 
+    // update the time spend in calibration after each execution, as those may
+    // be slow
+    update_calibration_time(afl, &calibration_start_us);
+
     /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
        we want to bail out quickly. */
 
@@ -650,6 +655,7 @@ abort_calibration:
 
   if (!first_run) { show_stats(afl); }
 
+  update_calibration_time(afl, &calibration_start_us);
   return fault;
 
 }
@@ -669,11 +675,16 @@ void sync_fuzzers(afl_state_t *afl) {
   afl->stage_max = afl->stage_cur = 0;
   afl->cur_depth = 0;
 
+  u64 sync_start_us = get_cur_time_us();
   /* Look at the entries created for every other fuzzer in the sync directory.
    */
 
   while ((sd_ent = readdir(sd))) {
 
+    // since sync can take substantial amounts of time, update time spend every
+    // iteration
+    update_sync_time(afl, &sync_start_us);
+
     u8  qd_synced_path[PATH_MAX], qd_path[PATH_MAX];
     u32 min_accept = 0, next_min_accept = 0;
 
@@ -811,7 +822,7 @@ void sync_fuzzers(afl_state_t *afl) {
         /* See what happens. We rely on save_if_interesting() to catch major
            errors and save the test case. */
 
-        (void)write_to_testcase(afl, (void **)&mem, st.st_size, 1);
+        u32 new_len = write_to_testcase(afl, (void **)&mem, st.st_size, 1);
 
         fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
 
@@ -819,7 +830,7 @@ void sync_fuzzers(afl_state_t *afl) {
 
         afl->syncing_party = sd_ent->d_name;
         afl->queued_imported +=
-            save_if_interesting(afl, mem, st.st_size, fault);
+            save_if_interesting(afl, mem, new_len, fault);
         afl->syncing_party = 0;
 
         munmap(mem, st.st_size);
@@ -861,6 +872,9 @@ void sync_fuzzers(afl_state_t *afl) {
 
   if (afl->foreign_sync_cnt) read_foreign_testcases(afl, 0);
 
+  // add time in sync one last time
+  update_sync_time(afl, &sync_start_us);
+
   afl->last_sync_time = get_cur_time();
   afl->last_sync_cycle = afl->queue_cycle;
 
@@ -872,8 +886,9 @@ void sync_fuzzers(afl_state_t *afl) {
 
 u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
+  u8  needs_write = 0, fault = 0;
   u32 orig_len = q->len;
-
+  u64 trim_start_us = get_cur_time_us();
   /* Custom mutator trimmer */
   if (afl->custom_mutators_count) {
 
@@ -897,11 +912,15 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
     }
 
-    if (custom_trimmed) return trimmed_case;
+    if (custom_trimmed) {
+
+      fault = trimmed_case;
+      goto abort_trimming;
+
+    }
 
   }
 
-  u8  needs_write = 0, fault = 0;
   u32 trim_exec = 0;
   u32 remove_len;
   u32 len_p2;
@@ -912,7 +931,12 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
      detected, it will still work to some extent, so we don't check for
      this. */
 
-  if (unlikely(q->len < 5)) { return 0; }
+  if (unlikely(q->len < 5)) {
+
+    fault = 0;
+    goto abort_trimming;
+
+  }
 
   afl->stage_name = afl->stage_name_buf;
   afl->bytes_trim_in += q->len;
@@ -946,6 +970,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
       fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
 
+      update_trim_time(afl, &trim_start_us);
+
       if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
 
       /* Note that we don't keep track of crashes or hangs here; maybe TODO?
@@ -972,7 +998,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
         /* Let's save a clean trace, which will be needed by
            update_bitmap_score once we're done with the trimming stuff. */
-
         if (!needs_write) {
 
           needs_write = 1;
@@ -987,7 +1012,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
       }
 
       /* Since this can be slow, update the screen every now and then. */
-
       if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); }
       ++afl->stage_cur;
 
@@ -1039,8 +1063,9 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
   }
 
 abort_trimming:
-
   afl->bytes_trim_out += q->len;
+  update_trim_time(afl, &trim_start_us);
+
   return fault;
 
 }
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index ae327117..c61f00bd 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -28,10 +28,6 @@
 #include "afl-fuzz.h"
 #include "envs.h"
 
-s8  interesting_8[] = {INTERESTING_8};
-s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
-s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
-
 char *power_names[POWER_SCHEDULES_NUM] = {"explore", "mmopt", "exploit",
                                           "fast",    "coe",   "lin",
                                           "quad",    "rare",  "seek"};
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index b6900506..7e1a3b92 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -133,6 +133,12 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
 
 }
 
+static bool starts_with(char *key, char *line) {
+
+  return strncmp(key, line, strlen(key)) == 0;
+
+}
+
 /* load some of the existing stats file when resuming.*/
 void load_stats_file(afl_state_t *afl) {
 
@@ -175,58 +181,84 @@ void load_stats_file(afl_state_t *afl) {
       strcpy(keystring, lstartptr);
       lptr++;
       char *nptr;
-      switch (lineno) {
-
-        case 3:
-          if (!strcmp(keystring, "run_time          "))
-            afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10);
-          break;
-        case 5:
-          if (!strcmp(keystring, "cycles_done       "))
-            afl->queue_cycle =
-                strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0;
-          break;
-        case 7:
-          if (!strcmp(keystring, "execs_done        "))
-            afl->fsrv.total_execs = strtoull(lptr, &nptr, 10);
-          break;
-        case 10:
-          if (!strcmp(keystring, "corpus_count      ")) {
-
-            u32 corpus_count = strtoul(lptr, &nptr, 10);
-            if (corpus_count != afl->queued_items) {
-
-              WARNF(
-                  "queue/ has been modified -- things might not work, you're "
-                  "on your own!");
-
-            }
-
-          }
-
-          break;
-        case 12:
-          if (!strcmp(keystring, "corpus_found      "))
-            afl->queued_discovered = strtoul(lptr, &nptr, 10);
-          break;
-        case 13:
-          if (!strcmp(keystring, "corpus_imported   "))
-            afl->queued_imported = strtoul(lptr, &nptr, 10);
-          break;
-        case 14:
-          if (!strcmp(keystring, "max_depth         "))
-            afl->max_depth = strtoul(lptr, &nptr, 10);
-          break;
-        case 21:
-          if (!strcmp(keystring, "saved_crashes    "))
-            afl->saved_crashes = strtoull(lptr, &nptr, 10);
-          break;
-        case 22:
-          if (!strcmp(keystring, "saved_hangs      "))
-            afl->saved_hangs = strtoull(lptr, &nptr, 10);
-          break;
-        default:
-          break;
+      if (starts_with("run_time", keystring)) {
+
+        afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10);
+
+      }
+
+      if (starts_with("cycles_done", keystring)) {
+
+        afl->queue_cycle =
+            strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0;
+
+      }
+
+      if (starts_with("calibration_time", keystring)) {
+
+        afl->calibration_time_us = strtoull(lptr, &nptr, 10) * 1000000;
+
+      }
+
+      if (starts_with("sync_time", keystring)) {
+
+        afl->sync_time_us = strtoull(lptr, &nptr, 10) * 1000000;
+
+      }
+
+      if (starts_with("trim_time", keystring)) {
+
+        afl->trim_time_us = strtoull(lptr, &nptr, 10) * 1000000;
+
+      }
+
+      if (starts_with("execs_done", keystring)) {
+
+        afl->fsrv.total_execs = strtoull(lptr, &nptr, 10);
+
+      }
+
+      if (starts_with("corpus_count", keystring)) {
+
+        u32 corpus_count = strtoul(lptr, &nptr, 10);
+        if (corpus_count != afl->queued_items) {
+
+          WARNF(
+              "queue/ has been modified -- things might not work, you're "
+              "on your own!");
+          sleep(3);
+
+        }
+
+      }
+
+      if (starts_with("corpus_found", keystring)) {
+
+        afl->queued_discovered = strtoul(lptr, &nptr, 10);
+
+      }
+
+      if (starts_with("corpus_imported", keystring)) {
+
+        afl->queued_imported = strtoul(lptr, &nptr, 10);
+
+      }
+
+      if (starts_with("max_depth", keystring)) {
+
+        afl->max_depth = strtoul(lptr, &nptr, 10);
+
+      }
+
+      if (starts_with("saved_crashes", keystring)) {
+
+        afl->saved_crashes = strtoull(lptr, &nptr, 10);
+
+      }
+
+      if (starts_with("saved_hangs", keystring)) {
+
+        afl->saved_hangs = strtoull(lptr, &nptr, 10);
 
       }
 
@@ -300,6 +332,10 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
       "cycles_done       : %llu\n"
       "cycles_wo_finds   : %llu\n"
       "time_wo_finds     : %llu\n"
+      "fuzz_time         : %llu\n"
+      "calibration_time  : %llu\n"
+      "sync_time         : %llu\n"
+      "trim_time         : %llu\n"
       "execs_done        : %llu\n"
       "execs_per_sec     : %0.02f\n"
       "execs_ps_last_min : %0.02f\n"
@@ -337,7 +373,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
       "\n"
       "target_mode       : %s%s%s%s%s%s%s%s%s%s\n"
       "command_line      : %s\n",
-      (afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000,
+      (afl->start_time /*- afl->prev_run_time*/) / 1000, cur_time / 1000,
       runtime / 1000, (u32)getpid(),
       afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds,
       afl->longest_find_time > cur_time - afl->last_find_time
@@ -345,7 +381,13 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
           : ((afl->start_time == 0 || afl->last_find_time == 0)
                  ? 0
                  : (cur_time - afl->last_find_time) / 1000),
-      afl->fsrv.total_execs, afl->fsrv.total_execs / ((double)(runtime) / 1000),
+      (runtime -
+       (afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) /
+           1000) /
+          1000,
+      afl->calibration_time_us / 1000000, afl->sync_time_us / 1000000,
+      afl->trim_time_us / 1000000, afl->fsrv.total_execs,
+      afl->fsrv.total_execs / ((double)(runtime) / 1000),
       afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored,
       afl->queued_discovered, afl->queued_imported, afl->queued_variable,
       afl->max_depth, afl->current_entry, afl->pending_favored,
@@ -876,6 +918,10 @@ void show_stats_normal(afl_state_t *afl) {
 
 #endif
 
+    if (banner_pad)
+      for (u32 i = 0; i < banner_pad; ++i)
+        strcat(banner, " ");
+
   }
 
   SAYF("\n%s\n", banner);
@@ -2435,3 +2481,27 @@ void show_init_stats(afl_state_t *afl) {
 
 }
 
+void update_calibration_time(afl_state_t *afl, u64 *time) {
+
+  u64 cur = get_cur_time_us();
+  afl->calibration_time_us += cur - *time;
+  *time = cur;
+
+}
+
+void update_trim_time(afl_state_t *afl, u64 *time) {
+
+  u64 cur = get_cur_time_us();
+  afl->trim_time_us += cur - *time;
+  *time = cur;
+
+}
+
+void update_sync_time(afl_state_t *afl, u64 *time) {
+
+  u64 cur = get_cur_time_us();
+  afl->sync_time_us += cur - *time;
+  *time = cur;
+
+}
+
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 443d93b0..00d24ab1 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -5,8 +5,9 @@
    Originally written by Michal Zalewski
 
    Now maintained by Marc Heuse <mh@mh-sec.de>,
-                        Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
-                        Andrea Fioraldi <andreafioraldi@gmail.com>
+                     Dominik Meier <mail@dmnk.co>,
+                     Andrea Fioraldi <andreafioraldi@gmail.com>, and
+                     Heiko Eissfeldt <heiko.eissfeldt@hexco.de>
 
    Copyright 2016, 2017 Google Inc. All rights reserved.
    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
@@ -199,7 +200,8 @@ static void usage(u8 *argv0, int more_help) {
 
       "Test settings:\n"
       "  -s seed       - use a fixed seed for the RNG\n"
-      "  -V seconds    - fuzz for a specified time then terminate\n"
+      "  -V seconds    - fuzz for a specified time then terminate (fuzz time "
+      "only!)\n"
       "  -E execs      - fuzz for an approx. no. of total executions then "
       "terminate\n"
       "                  Note: not precise and can have several more "
@@ -2073,6 +2075,17 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  /* Simply code if AFL_TMPDIR is used or not */
+  if (!afl->afl_env.afl_tmpdir) {
+
+    afl->tmp_dir = afl->out_dir;
+
+  } else {
+
+    afl->tmp_dir = afl->afl_env.afl_tmpdir;
+
+  }
+
   write_setup_file(afl, argc, argv);
 
   setup_cmdline_file(afl, argv + optind);
@@ -2085,8 +2098,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (!afl->timeout_given) { find_timeout(afl); }  // only for resumes!
 
-  if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL &&
-      !afl->in_place_resume) {
+  if (afl->afl_env.afl_tmpdir && !afl->in_place_resume) {
 
     char tmpfile[PATH_MAX];
 
@@ -2111,10 +2123,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
     }
 
-  } else {
-
-    afl->tmp_dir = afl->out_dir;
-
   }
 
   /* If we don't have a file name chosen yet, use a safe default. */
@@ -2537,8 +2545,6 @@ int main(int argc, char **argv_orig, char **envp) {
   }
 
   // (void)nice(-20);  // does not improve the speed
-  // real start time, we reset, so this works correctly with -V
-  afl->start_time = get_cur_time();
 
   #ifdef INTROSPECTION
   u32 prev_saved_crashes = 0, prev_saved_tmouts = 0;
@@ -2559,6 +2565,9 @@ int main(int argc, char **argv_orig, char **envp) {
   OKF("Writing mutation introspection to '%s'", ifn);
   #endif
 
+  // real start time, we reset, so this works correctly with -V
+  afl->start_time = get_cur_time();
+
   while (likely(!afl->stop_soon)) {
 
     cull_queue(afl);
@@ -2579,6 +2588,13 @@ int main(int argc, char **argv_orig, char **envp) {
 
         sync_fuzzers(afl);
 
+        if (!afl->queue_cycle && afl->afl_env.afl_import_first) {
+
+          // real start time, we reset, so this works correctly with -V
+          afl->start_time = get_cur_time();
+
+        }
+
       }
 
       ++afl->queue_cycle;
@@ -3068,7 +3084,7 @@ stop_fuzzing:
   afl_fsrv_deinit(&afl->fsrv);
 
   /* remove tmpfile */
-  if (afl->tmp_dir != NULL && !afl->in_place_resume && afl->fsrv.out_file) {
+  if (!afl->in_place_resume && afl->fsrv.out_file) {
 
     (void)unlink(afl->fsrv.out_file);
 
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 4e5dab41..994174ed 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -82,6 +82,8 @@ static u8 crash_mode,                  /* Crash-centric mode?               */
     remove_shm = 1,                    /* remove shmem on exit?             */
     debug;                             /* debug mode                        */
 
+static u32 del_len_limit = 1;          /* Minimum block deletion length     */
+
 static volatile u8 stop_soon;          /* Ctrl-C pressed?                   */
 
 static afl_forkserver_t *fsrv;
@@ -480,7 +482,7 @@ next_del_blksize:
 
   }
 
-  if (del_len > 1 && in_len >= 1) {
+  if (del_len > del_len_limit && in_len >= 1) {
 
     del_len /= 2;
     goto next_del_blksize;
@@ -796,8 +798,9 @@ static void usage(u8 *argv0) {
       "Minimization settings:\n"
 
       "  -e            - solve for edge coverage only, ignore hit counts\n"
-      "  -x            - treat non-zero exit codes as crashes\n\n"
-      "  -H            - minimize a hang (hang mode)\n"
+      "  -l bytes      - set minimum block deletion length to speed up minimization\n"
+      "  -x            - treat non-zero exit codes as crashes\n"
+      "  -H            - minimize a hang (hang mode)\n\n"
 
       "For additional tips, please consult %s/README.md.\n\n"
 
@@ -829,8 +832,9 @@ static void usage(u8 *argv0) {
 
 int main(int argc, char **argv_orig, char **envp) {
 
-  s32    opt;
-  u8     mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
+  s32 opt;
+  u8  mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0,
+     del_limit_given = 0;
   char **use_argv;
 
   char **argv = argv_cpy_dup(argc, argv_orig);
@@ -846,7 +850,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
 
-  while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXYHh")) > 0) {
+  while ((opt = getopt(argc, argv, "+i:o:f:m:t:l:B:xeAOQUWXYHh")) > 0) {
 
     switch (opt) {
 
@@ -1055,6 +1059,24 @@ int main(int argc, char **argv_orig, char **envp) {
         read_bitmap(optarg, mask_bitmap, map_size);
         break;
 
+      case 'l':
+        if (del_limit_given) { FATAL("Multiple -l options not supported"); }
+        del_limit_given = 1;
+
+        if (!optarg) { FATAL("Wrong usage of -l"); }
+
+        if (optarg[0] == '-') { FATAL("Dangerously low value of -l"); }
+
+        del_len_limit = atoi(optarg);
+
+        if (del_len_limit < 1 || del_len_limit > TMIN_MAX_FILE) {
+
+          FATAL("Value of -l out of range between 1 and TMIN_MAX_FILE");
+
+        }
+
+        break;
+
       case 'h':
         usage(argv[0]);
         return -1;
diff --git a/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py b/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py
index 1ac4c9f3..a202ac0e 100644
--- a/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py
+++ b/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py
@@ -89,8 +89,8 @@ def dump_arch_info():
 
 def dump_regs():
     reg_state = {}
-    for reg in current_arch.all_registers:
-        reg_val = get_register(reg)
+    for reg in gef.arch.registers:
+        reg_val = gef.arch.register(reg)
         reg_state[reg.strip().strip("$")] = reg_val
 
     return reg_state
@@ -101,7 +101,9 @@ def dump_process_memory(output_dir):
     final_segment_list = []
 
     # GEF:
-    vmmap = get_process_maps()
+    vmmap = gef.memory.maps
+    memory = GefMemoryManager()
+    
     if not vmmap:
         print("No address mapping information found")
         return final_segment_list
@@ -126,7 +128,7 @@ def dump_process_memory(output_dir):
         if entry.is_readable() and not "(deleted)" in entry.path:
             try:
                 # Compress and dump the content to a file
-                seg_content = read_memory(entry.page_start, entry.size)
+                seg_content = memory.read(entry.page_start, entry.size)
                 if seg_content == None:
                     print(
                         "Segment empty: @0x{0:016x} (size:UNKNOWN) {1}".format(