about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2023-05-15 11:51:37 +0300
committerGitHub <noreply@github.com>2023-05-15 10:51:37 +0200
commitc4b1566ba35c697cda7822bd0cf30e2e3eeee0c7 (patch)
tree3337fbdabebc223c5222b650127af7469a77f693
parent74be9ab5ce61d5b561faf688c245143da1a0141e (diff)
downloadafl++-c4b1566ba35c697cda7822bd0cf30e2e3eeee0c7.tar.gz
push to stable (#1734)
* afl++ -> AFL++

* update readme

* more debug

* slightly different weighting algo (#1719)

* better seed selection

* slightly different weighting calculation

* remove unnecessary memset

* Add "Hangs saved" to afl-whatsup (#1717)

The hangs could show long or infinite loops. This is important.

Co-authored-by: van Hauser <vh@thc.org>

* nits

* afl-showmap: Start a only a single fork server (#1718)

A forkserver is started by afl_fsrv_get_mapsize() when dynamically
finding the map size.  When an input directory option is specified a
second fork server was also started.  This commit re-arranges the inits
for several forkserver struct members so that we can re-use the server
started by the get_mapsize() call when not in coresight/qemu/unicorn
modes and just start the server otherwise.

* Source Code Coverage support for Nyx (Part 1) (#1720)

* Additional source code reformatting in afl-compiler-rt

* Add source code coverage support to afl-compiler-rt (for use with Nyx)

* doc, code format

* llvm 17 changes

* more llvm 17

* add frida mode tutorial

* fix effector map

* docs

* Should memset EFF_ALEN(len) of eff_map (#1722)

* fix reallocs

* fix afl-system-config for macos

* afl-fuzz.c: Document -i - in --help (#1725)

afl-fuzz.c: Document `-i -` in `--help`, to write that `-i` can be passed '-' to resume the prior fuzzing job. Also reference AFL_AUTORESUME so users know they can set that parameter to sidestep the issue entirely.

* tritondse custom mutator attempt

* tritondse fixes

* update libnyx (#1727)

* GNUmakefile: Update LLVM instructions (#1728)

Update LLVM instructions, because versions higher than 14 are supported and to be explicit that LLD is also required

* disable macos in the ci, works fine for me

* fix makefile

* better tritondse support

* next steps for tritondse

* qemuafl: Persistent mode for PPC32 targets

* update qemu_mode

* afl-clang-lto incomptable with -flto=thin

* add @responsefile support for afl-cc

---------

Co-authored-by: fxlb <devel.fx.lebail@orange.fr>
Co-authored-by: Nick Potenski <nick.potenski@garmin.com>
Co-authored-by: Christian Holler (:decoder) <choller@mozilla.com>
Co-authored-by: lazymio <mio@lazym.io>
Co-authored-by: Moshe Kaplan <me@moshekaplan.com>
Co-authored-by: Sergej Schumilo <sergej@schumilo.de>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
-rw-r--r--.github/workflows/ci.yml40
-rw-r--r--Dockerfile4
-rw-r--r--GNUmakefile17
-rw-r--r--GNUmakefile.gcc_plugin6
-rw-r--r--GNUmakefile.llvm11
-rw-r--r--README.md2
-rwxr-xr-xafl-cmin2
-rwxr-xr-xafl-system-config3
-rwxr-xr-xafl-whatsup3
-rw-r--r--custom_mutators/aflpp_tritondse/README.md17
-rw-r--r--custom_mutators/aflpp_tritondse/aflpp_tritondse.py148
-rw-r--r--docs/Changelog.md6
-rw-r--r--docs/FAQ.md8
-rw-r--r--docs/INSTALL.md12
-rw-r--r--docs/best_practices.md5
-rw-r--r--docs/custom_mutators.md28
-rw-r--r--docs/tutorials.md4
-rw-r--r--frida_mode/README.md2
-rw-r--r--include/afl-fuzz.h4
-rw-r--r--include/alloc-inl.h9
-rw-r--r--include/envs.h4
-rw-r--r--instrumentation/README.llvm.md24
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc32
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc2
-rw-r--r--instrumentation/afl-compiler-rt.o.c249
-rw-r--r--instrumentation/afl-llvm-common.cc2
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc2
-rw-r--r--nyx_mode/LIBNYX_VERSION2
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
-rwxr-xr-xqemu_mode/build_qemu_support.sh4
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-cc.c498
-rw-r--r--src/afl-forkserver.c6
-rw-r--r--src/afl-fuzz-init.c32
-rw-r--r--src/afl-fuzz-one.c18
-rw-r--r--src/afl-fuzz-queue.c92
-rw-r--r--src/afl-fuzz.c143
-rw-r--r--src/afl-ld-lto.c4
-rw-r--r--src/afl-showmap.c31
-rw-r--r--test/test-dlopen.c2
-rwxr-xr-xtest/test-gcc-plugin.sh2
-rwxr-xr-xtest/test-llvm.sh2
-rwxr-xr-xtest/test-performance.sh4
-rwxr-xr-xtest/test-pre.sh2
-rwxr-xr-xunicorn_mode/build_unicorn_support.sh2
45 files changed, 1163 insertions, 329 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 03e4151d..fdf618b9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,23 +36,23 @@ jobs:
         run: make distrib ASAN_BUILD=1 NO_NYX=1
       - name: run tests
         run: sudo -E ./afl-system-config; make tests
-  macos:
-    runs-on: macOS-latest
-    env:
-      AFL_MAP_SIZE: 65536
-      AFL_SKIP_CPUFREQ: 1
-      AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
-    steps:
-      - uses: actions/checkout@v3
-      - name: install
-        run: brew install make gcc llvm
-      - name: fix install
-        run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
-      - name: build
-        run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
-      - name: frida
-        run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
-      - name: run tests
-        run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
-      - name: force frida test for MacOS
-        run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
+ # macos:
+ #   runs-on: macOS-latest
+ #   env:
+ #     AFL_MAP_SIZE: 65536
+ #     AFL_SKIP_CPUFREQ: 1
+ #     AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
+ #   steps:
+ #     - uses: actions/checkout@v3
+ #     - name: install
+ #       run: brew install make gcc llvm
+ #     - name: fix install
+ #       run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
+ #     - name: build
+ #       run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
+ #     - name: frida
+ #       run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
+ #     - name: run tests
+ #       run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
+ #     - name: force frida test for MacOS
+ #       run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
diff --git a/Dockerfile b/Dockerfile
index 4e53de40..1b5ffd28 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@
 #
 
 FROM ubuntu:22.04 AS aflplusplus
-LABEL "maintainer"="afl++ team <afl@aflplus.plus>"
+LABEL "maintainer"="AFL++ team <afl@aflplus.plus>"
 LABEL "about"="AFLplusplus container image"
 
 ### Comment out to enable these features
@@ -94,4 +94,4 @@ RUN sed -i.bak 's/^	-/	/g' GNUmakefile && \
 RUN echo "set encoding=utf-8" > /root/.vimrc && \
     echo ". /etc/bash_completion" >> ~/.bashrc && \
     echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
-    echo "export PS1='"'[afl++ \h] \w \$ '"'" >> ~/.bashrc
+    echo "export PS1='"'[AFL++ \h] \w \$ '"'" >> ~/.bashrc
diff --git a/GNUmakefile b/GNUmakefile
index 23cae65d..31374c10 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -39,7 +39,7 @@ ASAN_OPTIONS=detect_leaks=0
 SYS = $(shell uname -s)
 ARCH = $(shell uname -m)
 
-$(info [*] Compiling afl++ for OS $(SYS) on ARCH $(ARCH))
+$(info [*] Compiling AFL++ for OS $(SYS) on ARCH $(ARCH))
 
 ifdef NO_SPLICING
   override CFLAGS_OPT += -DNO_SPLICING
@@ -316,7 +316,7 @@ all:	test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_bu
 	@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
 	@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
 	@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 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"
+	@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 and LLD 11+. 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"
 endif
@@ -359,7 +359,7 @@ performance-test:	source-only
 help:
 	@echo "HELP --- the following make targets exist:"
 	@echo "=========================================="
-	@echo "all: the main afl++ binaries and llvm/gcc instrumentation"
+	@echo "all: the main AFL++ binaries and llvm/gcc instrumentation"
 	@echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
 	@echo "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap"
 	@echo "distrib: everything (for both binary-only and source code fuzzing)"
@@ -367,7 +367,7 @@ help:
 	@echo "install: installs everything you have compiled with the build option above"
 	@echo "clean: cleans everything compiled (not downloads when on a checkout)"
 	@echo "deepclean: cleans everything including downloads"
-	@echo "uninstall: uninstall afl++ from the system"
+	@echo "uninstall: uninstall AFL++ from the system"
 	@echo "code-format: format the code, do this before you commit and send a PR please!"
 	@echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem"
 	@echo "unit: perform unit tests (based on cmocka and GNU linker)"
@@ -379,6 +379,7 @@ help:
 	@echo Known build environment options:
 	@echo "=========================================="
 	@echo STATIC - compile AFL++ static
+	@echo "CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)"
 	@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
 	@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
 	@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
@@ -394,7 +395,7 @@ help:
 	@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
 	@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)"
 	@echo "=========================================="
-	@echo e.g.: make ASAN_BUILD=1
+	@echo e.g.: make LLVM_CONFIG=llvm-config-16
 
 .PHONY: test_x86
 ifndef AFL_NO_X86
@@ -749,7 +750,7 @@ endif
 	@echo
 
 %.8:	%
-	@echo .TH $* 8 $(BUILD_DATE) "afl++" > $@
+	@echo .TH $* 8 $(BUILD_DATE) "AFL++" > $@
 	@echo .SH NAME >> $@
 	@echo .B $* >> $@
 	@echo >> $@
@@ -761,8 +762,8 @@ endif
 	@./$* -hh 2>&1 | tail -n +4 >> $@
 	@echo >> $@
 	@echo .SH AUTHOR >> $@
-	@echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> $@
-	@echo  The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@
+	@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> $@
+	@echo  The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> $@
 	@echo >> $@
 	@echo .SH LICENSE >> $@
 	@echo Apache License Version 2.0, January 2004 >> $@
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 4c4e10c4..41face4c 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -175,7 +175,7 @@ all_done: test_build
 .NOTPARALLEL: clean
 
 %.8: %
-	@echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ./$@
+	@echo .TH $* 8 `date "+%Y-%m-%d"` "AFL++" > ./$@
 	@echo .SH NAME >> ./$@
 	@echo .B $* >> ./$@
 	@echo >> ./$@
@@ -187,8 +187,8 @@ all_done: test_build
 	@./$* -h 2>&1 | tail -n +4 >> ./$@
 	@echo >> ./$@
 	@echo .SH AUTHOR >> ./$@
-	@echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> ./$@
-	@echo  The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
+	@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> ./$@
+	@echo  The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
 	@echo >> ./$@
 	@echo .SH LICENSE >> ./$@
 	@echo Apache License Version 2.0, January 2004 >> ./$@
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index a053403b..2bb4e7f8 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -274,6 +274,11 @@ ifndef LLVM_DEBUG
   CFLAGS_SAFE += -Wno-deprecated
 endif
 
+ifdef CODE_COVERAGE
+  override CFLAGS_SAFE += -D__AFL_CODE_COVERAGE=1
+  override LDFLAGS += -ldl
+endif
+
 override CFLAGS += $(CFLAGS_SAFE)
 
 ifdef AFL_TRACE_PC
@@ -510,7 +515,7 @@ install: all
 	install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/
 
 %.8: %
-	@echo .TH $* 8 $(BUILD_DATE) "afl++" > ./$@
+	@echo .TH $* 8 $(BUILD_DATE) "AFL++" > ./$@
 	@echo .SH NAME >> ./$@
 	@printf "%s" ".B $* \- " >> ./$@
 	@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ./$@
@@ -524,8 +529,8 @@ install: all
 	@./$* -h 2>&1 | tail -n +4 >> ./$@
 	@echo >> ./$@
 	@echo .SH AUTHOR >> ./$@
-	@echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> ./$@
-	@echo  The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
+	@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> ./$@
+	@echo  The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
 	@echo >> ./$@
 	@echo .SH LICENSE >> ./$@
 	@echo Apache License Version 2.0, January 2004 >> ./$@
diff --git a/README.md b/README.md
index c012c400..863c2fce 100644
--- a/README.md
+++ b/README.md
@@ -12,9 +12,9 @@ Repository:
 AFL++ is maintained by:
 
 * Marc "van Hauser" Heuse <mh@mh-sec.de>
-* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>
 * Andrea Fioraldi <andreafioraldi@gmail.com>
 * Dominik Maier <mail@dmnk.co>
+* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>
 * Documentation: Jana Aydinbas <jana.aydinbas@gmail.com>
 
 Originally developed by Michał "lcamtuf" Zalewski.
diff --git a/afl-cmin b/afl-cmin
index 63cfdd7e..ae723c1b 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -149,7 +149,7 @@ BEGIN {
     redirected = 0
   }
 
-  print "corpus minimization tool for afl++ (awk version)\n"
+  print "corpus minimization tool for AFL++ (awk version)\n"
 
   # defaults
   extra_par = ""
diff --git a/afl-system-config b/afl-system-config
index bf6397fa..b50bb06e 100755
--- a/afl-system-config
+++ b/afl-system-config
@@ -110,7 +110,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then
   sysctl kern.sysv.shmall=131072000
   echo Settings applied.
   echo
-  if [ $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ] ; then
+  if $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ; then
     echo
     echo Unloading the default crash reporter
     SL=/System/Library; PL=com.apple.ReportCrash
@@ -119,6 +119,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then
     echo
   fi
   echo It is recommended to disable System Integrity Protection for increased performance.
+  echo See: https://developer.apple.com/documentation/security/disabling_and_enabling_system_integrity_protection
   echo
   DONE=1
 fi
diff --git a/afl-whatsup b/afl-whatsup
index cec1ae28..6f29ab24 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -88,6 +88,7 @@ TOTAL_TIME=0
 TOTAL_EXECS=0
 TOTAL_EPS=0
 TOTAL_CRASHES=0
+TOTAL_HANGS=0
 TOTAL_PFAV=0
 TOTAL_PENDING=0
 
@@ -190,6 +191,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
   TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
   TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
   TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
+  TOTAL_HANGS=$((TOTAL_HANGS + saved_hangs))
   TOTAL_PENDING=$((TOTAL_PENDING + pending_total))
   TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))
 
@@ -301,6 +303,7 @@ if [ "$ALIVE_CNT" -gt "1" ]; then
 fi
 
 echo "       Crashes saved : $TOTAL_CRASHES"
+echo "         Hangs saved : $TOTAL_HANGS"
 echo "Cycles without finds : $TOTAL_WCOP"
 echo "  Time without finds : $TOTAL_LAST_FIND"
 echo
diff --git a/custom_mutators/aflpp_tritondse/README.md b/custom_mutators/aflpp_tritondse/README.md
new file mode 100644
index 00000000..8a5dd02b
--- /dev/null
+++ b/custom_mutators/aflpp_tritondse/README.md
@@ -0,0 +1,17 @@
+# An AFL++ custom mutator using TritonDSE
+
+## Installing the requirements
+
+`pip3 install tritondse`
+
+## How to run with an example
+
+```
+../../afl-cc -o ../../test-instr ../../test-instr.c
+mkdir -p in
+echo aaaa > in/in
+TRITON_DSE_TARGET=../../test-instr AFL_CUSTOM_MUTATOR_ONLY=1 AFL_SYNC_TIME=1 AFL_PYTHON_MODULE=aflpp_tritondse PYTHONPATH=. ../../afl-fuzz -i in -o out -- ../../test-instr
+```
+
+Note that this custom mutator works differently, new finds are synced
+after 10-60 seconds to the fuzzing instance.
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
new file mode 100644
index 00000000..e0219f0b
--- /dev/null
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -0,0 +1,148 @@
+import sys
+import os
+import logging
+import hashlib
+
+from tritondse import CleLoader
+from tritondse import CompositeData
+from tritondse import Config
+from tritondse import CoverageStrategy
+from tritondse import ProcessState
+from tritondse import Program
+from tritondse import Seed
+from tritondse import SeedFormat
+from tritondse import SymbolicExecutor
+from tritondse import SymbolicExplorator
+
+is_debug = False
+out_path = ""
+input_file = None
+prog = None
+config = None
+dse = None
+cycle = 0
+count = 0
+hashes = set()
+format = SeedFormat.RAW
+
+def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
+    global count
+    global hashes
+    if se.seed.hash not in hashes:
+        hashes.add(se.seed.hash)
+        filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
+        if not os.path.exists(filename):
+            if is_debug:
+                print('Creating queue input ' + filename)
+            with open(filename, 'wb') as file:
+                if input_file:
+                    file.write(se.seed.content.files[input_file])
+                else:
+                    file.write(se.seed.content)
+                count += 1
+    #if input_file:
+    #    if is_debug:
+    #        print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
+    #    with open(input_file, 'wb') as file:
+    #        file.write(se.seed.content)
+
+
+def init(seed):
+    global config
+    global dse
+    global format
+    global input_file
+    global is_debug
+    global out_path
+    global prog
+    # Load the program (LIEF-based program loader).
+    prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM'])
+    # Process other configuration environment variables.
+    argv = None
+    try:
+        foo = os.environ['AFL_DEBUG']
+        is_debug = True
+    except KeyError:
+        pass
+    try:
+        foo = os.environ['AFL_CUSTOM_INFO_OUT']
+        out_path = foo + '/../tritondse/queue'
+    except KeyError:
+        pass
+    try:
+        foo = os.environ['AFL_CUSTOM_INFO_PROGRAM_INPUT']
+        input_file = foo
+    except KeyError:
+        pass
+    try:
+        argv_list = os.environ['AFL_CUSTOM_INFO_PROGRAM_ARGV']
+        argv_tmp = [ os.environ['AFL_CUSTOM_INFO_PROGRAM'] ]
+        argv_tmp += argv_list.split()
+        argv = []
+        # now check for @@
+        for item in argv_tmp:
+            if "@@" in item:
+                input_file = out_path + '/../.input'
+                argv.append(input_file)
+            else:
+                argv.append(item)
+    except KeyError:
+        pass
+    # Create the output directory
+    os.makedirs(out_path, exist_ok=True)
+    # Debug
+    if is_debug:
+        print('DEBUG target: ' + os.environ['AFL_CUSTOM_INFO_PROGRAM'])
+        if argv:
+            print('DEBUG argv: ')
+            print(argv)
+        if input_file:
+            print('DEBUG input_file: ' + input_file)
+        print('DEBUG out_path: ' + out_path)
+        print('')
+    if input_file:
+        format = SeedFormat.COMPOSITE
+    # Now set up TritonDSE
+    config = Config(coverage_strategy = CoverageStrategy.PATH,
+                    debug = is_debug,
+                    pipe_stdout = is_debug,
+                    pipe_stderr = is_debug,
+                    execution_timeout = 1,
+                    program_argv = argv,
+                    smt_timeout= 50,
+                    seed_format = format)
+    # Create an instance of the Symbolic Explorator
+    dse = SymbolicExplorator(config, prog)
+    # Add callbacks.
+    dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
+
+
+#def fuzz(buf, add_buf, max_size):
+#    return b""
+
+
+def queue_new_entry(filename_new_queue, filename_orig_queue):
+    global cycle
+    global dse
+    # Add seed to the worklist.
+    with open(filename_new_queue, "rb") as file:
+        data = file.read()
+    hash = hashlib.md5(data).hexdigest()
+    if hash not in hashes:
+        hashes.add(hash)
+        if is_debug:
+            print("NEW FILE " + filename_new_queue + " hash " + hash + " count " + str(cycle))
+            cycle += 1
+        if input_file:
+            seed = Seed(CompositeData(files={"stdin": b"", # nothing on stdin
+                                  input_file: data}))
+        else:
+            seed = Seed(data)
+        dse.add_input_seed(seed)
+        # Start exploration!
+        #dse.step()
+        dse.explore()
+    pass
+
+def splice_optout():
+    pass
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 20b915fa..3602af50 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -11,13 +11,17 @@
     - new env `AFL_IGNORE_PROBLEMS_COVERAGE` to ignore coverage from
       loaded libs after forkserver initialization (required by Mozilla)
   - afl-cc:
+    - added @responsefile support
     - new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
       (https://github.com/fgsect/WAFL) project
+    - error and print help if afl-clan-lto is used with lto=thin
   - afl-showmap:
     - added custom mutator post_process and send support
     - add `-I filelist` option, an alternative to `-i in_dir`
   - afl-cmin + afl-cmin.bash:
     - `-T threads` parallel task support, can be a huge speedup!
+  - qemu_mode:
+    - Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
   - a new grammar custom mutator atnwalk was submitted by @voidptr127 !
 
 
@@ -229,7 +233,7 @@
     afl-showmap and other tools.
   - afl-cc:
     - detect overflow reads on initial input buffer for asan
-    - new cmplog mode (incompatible with older afl++ versions)
+    - new cmplog mode (incompatible with older AFL++ versions)
     - support llvm IR select instrumentation for default PCGUARD and LTO
     - fix for shared linking on MacOS
     - better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 76350c79..8178db46 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -171,6 +171,14 @@ If you find an interesting or important question missing, submit it via
   The more "unstable" edges there are, the harder it is for AFL++ to identify
   valid new paths.
 
+  If you fuzz in persistent mode (`AFL_LOOP` or `LLVMFuzzerTestOneInput()`
+  harnesses, a large number of unstable edges can mean that the target keeps
+  internal state and therefore it is possible that crashes cannot be replayed.
+  In such a case do either **not** fuzz in persistent mode (remove `AFL_LOOP()`
+  from your harness or call `LLVMFuzzerTestOneInput()` harnesses with `@@`),
+  or set a low  `AFL_LOOP` value, e.g. 100, and enable `AFL_PERSISTENT_RECORD`
+  in `config.h` with the same value.
+
   A value above 90% is usually fine and a value above 80% is also still ok, and
   even a value above 20% can still result in successful finds of bugs. However,
   it is recommended that for values below 90% or 80% you should take
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 591b7ded..637e8658 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -51,7 +51,7 @@ make source-only
 
 These build targets exist:
 
-* all: the main afl++ binaries and llvm/gcc instrumentation
+* all: the main AFL++ binaries and llvm/gcc instrumentation
 * binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode,
   qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator,
   libtokencap
@@ -79,22 +79,20 @@ make STATIC=1
 These build options exist:
 
 * STATIC - compile AFL++ static
+* CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
 * ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
-* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for
-  debug purposes
+* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
 * DEBUG - no optimization, -ggdb3, all warnings and -Werror
 * LLVM_DEBUG - shows llvm deprecation warnings
 * PROFILING - compile afl-fuzz with profiling information
 * INTROSPECTION - compile afl-fuzz with mutation introspection
 * NO_PYTHON - disable python support
-* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for
-  normal fuzzing
+* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
 * NO_NYX - disable building nyx mode dependencies
 * NO_CORESIGHT - disable building coresight (arm64 only)
 * NO_UNICORN_ARM64 - disable building unicorn on arm64
 * AFL_NO_X86 - if compiling on non-intel/amd platforms
-* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config
-  (e.g., Debian)
+* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)
 
 e.g.: `make LLVM_CONFIG=llvm-config-14`
 
diff --git a/docs/best_practices.md b/docs/best_practices.md
index 133c645e..459fcaf7 100644
--- a/docs/best_practices.md
+++ b/docs/best_practices.md
@@ -131,6 +131,11 @@ jitter, or is a hash map function etc., then it should not be instrumented.
 To be able to exclude these functions (based on AFL++'s measured stability), the
 following process will allow to identify functions with variable edges.
 
+Note that this is only useful for non-persistent targets!
+If a persistent target is unstable whereas when run non-persistent is fine,
+then this means that the target is keeping internal state, which is bad for
+fuzzing. Fuzz such targets **without** persistent mode.
+
 Four steps are required to do this and it also requires quite some knowledge of
 coding and/or disassembly and is effectively possible only with `afl-clang-fast`
 `PCGUARD` and `afl-clang-lto` `LTO` instrumentation.
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index a1de479e..3f7e9e6e 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -304,6 +304,34 @@ Note: for some distributions, you might also need the package `python[3]-apt`.
 In case your setup is different, set the necessary variables like this:
 `PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
 
+### Helpers
+
+For C/C++ custom mutators you get a pointer to `afl_state_t *afl` in the
+`afl_custom_init()` which contains all information that you need.
+Note that if you access it, you need to recompile your custom mutator if
+you update AFL++ because the structure might have changed!
+
+For mutators written in Python, Rust, GO, etc. there are a few environment
+variables set to help you to get started:
+
+`AFL_CUSTOM_INFO_PROGRAM` - the program name of the target that is executed.
+If your custom mutator is used with modes like Qemu (`-Q`), this will still
+contain the target program, not afl-qemu-trace.
+
+`AFL_CUSTOM_INFO_PROGRAM_INPUT` - if the `-f` parameter is used with afl-fuzz
+then this value is found in this environment variable.
+
+`AFL_CUSTOM_INFO_PROGRAM_ARGV` - this contains the parameters given to the
+target program and still has the `@@` identifier in there.
+
+Note: If `AFL_CUSTOM_INFO_PROGRAM_INPUT` is empty and `AFL_CUSTOM_INFO_PROGRAM_ARGV`
+is either empty or does not contain `@@` then the target gets the input via
+`stdin`.
+
+`AFL_CUSTOM_INFO_OUT` - This is the output directory for this fuzzer instance,
+so if `afl-fuzz` was called with `-o out -S foobar`, then this will be set to
+`out/foobar`.
+
 ### Custom Mutator Preparation
 
 For C/C++ mutators, the source code must be compiled as a shared object:
diff --git a/docs/tutorials.md b/docs/tutorials.md
index 758fddab..342080fd 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -20,6 +20,10 @@ training, then we can highly recommend the following:
 
 * [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
 
+Here is good workflow description for frida_mode:
+
+* [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
+
 If you are interested in fuzzing structured data (where you define what the
 structure is), these links have you covered (some are outdated though):
 
diff --git a/frida_mode/README.md b/frida_mode/README.md
index 49a1fe38..bfca443c 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -7,6 +7,8 @@ variables.
 
 In FRIDA mode, binary programs are instrumented, similarly to QEMU mode.
 
+A tutorial can be found at [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
+
 ## Current progress
 
 As FRIDA mode is new, it is missing a lot of features. The design is such that
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 831a0dbc..8fb7ecb1 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1223,7 +1223,7 @@ double rand_next_percent(afl_state_t *afl);
 
 static inline u32 rand_below(afl_state_t *afl, u32 limit) {
 
-  if (limit <= 1) return 0;
+  if (unlikely(limit <= 1)) return 0;
 
   /* The boundary not being necessarily a power of 2,
      we need to ensure the result uniformity. */
@@ -1256,7 +1256,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
    expand havoc mode */
 static inline u32 rand_below_datalen(afl_state_t *afl, u32 limit) {
 
-  if (limit <= 1) return 0;
+  if (unlikely(limit <= 1)) return 0;
 
   switch (rand_below(afl, 3)) {
 
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index ae37028e..1e9a192b 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -42,7 +42,7 @@
 // Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators
 
 #ifndef _WANT_ORIGINAL_AFL_ALLOC
-  // afl++ stuff without memory corruption checks - for speed
+  // AFL++ stuff without memory corruption checks - for speed
 
   /* User-facing macro to sprintf() to a dynamically allocated buffer. */
 
@@ -704,12 +704,11 @@ static inline void *afl_realloc(void **buf, size_t size_needed) {
     *buf = NULL;
     return NULL;
 
-  } else {
-
-    new_buf = newer_buf;
-
   }
 
+  new_buf = newer_buf;
+  memset(((u8 *)new_buf) + current_size, 0, next_size - current_size);
+
   new_buf->complete_size = next_size;
   *buf = (void *)(new_buf->buf);
   return *buf;
diff --git a/include/envs.h b/include/envs.h
index fe5ee0e3..edfd06e4 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -37,6 +37,10 @@ static char *afl_environment_variables[] = {
     "AFL_CRASH_EXITCODE",
     "AFL_CUSTOM_MUTATOR_LIBRARY",
     "AFL_CUSTOM_MUTATOR_ONLY",
+    "AFL_CUSTOM_INFO_PROGRAM",
+    "AFL_CUSTOM_INFO_PROGRAM_ARGV",
+    "AFL_CUSTOM_INFO_PROGRAM_INPUT",
+    "AFL_CUSTOM_INFO_OUT",
     "AFL_CXX",
     "AFL_CYCLE_SCHEDULES",
     "AFL_DEBUG",
diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md
index c0677474..126cf1a2 100644
--- a/instrumentation/README.llvm.md
+++ b/instrumentation/README.llvm.md
@@ -280,3 +280,27 @@ Please note that the default counter implementations are not thread safe!
 
 Support for thread safe counters in mode LLVM CLASSIC can be activated with
 setting `AFL_LLVM_THREADSAFE_INST=1`.
+
+## 8) Source code coverage through instrumentation
+
+Measuring source code coverage is a common task in fuzzing, but it is very
+difficut to do in some situations (e.g. when using snapshot fuzzing).
+
+When using the `AFL_LLVM_INSTRUMENT=llvm-codecov` option, afl-cc will use
+native trace-pc-guard instrumentation but additionally select options that
+are required to utilize the instrumentation for source code coverage.
+
+In particular, it will switch the instrumentation to be per basic block
+instead of instrumenting edges, disable all guard pruning and enable the
+experimental pc-table support that allows the runtime to gather 100% of
+instrumented basic blocks at start, including their locations.
+
+Note: You must compile AFL with the `CODE_COVERAGE=1` option to enable the
+respective parts in the AFL compiler runtime. Support is currently only
+implemented for Nyx, but can in theory also work without Nyx.
+
+Note: You might have to adjust `MAP_SIZE_POW2` in include/config.h to ensure
+that your coverage map is large enough to hold all basic blocks of your
+target program without any collisions.
+
+More documentation on how to utilize this with Nyx will follow.
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index e779bb79..b3b0d2cd 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1,4 +1,4 @@
-/* SanitizeCoverage.cpp ported to afl++ LTO :-) */
+/* SanitizeCoverage.cpp ported to AFL++ LTO :-) */
 
 #define AFL_LLVM_PASS
 
@@ -20,6 +20,8 @@
 #if LLVM_VERSION_MAJOR < 17
   #include "llvm/ADT/Triple.h"
   #include "llvm/Analysis/EHPersonalities.h"
+#else
+  #include "llvm/IR/EHPersonalities.h"
 #endif
 #include "llvm/Analysis/PostDominators.h"
 #include "llvm/Analysis/ValueTracking.h"
@@ -236,7 +238,7 @@ class ModuleSanitizerCoverageLTO
 
   SanitizerCoverageOptions Options;
 
-  // afl++ START
+  // AFL++ START
   // const SpecialCaseList *          Allowlist;
   // const SpecialCaseList *          Blocklist;
   uint32_t                         autodictionary = 1;
@@ -262,7 +264,7 @@ class ModuleSanitizerCoverageLTO
   Value                           *MapPtrFixed = NULL;
   std::ofstream                    dFile;
   size_t                           found = 0;
-  // afl++ END
+  // AFL++ END
 
 };
 
@@ -406,7 +408,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
   Int8Ty = IRB.getInt8Ty();
   Int1Ty = IRB.getInt1Ty();
 
-  /* afl++ START */
+  /* AFL++ START */
   char        *ptr;
   LLVMContext &Ctx = M.getContext();
   Ct = &Ctx;
@@ -980,7 +982,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
 
   }
 
-  // afl++ END
+  // AFL++ END
 
   SanCovTracePCIndir =
       M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
@@ -1004,7 +1006,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
   for (auto &F : M)
     instrumentFunction(F, DTCallback, PDTCallback);
 
-  // afl++ START
+  // AFL++ START
   if (dFile.is_open()) dFile.close();
 
   if (!getenv("AFL_LLVM_LTO_SKIPINIT") &&
@@ -1158,7 +1160,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
 
   }
 
-  // afl++ END
+  // AFL++ END
 
   // We don't reference these arrays directly in any of our runtime functions,
   // so we need to prevent them from being dead stripped.
@@ -1215,10 +1217,10 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
   // (catchswitch blocks).
   if (BB->getFirstInsertionPt() == BB->end()) return false;
 
-  // afl++ START
+  // AFL++ START
   if (!Options.NoPrune && &F.getEntryBlock() == BB && F.size() > 1)
     return false;
-  // afl++ END
+  // AFL++ END
 
   if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
 
@@ -1260,10 +1262,10 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
   // if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName()))
   // return;
 
-  // afl++ START
+  // AFL++ START
   if (!F.size()) return;
   if (!isInInstrumentList(&F, FMNAME)) return;
-  // afl++ END
+  // AFL++ END
 
   if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
     SplitAllCriticalEdges(
@@ -1561,7 +1563,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage(
 
   for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
 
-    // afl++ START
+    // AFL++ START
     if (BlockList.size()) {
 
       int skip = 0;
@@ -1583,7 +1585,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage(
 
     }
 
-    // afl++ END
+    // AFL++ END
 
     InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
 
@@ -1649,7 +1651,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function   &F,
 
   if (Options.TracePCGuard) {
 
-    // afl++ START
+    // AFL++ START
     ++afl_global_id;
 
     if (dFile.is_open()) {
@@ -1713,7 +1715,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function   &F,
     // done :)
 
     inst++;
-    // afl++ END
+    // AFL++ END
 
     /*
     XXXXXXXXXXXXXXXXXXX
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 8be9e329..41c38283 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -16,6 +16,8 @@
 #if LLVM_VERSION_MAJOR < 17
   #include "llvm/ADT/Triple.h"
   #include "llvm/Analysis/EHPersonalities.h"
+#else
+  #include "llvm/IR/EHPersonalities.h"
 #endif
 #include "llvm/Analysis/PostDominators.h"
 #include "llvm/IR/CFG.h"
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 0912e52b..5372fae0 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -14,6 +14,16 @@
 
 */
 
+#ifdef __AFL_CODE_COVERAGE
+  #ifndef _GNU_SOURCE
+    #define _GNU_SOURCE
+  #endif
+  #ifndef __USE_GNU
+    #define __USE_GNU
+  #endif
+  #include <dlfcn.h>
+#endif
+
 #ifdef __ANDROID__
   #include "android-ashmem.h"
 #endif
@@ -105,6 +115,44 @@ u32 __afl_dictionary_len;
 u64 __afl_map_addr;
 u32 __afl_first_final_loc;
 
+#ifdef __AFL_CODE_COVERAGE
+typedef struct afl_module_info_t afl_module_info_t;
+
+struct afl_module_info_t {
+
+  // A unique id starting with 0
+  u32 id;
+
+  // Name and base address of the module
+  char     *name;
+  uintptr_t base_address;
+
+  // PC Guard start/stop
+  u32 start;
+  u32 stop;
+
+  // PC Table begin/end
+  const uintptr_t *pcs_beg;
+  const uintptr_t *pcs_end;
+
+  u8 mapped;
+
+  afl_module_info_t *next;
+
+};
+
+typedef struct {
+
+  uintptr_t PC, PCFlags;
+
+} PCTableEntry;
+
+afl_module_info_t *__afl_module_info = NULL;
+
+u32        __afl_pcmap_size = 0;
+uintptr_t *__afl_pcmap_ptr = NULL;
+#endif  // __AFL_CODE_COVERAGE
+
 /* 1 if we are running in afl, and the forkserver was started, else 0 */
 u32 __afl_connected = 0;
 
@@ -499,6 +547,7 @@ static void __afl_map_shm(void) {
              u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
              if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
 
+               fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
                send_forkserver_error(FS_ERROR_MAP_SIZE);
                _exit(1);
 
@@ -678,6 +727,27 @@ static void __afl_map_shm(void) {
 
   }
 
+#ifdef __AFL_CODE_COVERAGE
+  char *pcmap_id_str = getenv("__AFL_PCMAP_SHM_ID");
+
+  if (pcmap_id_str) {
+
+    __afl_pcmap_size = __afl_map_size * sizeof(void *);
+    u32 shm_id = atoi(pcmap_id_str);
+
+    __afl_pcmap_ptr = (uintptr_t *)shmat(shm_id, NULL, 0);
+
+    if (__afl_debug) {
+
+      fprintf(stderr, "DEBUG: Received %p via shmat for pcmap\n",
+              __afl_pcmap_ptr);
+
+    }
+
+  }
+
+#endif  // __AFL_CODE_COVERAGE
+
 }
 
 /* unmap SHM. */
@@ -686,6 +756,17 @@ static void __afl_unmap_shm(void) {
 
   if (!__afl_already_initialized_shm) return;
 
+#ifdef __AFL_CODE_COVERAGE
+  if (__afl_pcmap_size) {
+
+    shmdt((void *)__afl_pcmap_ptr);
+    __afl_pcmap_ptr = NULL;
+    __afl_pcmap_size = 0;
+
+  }
+
+#endif  // __AFL_CODE_COVERAGE
+
   char *id_str = getenv(SHM_ENV_VAR);
 
   if (id_str) {
@@ -1507,6 +1588,102 @@ void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
 
 }
 
+#ifdef __AFL_CODE_COVERAGE
+void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
+                              const uintptr_t *pcs_end) {
+
+  if (__afl_debug) {
+
+    fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init called\n");
+
+  }
+
+  // If for whatever reason, we cannot get dlinfo here, then pc_guard_init also
+  // couldn't get it and we'd end up attributing to the wrong module.
+  Dl_info dlinfo;
+  if (!dladdr(__builtin_return_address(0), &dlinfo)) {
+
+    fprintf(stderr,
+            "WARNING: Ignoring __sanitizer_cov_pcs_init callback due to "
+            "missing module info\n");
+    return;
+
+  }
+
+  afl_module_info_t *last_module_info = __afl_module_info;
+  while (last_module_info && last_module_info->next) {
+
+    last_module_info = last_module_info->next;
+
+  }
+
+  if (!last_module_info) {
+
+    fprintf(stderr,
+            "ERROR: __sanitizer_cov_pcs_init called with no module info?!\n");
+    abort();
+
+  }
+
+  last_module_info->pcs_beg = pcs_beg;
+  last_module_info->pcs_end = pcs_end;
+
+  // Now update the pcmap. If this is the last module coming in, after all
+  // pre-loaded code, then this will also map all of our delayed previous
+  // modules.
+
+  if (!__afl_pcmap_ptr) { return; }
+
+  for (afl_module_info_t *mod_info = __afl_module_info; mod_info;
+       mod_info = mod_info->next) {
+
+    if (mod_info->mapped) { continue; }
+
+    PCTableEntry *start = (PCTableEntry *)(mod_info->pcs_beg);
+    PCTableEntry *end = (PCTableEntry *)(mod_info->pcs_end);
+
+    u32 in_module_index = 0;
+
+    while (start < end) {
+
+      if (mod_info->start + in_module_index >= __afl_map_size) {
+
+        fprintf(stderr, "ERROR: __sanitizer_cov_pcs_init out of bounds?!\n");
+        abort();
+
+      }
+
+      uintptr_t PC = start->PC;
+
+      // This is what `GetPreviousInstructionPc` in sanitizer runtime does
+      // for x86/x86-64. Needs more work for ARM and other archs.
+      PC = PC - 1;
+
+      // Calculate relative offset in module
+      PC = PC - mod_info->base_address;
+
+      __afl_pcmap_ptr[mod_info->start + in_module_index] = PC;
+
+      start++;
+      in_module_index++;
+
+    }
+
+    mod_info->mapped = 1;
+
+    if (__afl_debug) {
+
+      fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init initialized %u PCs\n",
+              in_module_index);
+
+    }
+
+  }
+
+}
+
+#endif  // __AFL_CODE_COVERAGE
+
 /* Init callback. Populates instrumentation IDs. Note that we're using
    ID of 0 as a special value to indicate non-instrumented bits. That may
    still touch the bitmap, but in a fairly harmless way. */
@@ -1538,6 +1715,62 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
 
   if (start == stop || *start) { return; }
 
+#ifdef __AFL_CODE_COVERAGE
+  u32               *orig_start = start;
+  afl_module_info_t *mod_info = NULL;
+
+  Dl_info dlinfo;
+  if (dladdr(__builtin_return_address(0), &dlinfo)) {
+
+    if (__afl_already_initialized_forkserver) {
+
+      fprintf(stderr, "[pcmap] Error: Module was not preloaded: %s\n",
+              dlinfo.dli_fname);
+
+    } else {
+
+      afl_module_info_t *last_module_info = __afl_module_info;
+      while (last_module_info && last_module_info->next) {
+
+        last_module_info = last_module_info->next;
+
+      }
+
+      mod_info = malloc(sizeof(afl_module_info_t));
+
+      mod_info->id = last_module_info ? last_module_info->id + 1 : 0;
+      mod_info->name = strdup(dlinfo.dli_fname);
+      mod_info->base_address = (uintptr_t)dlinfo.dli_fbase;
+      mod_info->start = 0;
+      mod_info->stop = 0;
+      mod_info->pcs_beg = NULL;
+      mod_info->pcs_end = NULL;
+      mod_info->mapped = 0;
+      mod_info->next = NULL;
+
+      if (last_module_info) {
+
+        last_module_info->next = mod_info;
+
+      } else {
+
+        __afl_module_info = mod_info;
+
+      }
+
+      fprintf(stderr, "[pcmap] Module: %s Base Address: %p\n", dlinfo.dli_fname,
+              dlinfo.dli_fbase);
+
+    }
+
+  } else {
+
+    fprintf(stderr, "[pcmap] dladdr call failed\n");
+
+  }
+
+#endif  // __AFL_CODE_COVERAGE
+
   x = getenv("AFL_INST_RATIO");
   if (x) {
 
@@ -1625,6 +1858,22 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
 
   }
 
+#ifdef __AFL_CODE_COVERAGE
+  if (mod_info) {
+
+    mod_info->start = *orig_start;
+    mod_info->stop = *(stop - 1);
+    if (__afl_debug) {
+
+      fprintf(stderr, "DEBUG: [pcmap] Start Index: %u Stop Index: %u\n",
+              mod_info->start, mod_info->stop);
+
+    }
+
+  }
+
+#endif  // __AFL_CODE_COVERAGE
+
   if (__afl_debug) {
 
     fprintf(stderr,
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index 5d82aa25..7f17b02d 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -584,7 +584,7 @@ bool isInInstrumentList(llvm::Function *F, std::string Filename) {
 }
 
 // Calculate the number of average collisions that would occur if all
-// location IDs would be assigned randomly (like normal afl/afl++).
+// location IDs would be assigned randomly (like normal afl/AFL++).
 // This uses the "balls in bins" algorithm.
 unsigned long long int calculateCollisions(uint32_t edges) {
 
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index 97155cd6..8ee13010 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -746,7 +746,7 @@ static void registerAFLdict2filePass(const PassManagerBuilder &,
 }
 
 static RegisterPass<AFLdict2filePass> X("afl-dict2file",
-                                        "afl++ dict2file instrumentation pass",
+                                        "AFL++ dict2file instrumentation pass",
                                         false, false);
 
 static RegisterStandardPasses RegisterAFLdict2filePass(
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index 86b32eec..ed88ec10 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-2da7f08
+c8a72dc
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index fa44d173..44ea5345 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-0569eff8a1
+a1321713c7
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index a064fe58..f59cba78 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -356,7 +356,7 @@ fi
 
 if ! command -v "$CROSS" > /dev/null ; then
   if [ "$CPU_TARGET" = "$(uname -m)" ] ; then
-    echo "[+] Building afl++ qemu support libraries with CC=$CC"
+    echo "[+] Building AFL++ qemu support libraries with CC=$CC"
     echo "[+] Building libcompcov ..."
     make -C libcompcov && echo "[+] libcompcov ready"
     echo "[+] Building unsigaction ..."
@@ -371,7 +371,7 @@ if ! command -v "$CROSS" > /dev/null ; then
     echo "[!] Cross compiler $CROSS could not be found, cannot compile libcompcov libqasan and unsigaction"
   fi
 else
-  echo "[+] Building afl++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\""
+  echo "[+] Building AFL++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\""
   echo "[+] Building libcompcov ..."
   make -C libcompcov CC="$CROSS $CROSS_FLAGS" && echo "[+] libcompcov ready"
   echo "[+] Building unsigaction ..."
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject 0569eff8a12dec73642b96757f6b5b51a618a03
+Subproject a1321713c7502c152dd7527555e0f8a800d5522
diff --git a/src/afl-cc.c b/src/afl-cc.c
index d1001187..972ac8cd 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -31,6 +31,8 @@
 #include <strings.h>
 #include <limits.h>
 #include <assert.h>
+#include <ctype.h>
+#include <sys/stat.h>
 
 #if (LLVM_MAJOR - 0 == 0)
   #undef LLVM_MAJOR
@@ -76,6 +78,7 @@ enum {
   INSTRUMENT_OPT_NGRAM = 16,
   INSTRUMENT_OPT_CALLER = 32,
   INSTRUMENT_OPT_CTX_K = 64,
+  INSTRUMENT_OPT_CODECOV = 128,
 
 };
 
@@ -375,15 +378,304 @@ void parse_fsanitize(char *string) {
 
 }
 
+static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
+          shared_linking = 0, preprocessor_only = 0, have_unroll = 0,
+          have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0,
+          non_dash = 0;
+
+static void process_params(u32 argc, char **argv) {
+
+  if (cc_par_cnt + argc >= 1024) { FATAL("Too many command line parameters"); }
+
+  if (lto_mode && argc > 1) {
+
+    u32 idx;
+    for (idx = 1; idx < argc; idx++) {
+
+      if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
+
+    }
+
+  }
+
+  // for (u32 x = 0; x < argc; ++x) fprintf(stderr, "[%u] %s\n", x, argv[x]);
+
+  /* Process the argument list. */
+
+  u8 skip_next = 0;
+  while (--argc) {
+
+    u8 *cur = *(++argv);
+
+    if (skip_next) {
+
+      skip_next = 0;
+      continue;
+
+    }
+
+    if (cur[0] != '-') { non_dash = 1; }
+    if (!strncmp(cur, "--afl", 5)) continue;
+
+    if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
+
+      FATAL(
+          "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
+          "use afl-clang-fast!");
+
+    }
+
+    if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
+    if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
+    if (!strncmp(cur, "-fno-unroll", 11)) continue;
+    if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
+    if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
+        !strcmp(cur, "--no-undefined")) {
+
+      continue;
+
+    }
+
+    if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
+
+    if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
+
+      u8 *param = *(argv + 1);
+      if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
+
+        skip_next = 1;
+        continue;
+
+      }
+
+    }
+
+    if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
+        !strncmp(cur, "-stdlib=", 8)) {
+
+      if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
+      continue;
+
+    }
+
+    if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
+
+      have_instr_list = 1;
+
+    }
+
+    if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
+        strchr(cur, ',')) {
+
+      parse_fsanitize(cur);
+      if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
+
+    } else if ((!strncmp(cur, "-fsanitize=fuzzer-",
+
+                         strlen("-fsanitize=fuzzer-")) ||
+                !strncmp(cur, "-fsanitize-coverage",
+                         strlen("-fsanitize-coverage"))) &&
+               (strncmp(cur, "sanitize-coverage-allow",
+                        strlen("sanitize-coverage-allow")) &&
+                strncmp(cur, "sanitize-coverage-deny",
+                        strlen("sanitize-coverage-deny")) &&
+                instrument_mode != INSTRUMENT_LLVMNATIVE)) {
+
+      if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
+      continue;
+
+    }
+
+    if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
+
+      u8 *afllib = find_object("libAFLDriver.a", argv[0]);
+
+      if (!be_quiet) {
+
+        OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
+
+      }
+
+      if (!afllib) {
+
+        if (!be_quiet) {
+
+          WARNF(
+              "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
+              "the flags - this will fail!");
+
+        }
+
+      } else {
+
+        cc_params[cc_par_cnt++] = afllib;
+
+#ifdef __APPLE__
+        cc_params[cc_par_cnt++] = "-undefined";
+        cc_params[cc_par_cnt++] = "dynamic_lookup";
+#endif
+
+      }
+
+      if (need_aflpplib) {
+
+        need_aflpplib = 0;
+
+      } else {
+
+        continue;
+
+      }
+
+    }
+
+    if (!strcmp(cur, "-m32")) bit_mode = 32;
+    if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
+    if (!strcmp(cur, "-m64")) bit_mode = 64;
+
+    if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
+      asan_set = 1;
+
+    if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
+
+    if (!strcmp(cur, "-x")) x_set = 1;
+    if (!strcmp(cur, "-E")) preprocessor_only = 1;
+    if (!strcmp(cur, "-shared")) shared_linking = 1;
+    if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
+    if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
+    if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
+    if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
+    if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
+    if (!strcmp(cur, "-r")) partial_linking = 1;
+    if (!strcmp(cur, "--relocatable")) partial_linking = 1;
+    if (!strcmp(cur, "-c")) have_c = 1;
+
+    if (!strncmp(cur, "-O", 2)) have_o = 1;
+    if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
+
+    if (*cur == '@') {
+
+      // response file support.
+      // we have two choices - move everything to the command line or
+      // rewrite the response files to temporary files and delete them
+      // afterwards. We choose the first for easiness.
+      // We do *not* support quotes in the rsp files to cope with spaces in
+      // filenames etc! If you need that then send a patch!
+      u8 *filename = cur + 1;
+      if (debug) { DEBUGF("response file=%s\n", filename); }
+      FILE       *f = fopen(filename, "r");
+      struct stat st;
+
+      // Check not found or empty? let the compiler complain if so.
+      if (!f || fstat(fileno(f), &st) < 0 || st.st_size < 1) {
+
+        cc_params[cc_par_cnt++] = cur;
+        continue;
+
+      }
+
+      u8    *tmpbuf = malloc(st.st_size + 1), *ptr;
+      char **args = malloc(sizeof(char *) * (st.st_size >> 1));
+      int    count = 1, cont = 0, cont_act = 0;
+
+      while (fgets(tmpbuf, st.st_size, f)) {
+
+        ptr = tmpbuf;
+        // no leading whitespace
+        while (isspace(*ptr)) {
+
+          ++ptr;
+          cont_act = 0;
+
+        }
+
+        // no comments, no empty lines
+        if (*ptr == '#' || *ptr == '\n' || !*ptr) { continue; }
+        // remove LF
+        if (ptr[strlen(ptr) - 1] == '\n') { ptr[strlen(ptr) - 1] = 0; }
+        // remove CR
+        if (*ptr && ptr[strlen(ptr) - 1] == '\r') { ptr[strlen(ptr) - 1] = 0; }
+        // handle \ at end of line
+        if (*ptr && ptr[strlen(ptr) - 1] == '\\') {
+
+          cont = 1;
+          ptr[strlen(ptr) - 1] = 0;
+
+        }
+
+        // remove whitespace at end
+        while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
+
+          ptr[strlen(ptr) - 1] = 0;
+          cont = 0;
+
+        }
+
+        if (*ptr) {
+
+          do {
+
+            u8 *value = ptr;
+            while (*ptr && !isspace(*ptr)) {
+
+              ++ptr;
+
+            }
+
+            while (*ptr && isspace(*ptr)) {
+
+              *ptr++ = 0;
+
+            }
+
+            if (cont_act) {
+
+              u32 len = strlen(args[count - 1]) + strlen(value) + 1;
+              u8 *tmp = malloc(len);
+              snprintf(tmp, len, "%s%s", args[count - 1], value);
+              free(args[count - 1]);
+              args[count - 1] = tmp;
+              cont_act = 0;
+
+            } else {
+
+              args[count++] = strdup(value);
+
+            }
+
+          } while (*ptr);
+
+        }
+
+        if (cont) {
+
+          cont_act = 1;
+          cont = 0;
+
+        }
+
+      }
+
+      if (count) { process_params(count, args); }
+
+      // we cannot free args[]
+      free(tmpbuf);
+
+      continue;
+
+    }
+
+    cc_params[cc_par_cnt++] = cur;
+
+  }
+
+}
+
 /* Copy argv to cc_params, making the necessary edits. */
 
 static void edit_params(u32 argc, char **argv, char **envp) {
 
-  u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0,
-     preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0,
-     have_c = 0, partial_linking = 0;
-
-  cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
+  cc_params = ck_alloc(1024 * sizeof(u8 *));
 
   if (lto_mode) {
 
@@ -642,7 +934,7 @@ 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 the old pass manager in LLVM 14 which the AFL++ passes still
     //    use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
     //#endif
 
@@ -751,7 +1043,21 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       } else if (instrument_mode == INSTRUMENT_LLVMNATIVE) {
 
 #if LLVM_MAJOR >= 4
-        cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+        if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
+
+  #if LLVM_MAJOR >= 6
+          cc_params[cc_par_cnt++] =
+              "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
+  #else
+          FATAL("pcguard instrumentation with pc-table requires llvm 6.0.1+");
+  #endif
+
+        } else {
+
+          cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+
+        }
+
 #else
         FATAL("pcguard instrumentation requires llvm 4.0.1+");
 #endif
@@ -816,159 +1122,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       }
 
-      if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC";
-
     }
 
   }
 
-  /* Detect stray -v calls from ./configure scripts. */
-
-  u8 skip_next = 0, non_dash = 0;
-  while (--argc) {
-
-    u8 *cur = *(++argv);
-
-    if (skip_next) {
-
-      skip_next = 0;
-      continue;
-
-    }
-
-    if (cur[0] != '-') { non_dash = 1; }
-    if (!strncmp(cur, "--afl", 5)) continue;
-    if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
-    if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
-    if (!strncmp(cur, "-fno-unroll", 11)) continue;
-    if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
-    if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
-        !strcmp(cur, "--no-undefined")) {
-
-      continue;
-
-    }
-
-    if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
-
-    if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
-
-      u8 *param = *(argv + 1);
-      if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
-
-        skip_next = 1;
-        continue;
-
-      }
-
-    }
-
-    if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
-        !strncmp(cur, "-stdlib=", 8)) {
-
-      if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
-      continue;
-
-    }
-
-    if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
-
-      have_instr_list = 1;
-
-    }
-
-    if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
-        strchr(cur, ',')) {
-
-      parse_fsanitize(cur);
-      if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
-
-    } else if ((!strncmp(cur, "-fsanitize=fuzzer-",
-
-                         strlen("-fsanitize=fuzzer-")) ||
-                !strncmp(cur, "-fsanitize-coverage",
-                         strlen("-fsanitize-coverage"))) &&
-               (strncmp(cur, "sanitize-coverage-allow",
-                        strlen("sanitize-coverage-allow")) &&
-                strncmp(cur, "sanitize-coverage-deny",
-                        strlen("sanitize-coverage-deny")) &&
-                instrument_mode != INSTRUMENT_LLVMNATIVE)) {
-
-      if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
-      continue;
-
-    }
-
-    if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
-
-      u8 *afllib = find_object("libAFLDriver.a", argv[0]);
-
-      if (!be_quiet) {
-
-        OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
-
-      }
-
-      if (!afllib) {
-
-        if (!be_quiet) {
-
-          WARNF(
-              "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
-              "the flags - this will fail!");
-
-        }
-
-      } else {
-
-        cc_params[cc_par_cnt++] = afllib;
-
-#ifdef __APPLE__
-        cc_params[cc_par_cnt++] = "-undefined";
-        cc_params[cc_par_cnt++] = "dynamic_lookup";
-#endif
-
-      }
-
-      if (need_aflpplib) {
-
-        need_aflpplib = 0;
-
-      } else {
-
-        continue;
-
-      }
+  /* Inspect the command line parameters. */
 
-    }
+  process_params(argc, argv);
 
-    if (!strcmp(cur, "-m32")) bit_mode = 32;
-    if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
-    if (!strcmp(cur, "-m64")) bit_mode = 64;
-
-    if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
-      asan_set = 1;
-
-    if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
-
-    if (!strcmp(cur, "-x")) x_set = 1;
-    if (!strcmp(cur, "-E")) preprocessor_only = 1;
-    if (!strcmp(cur, "-shared")) shared_linking = 1;
-    if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
-    if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
-    if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
-    if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
-    if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
-    if (!strcmp(cur, "-r")) partial_linking = 1;
-    if (!strcmp(cur, "--relocatable")) partial_linking = 1;
-    if (!strcmp(cur, "-c")) have_c = 1;
-
-    if (!strncmp(cur, "-O", 2)) have_o = 1;
-    if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
-
-    cc_params[cc_par_cnt++] = cur;
-
-  }
+  if (!have_pic) { cc_params[cc_par_cnt++] = "-fPIC"; }
 
   // in case LLVM is installed not via a package manager or "make install"
   // e.g. compiled download or compiled from github then its ./lib directory
@@ -1651,13 +1813,17 @@ int main(int argc, char **argv, char **envp) {
           instrument_mode = INSTRUMENT_CLASSIC;
           lto_mode = 1;
 
-        } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL)
+        } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) {
 
           instrument_mode = INSTRUMENT_AFL;
-        else
+
+        } else {
+
           FATAL("main instrumentation mode already set with %s",
                 instrument_mode_string[instrument_mode]);
 
+        }
+
       }
 
       if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
@@ -1682,6 +1848,23 @@ int main(int argc, char **argv, char **envp) {
 
       }
 
+      if (strncasecmp(ptr2, "llvmcodecov", strlen("llvmcodecov")) == 0 ||
+          strncasecmp(ptr2, "llvm-codecov", strlen("llvm-codecov")) == 0) {
+
+        if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) {
+
+          instrument_mode = INSTRUMENT_LLVMNATIVE;
+          instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
+
+        } else {
+
+          FATAL("main instrumentation mode already set with %s",
+                instrument_mode_string[instrument_mode]);
+
+        }
+
+      }
+
       if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
           strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) {
 
@@ -2241,7 +2424,8 @@ int main(int argc, char **argv, char **envp) {
         "(requires LLVM 11 or higher)");
 #endif
 
-  if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC)
+  if (instrument_opt_mode && instrument_opt_mode != INSTRUMENT_OPT_CODECOV &&
+      instrument_mode != INSTRUMENT_CLASSIC)
     FATAL(
         "CALLER, CTX and NGRAM instrumentation options can only be used with "
         "the LLVM CLASSIC instrumentation mode.");
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index aa8c8622..30c8901c 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -489,7 +489,7 @@ static void report_error_and_exit(int error) {
       break;
     case FS_ERROR_OLD_CMPLOG:
       FATAL(
-          "the -c cmplog target was instrumented with an too old afl++ "
+          "the -c cmplog target was instrumented with an too old AFL++ "
           "version, you need to recompile it.");
       break;
     case FS_ERROR_OLD_CMPLOG_QEMU:
@@ -987,7 +987,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
 
-      // workaround for recent afl++ versions
+      // workaround for recent AFL++ versions
       if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
         status = (status & 0xf0ffffff);
 
@@ -1059,7 +1059,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
           FATAL(
               "Target's coverage map size of %u is larger than the one this "
-              "afl++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
+              "AFL++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
               " afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile "
               "afl-fuzz",
               tmp_map_size, fsrv->map_size, tmp_map_size);
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index bd591c8f..baf56a5f 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -716,6 +716,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
 
   }
 
+  // if (getenv("MYTEST")) afl->in_place_resume = 1;
+
   if (nl_cnt) {
 
     u32 done = 0;
@@ -827,6 +829,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
 
   }
 
+  // if (getenv("MYTEST")) afl->in_place_resume = 0;
+
   free(nl);                                                  /* not tracked */
 
   if (!afl->queued_items && directory == NULL) {
@@ -908,8 +912,10 @@ void perform_dry_run(afl_state_t *afl) {
 
     if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) {
 
-      SAYF(cGRA "    len = %u, map size = %u, exec speed = %llu us\n" cRST,
-           q->len, q->bitmap_size, q->exec_us);
+      SAYF(cGRA
+           "    len = %u, map size = %u, exec speed = %llu us, hash = "
+           "%016llx\n" cRST,
+           q->len, q->bitmap_size, q->exec_us, q->exec_cksum);
 
     }
 
@@ -1164,14 +1170,14 @@ void perform_dry_run(afl_state_t *afl) {
 
   u32 duplicates = 0, i;
 
-  for (idx = 0; idx < afl->queued_items; idx++) {
+  for (idx = 0; idx < afl->queued_items - 1; idx++) {
 
     q = afl->queue_buf[idx];
     if (!q || q->disabled || q->cal_failed || !q->exec_cksum) { continue; }
-
     u32 done = 0;
+
     for (i = idx + 1;
-         i < afl->queued_items && !done && likely(afl->queue_buf[i]); i++) {
+         likely(i < afl->queued_items && afl->queue_buf[i] && !done); ++i) {
 
       struct queue_entry *p = afl->queue_buf[i];
       if (p->disabled || p->cal_failed || !p->exec_cksum) { continue; }
@@ -1194,6 +1200,13 @@ void perform_dry_run(afl_state_t *afl) {
           p->disabled = 1;
           p->perf_score = 0;
 
+          if (afl->debug) {
+
+            WARNF("Same coverage - %s is kept active, %s is disabled.",
+                  q->fname, p->fname);
+
+          }
+
         } else {
 
           if (!q->was_fuzzed) {
@@ -1207,7 +1220,14 @@ void perform_dry_run(afl_state_t *afl) {
           q->disabled = 1;
           q->perf_score = 0;
 
-          done = 1;
+          if (afl->debug) {
+
+            WARNF("Same coverage - %s is kept active, %s is disabled.",
+                  p->fname, q->fname);
+
+          }
+
+          done = 1;  // end inner loop because outer loop entry is disabled now
 
         }
 
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index ee562f96..c6e9a295 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -842,6 +842,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
 
   eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
   if (unlikely(!eff_map)) { PFATAL("alloc"); }
+  memset(eff_map, 0, EFF_ALEN(len));
   eff_map[0] = 1;
 
   if (EFF_APOS(len - 1) != 0) {
@@ -2047,20 +2048,22 @@ custom_mutator_stage:
   afl->queue_cur->stats_mutated += afl->stage_max;
 #endif
 
-  if (likely(afl->custom_only)) {
+  /****************
+   * RANDOM HAVOC *
+   ****************/
+
+havoc_stage:
+
+  if (unlikely(afl->custom_only)) {
 
+    /* Force UI update */
+    show_stats(afl);
     /* Skip other stages */
     ret_val = 0;
     goto abandon_entry;
 
   }
 
-  /****************
-   * RANDOM HAVOC *
-   ****************/
-
-havoc_stage:
-
   afl->stage_cur_byte = -1;
 
   /* The havoc stage mutation code is also invoked when splicing files; if the
@@ -3570,6 +3573,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
   eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
   if (unlikely(!eff_map)) { PFATAL("alloc"); }
+  memset(eff_map, 0, EFF_ALEN(len));
   eff_map[0] = 1;
 
   if (EFF_APOS(len - 1) != 0) {
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 8ad7cd97..b10bf749 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -49,11 +49,13 @@ inline u32 select_next_queue_entry(afl_state_t *afl) {
 
   u32    s = rand_below(afl, afl->queued_items);
   double p = rand_next_percent(afl);
+
   /*
   fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u"
   " ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p <
   afl->alias_probability[s] ? s : afl->alias_table[s]);
   */
+
   return (p < afl->alias_probability[s] ? s : afl->alias_table[s]);
 
 }
@@ -87,25 +89,28 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q,
 
 void create_alias_table(afl_state_t *afl) {
 
-  u32    n = afl->queued_items, i = 0, a, g;
+  u32    n = afl->queued_items, i = 0, nSmall = 0, nLarge = n - 1;
   double sum = 0;
 
+  double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
+  u32 *Small = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
+  u32 *Large = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
+
   afl->alias_table =
       (u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32));
   afl->alias_probability = (double *)afl_realloc(
       (void **)&afl->alias_probability, n * sizeof(double));
-  double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
-  int    *S = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
-  int    *L = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
 
-  if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) {
+  if (!P || !Small || !Large || !afl->alias_table || !afl->alias_probability) {
 
     FATAL("could not acquire memory for alias table");
 
   }
 
-  memset((void *)afl->alias_table, 0, n * sizeof(u32));
   memset((void *)afl->alias_probability, 0, n * sizeof(double));
+  memset((void *)afl->alias_table, 0, n * sizeof(u32));
+  memset((void *)Small, 0, n * sizeof(u32));
+  memset((void *)Large, 0, n * sizeof(u32));
 
   if (likely(afl->schedule < RARE)) {
 
@@ -166,7 +171,15 @@ void create_alias_table(afl_state_t *afl) {
     for (i = 0; i < n; i++) {
 
       // weight is always 0 for disabled entries
-      P[i] = (afl->queue_buf[i]->weight * n) / sum;
+      if (unlikely(afl->queue_buf[i]->disabled)) {
+
+        P[i] = 0;
+
+      } else {
+
+        P[i] = (afl->queue_buf[i]->weight * n) / sum;
+
+      }
 
     }
 
@@ -176,60 +189,81 @@ void create_alias_table(afl_state_t *afl) {
 
       struct queue_entry *q = afl->queue_buf[i];
 
-      if (likely(!q->disabled)) { q->perf_score = calculate_score(afl, q); }
+      if (likely(!q->disabled)) {
+
+        q->perf_score = calculate_score(afl, q);
+        sum += q->perf_score;
 
-      sum += q->perf_score;
+      }
 
     }
 
     for (i = 0; i < n; i++) {
 
       // perf_score is always 0 for disabled entries
-      P[i] = (afl->queue_buf[i]->perf_score * n) / sum;
+      if (unlikely(afl->queue_buf[i]->disabled)) {
+
+        P[i] = 0;
+
+      } else {
+
+        P[i] = (afl->queue_buf[i]->perf_score * n) / sum;
+
+      }
 
     }
 
   }
 
-  int nS = 0, nL = 0, s;
-  for (s = (s32)n - 1; s >= 0; --s) {
+  // Done collecting weightings in P, now create the arrays.
+
+  for (s32 j = (s32)(n - 1); j >= 0; j--) {
 
-    if (P[s] < 1) {
+    if (P[j] < 1) {
 
-      S[nS++] = s;
+      Small[nSmall++] = (u32)j;
 
     } else {
 
-      L[nL++] = s;
+      Large[nLarge--] = (u32)j;
 
     }
 
   }
 
-  while (nS && nL) {
+  while (nSmall && nLarge != n - 1) {
+
+    u32 small = Small[--nSmall];
+    u32 large = Large[++nLarge];
+
+    afl->alias_probability[small] = P[small];
+    afl->alias_table[small] = large;
 
-    a = S[--nS];
-    g = L[--nL];
-    afl->alias_probability[a] = P[a];
-    afl->alias_table[a] = g;
-    P[g] = P[g] + P[a] - 1;
-    if (P[g] < 1) {
+    P[large] = P[large] - (1 - P[small]);
 
-      S[nS++] = g;
+    if (P[large] < 1) {
+
+      Small[nSmall++] = large;
 
     } else {
 
-      L[nL++] = g;
+      Large[nLarge--] = large;
 
     }
 
   }
 
-  while (nL)
-    afl->alias_probability[L[--nL]] = 1;
+  while (nSmall) {
+
+    afl->alias_probability[Small[--nSmall]] = 1;
+
+  }
 
-  while (nS)
-    afl->alias_probability[S[--nS]] = 1;
+  while (nLarge != n - 1) {
+
+    afl->alias_probability[Large[++nLarge]] = 1;
+
+  }
 
   afl->reinit_table = 0;
 
@@ -264,7 +298,7 @@ void create_alias_table(afl_state_t *afl) {
   */
   /*
   fprintf(stderr, "  entry  alias  probability  perf_score   weight
-  filename\n"); for (u32 i = 0; i < n; ++i) fprintf(stderr, "  %5u  %5u  %11u
+  filename\n"); for (i = 0; i < n; ++i) fprintf(stderr, "  %5u  %5u  %11u
   %0.9f  %0.9f  %s\n", i, afl->alias_table[i], afl->alias_probability[i],
   afl->queue_buf[i]->perf_score, afl->queue_buf[i]->weight,
             afl->queue_buf[i]->fname);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 71d2afd8..4339ddd2 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -124,7 +124,8 @@ static void usage(u8 *argv0, int more_help) {
       "\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
 
       "Required parameters:\n"
-      "  -i dir        - input directory with test cases\n"
+      "  -i dir        - input directory with test cases (or '-' to resume, "
+      "also see AFL_AUTORESUME)\n"
       "  -o dir        - output directory for fuzzer findings\n\n"
 
       "Execution control settings:\n"
@@ -1280,16 +1281,16 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
 
-  OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
-      "Eißfeldt, Andrea Fioraldi and Dominik Maier");
-  OKF("afl++ is open source, get it at "
+  OKF("AFL++ is maintained by Marc \"van Hauser\" Heuse, Dominik Maier, Andrea "
+      "Fioraldi and Heiko \"hexcoder\" Eißfeldt");
+  OKF("AFL++ is open source, get it at "
       "https://github.com/AFLplusplus/AFLplusplus");
-  OKF("NOTE: afl++ >= v3 has changed defaults and behaviours - see README.md");
+  OKF("NOTE: AFL++ >= v3 has changed defaults and behaviours - see README.md");
 
   #ifdef __linux__
   if (afl->fsrv.nyx_mode) {
 
-    OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
+    OKF("AFL++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
     OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz");
 
   }
@@ -1529,29 +1530,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
-
-    if (afl->custom_only) {
-
-      FATAL("Custom mutators are incompatible with MOpt (-L)");
-
-    }
-
-    u32 custom_fuzz = 0;
-    LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
-
-      if (el->afl_custom_fuzz) { custom_fuzz = 1; }
-
-    });
-
-    if (custom_fuzz) {
-
-      WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
-
-    }
-
-  }
-
   if (afl->afl_env.afl_max_det_extras) {
 
     s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
@@ -1826,8 +1804,76 @@ int main(int argc, char **argv_orig, char **envp) {
     printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
   #endif
 
+  if (!getenv("AFL_CUSTOM_INFO_PROGRAM")) {
+
+    setenv("AFL_CUSTOM_INFO_PROGRAM", argv[optind], 1);
+
+  }
+
+  if (!getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT") && afl->fsrv.out_file) {
+
+    setenv("AFL_CUSTOM_INFO_PROGRAM_INPUT", afl->fsrv.out_file, 1);
+
+  }
+
+  {
+
+    u8 envbuf[8096] = "", tmpbuf[8096] = "";
+    for (s32 i = optind + 1; i < argc; ++i) {
+
+      strcpy(tmpbuf, envbuf);
+      if (strchr(argv[i], ' ') && !strchr(argv[i], '"') &&
+          !strchr(argv[i], '\'')) {
+
+        if (!strchr(argv[i], '\'')) {
+
+          snprintf(envbuf, sizeof(tmpbuf), "%s '%s'", tmpbuf, argv[i]);
+
+        } else {
+
+          snprintf(envbuf, sizeof(tmpbuf), "%s \"%s\"", tmpbuf, argv[i]);
+
+        }
+
+      } else {
+
+        snprintf(envbuf, sizeof(tmpbuf), "%s %s", tmpbuf, argv[i]);
+
+      }
+
+    }
+
+    setenv("AFL_CUSTOM_INFO_PROGRAM_ARGV", envbuf + 1, 1);
+
+  }
+
+  setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1);  // same as __AFL_OUT_DIR
+
   setup_custom_mutators(afl);
 
+  if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
+
+    if (afl->custom_only) {
+
+      FATAL("Custom mutators are incompatible with MOpt (-L)");
+
+    }
+
+    u32 custom_fuzz = 0;
+    LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+      if (el->afl_custom_fuzz) { custom_fuzz = 1; }
+
+    });
+
+    if (custom_fuzz) {
+
+      WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
+
+    }
+
+  }
+
   write_setup_file(afl, argc, argv);
 
   setup_cmdline_file(afl, argv + optind);
@@ -1979,6 +2025,7 @@ int main(int argc, char **argv_orig, char **envp) {
   if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
       afl->fsrv.frida_mode || afl->fsrv.cs_mode || afl->unicorn_mode) {
 
+    u32 old_map_size = map_size;
     map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE;
     afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
     afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size);
@@ -1990,6 +2037,18 @@ int main(int argc, char **argv_orig, char **envp) {
     afl->first_trace = ck_realloc(afl->first_trace, map_size);
     afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size);
 
+    if (old_map_size < map_size) {
+
+      memset(afl->var_bytes + old_map_size, 0, map_size - old_map_size);
+      memset(afl->top_rated + old_map_size, 0, map_size - old_map_size);
+      memset(afl->clean_trace + old_map_size, 0, map_size - old_map_size);
+      memset(afl->clean_trace_custom + old_map_size, 0,
+             map_size - old_map_size);
+      memset(afl->first_trace + old_map_size, 0, map_size - old_map_size);
+      memset(afl->map_tmp_buf + old_map_size, 0, map_size - old_map_size);
+
+    }
+
   }
 
   afl->argv = use_argv;
@@ -2017,6 +2076,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
       OKF("Re-initializing maps to %u bytes", new_map_size);
 
+      u32 old_map_size = map_size;
       afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
       afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
       afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
@@ -2029,6 +2089,18 @@ int main(int argc, char **argv_orig, char **envp) {
       afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
       afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
 
+      if (old_map_size < new_map_size) {
+
+        memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->clean_trace_custom + old_map_size, 0,
+               new_map_size - old_map_size);
+        memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
+
+      }
+
       afl_fsrv_kill(&afl->fsrv);
       afl_shm_deinit(&afl->shm);
       afl->fsrv.map_size = new_map_size;
@@ -2079,6 +2151,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
       OKF("Re-initializing maps to %u bytes due cmplog", new_map_size);
 
+      u32 old_map_size = map_size;
       afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
       afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
       afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
@@ -2091,6 +2164,18 @@ int main(int argc, char **argv_orig, char **envp) {
       afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
       afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
 
+      if (old_map_size < new_map_size) {
+
+        memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->clean_trace_custom + old_map_size, 0,
+               new_map_size - old_map_size);
+        memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
+        memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
+
+      }
+
       afl_fsrv_kill(&afl->fsrv);
       afl_fsrv_kill(&afl->cmplog_fsrv);
       afl_shm_deinit(&afl->shm);
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index 5438bd9f..420dd817 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -2,7 +2,7 @@
   american fuzzy lop++ - wrapper for llvm 11+ lld
   -----------------------------------------------
 
-  Written by Marc Heuse <mh@mh-sec.de> for afl++
+  Written by Marc Heuse <mh@mh-sec.de> for AFL++
 
   Maintained by Marc Heuse <mh@mh-sec.de>,
                 Heiko Eißfeldt <heiko.eissfeldt@hexco.de>
@@ -210,7 +210,7 @@ static void edit_params(int argc, char **argv) {
 
     if (strcmp(argv[i], "--afl") == 0) {
 
-      if (!be_quiet) OKF("afl++ test command line flag detected, exiting.");
+      if (!be_quiet) OKF("AFL++ test command line flag detected, exiting.");
       exit(0);
 
     }
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index d0e01cb1..9c029035 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1287,7 +1287,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
         break;
 
-      case 'Y':  // fallthough
+      case 'Y':  // fallthrough
 #ifdef __linux__
       case 'X':                                                 /* NYX mode */
 
@@ -1421,6 +1421,14 @@ int main(int argc, char **argv_orig, char **envp) {
     // If @@ are in the target args, replace them and also set use_stdin=false.
     detect_file_args(argv + optind, stdin_file, &fsrv->use_stdin);
 
+    fsrv->dev_null_fd = open("/dev/null", O_RDWR);
+    if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
+
+    fsrv->out_file = stdin_file;
+    fsrv->out_fd =
+        open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+    if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", stdin_file); }
+
   } else {
 
     // If @@ are in the target args, replace them and also set use_stdin=false.
@@ -1588,6 +1596,14 @@ int main(int argc, char **argv_orig, char **envp) {
 
     fsrv->map_size = map_size;
 
+  } else {
+
+    afl_fsrv_start(fsrv, use_argv, &stop_soon,
+                   (get_afl_env("AFL_DEBUG_CHILD") ||
+                    get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
+                       ? 1
+                       : 0);
+
   }
 
   if (in_dir || in_filelist) {
@@ -1617,9 +1633,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
     if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
 
-    fsrv->dev_null_fd = open("/dev/null", O_RDWR);
-    if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
-
     if (in_filelist) {
 
       if (!be_quiet) ACTF("Reading from file list '%s'...", in_filelist);
@@ -1666,10 +1679,6 @@ int main(int argc, char **argv_orig, char **envp) {
     }
 
     atexit(at_exit_handler);
-    fsrv->out_file = stdin_file;
-    fsrv->out_fd =
-        open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
-    if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
 
     if (get_afl_env("AFL_DEBUG")) {
 
@@ -1685,12 +1694,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
     }
 
-    afl_fsrv_start(fsrv, use_argv, &stop_soon,
-                   (get_afl_env("AFL_DEBUG_CHILD") ||
-                    get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
-                       ? 1
-                       : 0);
-
     map_size = fsrv->map_size;
 
     if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
diff --git a/test/test-dlopen.c b/test/test-dlopen.c
index b81bab13..39442f93 100644
--- a/test/test-dlopen.c
+++ b/test/test-dlopen.c
@@ -28,7 +28,7 @@ int main(int argc, char **argv) {
 
   }
 
-  // must use deferred forkserver as otherwise afl++ instrumentation aborts
+  // must use deferred forkserver as otherwise AFL++ instrumentation aborts
   // because all dlopen() of instrumented libs must be before the forkserver
   __AFL_INIT();
 
diff --git a/test/test-gcc-plugin.sh b/test/test-gcc-plugin.sh
index 54e6987f..3690a80a 100755
--- a/test/test-gcc-plugin.sh
+++ b/test/test-gcc-plugin.sh
@@ -23,7 +23,7 @@ test -e ../afl-gcc-fast -a -e ../afl-compiler-rt.o && {
           $ECHO "$GREEN[+] gcc_plugin run reported $TUPLES instrumented locations which is fine"
         } || {
           $ECHO "$RED[!] gcc_plugin instrumentation produces a weird numbers: $TUPLES"
-          $ECHO "$YELLOW[-] this is a known issue in gcc, not afl++. It is not flagged as an error because travis builds would all fail otherwise :-("
+          $ECHO "$YELLOW[-] this is a known issue in gcc, not AFL++. It is not flagged as an error because travis builds would all fail otherwise :-("
           #CODE=1
         }
         test "$TUPLES" -lt 2 && SKIP=1
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 0e66cc97..714bda93 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -263,7 +263,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
     {
       mkdir -p in
       echo 00000000000000000000000000000000 > in/in
-      AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V15 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
+      AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V30 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
     } >>errors 2>&1
     test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && {
       $ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
diff --git a/test/test-performance.sh b/test/test-performance.sh
index d61e2f2a..50957141 100755
--- a/test/test-performance.sh
+++ b/test/test-performance.sh
@@ -7,7 +7,7 @@ FILE=$AFL_PERFORMANCE_FILE
 test -z "$FILE" && FILE=.afl_performance
 
 test -e $FILE || {
-  echo Warning: This script measure the performance of afl++ and saves the result for future comparisons into $FILE
+  echo Warning: This script measure the performance of AFL++ and saves the result for future comparisons into $FILE
   echo Press ENTER to continue or CONTROL-C to abort
   read IN
 }
@@ -74,7 +74,7 @@ afl-system-config > /dev/null 2>&1
 echo Performance settings applied.
 echo
 
-$ECHO "${RESET}${GREY}[*] starting afl++ performance test framework ..."
+$ECHO "${RESET}${GREY}[*] starting AFL++ performance test framework ..."
 
 $ECHO "$BLUE[*] Testing: ${AFL_GCC}"
 GCC=x
diff --git a/test/test-pre.sh b/test/test-pre.sh
index b8b286e5..1ca9dfb5 100755
--- a/test/test-pre.sh
+++ b/test/test-pre.sh
@@ -133,7 +133,7 @@ MEM_LIMIT=none
 
 export PATH="${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
 
-$ECHO "${RESET}${GREY}[*] starting afl++ test framework ..."
+$ECHO "${RESET}${GREY}[*] starting AFL++ test framework ..."
 
 test -z "$SYS" && $ECHO "$YELLOW[-] uname -m did not succeed"
 
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index 53ec2481..d3d16ad5 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -182,7 +182,7 @@ git pull
 sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
 git checkout "$UNICORNAFL_VERSION" || exit 1
 
-echo "[*] making sure afl++ header files match"
+echo "[*] making sure AFL++ header files match"
 cp "../../include/config.h" "./include" || exit 1
 
 echo "[*] Configuring Unicorn build..."