about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile3
-rw-r--r--GNUmakefile.llvm14
-rw-r--r--README.md4
-rwxr-xr-xafl-cmin3
-rw-r--r--docs/Changelog.md10
-rw-r--r--docs/custom_mutators.md6
-rw-r--r--docs/env_variables.md15
-rw-r--r--frida_mode/GNUmakefile59
-rw-r--r--frida_mode/hook/frida_hook.c2
-rw-r--r--frida_mode/src/ctx/ctx_arm32.c2
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c76
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c35
-rw-r--r--frida_mode/src/instrument/instrument_x64.c39
-rw-r--r--frida_mode/src/instrument/instrument_x86.c39
-rw-r--r--frida_mode/src/js/js.c8
-rw-r--r--frida_mode/src/prefetch.c1
-rw-r--r--frida_mode/src/stats/stats_arm32.c1
-rw-r--r--include/afl-fuzz.h4
-rw-r--r--include/common.h18
-rw-r--r--include/config.h2
-rw-r--r--include/envs.h2
-rw-r--r--include/forkserver.h4
-rw-r--r--instrumentation/afl-compiler-rt.o.c1
-rw-r--r--instrumentation/afl-gcc-cmplog-pass.so.cc4
-rw-r--r--instrumentation/afl-gcc-common.h5
-rw-r--r--instrumentation/afl-gcc-pass.so.cc2
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
-rw-r--r--qemu_mode/README.md15
-rw-r--r--qemu_mode/README.persistent.md11
-rwxr-xr-xqemu_mode/build_qemu_support.sh9
-rw-r--r--qemu_mode/fastexit/Makefile30
-rw-r--r--qemu_mode/fastexit/README.md5
-rw-r--r--qemu_mode/fastexit/fastexit.c6
-rw-r--r--qemu_mode/libqasan/malloc.c4
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-analyze.c12
-rw-r--r--src/afl-cc.c24
-rw-r--r--src/afl-common.c55
-rw-r--r--src/afl-forkserver.c18
-rw-r--r--src/afl-fuzz-state.c23
-rw-r--r--src/afl-fuzz-stats.c12
-rw-r--r--src/afl-fuzz.c28
-rw-r--r--src/afl-showmap.c44
-rw-r--r--src/afl-tmin.c14
-rwxr-xr-xtest/test-qemu-mode.sh23
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
m---------unicorn_mode/unicornafl0
-rw-r--r--utils/aflpp_driver/aflpp_driver.c10
-rw-r--r--utils/libdislocator/libdislocator.so.c2
49 files changed, 529 insertions, 179 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 70299fc3..f5f2dcb2 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -425,7 +425,7 @@ test_python:
 	@echo "[+] $(PYTHON_VERSION) support seems to be working."
 else
 test_python:
-	@echo "[-] You seem to need to install the package python3-dev, python2-dev or python-dev (and perhaps python[23]-apt), but it is optional so we continue"
+	@echo "[-] You seem to need to install the package python3-dev or python-dev (and perhaps python[3]-apt), but it is optional so we continue"
 endif
 
 .PHONY: ready
@@ -592,6 +592,7 @@ clean:
 	-$(MAKE) -C utils/argv_fuzzing clean
 	-$(MAKE) -C utils/plot_ui clean
 	-$(MAKE) -C qemu_mode/unsigaction clean
+	-$(MAKE) -C qemu_mode/fastexit clean
 	-$(MAKE) -C qemu_mode/libcompcov clean
 	-$(MAKE) -C qemu_mode/libqasan clean
 	-$(MAKE) -C frida_mode clean
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index c37c4a51..4dc5a56e 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -89,7 +89,6 @@ endif
 ifeq "$(LLVM_HAVE_LTO)" "1"
   $(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation)
   LLVM_LTO = 1
-  #TEST_MMAP = 1
 endif
 
 ifeq "$(LLVM_LTO)" "0"
@@ -214,6 +213,17 @@ ifeq "$(LLVM_LTO)" "1"
     ifeq "$(AFL_REAL_LD)" ""
       ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" ""
         AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld
+      else ifneq "$(shell command -v ld.lld 2>/dev/null)" ""
+        AFL_REAL_LD = $(shell command -v ld.lld)
+        TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | awk '{ print $$2 }')
+        ifeq "$(LLVMVER)" "$(TMP_LDLDD_VERSION)"
+          $(warning ld.lld found in a weird location ($(AFL_REAL_LD)), but its the same version as LLVM so we will allow it)
+        else
+          $(warning ld.lld found in a weird location ($(AFL_REAL_LD)) and its of a different version than LLMV ($(TMP_LDLDD_VERSION) vs. $(LLVMVER)) - cannot enable LTO mode)
+          AFL_REAL_LD=
+          LLVM_LTO = 0
+        endif
+        undefine TMP_LDLDD_VERSION
       else
         $(warning ld.lld not found, cannot enable LTO mode)
         LLVM_LTO = 0
@@ -229,7 +239,7 @@ AFL_CLANG_FUSELD=
 ifeq "$(LLVM_LTO)" "1"
   ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
     AFL_CLANG_FUSELD=1
-    ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=ld.lld --ld-path=$(LLVM_BINDIR)/ld.lld -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+    ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=ld.lld --ld-path=$(AFL_REAL_LD) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
       AFL_CLANG_LDPATH=1
     endif
   else
diff --git a/README.md b/README.md
index 935c71ce..4ff8c514 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
 
 <img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/master/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
 
-Release version: [4.03c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.04c](https://github.com/AFLplusplus/AFLplusplus/releases)
 
-GitHub version: 4.04a
+GitHub version: 4.05a
 
 Repository:
 [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/afl-cmin b/afl-cmin
index 8fe35ced..15b61f89 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -123,6 +123,9 @@ function usage() {
 "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \
 "AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
 "AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \
+"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on termination\n" \
+"                             (default: SIGTERM). If this is not set and AFL_KILL_SIGNAL is set,\n" \
+"                             this will be set to the same value as AFL_KILL_SIGNAL.\n" \
 "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \
 "AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\n" \
 "AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \
diff --git a/docs/Changelog.md b/docs/Changelog.md
index d4dfb709..38e2e6bc 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,16 +3,24 @@
   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.05a (dev)
+  - your PR? :)
 
-### Version ++4.04a (dev)
+
+### Version ++4.04c (release)
   - fix gramatron and grammar_mutator build scripts
   - enhancements to the afl-persistent-config and afl-system-config
     scripts
+  - afl-fuzz:
+    - force writing all stats on exit
+    - ensure targets are killed on exit
+    - `AFL_FORK_SERVER_KILL_SIGNAL` added
   - afl-cc:
     - make gcc_mode (afl-gcc-fast) work with gcc down to version 3.6
   - qemu_mode:
     - fixed 10x speed degredation in v4.03c, thanks to @ele7enxxh for
       reporting!
+    - added qemu_mode/fastexit helper library
   - unicorn_mode:
     - Enabled tricore arch (by @jma-qb)
     - Updated Capstone version in Rust bindings
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 6b72430a..ffd3cce8 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -269,10 +269,10 @@ sudo apt install python-dev
 ```
 
 Then, AFL++ can be compiled with Python support. The AFL++ Makefile detects
-Python 2 and 3 through `python-config` if it is in the PATH and compiles
-`afl-fuzz` with the feature if available.
+Python3 through `python-config`/`python3-config` if it is in the PATH and
+compiles `afl-fuzz` with the feature if available.
 
-Note: for some distributions, you might also need the package `python[23]-apt`.
+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`.
 
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 1abe9438..d1c13e15 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -409,11 +409,22 @@ checks or alter some of the more exotic semantics of the tool:
     the afl-fuzz -g/-G command line option to control the minimum/maximum
     of fuzzing input generated.
 
-  - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on
-    timeout. Unless you implement your own targets or instrumentation, you
+  - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes
+    on timeout. Unless you implement your own targets or instrumentation, you
     likely don't have to set it. By default, on timeout and on exit, `SIGKILL`
     (`AFL_KILL_SIGNAL=9`) will be delivered to the child.
 
+  - `AFL_FORK_SERVER_KILL_SIGNAL`: Set the signal ID to be delivered to the
+    fork server when AFL++ is terminated. Unless you implement your
+    fork server, you likely do not have to set it. By default, `SIGTERM`
+    (`AFL_FORK_SERVER_KILL_SIGNAL=15`) will be delivered to the fork server.
+    If only `AFL_KILL_SIGNAL` is provided, `AFL_FORK_SERVER_KILL_SIGNAL` will
+    be set to same value as `AFL_KILL_SIGNAL` to provide backward compatibility.
+    If `AFL_FORK_SERVER_KILL_SIGNAL` is also set, it takes precedence.
+
+    NOTE: Uncatchable signals, such as `SIGKILL`, cause child processes of
+    the fork server to be orphaned and leaves them in a zombie state.
+
   - `AFL_MAP_SIZE` sets the size of the shared map that afl-analyze, afl-fuzz,
     afl-showmap, and afl-tmin create to gather instrumentation data from the
     target. This must be equal or larger than the size the target was compiled
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index 39c96d5b..9f2bcd42 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -57,7 +57,10 @@ ifdef DEBUG
 CFLAGS+=-Werror \
 		-Wall \
 		-Wextra \
-		-Wpointer-arith
+		-Wpointer-arith \
+		-Wno-unknown-pragmas \
+		-Wno-pointer-to-int-cast \
+		-Wno-int-to-pointer-cast
 else
 CFLAGS+=-Wno-pointer-arith
 endif
@@ -142,7 +145,7 @@ ifndef OS
  $(error "Operating system unsupported")
 endif
 
-GUM_DEVKIT_VERSION=15.2.1
+GUM_DEVKIT_VERSION=16.0.1
 GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz
 GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)"
 
@@ -206,7 +209,7 @@ $(FRIDA_MAKEFILE): | $(BUILD_DIR)
 .PHONY: $(GUM_DEVIT_LIBRARY)
 
 $(GUM_DEVIT_LIBRARY): $(FRIDA_MAKEFILE)
-	cd $(FRIDA_DIR) && make gum-$(OS)$(GUM_ARCH)
+	cd $(FRIDA_DIR) && make gum-$(OS)$(GUM_ARCH) FRIDA_V8=disabled
 
 $(GUM_DEVIT_HEADER): $(FRIDA_MAKEFILE) | $(FRIDA_BUILD_DIR)
 	echo "#include <stdio.h>" > $@
@@ -245,40 +248,40 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
 
 else ifeq "$(ARCH)" "arm64"
 
-CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \
-	    -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
-		-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
-		-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \
-		-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
+CFLAGS+=-I $(FRIDA_DIR)build/$(OS)-$(ARCH)/include/frida-1.0 \
+	    -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
+		-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
+		-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \
+		-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
 
 ifeq "$(OS)" "android"
 CFLAGS += -static-libstdc++
 endif
 else
-CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \
-	    -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
-		-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
-		-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \
-		-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
+CFLAGS+=-I $(FRIDA_DIR)build/$(OS)-$(ARCH)/include/frida-1.0 \
+	    -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
+		-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
+		-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \
+		-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
 
 endif
 
 TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libtcc.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libquickjs.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libcapstone.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libunwind.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libffi.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libdwarf.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libelf.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \
-			   $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libtcc.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libquickjs.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libcapstone.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libunwind.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libffi.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libdwarf.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libelf.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.a \
+			   $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libz.a \
 
 CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \
 	    -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
diff --git a/frida_mode/hook/frida_hook.c b/frida_mode/hook/frida_hook.c
index 79e2348d..da1a59b2 100644
--- a/frida_mode/hook/frida_hook.c
+++ b/frida_mode/hook/frida_hook.c
@@ -54,10 +54,12 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
 
 __attribute__((visibility("default"))) void afl_persistent_hook(
     GumCpuContext *regs, uint8_t *input_buf, uint32_t input_buf_len) {
+
   // do a length check matching the target!
 
   memcpy((void *)regs->r[0], input_buf, input_buf_len);
   regs->r[1] = input_buf_len;
+
 }
 
 #else
diff --git a/frida_mode/src/ctx/ctx_arm32.c b/frida_mode/src/ctx/ctx_arm32.c
index 28fc706b..0e5b25a4 100644
--- a/frida_mode/src/ctx/ctx_arm32.c
+++ b/frida_mode/src/ctx/ctx_arm32.c
@@ -7,6 +7,8 @@
 
 gsize ctx_read_reg(GumArmCpuContext *ctx, arm_reg reg) {
 
+  UNUSED_PARAMETER(ctx);
+  UNUSED_PARAMETER(reg);
   FFATAL("ctx_read_reg unimplemented for this architecture");
 
 }
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index f2e825ee..cb2a322b 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -1,6 +1,7 @@
 #include "frida-gumjs.h"
 
 #include "instrument.h"
+#include "stalker.h"
 #include "util.h"
 
 #if defined(__arm__)
@@ -8,8 +9,9 @@
   #define PAGE_MASK (~(GUM_ADDRESS(0xfff)))
   #define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x))
 
-gboolean instrument_cache_enabled = FALSE;
-gsize    instrument_cache_size = 0;
+gboolean           instrument_cache_enabled = FALSE;
+gsize              instrument_cache_size = 0;
+static GHashTable *coverage_blocks = NULL;
 
 extern __thread guint64 instrument_previous_pc;
 
@@ -22,7 +24,24 @@ typedef struct {
   // shared_mem[cur_location ^ prev_location]++;
   // prev_location = cur_location >> 1;
 
-  /* We can remove this branch when we add support for branch suppression */
+  // str     r0, [sp, #-128] ; 0xffffff80
+  // str     r1, [sp, #-132] ; 0xffffff7c
+  // ldr     r0, [pc, #-20]  ; 0xf691b29c
+  // ldrh    r1, [r0]
+  // movw    r0, #33222      ; 0x81c6
+  // eor     r0, r0, r1
+  // ldr     r1, [pc, #-40]  ; 0xf691b298
+  // add     r1, r1, r0
+  // ldrb    r0, [r1]
+  // add     r0, r0, #1
+  // add     r0, r0, r0, lsr #8
+  // strb    r0, [r1]
+  // movw    r0, #49379      ; 0xc0e3
+  // ldr     r1, [pc, #-64]  ; 0xf691b29c
+  // strh    r0, [r1]
+  // ldr     r1, [sp, #-132] ; 0xffffff7c
+  // ldr     r0, [sp, #-128] ; 0xffffff80
+
   uint32_t  b_code;                                                /* b imm */
   uint8_t  *shared_mem;
   uint64_t *prev_location;
@@ -115,6 +134,46 @@ gboolean instrument_is_coverage_optimize_supported(void) {
 
 }
 
+static void instrument_coverage_switch(GumStalkerObserver *self,
+                                       gpointer            from_address,
+                                       gpointer start_address, void *from_insn,
+                                       gpointer *target) {
+
+  UNUSED_PARAMETER(self);
+  UNUSED_PARAMETER(from_address);
+  UNUSED_PARAMETER(start_address);
+  UNUSED_PARAMETER(from_insn);
+
+  if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) {
+
+    return;
+
+  }
+
+  *target =
+      (guint8 *)*target + G_STRUCT_OFFSET(afl_log_code_asm_t, str_r0_sp_rz);
+
+}
+
+static void instrument_coverage_suppress_init(void) {
+
+  static gboolean initialized = false;
+  if (initialized) { return; }
+  initialized = true;
+
+  GumStalkerObserver          *observer = stalker_get_observer();
+  GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
+  iface->switch_callback = instrument_coverage_switch;
+
+  coverage_blocks = g_hash_table_new(g_direct_hash, g_direct_equal);
+  if (coverage_blocks == NULL) {
+
+    FATAL("Failed to g_hash_table_new, errno: %d", errno);
+
+  }
+
+}
+
 static void patch_t3_insn(uint32_t *insn, uint16_t val) {
 
   uint32_t orig = GUINT32_FROM_LE(*insn);
@@ -135,14 +194,17 @@ void instrument_coverage_optimize(const cs_insn    *instr,
   guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
   gsize   map_size_pow2;
   gsize   area_offset_ror;
-  GumAddress code_addr = 0;
-
-  // gum_arm64_writer_put_brk_imm(cw, 0x0);
 
-  code_addr = cw->pc;
+  instrument_coverage_suppress_init();
 
   block_start = GSIZE_TO_POINTER(GUM_ADDRESS(cw->code));
 
+  if (!g_hash_table_add(coverage_blocks, block_start)) {
+
+    FATAL("Failed - g_hash_table_add");
+
+  }
+
   code.code = template;
 
   g_assert(PAGE_ALIGNED(__afl_area_ptr));
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index 87811b38..c7584a87 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -156,26 +156,47 @@ static gboolean instrument_is_deterministic(const cs_insn *from_insn) {
 
 }
 
+cs_insn *instrument_disassemble(gconstpointer address) {
+
+  csh      capstone;
+  cs_insn *insn = NULL;
+
+  cs_open(CS_ARCH_ARM64, GUM_DEFAULT_CS_ENDIAN, &capstone);
+  cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON);
+
+  cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn);
+
+  cs_close(&capstone);
+
+  return insn;
+
+}
+
 static void instrument_coverage_switch(GumStalkerObserver *self,
                                        gpointer            from_address,
-                                       gpointer            start_address,
-                                       const cs_insn      *from_insn,
-                                       gpointer           *target) {
+                                       gpointer start_address, void *from_insn,
+                                       gpointer *target) {
 
   UNUSED_PARAMETER(self);
   UNUSED_PARAMETER(from_address);
   UNUSED_PARAMETER(start_address);
 
-  gsize fixup_offset;
+  cs_insn *insn = NULL;
+  gboolean deterministic = FALSE;
+  gsize    fixup_offset;
 
   if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target)) &&
-      !g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target + 4))) {
+      !g_hash_table_contains(coverage_blocks,
+                             GSIZE_TO_POINTER((guint8 *)*target + 4))) {
 
     return;
 
   }
 
-  if (instrument_is_deterministic(from_insn)) { return; }
+  insn = instrument_disassemble(from_insn);
+  deterministic = instrument_is_deterministic(insn);
+  cs_free(insn, 1);
+  if (deterministic) { return; }
 
   /*
    * Since each block is prefixed with a restoration prologue, we need to be
@@ -208,7 +229,7 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
    */
   fixup_offset = GUM_RESTORATION_PROLOG_SIZE +
                  G_STRUCT_OFFSET(afl_log_code_asm_t, restoration_prolog);
-  *target += fixup_offset;
+  *target = (guint8 *)*target + fixup_offset;
 
 }
 
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 13ced4a3..f7b7d6c5 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -171,11 +171,11 @@ void instrument_coverage_optimize_init(void) {
 
 }
 
-static void instrument_coverage_switch(GumStalkerObserver *self,
-                                       gpointer            from_address,
-                                       gpointer            start_address,
-                                       const cs_insn      *from_insn,
-                                       gpointer           *target) {
+static void instrument_coverage_switch_insn(GumStalkerObserver *self,
+                                            gpointer            from_address,
+                                            gpointer            start_address,
+                                            const cs_insn      *from_insn,
+                                            gpointer           *target) {
 
   UNUSED_PARAMETER(self);
   UNUSED_PARAMETER(from_address);
@@ -224,6 +224,35 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
 
 }
 
+cs_insn *instrument_disassemble(gconstpointer address) {
+
+  csh      capstone;
+  cs_insn *insn = NULL;
+
+  cs_open(CS_ARCH_X86, GUM_CPU_MODE, &capstone);
+  cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON);
+
+  cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn);
+
+  cs_close(&capstone);
+
+  return insn;
+
+}
+
+static void instrument_coverage_switch(GumStalkerObserver *self,
+                                       gpointer            from_address,
+                                       gpointer start_address, void *from_insn,
+                                       gpointer *target) {
+
+  if (from_insn == NULL) { return; }
+  cs_insn *insn = instrument_disassemble(from_insn);
+  instrument_coverage_switch_insn(self, from_address, start_address, insn,
+                                  target);
+  cs_free(insn, 1);
+
+}
+
 static void instrument_coverage_suppress_init(void) {
 
   static gboolean initialized = false;
diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c
index eabd5be4..f15893cb 100644
--- a/frida_mode/src/instrument/instrument_x86.c
+++ b/frida_mode/src/instrument/instrument_x86.c
@@ -83,11 +83,11 @@ gboolean instrument_is_coverage_optimize_supported(void) {
 
 }
 
-static void instrument_coverage_switch(GumStalkerObserver *self,
-                                       gpointer            from_address,
-                                       gpointer            start_address,
-                                       const cs_insn      *from_insn,
-                                       gpointer           *target) {
+static void instrument_coverage_switch_insn(GumStalkerObserver *self,
+                                            gpointer            from_address,
+                                            gpointer            start_address,
+                                            const cs_insn      *from_insn,
+                                            gpointer           *target) {
 
   UNUSED_PARAMETER(self);
   UNUSED_PARAMETER(from_address);
@@ -130,6 +130,35 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
 
 }
 
+cs_insn *instrument_disassemble(gconstpointer address) {
+
+  csh      capstone;
+  cs_insn *insn = NULL;
+
+  cs_open(CS_ARCH_X86, GUM_CPU_MODE, &capstone);
+  cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON);
+
+  cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn);
+
+  cs_close(&capstone);
+
+  return insn;
+
+}
+
+static void instrument_coverage_switch(GumStalkerObserver *self,
+                                       gpointer            from_address,
+                                       gpointer start_address, void *from_insn,
+                                       gpointer *target) {
+
+  if (from_insn == NULL) { return; }
+  cs_insn *insn = instrument_disassemble(from_insn);
+  instrument_coverage_switch_insn(self, from_address, start_address, insn,
+                                  target);
+  cs_free(insn, 1);
+
+}
+
 static void instrument_coverage_suppress_init(void) {
 
   static gboolean initialized = false;
diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c
index 6bc31864..25187694 100644
--- a/frida_mode/src/js/js.c
+++ b/frida_mode/src/js/js.c
@@ -18,10 +18,8 @@ static GumScriptScheduler *scheduler;
 static GMainContext       *context;
 static GMainLoop          *main_loop;
 
-static void js_msg(GumScript *script, const gchar *message, GBytes *data,
-                   gpointer user_data) {
+static void js_msg(const gchar *message, GBytes *data, gpointer user_data) {
 
-  UNUSED_PARAMETER(script);
   UNUSED_PARAMETER(data);
   UNUSED_PARAMETER(user_data);
   FOKF("%s", message);
@@ -124,8 +122,8 @@ void js_start(void) {
   main_loop = g_main_loop_new(context, true);
   g_main_context_push_thread_default(context);
 
-  gum_script_backend_create(backend, "example", source, cancellable, create_cb,
-                            &error);
+  gum_script_backend_create(backend, "example", source, NULL, cancellable,
+                            create_cb, &error);
 
   while (g_main_context_pending(context))
     g_main_context_iteration(context, FALSE);
diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c
index 905e0ae9..f093cd53 100644
--- a/frida_mode/src/prefetch.c
+++ b/frida_mode/src/prefetch.c
@@ -29,7 +29,6 @@ gboolean prefetch_enable = TRUE;
 gboolean prefetch_backpatch = TRUE;
 
 static prefetch_data_t *prefetch_data = NULL;
-static int              prefetch_shm_id = -1;
 
 static GHashTable *cant_prefetch = NULL;
 
diff --git a/frida_mode/src/stats/stats_arm32.c b/frida_mode/src/stats/stats_arm32.c
index bd652aa3..6c72a476 100644
--- a/frida_mode/src/stats/stats_arm32.c
+++ b/frida_mode/src/stats/stats_arm32.c
@@ -13,6 +13,7 @@ void starts_arch_init(void) {
 
 void stats_write_arch(stats_data_t *data) {
 
+  UNUSED_PARAMETER(data);
   FFATAL("Stats not supported on this architecture");
 
 }
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 23c20cc4..c8ca8e9b 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -393,8 +393,8 @@ typedef struct afl_env_vars {
       *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
       *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
       *afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
-      *afl_testcache_entries, *afl_kill_signal, *afl_target_env,
-      *afl_persistent_record, *afl_exit_on_time;
+      *afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal,
+      *afl_target_env, *afl_persistent_record, *afl_exit_on_time;
 
 } afl_env_vars_t;
 
diff --git a/include/common.h b/include/common.h
index a983bb0e..9d9a948c 100644
--- a/include/common.h
+++ b/include/common.h
@@ -32,6 +32,7 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <stdbool.h>
+#include "forkserver.h"
 #include "types.h"
 
 /* STRINGIFY_VAL_SIZE_MAX will fit all stringify_ strings. */
@@ -67,10 +68,19 @@ u8 *find_binary(u8 *fname);
 
 u8 *find_afl_binary(u8 *own_loc, u8 *fname);
 
-/* Parses the kill signal environment variable, FATALs on error.
-  If the env is not set, sets the env to default_signal for the signal handlers
-  and returns the default_signal. */
-int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal);
+/* Parses the (numeric) kill signal environment variable passed
+   via `numeric_signal_as_str`.
+   If NULL is passed, the `default_signal` value is returned.
+   FATALs if `numeric_signal_as_str` is not a valid integer .*/
+int parse_afl_kill_signal(u8 *numeric_signal_as_str, int default_signal);
+
+/* Configure the signals that are used to kill the forkserver
+   and the forked childs. If `afl_kill_signal_env` or `afl_fsrv_kill_signal_env`
+   is NULL, the appropiate values are read from the environment. */
+void configure_afl_kill_signals(afl_forkserver_t *fsrv,
+                                char             *afl_kill_signal_env,
+                                char             *afl_fsrv_kill_signal_env,
+                                int               default_server_kill_signal);
 
 /* Read a bitmap from file fname to memory
    This is for the -B option again. */
diff --git a/include/config.h b/include/config.h
index 21701515..22c1a162 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.04a"
+#define VERSION "++4.05a"
 
 /******************************************************
  *                                                    *
diff --git a/include/envs.h b/include/envs.h
index 2204a100..68d83f8c 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -42,6 +42,7 @@ static char *afl_environment_variables[] = {
     "AFL_DEBUG",
     "AFL_DEBUG_CHILD",
     "AFL_DEBUG_GDB",
+    "AFL_DEBUG_UNICORN",
     "AFL_DISABLE_TRIM",
     "AFL_DISABLE_LLVM_INSTRUMENTATION",
     "AFL_DONT_OPTIMIZE",
@@ -110,6 +111,7 @@ static char *afl_environment_variables[] = {
     "AFL_INST_RATIO",
     "AFL_KEEP_TIMEOUTS",
     "AFL_KILL_SIGNAL",
+    "AFL_FORK_SERVER_KILL_SIGNAL",
     "AFL_KEEP_TRACES",
     "AFL_KEEP_ASSEMBLY",
     "AFL_LD_HARD_FAIL",
diff --git a/include/forkserver.h b/include/forkserver.h
index 59ce0ee7..a8a7e777 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -163,7 +163,9 @@ typedef struct afl_forkserver {
 
   void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len);
 
-  u8 kill_signal;
+  u8 child_kill_signal;
+  u8 fsrv_kill_signal;
+
   u8 persistent_mode;
 
 #ifdef __linux__
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 9dded1dd..8b743de9 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -162,6 +162,7 @@ static void at_exit(int signal) {
   if (unlikely(child_pid > 0)) {
 
     kill(child_pid, SIGKILL);
+    waitpid(child_pid, NULL, 0);
     child_pid = -1;
 
   }
diff --git a/instrumentation/afl-gcc-cmplog-pass.so.cc b/instrumentation/afl-gcc-cmplog-pass.so.cc
index e42e8bc0..3c781fd7 100644
--- a/instrumentation/afl-gcc-cmplog-pass.so.cc
+++ b/instrumentation/afl-gcc-cmplog-pass.so.cc
@@ -245,7 +245,7 @@ struct afl_cmplog_pass : afl_base_pass {
 
       tree   s = make_ssa_name(t);
       gimple g = gimple_build_assign(s, VIEW_CONVERT_EXPR,
-                                      build1(VIEW_CONVERT_EXPR, t, lhs));
+                                     build1(VIEW_CONVERT_EXPR, t, lhs));
       lhs = s;
       gsi_insert_before(&gsi, g, GSI_SAME_STMT);
 
@@ -281,7 +281,7 @@ struct afl_cmplog_pass : afl_base_pass {
     }
 
     /* Insert the call.  */
-    tree    att = build_int_cst(t8u, attr);
+    tree   att = build_int_cst(t8u, attr);
     gimple call;
     if (pass_n)
       call = gimple_build_call(fn, 4, lhs, rhs, att,
diff --git a/instrumentation/afl-gcc-common.h b/instrumentation/afl-gcc-common.h
index 766c0eff..cda3f9d8 100644
--- a/instrumentation/afl-gcc-common.h
+++ b/instrumentation/afl-gcc-common.h
@@ -501,7 +501,8 @@ struct afl_base_pass : gimple_opt_pass {
 // compatibility for older gcc versions
 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
     60200                                               /* >= version 6.2.0 */
-#define gimple gimple *
+  #define gimple gimple *
 #else
-#define gimple gimple
+  #define gimple gimple
 #endif
+
diff --git a/instrumentation/afl-gcc-pass.so.cc b/instrumentation/afl-gcc-pass.so.cc
index 2b251075..ea938a7f 100644
--- a/instrumentation/afl-gcc-pass.so.cc
+++ b/instrumentation/afl-gcc-pass.so.cc
@@ -127,7 +127,7 @@
 #include "afl-gcc-common.h"
 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
     60200                                               /* >= version 6.2.0 */
-#include "memmodel.h"
+  #include "memmodel.h"
 #endif
 
 /* This plugin, being under the same license as GCC, satisfies the
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 8f4db04a..8d384d31 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-ff9de4fbeb
+fa07ebfff5
diff --git a/qemu_mode/README.md b/qemu_mode/README.md
index 3ebfc54c..4ed2f298 100644
--- a/qemu_mode/README.md
+++ b/qemu_mode/README.md
@@ -13,8 +13,8 @@ afl-cc.
 The usual performance cost is 2-5x, which is considerably better than seen so
 far in experiments with tools such as DynamoRIO and PIN.
 
-The idea and much of the initial implementation comes from Andrew Griffiths. The
-actual implementation on current QEMU (shipped as qemuafl) is from Andrea
+The idea and much of the initial implementation comes from Andrew Griffiths.
+The actual implementation on current QEMU (shipped as qemuafl) is from Andrea
 Fioraldi. Special thanks to abiondo that re-enabled TCG chaining.
 
 ## 2) How to use QEMU mode
@@ -30,17 +30,13 @@ glib2-devel).
 Once the binaries are compiled, you can leverage the QEMU tool by calling
 afl-fuzz and all the related utilities with `-Q` in the command line.
 
-Note that QEMU requires a generous memory limit to run; somewhere around 200 MB
-is a good starting point, but considerably more may be needed for more complex
-programs. The default `-m` limit will be automatically bumped up to 200 MB when
-specifying `-Q` to afl-fuzz; be careful when overriding this.
-
 In principle, if you set `CPU_TARGET` before calling ./build_qemu_support.sh,
 you should get a build capable of running non-native binaries (say, you can try
 `CPU_TARGET=arm`). This is also necessary for running 32-bit binaries on a
 64-bit system (`CPU_TARGET=i386`). If you're trying to run QEMU on a different
 architecture, you can also set `HOST` to the cross-compiler prefix to use (for
 example `HOST=arm-linux-gnueabi` to use arm-linux-gnueabi-gcc).
+Another common target is `CPU_TARGET=aarch64`.
 
 You can also compile statically-linked binaries by setting `STATIC=1`. This can
 be useful when compiling QEMU on a different system than the one you're planning
@@ -219,9 +215,6 @@ program may be utilizing. In particular, it does not appear to have full support
 for AVX2/FMA3. Using binaries for older CPUs or recompiling them with
 `-march=core2`, can help.
 
-Beyond that, this is an early-stage mechanism, so fields reports are welcome.
-You can send them to <afl-users@googlegroups.com>.
-
 ## 14) Alternatives: static rewriting
 
 Statically rewriting binaries just once, instead of attempting to translate them
@@ -230,4 +223,4 @@ with peril, because it depends on being able to properly and fully model program
 control flow without actually executing each and every code path.
 
 For more information and hints, check out
-[docs/fuzzing_binary-only_targets.md](../docs/fuzzing_binary-only_targets.md).
\ No newline at end of file
+[docs/fuzzing_binary-only_targets.md](../docs/fuzzing_binary-only_targets.md).
diff --git a/qemu_mode/README.persistent.md b/qemu_mode/README.persistent.md
index ab45860d..ef8fb71b 100644
--- a/qemu_mode/README.persistent.md
+++ b/qemu_mode/README.persistent.md
@@ -27,11 +27,12 @@ function and will patch the return address (on stack or in the link register) to
 return to START (like WinAFL).
 
 *Note:* If the target is compiled with position independent code (PIE/PIC) qemu
-loads these to a specific base address. For 64 bit you have to add 0x4000000000
-(9 zeroes) and for 32 bit 0x40000000 (7 zeroes) to the address. On strange
-setups the base address set by QEMU for PIE executable may change. You can check
-it printing the process map using `AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace
-TARGET-BINARY`.
+loads these to a specific base address. For amd64 bit you have to add
+0x4000000000 (9 zeroes) and for 32 bit 0x40000000 (7 zeroes) to the address.
+For aarch64 it is usually 0x5500000000.
+On strange setups the base address set by QEMU for PIE executable may change.
+You can check it printing the process map using
+`AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace TARGET-BINARY`.
 
 If this address is not valid, afl-fuzz will error during startup with the
 message that the forkserver was not found.
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index 277a6323..f31f3cef 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -251,6 +251,7 @@ else
     --disable-qom-cast-debug \
     --disable-stack-protector \
     --disable-werror \
+    --disable-docs \
     "
 
 fi
@@ -360,8 +361,10 @@ if ! command -v "$CROSS" > /dev/null ; then
     make -C libcompcov && echo "[+] libcompcov ready"
     echo "[+] Building unsigaction ..."
     make -C unsigaction && echo "[+] unsigaction ready"
+    echo "[+] Building fastexit ..."
+    make -C fastexit && echo "[+] fastexit ready"
     echo "[+] Building libqasan ..."
-    make -C libqasan && echo "[+] unsigaction ready"
+    make -C libqasan && echo "[+] libqasan ready"
     echo "[+] Building qemu libfuzzer helpers ..."
     make -C ../utils/aflpp_driver
   else
@@ -373,8 +376,10 @@ else
   make -C libcompcov CC="$CROSS $CROSS_FLAGS" && echo "[+] libcompcov ready"
   echo "[+] Building unsigaction ..."
   make -C unsigaction CC="$CROSS $CROSS_FLAGS" && echo "[+] unsigaction ready"
+  echo "[+] Building fastexit ..."
+  make -C fastexit CC="$CROSS $CROSS_FLAGS" && echo "[+] fastexit ready"
   echo "[+] Building libqasan ..."
-  make -C libqasan CC="$CROSS $CROSS_FLAGS" && echo "[+] unsigaction ready"
+  make -C libqasan CC="$CROSS $CROSS_FLAGS" && echo "[+] libqasan ready"
 fi
 
 echo "[+] All done for qemu_mode, enjoy!"
diff --git a/qemu_mode/fastexit/Makefile b/qemu_mode/fastexit/Makefile
new file mode 100644
index 00000000..80a5ec48
--- /dev/null
+++ b/qemu_mode/fastexit/Makefile
@@ -0,0 +1,30 @@
+#
+# american fuzzy lop++ - fastexit
+# --------------------------------
+#
+# Written by Andrea Fioraldi <andreafioraldi@gmail.com>
+#
+# Copyright 2019-2022 Andrea Fioraldi. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+
+TARGETS=fastexit.so fastexit32.so fastexit64.so
+
+all:  $(TARGETS)
+
+fastexit.so: fastexit.c
+	@if $(CC) -fPIC -shared fastexit.c -o fastexit.so 2>/dev/null ; then echo "fastexit build success"; else echo "fastexit build failure (that's fine)"; fi
+
+fastexit32.so: fastexit.c
+	@if $(CC) -fPIC -m32 -shared fastexit.c -o fastexit32.so 2>/dev/null ; then echo "fastexit32 build success"; else echo "fastexit32 build failure (that's fine)"; fi
+
+fastexit64.so: fastexit.c
+	@if $(CC) -fPIC -m64 -shared fastexit.c -o fastexit64.so 2>/dev/null ; then echo "fastexit64 build success"; else echo "fastexit64 build failure (that's fine)"; fi
+
+clean:
+	rm -f fastexit.so
diff --git a/qemu_mode/fastexit/README.md b/qemu_mode/fastexit/README.md
new file mode 100644
index 00000000..66763e94
--- /dev/null
+++ b/qemu_mode/fastexit/README.md
@@ -0,0 +1,5 @@
+# fastexit
+
+This library forces _exit on exit when preloaded to gain speed.
+
+Gives speed on complex targets like Android or Wine.
diff --git a/qemu_mode/fastexit/fastexit.c b/qemu_mode/fastexit/fastexit.c
new file mode 100644
index 00000000..44141af1
--- /dev/null
+++ b/qemu_mode/fastexit/fastexit.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+void exit(int status) {
+  _exit(status);
+}
diff --git a/qemu_mode/libqasan/malloc.c b/qemu_mode/libqasan/malloc.c
index c83b5eb2..d81b15e9 100644
--- a/qemu_mode/libqasan/malloc.c
+++ b/qemu_mode/libqasan/malloc.c
@@ -306,9 +306,7 @@ int __libqasan_posix_memalign(void **ptr, size_t align, size_t len) {
 
   }
 
-  size_t rem = len % align;
-  size_t size = len;
-  if (rem) size += rem;
+  size_t size = len + align;
 
   int state = QASAN_SWAP(QASAN_DISABLED);  // disable qasan for this thread
 
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject ff9de4fbeb33088b0273f9bb05ecf374a749222
+Subproject fa07ebfff5de3d7a531caf2f9e0306960953a5e
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index a21f014f..a9b5b326 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -114,7 +114,7 @@ static void kill_child() {
 
   if (fsrv.child_pid > 0) {
 
-    kill(fsrv.child_pid, fsrv.kill_signal);
+    kill(fsrv.child_pid, fsrv.child_kill_signal);
     fsrv.child_pid = -1;
 
   }
@@ -862,11 +862,15 @@ static void usage(u8 *argv0) {
       "MSAN_OPTIONS: custom settings for MSAN\n"
       "              (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
       "AFL_ANALYZE_HEX: print file offsets in hexadecimal instead of decimal\n"
+      "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
+      "                 (default: SIGKILL)\n"
+      "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
+      "                             (default: SIGTERM). If unset and AFL_KILL_SIGNAL is\n"
+      "                             set, that value will be used.\n"
       "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
       "              the target was compiled for\n"
       "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
       "AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n"
-
       , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
 
   exit(1);
@@ -1115,8 +1119,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  fsrv.kill_signal =
-      parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
+  configure_afl_kill_signals(
+      &fsrv, NULL, NULL, (fsrv.qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM);
 
   read_initial_file();
   (void)check_binary_signatures(fsrv.target_path);
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 15284a65..1c3b5405 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -514,7 +514,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (lto_mode && have_instr_env) {
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] = alloc_printf(
           "-fpass-plugin=%s/afl-llvm-lto-instrumentlist.so", obj_path);
 #else
@@ -530,7 +532,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (getenv("AFL_LLVM_DICT2FILE")) {
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-fpass-plugin=%s/afl-llvm-dict2file.so", obj_path);
 #else
@@ -547,7 +551,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) {
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
 #else
@@ -564,7 +570,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path);
 #else
@@ -581,7 +589,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) {
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path);
 #else
@@ -604,10 +614,14 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       cc_params[cc_par_cnt++] = "-fno-inline";
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-fpass-plugin=%s/cmplog-switches-pass.so", obj_path);
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
 #else
@@ -705,7 +719,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         } else {
 
     #if LLVM_MAJOR >= 11                            /* use new pass manager */
+      #if LLVM_MAJOR < 16
           cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+      #endif
           cc_params[cc_par_cnt++] = alloc_printf(
               "-fpass-plugin=%s/SanitizerCoveragePCGUARD.so", obj_path);
     #else
@@ -743,7 +759,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       } else {
 
 #if LLVM_MAJOR >= 11                                /* use new pass manager */
+  #if LLVM_MAJOR < 16
         cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
         cc_params[cc_par_cnt++] =
             alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
 #else
@@ -761,10 +779,14 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (cmplog_mode) {
 
 #if LLVM_MAJOR >= 11
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] = alloc_printf(
           "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path);
+  #if LLVM_MAJOR < 16
       cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+  #endif
       cc_params[cc_par_cnt++] =
           alloc_printf("-fpass-plugin=%s/cmplog-routines-pass.so", obj_path);
 #else
@@ -955,7 +977,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
   if (plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) &&
       strncmp(libdir, "/lib", 4)) {
 
-    cc_params[cc_par_cnt++] = "-rpath";
+    cc_params[cc_par_cnt++] = "-Wl,-rpath";
     cc_params[cc_par_cnt++] = libdir;
 
   } else {
diff --git a/src/afl-common.c b/src/afl-common.c
index f3e78ac5..31005804 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -25,6 +25,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include "forkserver.h"
 #ifndef _GNU_SOURCE
   #define _GNU_SOURCE
 #endif
@@ -47,6 +48,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <signal.h>
 
 u8  be_quiet = 0;
 u8 *doc_path = "";
@@ -456,38 +458,57 @@ u8 *find_afl_binary(u8 *own_loc, u8 *fname) {
 
 }
 
-/* Parses the kill signal environment variable, FATALs on error.
-  If the env is not set, sets the env to default_signal for the signal handlers
-  and returns the default_signal. */
-int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal) {
+int parse_afl_kill_signal(u8 *numeric_signal_as_str, int default_signal) {
 
-  if (afl_kill_signal_env && afl_kill_signal_env[0]) {
+  if (numeric_signal_as_str && numeric_signal_as_str[0]) {
 
     char *endptr;
     u8    signal_code;
-    signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10);
+    signal_code = (u8)strtoul(numeric_signal_as_str, &endptr, 10);
     /* Did we manage to parse the full string? */
-    if (*endptr != '\0' || endptr == (char *)afl_kill_signal_env) {
+    if (*endptr != '\0' || endptr == (char *)numeric_signal_as_str) {
 
-      FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)",
-            afl_kill_signal_env);
+      FATAL("Invalid signal name: %s", numeric_signal_as_str);
+
+    } else {
+
+      return signal_code;
 
     }
 
-    return signal_code;
+  }
 
-  } else {
+  return default_signal;
 
-    char *sigstr = alloc_printf("%d", default_signal);
-    if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); }
+}
 
-    /* Set the env for signal handler */
-    setenv("AFL_KILL_SIGNAL", sigstr, 1);
-    free(sigstr);
-    return default_signal;
+void configure_afl_kill_signals(afl_forkserver_t *fsrv,
+                                char             *afl_kill_signal_env,
+                                char             *afl_fsrv_kill_signal_env,
+                                int               default_server_kill_signal) {
+
+  afl_kill_signal_env =
+      afl_kill_signal_env ? afl_kill_signal_env : getenv("AFL_KILL_SIGNAL");
+  afl_fsrv_kill_signal_env = afl_fsrv_kill_signal_env
+                                 ? afl_fsrv_kill_signal_env
+                                 : getenv("AFL_FORK_SERVER_KILL_SIGNAL");
+
+  fsrv->child_kill_signal = parse_afl_kill_signal(afl_kill_signal_env, SIGKILL);
+
+  if (afl_kill_signal_env && !afl_fsrv_kill_signal_env) {
+
+    /*
+    Set AFL_FORK_SERVER_KILL_SIGNAL to the value of AFL_KILL_SIGNAL for
+    backwards compatibility. However, if AFL_FORK_SERVER_KILL_SIGNAL is set, is
+    takes precedence.
+    */
+    afl_fsrv_kill_signal_env = afl_kill_signal_env;
 
   }
 
+  fsrv->fsrv_kill_signal = parse_afl_kill_signal(afl_fsrv_kill_signal_env,
+                                                 default_server_kill_signal);
+
 }
 
 static inline unsigned int helper_min3(unsigned int a, unsigned int b,
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 628ff590..a241f2c6 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -100,7 +100,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
   fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT;
   fsrv->mem_limit = MEM_LIMIT;
   fsrv->out_file = NULL;
-  fsrv->kill_signal = SIGKILL;
+  fsrv->child_kill_signal = SIGKILL;
 
   /* exec related stuff */
   fsrv->child_pid = -1;
@@ -134,7 +134,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
   fsrv_to->no_unlink = from->no_unlink;
   fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode;
   fsrv_to->crash_exitcode = from->crash_exitcode;
-  fsrv_to->kill_signal = from->kill_signal;
+  fsrv_to->child_kill_signal = from->child_kill_signal;
   fsrv_to->debug = from->debug;
 
   // These are forkserver specific.
@@ -793,7 +793,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
       s32 tmp_pid = fsrv->fsrv_pid;
       if (tmp_pid > 0) {
 
-        kill(tmp_pid, fsrv->kill_signal);
+        kill(tmp_pid, fsrv->child_kill_signal);
         fsrv->fsrv_pid = -1;
 
       }
@@ -804,7 +804,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
       s32 tmp_pid = fsrv->fsrv_pid;
       if (tmp_pid > 0) {
 
-        kill(tmp_pid, fsrv->kill_signal);
+        kill(tmp_pid, fsrv->child_kill_signal);
         fsrv->fsrv_pid = -1;
 
       }
@@ -1242,11 +1242,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
 void afl_fsrv_kill(afl_forkserver_t *fsrv) {
 
-  if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); }
+  if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->child_kill_signal); }
   if (fsrv->fsrv_pid > 0) {
 
-    kill(fsrv->fsrv_pid, fsrv->kill_signal);
-    if (waitpid(fsrv->fsrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); }
+    kill(fsrv->fsrv_pid, fsrv->fsrv_kill_signal);
+    waitpid(fsrv->fsrv_pid, NULL, 0);
 
   }
 
@@ -1545,7 +1545,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
     s32 tmp_pid = fsrv->child_pid;
     if (tmp_pid > 0) {
 
-      kill(tmp_pid, fsrv->kill_signal);
+      kill(tmp_pid, fsrv->child_kill_signal);
       fsrv->child_pid = -1;
 
     }
@@ -1605,7 +1605,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
   /* Did we timeout? */
   if (unlikely(fsrv->last_run_timed_out)) {
 
-    fsrv->last_kill_signal = fsrv->kill_signal;
+    fsrv->last_kill_signal = fsrv->child_kill_signal;
     return FSRV_RUN_TMOUT;
 
   }
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 5199f7e6..8bd465f0 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -23,6 +23,7 @@
 
  */
 
+#include <signal.h>
 #include "afl-fuzz.h"
 #include "envs.h"
 
@@ -487,7 +488,14 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
 
                               afl_environment_variable_len)) {
 
-            afl->afl_env.afl_kill_signal =
+            afl->afl_env.afl_child_kill_signal =
+                (u8 *)get_afl_env(afl_environment_variables[i]);
+
+          } else if (!strncmp(env, "AFL_FORK_SERVER_KILL_SIGNAL",
+
+                              afl_environment_variable_len)) {
+
+            afl->afl_env.afl_fsrv_kill_signal =
                 (u8 *)get_afl_env(afl_environment_variables[i]);
 
           } else if (!strncmp(env, "AFL_TARGET_ENV",
@@ -654,8 +662,17 @@ void afl_states_stop(void) {
 
   LIST_FOREACH(&afl_states, afl_state_t, {
 
-    if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, el->fsrv.kill_signal);
-    if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, el->fsrv.kill_signal);
+    /* NOTE: We need to make sure that the parent (the forkserver) reap the
+     * child (see below). */
+    if (el->fsrv.child_pid > 0)
+      kill(el->fsrv.child_pid, el->fsrv.child_kill_signal);
+    if (el->fsrv.fsrv_pid > 0) {
+
+      kill(el->fsrv.fsrv_pid, el->fsrv.fsrv_kill_signal);
+      /* Make sure the forkserver does not end up as zombie. */
+      waitpid(el->fsrv.fsrv_pid, NULL, 0);
+
+    }
 
   });
 
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 713f3a3c..61956dc3 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -1410,9 +1410,15 @@ void show_stats_pizza(afl_state_t *afl) {
 
   /* AFL_EXIT_ON_TIME. */
 
-  if (unlikely(afl->last_find_time && !afl->non_instrumented_mode &&
-               afl->afl_env.afl_exit_on_time &&
-               (cur_ms - afl->last_find_time) > afl->exit_on_time)) {
+  /* If no coverage was found yet, check whether run time is greater than
+   * exit_on_time. */
+
+  if (unlikely(
+          !afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time &&
+          ((afl->last_find_time &&
+            (cur_ms - afl->last_find_time) > afl->exit_on_time) ||
+           (!afl->last_find_time && (afl->prev_run_time + cur_ms -
+                                     afl->start_time) > afl->exit_on_time)))) {
 
     afl->stop_soon = 2;
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 84ae54ff..acb0b2ec 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -25,6 +25,7 @@
 
 #include "afl-fuzz.h"
 #include "cmplog.h"
+#include "common.h"
 #include <limits.h>
 #include <stdlib.h>
 #ifndef USEMMAP
@@ -248,19 +249,24 @@ static void usage(u8 *argv0, int more_help) {
       "AFL_DISABLE_TRIM: disable the trimming of test cases\n"
       "AFL_DUMB_FORKSRV: use fork server without feedback from target\n"
       "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n"
-      "AFL_EXIT_ON_TIME: exit when no new coverage finds are made within the specified time period\n"
-      "AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\n"
+      "AFL_EXIT_ON_TIME: exit when no new coverage is found within the specified time\n"
+      "AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60\n"
+      "                      minutes and a cycle without finds)\n"
       "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n"
       "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
-      "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
+      "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in ms)\n"
       "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
       "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
       "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
-      "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected during a run\n"
+      "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n"
       "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
       "AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n"
       "AFL_PIZZA_MODE: 1 - enforce pizza mode, 0 - disable for April 1st\n"
-      "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
+      "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
+      "                 (default: SIGKILL)\n"
+      "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
+      "                             (default: SIGTERM). If unset and AFL_KILL_SIGNAL is\n"
+      "                             set, that value will be used.\n"
       "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
       "              the target was compiled for\n"
       "AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n"
@@ -1358,8 +1364,15 @@ int main(int argc, char **argv_orig, char **envp) {
 
   #endif
 
-  afl->fsrv.kill_signal =
-      parse_afl_kill_signal_env(afl->afl_env.afl_kill_signal, SIGKILL);
+  configure_afl_kill_signals(&afl->fsrv, afl->afl_env.afl_child_kill_signal,
+                             afl->afl_env.afl_fsrv_kill_signal,
+                             (afl->fsrv.qemu_mode || afl->unicorn_mode
+  #ifdef __linux__
+                              || afl->fsrv.nyx_mode
+  #endif
+                              )
+                                 ? SIGKILL
+                                 : SIGTERM);
 
   setup_signal_handlers();
   check_asan_opts(afl);
@@ -2570,6 +2583,7 @@ int main(int argc, char **argv_orig, char **envp) {
 stop_fuzzing:
 
   afl->force_ui_update = 1;  // ensure the screen is reprinted
+  afl->stop_soon = 1;        // ensure everything is written
   show_stats(afl);           // print the screen one last time
   write_bitmap(afl);
   save_auto(afl);
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 0b724758..93339a8f 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -129,7 +129,7 @@ static void kill_child() {
   timed_out = 1;
   if (fsrv->child_pid > 0) {
 
-    kill(fsrv->child_pid, fsrv->kill_signal);
+    kill(fsrv->child_pid, fsrv->child_kill_signal);
     fsrv->child_pid = -1;
 
   }
@@ -515,11 +515,11 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
     it.it_value.tv_sec = (fsrv->exec_tmout / 1000);
     it.it_value.tv_usec = (fsrv->exec_tmout % 1000) * 1000;
 
-  }
+    signal(SIGALRM, kill_child);
 
-  signal(SIGALRM, kill_child);
+    setitimer(ITIMER_REAL, &it, NULL);
 
-  setitimer(ITIMER_REAL, &it, NULL);
+  }
 
   if (waitpid(fsrv->child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); }
 
@@ -822,8 +822,8 @@ static void usage(u8 *argv0) {
       "  -o file    - file to write the trace data to\n\n"
 
       "Execution control settings:\n"
-      "  -t msec    - timeout for each run (none)\n"
-      "  -m megs    - memory limit for child process (%u MB)\n"
+      "  -t msec    - timeout for each run (default: 1000ms)\n"
+      "  -m megs    - memory limit for child process (default: none)\n"
 #if defined(__linux__) && defined(__aarch64__)
       "  -A         - use binary-only instrumentation (ARM CoreSight mode)\n"
 #endif
@@ -865,15 +865,22 @@ static void usage(u8 *argv0) {
       "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during "
       "startup (in milliseconds)\n"
       "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, "
-      "etc. (default: SIGKILL)\n"
+      "etc.\n"
+      "                 (default: SIGKILL)\n"
+      "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on "
+      "termination\n"
+      "                             (default: SIGTERM). If unset and "
+      "AFL_KILL_SIGNAL is\n"
+      "                             set, that value will be used.\n"
       "AFL_MAP_SIZE: the shared memory size for that target. must be >= the "
-      "size the target was compiled for\n"
+      "size the\n"
+      "              target was compiled for\n"
       "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
-      "AFL_PRINT_FILENAMES: If set, the filename currently processed will be "
-      "printed to stdout\n"
+      "AFL_PRINT_FILENAMES: Print the queue entry currently processed will to "
+      "stdout\n"
       "AFL_QUIET: do not print extra informational output\n"
       "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n",
-      argv0, MEM_LIMIT, doc_path);
+      argv0, doc_path);
 
   exit(1);
 
@@ -1009,6 +1016,16 @@ int main(int argc, char **argv_orig, char **envp) {
 
           }
 
+        } else {
+
+          // The forkserver code does not have a way to completely
+          // disable the timeout, so we'll use a very, very long
+          // timeout instead.
+          WARNF(
+              "Setting an execution timeout of 120 seconds ('none' is not "
+              "allowed).");
+          fsrv->exec_tmout = 120 * 1000;
+
         }
 
         break;
@@ -1258,8 +1275,9 @@ int main(int argc, char **argv_orig, char **envp) {
                                  : 0);
     be_quiet = save_be_quiet;
 
-    fsrv->kill_signal =
-        parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
+    configure_afl_kill_signals(
+        fsrv, NULL, NULL,
+        (fsrv->qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM);
 
     if (new_map_size) {
 
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 694c9c21..d93b9a41 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -113,7 +113,7 @@ static void kill_child() {
 
   if (fsrv->child_pid > 0) {
 
-    kill(fsrv->child_pid, fsrv->kill_signal);
+    kill(fsrv->child_pid, fsrv->child_kill_signal);
     fsrv->child_pid = -1;
 
   }
@@ -879,8 +879,12 @@ static void usage(u8 *argv0) {
 
       "Environment variables used:\n"
       "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n"
-      "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
-      "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
+      "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in ms)\n"
+      "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
+      "                 (default: SIGKILL)\n"
+      "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
+      "                             (default: SIGTERM). If unset and AFL_KILL_SIGNAL is\n"
+      "                             set, that value will be used.\n"
       "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
       "              the target was compiled for\n"
       "AFL_PRELOAD:  LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
@@ -1195,8 +1199,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  fsrv->kill_signal =
-      parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
+  configure_afl_kill_signals(
+      fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM);
 
   if (getenv("AFL_CRASH_EXITCODE")) {
 
diff --git a/test/test-qemu-mode.sh b/test/test-qemu-mode.sh
index 46b138ff..c7734217 100755
--- a/test/test-qemu-mode.sh
+++ b/test/test-qemu-mode.sh
@@ -107,14 +107,21 @@ test -e ../afl-qemu-trace && {
       test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" -o "$SYS" = "aarch64" -o ! "${SYS%%arm*}" && {
         $ECHO "$GREY[*] running afl-fuzz for persistent qemu_mode, this will take approx 10 seconds"
         {
-          if file test-instr | grep -q "32-bit"; then
-            # for 32-bit reduce 8 nibbles to the lower 7 nibbles
-	    ADDR_LOWER_PART=`nm test-instr | grep "T main" | awk '{print $1}' | sed 's/^.//'`
-          else
-            # for 64-bit reduce 16 nibbles to the lower 9 nibbles
-	    ADDR_LOWER_PART=`nm test-instr | grep "T main" | awk '{print $1}' | sed 's/^.......//'`
-          fi
-          export AFL_QEMU_PERSISTENT_ADDR=`expr 0x4${ADDR_LOWER_PART}`
+          IS_STATIC=""
+          file test-instr | grep -q 'statically linked' && IS_STATIC=1
+          test -z "$IS_STATIC" && {
+            if file test-instr | grep -q "32-bit"; then
+              # for 32-bit reduce 8 nibbles to the lower 7 nibbles
+  	      ADDR_LOWER_PART=`nm test-instr | grep "T main" | awk '{print $1}' | sed 's/^.//'`
+            else
+              # for 64-bit reduce 16 nibbles to the lower 9 nibbles
+  	      ADDR_LOWER_PART=`nm test-instr | grep "T main" | awk '{print $1}' | sed 's/^.......//'`
+            fi
+            export AFL_QEMU_PERSISTENT_ADDR=`expr 0x4${ADDR_LOWER_PART}`
+          }
+          test -n "$IS_STATIC" && {
+            export AFL_QEMU_PERSISTENT_ADDR=0x`nm test-instr | grep "T main" |  awk '{print $1}'`
+          }
           export AFL_QEMU_PERSISTENT_GPR=1
           $ECHO "Info: AFL_QEMU_PERSISTENT_ADDR=$AFL_QEMU_PERSISTENT_ADDR <= $(nm test-instr | grep "T main" | awk '{print $1}')"
           env|grep AFL_|sort
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 09bc04ad..bba4215c 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-0a31c2b28bf7037fe8b0ff376521fdbdf28a9efe
+6e00ceac
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
-Subproject 0a31c2b28bf7037fe8b0ff376521fdbdf28a9ef
+Subproject 6e00ceac6fd5627e42e1858c543c84f2fbdaedd
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index 87bd2aa2..03376b6a 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -292,10 +292,10 @@ int LLVMFuzzerRunDriver(int *argcp, char ***argvp,
   }
 
   bool in_afl = !(!getenv(SHM_FUZZ_ENV_VAR) || !getenv(SHM_ENV_VAR) ||
-                 fcntl(FORKSRV_FD, F_GETFD) == -1 ||
-                 fcntl(FORKSRV_FD + 1, F_GETFD) == -1);
+                  fcntl(FORKSRV_FD, F_GETFD) == -1 ||
+                  fcntl(FORKSRV_FD + 1, F_GETFD) == -1);
 
-  if (!in_afl) { __afl_sharedmem_fuzzing = 0;  }
+  if (!in_afl) { __afl_sharedmem_fuzzing = 0; }
 
   output_file = stderr;
   maybe_duplicate_stderr();
@@ -336,6 +336,10 @@ int LLVMFuzzerRunDriver(int *argcp, char ***argvp,
 
     return ExecuteFilesOnyByOne(argc, argv, callback);
 
+  } else {
+
+    N = INT_MAX;
+
   }
 
   assert(N > 0);
diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c
index 638735ef..c390d004 100644
--- a/utils/libdislocator/libdislocator.so.c
+++ b/utils/libdislocator/libdislocator.so.c
@@ -512,7 +512,7 @@ __attribute__((alloc_size(2, 3))) void *reallocarray(void *ptr, size_t elem_len,
 
 int reallocarr(void *ptr, size_t elem_len, size_t elem_cnt) {
 
-  void *ret = NULL;
+  void        *ret = NULL;
   const size_t elem_tot = elem_len * elem_cnt;
 
   if (elem_tot == 0) {