about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rw-r--r--README.md23
-rw-r--r--docs/Changelog.md15
-rw-r--r--docs/binaryonly_fuzzing.md2
-rw-r--r--docs/notes_for_asan.md6
-rw-r--r--docs/parallel_fuzzing.md38
-rw-r--r--docs/power_schedules.md2
-rw-r--r--docs/status_screen.md4
-rw-r--r--examples/aflpp_driver/GNUmakefile16
-rw-r--r--examples/aflpp_driver/aflpp_driver.cpp10
-rw-r--r--examples/aflpp_driver/aflpp_qemu_driver.c38
-rw-r--r--examples/aflpp_driver/aflpp_qemu_driver_hook.c22
-rw-r--r--examples/persistent_demo/Makefile6
-rw-r--r--examples/persistent_demo/persistent_demo.c1
-rw-r--r--examples/persistent_demo/persistent_demo_new.c3
-rw-r--r--examples/persistent_demo/test-instr.c69
-rw-r--r--examples/qemu_persistent_hook/read_into_rdi.c20
-rw-r--r--gcc_plugin/README.md2
-rw-r--r--include/afl-fuzz.h16
-rw-r--r--include/common.h9
-rw-r--r--include/forkserver.h6
-rw-r--r--include/sharedmem.h2
-rw-r--r--llvm_mode/GNUmakefile13
-rw-r--r--llvm_mode/README.persistent_mode.md2
-rw-r--r--llvm_mode/README.whitelist.md4
-rw-r--r--llvm_mode/afl-clang-fast.c9
-rw-r--r--llvm_mode/afl-llvm-common.cc19
-rw-r--r--llvm_mode/afl-llvm-lto-whitelist.so.cc6
-rw-r--r--llvm_mode/afl-llvm-rt.o.c75
-rw-r--r--qemu_mode/patches/afl-qemu-common.h8
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-inl.h79
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-translate-inl.h3
-rw-r--r--qemu_mode/patches/afl-qemu-tcg-runtime-inl.h2
-rw-r--r--src/afl-common.c57
-rw-r--r--src/afl-forkserver.c86
-rw-r--r--src/afl-fuzz-bitmap.c8
-rw-r--r--src/afl-fuzz-init.c79
-rw-r--r--src/afl-fuzz-one.c37
-rw-r--r--src/afl-fuzz-queue.c2
-rw-r--r--src/afl-fuzz-run.c40
-rw-r--r--src/afl-fuzz-stats.c41
-rw-r--r--src/afl-fuzz.c65
-rw-r--r--src/afl-sharedmem.c25
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
-rw-r--r--unicorn_mode/samples/c/harness.c2
-rw-r--r--unicorn_mode/samples/persistent/Makefile2
-rw-r--r--unicorn_mode/samples/persistent/harness.c32
m---------unicorn_mode/unicornafl0
48 files changed, 673 insertions, 337 deletions
diff --git a/GNUmakefile b/GNUmakefile
index dd817d35..7556b617 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -100,7 +100,7 @@ ifeq "$(shell uname -s)" "DragonFly"
 endif
 
 ifeq "$(shell uname -s)" "OpenBSD"
-  override CFLAGS  += -I /usr/local/include/
+  override CFLAGS  += -I /usr/local/include/ -mno-retpoline
   LDFLAGS += -Wl,-z,notext -L /usr/local/lib/
 endif
 
diff --git a/README.md b/README.md
index 5ebd6b6b..76f510c8 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@
 
   * LLVM mode Ngram coverage by Adrian Herrera [https://github.com/adrianherrera/afl-ngram-pass](https://github.com/adrianherrera/afl-ngram-pass)
 
-  A more thorough list is available in the PATCHES file.
+  A more thorough list is available in the [PATCHES](docs/PATCHES.md) file.
 
   | Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode        | unicorn_mode |
   | ----------------------- |:-------:|:---------:|:----------:|:----------------:|:------------:|
@@ -134,6 +134,8 @@ For everyone who wants to contribute (and send pull requests) please read
 ## Building and installing afl++
 
 An easy way to install afl++ with everything compiled is available via docker:
+You can use the [Dockerfile](Dockerfile) (which has gcc-10 and clang-11 -
+hence afl-clang-lto is available!) or just pull directly from the docker hub:
 ```shell
 docker pull aflplusplus/aflplusplus
 docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
@@ -149,6 +151,8 @@ sudo apt install build-essential libtool-bin python3-dev automake flex bison lib
 make distrib
 sudo make install
 ```
+It is recommended to install the newest available gcc and clang and llvm-dev
+possible in your distribution!
 
 Note that "make distrib" also builds llvm_mode, qemu_mode, unicorn_mode and
 more. If you just want plain afl then do "make all", however compiling and
@@ -193,17 +197,6 @@ These build options exist:
 
 e.g.: make ASAN_BUILD=1
 
-
-Note that afl++ is faster and better the newer the compilers used are.
-Hence at least gcc-9 and especially llvm-9 should be the compilers of choice.
-If your distribution does not have them, you can use the Dockerfile:
-
-```shell
-cd AFLplusplus
-sudo docker build -t aflplusplus .
-```
-
-
 ## Challenges of guided fuzzing
 
 Fuzzing is one of the most powerful and proven strategies for identifying
@@ -388,10 +381,10 @@ The available schedules are:
  - rare (experimental)
 
 In parallel mode (-M/-S, several instances with the shared queue), we suggest to
-run the master using the explore or fast schedule (-p explore) and the slaves
-with a combination of cut-off-exponential (-p coe), exponential (-p fast),
+run the main node using the explore or fast schedule (-p explore) and the secondary
+nodes with a combination of cut-off-exponential (-p coe), exponential (-p fast),
 explore (-p explore) and mmopt (-p mmopt) schedules. If a schedule does
-not perform well for a target, restart the slave with a different schedule.
+not perform well for a target, restart the secondary nodes with a different schedule.
 
 In single mode, using -p fast is usually slightly more beneficial than the
 default explore mode.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e7ba208c..87e02938 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -11,11 +11,11 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 ### Version ++2.65d (dev)
   - afl-fuzz:
-     - -S slaves now only sync from the master to increase performance,
-       the -M master still syncs from everyone. Added checks that ensure
-       exactly one master is present and warn otherwise
-     - If no master is present at a sync one slave automatically becomes
-       a temporary master until a real master shows up
+     - -S secondary nodes now only sync from the main node to increase performance,
+       the -M main node still syncs from everyone. Added checks that ensure
+       exactly one main node is present and warn otherwise
+     - If no main node is present at a sync one secondary node automatically becomes
+       a temporary main node until a real main nodes shows up
      - fix/update to MOpt (thanks to arnow117)
   - llvm_mode:
     - the default instrumentation is now PCGUARD, as it is faster and provides
@@ -24,6 +24,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
       feature is used.
     - lowered minimum required llvm version to 3.4 (except LLVMInsTrim,
       which needs 3.8.0)
+    - WHITELIST feature now supports wildcards (thanks to sirmc)
     - small change to cmplog to make it work with current llvm 11-dev
     - added AFL_LLVM_LAF_ALL, sets all laf-intel settings
     - LTO whitelist functionality rewritten, now main, _init etc functions
@@ -32,6 +33,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
       tried to be instrumented with LTO
     - fixed crash in cmplog with LTO
     - enable snapshot lkm also for persistent mode
+  - Unicornafl
+    - Added powerPC support from unicorn/next
   - persistent mode shared memory testcase handover (instead of via
     files/stdin) - 10-100% performance increase
   - General support for 64 bit PowerPC, RiscV, Sparc etc.
@@ -909,7 +912,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - Switched from exit() to _exit() in injected code to avoid snafus with
     destructors in C++ code. Spotted by sunblate.
 
-  - Made a change to avoid spuriously setting __AFL_SHM_ID when 
+  - Made a change to avoid spuriously setting __AFL_SHM_ID when
     AFL_DUMB_FORKSRV is set in conjunction with -n. Spotted by Jakub Wilk.
 
 ### Version 1.94b:
diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md
index f005a9b7..7c9be418 100644
--- a/docs/binaryonly_fuzzing.md
+++ b/docs/binaryonly_fuzzing.md
@@ -4,7 +4,7 @@
   it allows for very fast and coverage guided fuzzing.
 
   However, if there is only the binary program and no source code available,
-  then standard `afl-fuzz -n` (dumb mode) is not effective.
+  then standard `afl-fuzz -n` (non-instrumented mode) is not effective.
 
   The following is a description of how these binaries can be fuzzed with afl++
 
diff --git a/docs/notes_for_asan.md b/docs/notes_for_asan.md
index 6a4806c0..2e18c15f 100644
--- a/docs/notes_for_asan.md
+++ b/docs/notes_for_asan.md
@@ -28,9 +28,9 @@ Note that ASAN is incompatible with -static, so be mindful of that.
 
 (You can also use AFL_USE_MSAN=1 to enable MSAN instead.)
 
-NOTE: if you run several slaves only one should run the target compiled with
-ASAN (and UBSAN, CFISAN), the others should run the target with no sanitizers
-compiled in.
+NOTE: if you run several secondary instances, only one should run the target
+compiled with ASAN (and UBSAN, CFISAN), the others should run the target with
+no sanitizers compiled in.
 
 There is also the option of generating a corpus using a non-ASAN binary, and
 then feeding it to an ASAN-instrumented one to check for bugs. This is faster,
diff --git a/docs/parallel_fuzzing.md b/docs/parallel_fuzzing.md
index c6e54218..271f8369 100644
--- a/docs/parallel_fuzzing.md
+++ b/docs/parallel_fuzzing.md
@@ -13,12 +13,12 @@ In fact, if you rely on just a single job on a multi-core system, you will
 be underutilizing the hardware. So, parallelization is usually the right
 way to go.
 
-When targeting multiple unrelated binaries or using the tool in "dumb" (-n)
-mode, it is perfectly fine to just start up several fully separate instances
-of afl-fuzz. The picture gets more complicated when you want to have multiple
-fuzzers hammering a common target: if a hard-to-hit but interesting test case
-is synthesized by one fuzzer, the remaining instances will not be able to use
-that input to guide their work.
+When targeting multiple unrelated binaries or using the tool in
+"non-instrumented" (-n) mode, it is perfectly fine to just start up several
+fully separate instances of afl-fuzz. The picture gets more complicated when
+you want to have multiple fuzzers hammering a common target: if a hard-to-hit
+but interesting test case is synthesized by one fuzzer, the remaining instances
+will not be able to use that input to guide their work.
 
 To help with this problem, afl-fuzz offers a simple way to synchronize test
 cases on the fly.
@@ -37,7 +37,7 @@ system, simply create a new, empty output directory ("sync dir") that will be
 shared by all the instances of afl-fuzz; and then come up with a naming scheme
 for every instance - say, "fuzzer01", "fuzzer02", etc. 
 
-Run the first one ("master", -M) like this:
+Run the first one ("main node", -M) like this:
 
 ```
 ./afl-fuzz -i testcase_dir -o sync_dir -M fuzzer01 [...other stuff...]
@@ -57,26 +57,26 @@ Each fuzzer will keep its state in a separate subdirectory, like so:
 Each instance will also periodically rescan the top-level sync directory
 for any test cases found by other fuzzers - and will incorporate them into
 its own fuzzing when they are deemed interesting enough.
-For performance reasons only -M masters sync the queue with everyone, the
--S slaves will only sync from the master.
+For performance reasons only -M main node syncs the queue with everyone, the
+-S secondary nodes will only sync from the main node.
 
-The difference between the -M and -S modes is that the master instance will
+The difference between the -M and -S modes is that the main instance will
 still perform deterministic checks; while the secondary instances will
 proceed straight to random tweaks.
 
-Note that you must always have one -M master instance!
+Note that you must always have one -M main instance!
 
 Note that running multiple -M instances is wasteful, although there is an
 experimental support for parallelizing the deterministic checks. To leverage
 that, you need to create -M instances like so:
 
 ```
-./afl-fuzz -i testcase_dir -o sync_dir -M masterA:1/3 [...]
-./afl-fuzz -i testcase_dir -o sync_dir -M masterB:2/3 [...]
-./afl-fuzz -i testcase_dir -o sync_dir -M masterC:3/3 [...]
+./afl-fuzz -i testcase_dir -o sync_dir -M mainA:1/3 [...]
+./afl-fuzz -i testcase_dir -o sync_dir -M mainB:2/3 [...]
+./afl-fuzz -i testcase_dir -o sync_dir -M mainC:3/3 [...]
 ```
 
-...where the first value after ':' is the sequential ID of a particular master
+...where the first value after ':' is the sequential ID of a particular main
 instance (starting at 1), and the second value is the total number of fuzzers to
 distribute the deterministic fuzzing across. Note that if you boot up fewer
 fuzzers than indicated by the second number passed to -M, you may end up with
@@ -168,7 +168,7 @@ to keep in mind:
     This arrangement would allow test interesting cases to propagate across
     the fleet without having to copy every fuzzer queue to every single host.
 
-  - You do not want a "master" instance of afl-fuzz on every system; you should
+  - You do not want a "main" instance of afl-fuzz on every system; you should
     run them all with -S, and just designate a single process somewhere within
     the fleet to run with -M.
 
@@ -185,10 +185,10 @@ also basic machine-readable information always written to the fuzzer_stats file
 in the output directory. Locally, that information can be interpreted with
 afl-whatsup.
 
-In principle, you can use the status screen of the master (-M) instance to
+In principle, you can use the status screen of the main (-M) instance to
 monitor the overall fuzzing progress and decide when to stop. In this
 mode, the most important signal is just that no new paths are being found
-for a longer while. If you do not have a master instance, just pick any
+for a longer while. If you do not have a main instance, just pick any
 single secondary instance to watch and go by that.
 
 You can also rely on that instance's output directory to collect the
@@ -197,7 +197,7 @@ within the fleet. Secondary (-S) instances do not require any special
 monitoring, other than just making sure that they are up.
 
 Keep in mind that crashing inputs are *not* automatically propagated to the
-master instance, so you may still want to monitor for crashes fleet-wide
+main instance, so you may still want to monitor for crashes fleet-wide
 from within your synchronization or health checking scripts (see afl-whatsup).
 
 ## 5) Asymmetric setups
diff --git a/docs/power_schedules.md b/docs/power_schedules.md
index c69c64d2..067a1d91 100644
--- a/docs/power_schedules.md
+++ b/docs/power_schedules.md
@@ -25,7 +25,7 @@ where *α(i)* is the performance score that AFL uses to compute for the seed inp
   
 More details can be found in the paper that was accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/).
 
-PS: In parallel mode (several instances with shared queue), we suggest to run the master using the exploit schedule (-p exploit) and the slaves with a combination of cut-off-exponential (-p coe), exponential (-p fast; default), and explore (-p explore) schedules. In single mode, the default settings will do. **EDIT:** In parallel mode, AFLFast seems to perform poorly because the path probability estimates are incorrect for the imported seeds. Pull requests to fix this issue by syncing the estimates accross instances are appreciated :)
+PS: In parallel mode (several instances with shared queue), we suggest to run the main node using the exploit schedule (-p exploit) and the secondary nodes with a combination of cut-off-exponential (-p coe), exponential (-p fast; default), and explore (-p explore) schedules. In single mode, the default settings will do. **EDIT:** In parallel mode, AFLFast seems to perform poorly because the path probability estimates are incorrect for the imported seeds. Pull requests to fix this issue by syncing the estimates across instances are appreciated :)
 
 Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
 Released under terms and conditions of Apache License, Version 2.0.
diff --git a/docs/status_screen.md b/docs/status_screen.md
index a66558b9..b89468ce 100644
--- a/docs/status_screen.md
+++ b/docs/status_screen.md
@@ -33,7 +33,7 @@ The top line shows you which mode afl-fuzz is running in
 (normal: "american fuzy lop", crash exploration mode: "peruvian rabbit mode")
 and the version of afl++.
 Next to the version is the banner, which, if not set with -T by hand, will
-either show the binary name being fuzzed, or the -M/-S master/slave name for
+either show the binary name being fuzzed, or the -M/-S main/secondary name for
 parallel fuzzing.
 Finally, the last item is the power schedule mode being run (default: explore).
 
@@ -404,7 +404,7 @@ directory. This includes:
   - `var_byte_count`    - how many edges are non-deterministic
   - `afl_banner`        - banner text (e.g. the target name)
   - `afl_version`       - the version of afl used
-  - `target_mode`       - default, persistent, qemu, unicorn, dumb
+  - `target_mode`       - default, persistent, qemu, unicorn, non-instrumented
   - `command_line`      - full command line used for the fuzzing session
 
 Most of these map directly to the UI elements discussed earlier on.
diff --git a/examples/aflpp_driver/GNUmakefile b/examples/aflpp_driver/GNUmakefile
index a681d2cf..05ddebb0 100644
--- a/examples/aflpp_driver/GNUmakefile
+++ b/examples/aflpp_driver/GNUmakefile
@@ -9,7 +9,7 @@ endif
 
 FLAGS=-O3 -funroll-loops
 
-all:	libAFLDriver.a
+all:	libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so
 
 aflpp_driver.o:	aflpp_driver.cpp
 	$(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
@@ -17,5 +17,17 @@ aflpp_driver.o:	aflpp_driver.cpp
 libAFLDriver.a:	aflpp_driver.o
 	ar ru libAFLDriver.a aflpp_driver.o
 
+aflpp_qemu_driver.o:	aflpp_qemu_driver.c
+	$(LLVM_BINDIR)clang $(FLAGS) -funroll-loops -c aflpp_qemu_driver.c
+
+libAFLQemuDriver.a:	aflpp_qemu_driver.o
+	ar ru libAFLQemuDriver.a aflpp_qemu_driver.o
+
+aflpp_qemu_driver_hook.so:	aflpp_qemu_driver_hook.o
+	$(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so
+
+aflpp_qemu_driver_hook.o:	aflpp_qemu_driver_hook.c
+	$(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c
+
 clean:
-	rm -f *.o libAFLDriver*.a *~ core
+	rm -f *.o libAFLDriver*.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so *~ core
diff --git a/examples/aflpp_driver/aflpp_driver.cpp b/examples/aflpp_driver/aflpp_driver.cpp
index 3dcc8c3c..f2c604da 100644
--- a/examples/aflpp_driver/aflpp_driver.cpp
+++ b/examples/aflpp_driver/aflpp_driver.cpp
@@ -252,18 +252,18 @@ int main(int argc, char **argv) {
   else if(argc == 2 && (N = atoi(argv[1])) > 0)
       Printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N);
   else if (argc > 1) {
-    if (!getenv("AFL_DRIVER_DONT_DEFER")) {
+//    if (!getenv("AFL_DRIVER_DONT_DEFER")) {
       __afl_sharedmem_fuzzing = 0;
       __afl_manual_init();
-    }
+//    }
     return ExecuteFilesOnyByOne(argc, argv);
     exit(0);
   }
 
   assert(N > 0);
 
-  if (!getenv("AFL_DRIVER_DONT_DEFER"))
-    __afl_manual_init();
+//  if (!getenv("AFL_DRIVER_DONT_DEFER"))
+  __afl_manual_init();
 
   // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization
   // on the first execution of LLVMFuzzerTestOneInput is ignored.
@@ -272,7 +272,7 @@ int main(int argc, char **argv) {
 
   int num_runs = 0;
   while (__afl_persistent_loop(N)) {
-    if (__afl_fuzz_len > 0) {
+    if (__afl_fuzz_len) {
       num_runs++;
       LLVMFuzzerTestOneInput(__afl_fuzz_ptr, __afl_fuzz_len);
     }
diff --git a/examples/aflpp_driver/aflpp_qemu_driver.c b/examples/aflpp_driver/aflpp_qemu_driver.c
new file mode 100644
index 00000000..604feb91
--- /dev/null
+++ b/examples/aflpp_driver/aflpp_qemu_driver.c
@@ -0,0 +1,38 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+// libFuzzer interface is thin, so we don't include any libFuzzer headers.
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
+
+static const size_t kMaxAflInputSize = 1 << 20;
+static uint8_t      AflInputBuf[kMaxAflInputSize];
+
+void __attribute__((noinline)) afl_qemu_driver_stdin_input(void) {
+
+  size_t l = read(0, AflInputBuf, kMaxAflInputSize);
+  LLVMFuzzerTestOneInput(AflInputBuf, l);
+
+}
+
+int main(int argc, char **argv) {
+
+  if (LLVMFuzzerInitialize) LLVMFuzzerInitialize(&argc, &argv);
+  // Do any other expensive one-time initialization here.
+
+  if (getenv("AFL_QEMU_DRIVER_NO_HOOK")) {
+
+    afl_qemu_driver_stdin_input();
+
+  } else {
+
+    uint8_t dummy_input[1] = {0};
+    LLVMFuzzerTestOneInput(dummy_input, 1);
+
+  }
+
+  return 0;
+
+}
+
diff --git a/examples/aflpp_driver/aflpp_qemu_driver_hook.c b/examples/aflpp_driver/aflpp_qemu_driver_hook.c
new file mode 100644
index 00000000..823cc42d
--- /dev/null
+++ b/examples/aflpp_driver/aflpp_qemu_driver_hook.c
@@ -0,0 +1,22 @@
+#include <stdint.h>
+#include <string.h>
+
+#define g2h(x) ((void *)((unsigned long)(x) + guest_base))
+
+#define REGS_RDI 7
+#define REGS_RSI 6
+
+void afl_persistent_hook(uint64_t *regs, uint64_t guest_base,
+                         uint8_t *input_buf, uint32_t input_len) {
+
+  memcpy(g2h(regs[REGS_RDI]), input_buf, input_len);
+  regs[REGS_RSI] = input_len;
+
+}
+
+int afl_persistent_hook_init(void) {
+
+  return 1;
+
+}
+
diff --git a/examples/persistent_demo/Makefile b/examples/persistent_demo/Makefile
index cbbb7239..6fa1c30e 100644
--- a/examples/persistent_demo/Makefile
+++ b/examples/persistent_demo/Makefile
@@ -1,6 +1,10 @@
 all:
 	afl-clang-fast -o persistent_demo persistent_demo.c
 	afl-clang-fast -o persistent_demo_new persistent_demo_new.c
+	AFL_DONT_OPTIMIZE=1 afl-clang-fast -o test-instr test-instr.c
+
+document:
+	AFL_DONT_OPTIMIZE=1 afl-clang-fast -D_AFL_DOCUMENT_MUTATIONS -o test-instr test-instr.c
 
 clean:
-	rm -f persistent_demo persistent_demo_new
+	rm -f persistent_demo persistent_demo_new test-instr
diff --git a/examples/persistent_demo/persistent_demo.c b/examples/persistent_demo/persistent_demo.c
index 2da49bb0..4cedc32c 100644
--- a/examples/persistent_demo/persistent_demo.c
+++ b/examples/persistent_demo/persistent_demo.c
@@ -41,6 +41,7 @@ int main(int argc, char **argv) {
      terminate normally. This limits the impact of accidental memory leaks
      and similar hiccups. */
 
+  __AFL_INIT();
   while (__AFL_LOOP(1000)) {
 
     /*** PLACEHOLDER CODE ***/
diff --git a/examples/persistent_demo/persistent_demo_new.c b/examples/persistent_demo/persistent_demo_new.c
index 36411e13..98909442 100644
--- a/examples/persistent_demo/persistent_demo_new.c
+++ b/examples/persistent_demo/persistent_demo_new.c
@@ -42,9 +42,10 @@ int main(int argc, char **argv) {
      terminate normally. This limits the impact of accidental memory leaks
      and similar hiccups. */
 
+  __AFL_INIT();
   buf = __AFL_FUZZ_TESTCASE_BUF;
 
-  while (__AFL_LOOP(1000)) {
+  while (__AFL_LOOP(1000)) {  // increase if you have good stability
 
     len = __AFL_FUZZ_TESTCASE_LEN;
 
diff --git a/examples/persistent_demo/test-instr.c b/examples/persistent_demo/test-instr.c
new file mode 100644
index 00000000..a6188b22
--- /dev/null
+++ b/examples/persistent_demo/test-instr.c
@@ -0,0 +1,69 @@
+/*
+   american fuzzy lop++ - a trivial program to test the build
+   --------------------------------------------------------
+   Originally written by Michal Zalewski
+   Copyright 2014 Google Inc. All rights reserved.
+   Copyright 2019-2020 AFLplusplus Project. 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
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+__AFL_FUZZ_INIT();
+
+int main(int argc, char **argv) {
+
+  __AFL_INIT();
+  unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
+
+  while (__AFL_LOOP(2147483647)) {  // MAX_INT if you have 100% stability
+
+    unsigned int len = __AFL_FUZZ_TESTCASE_LEN;
+
+#ifdef _AFL_DOCUMENT_MUTATIONS
+    static unsigned int counter = 0;
+    char                fn[32];
+    sprintf(fn, "%09u:test-instr", counter);
+    int fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+    if (fd_doc >= 0) {
+
+      if (write(fd_doc, buf, len) != __afl_fuzz_len) {
+
+        fprintf(stderr, "write of mutation file failed: %s\n", fn);
+        unlink(fn);
+
+      }
+
+      close(fd_doc);
+
+    }
+
+    counter++;
+#endif
+
+    // fprintf(stderr, "len: %u\n", len);
+
+    if (!len) continue;
+
+    if (buf[0] == '0')
+      printf("Looks like a zero to me!\n");
+    else if (buf[0] == '1')
+      printf("Pretty sure that is a one!\n");
+    else
+      printf("Neither one or zero? How quaint!\n");
+
+  }
+
+  return 0;
+
+}
+
diff --git a/examples/qemu_persistent_hook/read_into_rdi.c b/examples/qemu_persistent_hook/read_into_rdi.c
index 6cf66ddf..180d9f00 100644
--- a/examples/qemu_persistent_hook/read_into_rdi.c
+++ b/examples/qemu_persistent_hook/read_into_rdi.c
@@ -35,16 +35,26 @@ enum {
 
 };
 
-void afl_persistent_hook(uint64_t *regs, uint64_t guest_base) {
+void afl_persistent_hook(uint64_t *regs, uint64_t guest_base,
+                         uint8_t *input_buf, uint32_t input_len) {
 
   // In this example the register RDI is pointing to the memory location
   // of the target buffer, and the length of the input is in RSI.
   // This can be seen with a debugger, e.g. gdb (and "disass main")
 
-  printf("reading into %p\n", regs[R_EDI]);
-  size_t r = read(0, g2h(regs[R_EDI]), 1024);
-  regs[R_ESI] = r;
-  printf("read %ld bytes\n", r);
+  printf("placing input into %p\n", regs[R_EDI]);
+
+  if (input_len > 1024) input_len = 1024;
+  memcpy(g2h(regs[R_EDI]), input_buf, input_len);
+  regs[R_ESI] = input_len;
+
+}
+
+int afl_persistent_hook_init(void) {
+
+  // 1 for shared memory input (faster), 0 for normal input (you have to use
+  // read(), input_buf will be NULL)
+  return 1;
 
 }
 
diff --git a/gcc_plugin/README.md b/gcc_plugin/README.md
index fcc778fa..f762131e 100644
--- a/gcc_plugin/README.md
+++ b/gcc_plugin/README.md
@@ -71,7 +71,7 @@ reports to <hexcoder-@github.com>.
 ## 4) Bonus feature #1: deferred initialization
 
 AFL tries to optimize performance by executing the targeted binary just once,
-stopping it just before main(), and then cloning this "master" process to get
+stopping it just before main(), and then cloning this "main" process to get
 a steady supply of targets to fuzz.
 
 Although this approach eliminates much of the OS-, linker- and libc-level
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 32ae2a58..3b5cc0e2 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -408,8 +408,8 @@ typedef struct afl_state {
       debug,                            /* Debug mode                       */
       custom_only,                      /* Custom mutator only mode         */
       python_only,                      /* Python-only mode                 */
-      is_master,                        /* if this is a master              */
-      is_slave;                         /* if this is a slave               */
+      is_main_node,                     /* if this is the main node         */
+      is_secondary_node;                /* if this is a secondary instance  */
 
   u32 stats_update_freq;                /* Stats update frequency (execs)   */
 
@@ -421,7 +421,7 @@ typedef struct afl_state {
 
   u8 skip_deterministic,                /* Skip deterministic stages?       */
       use_splicing,                     /* Recombine input files?           */
-      dumb_mode,                        /* Run in non-instrumented mode?    */
+      non_instrumented_mode,            /* Run in non-instrumented mode?    */
       score_changed,                    /* Scoring for favorites changed?   */
       resuming_fuzz,                    /* Resuming an older fuzzing job?   */
       timeout_given,                    /* Specific timeout given?          */
@@ -444,7 +444,8 @@ typedef struct afl_state {
       deferred_mode,                    /* Deferred forkserver mode?        */
       fixed_seed,                       /* do not reseed                    */
       fast_cal,                         /* Try to calibrate faster?         */
-      disable_trim;                     /* Never trim in fuzz_one           */
+      disable_trim,                     /* Never trim in fuzz_one           */
+      shmem_testcase_mode;              /* If sharedmem testcases are used  */
 
   u8 *virgin_bits,                      /* Regions yet untouched by fuzzing */
       *virgin_tmout,                    /* Bits we haven't seen in tmouts   */
@@ -502,7 +503,7 @@ typedef struct afl_state {
   s32 stage_cur, stage_max;             /* Stage progression                */
   s32 splicing_with;                    /* Splicing with which test case?   */
 
-  u32 master_id, master_max;            /* Master instance job splitting    */
+  u32 main_node_id, main_node_max;      /*   Main instance job splitting    */
 
   u32 syncing_case;                     /* Syncing with case #...           */
 
@@ -806,6 +807,9 @@ void afl_states_clear_screen(void);
 /* Sets the skip flag on all states */
 void afl_states_request_skip(void);
 
+/* Setup shmem for testcase delivery */
+void setup_testcase_shmem(afl_state_t *afl);
+
 void read_afl_environment(afl_state_t *, char **);
 
 /**** Prototypes ****/
@@ -912,7 +916,7 @@ u32    find_start_position(afl_state_t *);
 void   find_timeout(afl_state_t *);
 double get_runnable_processes(void);
 void   nuke_resume_dir(afl_state_t *);
-int    check_master_exists(afl_state_t *);
+int    check_main_node_exists(afl_state_t *);
 void   setup_dirs_fds(afl_state_t *);
 void   setup_cmdline_file(afl_state_t *, char **);
 void   setup_stdio_file(afl_state_t *);
diff --git a/include/common.h b/include/common.h
index 4aed9572..87a7425b 100644
--- a/include/common.h
+++ b/include/common.h
@@ -107,14 +107,7 @@ u8 *u_stringify_mem_size(u8 *buf, u64 val);
 
 u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms);
 
-/* Wrapper for select() and read(), reading exactly len bytes.
-  Returns the time passed to read.
-  stop_soon should point to a variable indicating ctrl+c was pressed.
-  If the wait times out, returns timeout_ms + 1;
-  Returns 0 if an error occurred (fd closed, signal, ...); */
-u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms,
-               volatile u8 *stop_soon_p);
-
+/* Reads the map size from ENV */
 u32 get_map_size(void);
 
 #endif
diff --git a/include/forkserver.h b/include/forkserver.h
index 00555d7e..fa132837 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -75,15 +75,15 @@ typedef struct afl_forkserver {
 
   u8 use_shdmen_fuzz;                   /* use shared mem for test cases    */
 
-  u8 support_shdmen_fuzz;               /* set by afl-fuzz                  */
+  u8 support_shmem_fuzz;                /* set by afl-fuzz                  */
 
   u8 use_fauxsrv;                       /* Fauxsrv for non-forking targets? */
 
   u8 qemu_mode;                         /* if running in qemu mode or not   */
 
-  u32 shdmem_fuzz_len;                   /* length of the fuzzing test case */
+  u32 *shmem_fuzz_len;                  /* length of the fuzzing test case  */
 
-  u8 *shdmem_fuzz;                      /* allocated memory for fuzzing     */
+  u8 *shmem_fuzz;                       /* allocated memory for fuzzing     */
 
   char *cmplog_binary;                  /* the name of the cmplog binary    */
 
diff --git a/include/sharedmem.h b/include/sharedmem.h
index 066a9904..a77ab7c0 100644
--- a/include/sharedmem.h
+++ b/include/sharedmem.h
@@ -53,7 +53,7 @@ typedef struct sharedmem {
 
 } sharedmem_t;
 
-u8 * afl_shm_init(sharedmem_t *, size_t, unsigned char dumb_mode);
+u8 * afl_shm_init(sharedmem_t *, size_t, unsigned char non_instrumented_mode);
 void afl_shm_deinit(sharedmem_t *);
 
 #endif
diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile
index 50a6be2b..5efe1e12 100644
--- a/llvm_mode/GNUmakefile
+++ b/llvm_mode/GNUmakefile
@@ -226,6 +226,10 @@ endif
 
 ifeq "$(shell uname)" "OpenBSD"
   CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
+  CLANG_CFL += -mno-retpoline
+  CFLAGS += -mno-retpoline
+  # Needed for unwind symbols
+  LDFLAGS += -lc++abi
 endif
 
 ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
@@ -354,16 +358,21 @@ endif
 ../cmplog-instructions-pass.so:	cmplog-instructions-pass.cc afl-llvm-common.o | test_deps
 	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
 
+document:
+	$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
+	@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m32 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
+	@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m64 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
+
 ../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
 	$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -fPIC -c $< -o $@
 
 ../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
 	@printf "[*] Building 32-bit variant of the runtime (-m32)... "
-	@$(CC_SAVE) $(CFLAGS) -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
+	@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
 
 ../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
 	@printf "[*] Building 64-bit variant of the runtime (-m64)... "
-	@$(CC_SAVE) $(CFLAGS) -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
+	@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
 
 test_build: $(PROGS)
 	@echo "[*] Testing the CC wrapper and instrumentation output..."
diff --git a/llvm_mode/README.persistent_mode.md b/llvm_mode/README.persistent_mode.md
index 7aae8faa..83cc7f4d 100644
--- a/llvm_mode/README.persistent_mode.md
+++ b/llvm_mode/README.persistent_mode.md
@@ -55,7 +55,7 @@ The speed increase is usually x10 to x20.
 ## 3) deferred initialization
 
 AFL tries to optimize performance by executing the targeted binary just once,
-stopping it just before main(), and then cloning this "master" process to get
+stopping it just before main(), and then cloning this "main" process to get
 a steady supply of targets to fuzz.
 
 Although this approach eliminates much of the OS-, linker- and libc-level
diff --git a/llvm_mode/README.whitelist.md b/llvm_mode/README.whitelist.md
index 72fb5d09..6393fae8 100644
--- a/llvm_mode/README.whitelist.md
+++ b/llvm_mode/README.whitelist.md
@@ -73,3 +73,7 @@ For old LLVM versions this feature might require to be compiled with debug
 information (-g), however at least from llvm version 6.0 onwards this is not
 required anymore (and might hurt performance and crash detection, so better not
 use -g).
+
+## 4) UNIX-style filename pattern matching
+You can add UNIX-style pattern matching in the whitelist entries. See `man
+fnmatch` for the syntax. We do not set any of the `fnmatch` flags.
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index 0b081ae6..75504ea5 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -176,7 +176,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
           "Using afl-clang-lto is not possible because Makefile magic did not "
           "identify the correct -flto flag");
 
-  if (!strcmp(name, "afl-clang-fast++") || !strcmp(name, "afl-clang-lto++")) {
+  if (!strcmp(name, "afl-clang-fast++") || !strcmp(name, "afl-clang-lto++") ||
+      !strcmp(name, "afl-clang++")) {
 
     u8 *alt_cxx = getenv("AFL_CXX");
     if (USE_BINDIR)
@@ -188,7 +189,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   } else if (!strcmp(name, "afl-clang-fast") ||
 
-             !strcmp(name, "afl-clang-lto")) {
+             !strcmp(name, "afl-clang-lto") || !strcmp(name, "afl-clang")) {
 
     u8 *alt_cc = getenv("AFL_CC");
     if (USE_BINDIR)
@@ -494,14 +495,14 @@ static void edit_params(u32 argc, char **argv, char **envp) {
   cc_params[cc_par_cnt++] =
       "-D__AFL_FUZZ_INIT()="
       "int __afl_sharedmem_fuzzing = 1;"
-      "extern unsigned int __afl_fuzz_len;"
+      "extern unsigned int *__afl_fuzz_len;"
       "extern unsigned char *__afl_fuzz_ptr;"
       "unsigned char *__afl_fuzz_alt_ptr;";
   cc_params[cc_par_cnt++] =
       "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
       "(__afl_fuzz_alt_ptr = malloc(1 * 1024 * 1024)))";
   cc_params[cc_par_cnt++] =
-      "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? __afl_fuzz_len : read(0, "
+      "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : read(0, "
       "__afl_fuzz_alt_ptr, 1 * 1024 * 1024))";
 
   cc_params[cc_par_cnt++] =
diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc
index 35eabbf0..6c7222cd 100644
--- a/llvm_mode/afl-llvm-common.cc
+++ b/llvm_mode/afl-llvm-common.cc
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/time.h>
+#include <fnmatch.h>
 
 #include <list>
 #include <string>
@@ -152,12 +153,13 @@ bool isInWhitelist(llvm::Function *F) {
         /* We don't check for filename equality here because
          * filenames might actually be full paths. Instead we
          * check that the actual filename ends in the filename
-         * specified in the list. */
+         * specified in the list. We also allow UNIX-style pattern
+         * matching */
+
         if (instFilename.str().length() >= it->length()) {
 
-          if (instFilename.str().compare(
-                  instFilename.str().length() - it->length(), it->length(),
-                  *it) == 0) {
+          if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
+              0) {
 
             return true;
 
@@ -189,12 +191,13 @@ bool isInWhitelist(llvm::Function *F) {
         /* We don't check for filename equality here because
          * filenames might actually be full paths. Instead we
          * check that the actual filename ends in the filename
-         * specified in the list. */
+         * specified in the list. We also allow UNIX-style pattern
+         * matching */
+
         if (instFilename.str().length() >= it->length()) {
 
-          if (instFilename.str().compare(
-                  instFilename.str().length() - it->length(), it->length(),
-                  *it) == 0) {
+          if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
+              0) {
 
             return true;
 
diff --git a/llvm_mode/afl-llvm-lto-whitelist.so.cc b/llvm_mode/afl-llvm-lto-whitelist.so.cc
index 8856ce21..33d40da8 100644
--- a/llvm_mode/afl-llvm-lto-whitelist.so.cc
+++ b/llvm_mode/afl-llvm-lto-whitelist.so.cc
@@ -36,6 +36,7 @@
 #include <string>
 #include <fstream>
 #include <sys/time.h>
+#include <fnmatch.h>
 
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/BasicBlock.h"
@@ -175,9 +176,8 @@ bool AFLwhitelist::runOnModule(Module &M) {
              * specified in the list. */
             if (instFilename.str().length() >= it->length()) {
 
-              if (instFilename.str().compare(
-                      instFilename.str().length() - it->length(), it->length(),
-                      *it) == 0) {
+              if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
+                  0) {
 
                 instrumentFunction = true;
                 break;
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index 3a0584e4..4bca3d37 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -74,10 +74,11 @@ u8 __afl_area_initial[MAP_INITIAL_SIZE];
 #else
 u8                  __afl_area_initial[MAP_SIZE];
 #endif
-u8 *__afl_area_ptr = __afl_area_initial;
-u8 *__afl_dictionary;
-u8 *__afl_fuzz_ptr;
-u32 __afl_fuzz_len;
+u8 * __afl_area_ptr = __afl_area_initial;
+u8 * __afl_dictionary;
+u8 * __afl_fuzz_ptr;
+u32  __afl_fuzz_len_dummy;
+u32 *__afl_fuzz_len = &__afl_fuzz_len_dummy;
 
 u32 __afl_final_loc;
 u32 __afl_map_size = MAP_SIZE;
@@ -136,18 +137,18 @@ static void __afl_map_shm_fuzz() {
 
     }
 
-    __afl_fuzz_ptr = mmap(0, MAX_FILE, PROT_READ, MAP_SHARED, shm_fd, 0);
+    __afl_fuzz_len = (u32 *)mmap(0, MAX_FILE, PROT_READ, MAP_SHARED, shm_fd, 0);
 
 #else
     u32 shm_id = atoi(id_str);
 
-    __afl_fuzz_ptr = shmat(shm_id, NULL, 0);
+    __afl_fuzz_len = (u32 *)shmat(shm_id, NULL, 0);
 
 #endif
 
     /* Whooooops. */
 
-    if (__afl_fuzz_ptr == (void *)-1) {
+    if (__afl_fuzz_len == (void *)-1) {
 
       fprintf(stderr, "Error: could not access fuzzing shared memory\n");
       exit(1);
@@ -164,6 +165,8 @@ static void __afl_map_shm_fuzz() {
 
   }
 
+  __afl_fuzz_ptr = (u8 *)(__afl_fuzz_len + sizeof(int));
+
 }
 
 /* SHM setup. */
@@ -420,7 +423,7 @@ static void __afl_start_snapshots(void) {
 
     } else {
 
-      // uh this forkserver master does not understand extended option passing
+      // uh this forkserver does not understand extended option passing
       // or does not want the dictionary
       if (!__afl_fuzz_ptr) already_read_first = 1;
 
@@ -443,8 +446,31 @@ static void __afl_start_snapshots(void) {
 
     }
 
-    __afl_fuzz_len = (was_killed >> 8);
-    was_killed = (was_killed & 0xff);
+  #ifdef _AFL_DOCUMENT_MUTATIONS
+    if (__afl_fuzz_ptr) {
+
+      static uint32_t counter = 0;
+      char            fn[32];
+      sprintf(fn, "%09u:forkserver", counter);
+      s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+      if (fd_doc >= 0) {
+
+        if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) {
+
+          fprintf(stderr, "write of mutation file failed: %s\n", fn);
+          unlink(fn);
+
+        }
+
+        close(fd_doc);
+
+      }
+
+      counter++;
+
+    }
+
+  #endif
 
     /* If we stopped the child in persistent mode, but there was a race
        condition and afl-fuzz already issued SIGKILL, write off the old
@@ -596,7 +622,7 @@ static void __afl_start_forkserver(void) {
 
     } else {
 
-      // uh this forkserver master does not understand extended option passing
+      // uh this forkserver does not understand extended option passing
       // or does not want the dictionary
       if (!__afl_fuzz_ptr) already_read_first = 1;
 
@@ -620,8 +646,31 @@ static void __afl_start_forkserver(void) {
 
     }
 
-    __afl_fuzz_len = (was_killed >> 8);
-    was_killed = (was_killed & 0xff);
+#ifdef _AFL_DOCUMENT_MUTATIONS
+    if (__afl_fuzz_ptr) {
+
+      static uint32_t counter = 0;
+      char            fn[32];
+      sprintf(fn, "%09u:forkserver", counter);
+      s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+      if (fd_doc >= 0) {
+
+        if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) {
+
+          fprintf(stderr, "write of mutation file failed: %s\n", fn);
+          unlink(fn);
+
+        }
+
+        close(fd_doc);
+
+      }
+
+      counter++;
+
+    }
+
+#endif
 
     /* If we stopped the child in persistent mode, but there was a race
        condition and afl-fuzz already issued SIGKILL, write off the old
diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h
index 057e1b62..92c33b50 100644
--- a/qemu_mode/patches/afl-qemu-common.h
+++ b/qemu_mode/patches/afl-qemu-common.h
@@ -63,7 +63,9 @@
   #define INC_AFL_AREA(loc) afl_area_ptr[loc]++
 #endif
 
-typedef void (*afl_persistent_hook_fn)(uint64_t *regs, uint64_t guest_base);
+typedef void (*afl_persistent_hook_fn)(uint64_t *regs, uint64_t guest_base,
+                                       uint8_t *input_buf,
+                                       uint32_t input_buf_len);
 
 /* Declared in afl-qemu-cpu-inl.h */
 
@@ -81,6 +83,10 @@ extern unsigned char  persistent_save_gpr;
 extern uint64_t       persistent_saved_gpr[AFL_REGS_NUM];
 extern int            persisent_retaddr_offset;
 
+extern u8 * shared_buf;
+extern u32 *shared_buf_len;
+extern u8   sharedmem_fuzzing;
+
 extern afl_persistent_hook_fn afl_persistent_hook_ptr;
 
 extern __thread abi_ulong afl_prev_loc;
diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h
index e4ebaf88..d3893066 100644
--- a/qemu_mode/patches/afl-qemu-cpu-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-inl.h
@@ -83,6 +83,10 @@ unsigned char persistent_save_gpr;
 uint64_t      persistent_saved_gpr[AFL_REGS_NUM];
 int           persisent_retaddr_offset;
 
+u8 * shared_buf;
+u32 *shared_buf_len;
+u8   sharedmem_fuzzing;
+
 afl_persistent_hook_fn afl_persistent_hook_ptr;
 
 /* Instrumentation ratio: */
@@ -128,6 +132,7 @@ static inline TranslationBlock *tb_find(CPUState *, TranslationBlock *, int,
 static inline void              tb_add_jump(TranslationBlock *tb, int n,
                                             TranslationBlock *tb_next);
 int                             open_self_maps(void *cpu_env, int fd);
+static void                     afl_map_shm_fuzz(void);
 
 /*************************
  * ACTUAL IMPLEMENTATION *
@@ -135,6 +140,38 @@ int                             open_self_maps(void *cpu_env, int fd);
 
 /* Set up SHM region and initialize other stuff. */
 
+static void afl_map_shm_fuzz(void) {
+
+  char *id_str = getenv(SHM_FUZZ_ENV_VAR);
+
+  if (id_str) {
+
+    u32 shm_id = atoi(id_str);
+    shared_buf_len = (u32 *)shmat(shm_id, NULL, 0);
+    shared_buf = (u8 *)(shared_buf_len + sizeof(int));
+
+    /* Whooooops. */
+
+    if (shared_buf == (void *)-1) {
+
+      fprintf(stderr, "[AFL] ERROR:  could not access fuzzing shared memory\n");
+      exit(1);
+
+    }
+
+    if (getenv("AFL_DEBUG"))
+      fprintf(stderr, "[AFL] DEBUG: successfully got fuzzing shared memory\n");
+
+  } else {
+
+    fprintf(stderr,
+            "[AFL] ERROR:  variable for fuzzing shared memory is not set\n");
+    exit(1);
+
+  }
+
+}
+
 void afl_setup(void) {
 
   char *id_str = getenv(SHM_ENV_VAR), *inst_r = getenv("AFL_INST_RATIO");
@@ -248,6 +285,11 @@ void afl_setup(void) {
 
     }
 
+    int (*afl_persistent_hook_init_ptr)(void) =
+        dlsym(plib, "afl_persistent_hook_init");
+    if (afl_persistent_hook_init_ptr)
+      sharedmem_fuzzing = afl_persistent_hook_init_ptr();
+
     afl_persistent_hook_ptr = dlsym(plib, "afl_persistent_hook");
     if (!afl_persistent_hook_ptr) {
 
@@ -278,7 +320,7 @@ void afl_setup(void) {
 
 void afl_forkserver(CPUState *cpu) {
 
-  u32           map_size = 0;
+  // u32           map_size = 0;
   unsigned char tmp[4] = {0};
 
   if (forkserver_installed == 1) return;
@@ -291,15 +333,15 @@ void afl_forkserver(CPUState *cpu) {
   pid_t child_pid;
   int   t_fd[2];
   u8    child_stopped = 0;
+  u32   was_killed;
+  int   status;
 
-  // if in the future qemu has non-collding coverage then switch MAP_SIZE
   // with the max ID value
-  if (MAP_SIZE <= 0x800000) {
-
-    map_size = (FS_OPT_ENABLED | FS_OPT_MAPSIZE | FS_OPT_SET_MAPSIZE(MAP_SIZE));
-    memcpy(tmp, &map_size, 4);
-
-  }
+  if (MAP_SIZE <= FS_OPT_MAX_MAPSIZE)
+    status |= (FS_OPT_SET_MAPSIZE(MAP_SIZE) | FS_OPT_MAPSIZE);
+  if (sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
+  if (status) status |= (FS_OPT_ENABLED);
+  memcpy(tmp, &status, 4);
 
   /* Tell the parent that we're alive. If the parent doesn't want
      to talk, assume that we're not running in forkserver mode. */
@@ -310,13 +352,28 @@ void afl_forkserver(CPUState *cpu) {
 
   int first_run = 1;
 
+  if (sharedmem_fuzzing) {
+
+    if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2);
+
+    if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) ==
+        (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))
+      afl_map_shm_fuzz();
+    else {
+
+      fprintf(stderr,
+              "[AFL] ERROR: afl-fuzz is old and does not support"
+              " shmem input");
+      exit(1);
+
+    }
+
+  }
+
   /* All right, let's await orders... */
 
   while (1) {
 
-    int status;
-    u32 was_killed;
-
     /* Whoops, parent dead? */
 
     if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2);
diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
index 083c27e5..8553f194 100644
--- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
@@ -161,7 +161,8 @@ static void log_x86_sp_content(void) {
 
 static void callback_to_persistent_hook(void) {
 
-  afl_persistent_hook_ptr(persistent_saved_gpr, guest_base);
+  afl_persistent_hook_ptr(persistent_saved_gpr, guest_base, shared_buf,
+                          *shared_buf_len);
 
 }
 
diff --git a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
index a0246198..400ebf24 100644
--- a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
+++ b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
@@ -215,7 +215,7 @@ void HELPER(afl_cmplog_rtn)(CPUArchState *env) {
 
 #else
 
-  // dumb code to make it compile
+  // stupid code to make it compile
   void *ptr1 = NULL;
   void *ptr2 = NULL;
   return;
diff --git a/src/afl-common.c b/src/afl-common.c
index 1bb58a60..f4cba573 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -253,7 +253,8 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
        "binaries that are\n"
        "    instrumented at compile time with afl-gcc. It is also possible to "
        "use it as a\n"
-       "    traditional \"dumb\" fuzzer by specifying '-n' in the command "
+       "    traditional non-instrumented fuzzer by specifying '-n' in the "
+       "command "
        "line.\n");
 
   FATAL("Failed to locate 'afl-qemu-trace'.");
@@ -353,7 +354,8 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
        "binaries that are\n"
        "    instrumented at compile time with afl-gcc. It is also possible to "
        "use it as a\n"
-       "    traditional \"dumb\" fuzzer by specifying '-n' in the command "
+       "    traditional non-instrumented fuzzer by specifying '-n' in the "
+       "command "
        "line.\n",
        ncp);
 
@@ -869,56 +871,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
 
 }
 
-/* Wrapper for select() and read(), reading exactly len bytes.
-  Returns the time passed to read.
-  If the wait times out, returns timeout_ms + 1;
-  Returns 0 if an error occurred (fd closed, signal, ...); */
-u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms,
-               volatile u8 *stop_soon_p) {
-
-  struct timeval timeout;
-  fd_set         readfds;
-  FD_ZERO(&readfds);
-  FD_SET(fd, &readfds);
-
-  timeout.tv_sec = (timeout_ms / 1000);
-  timeout.tv_usec = (timeout_ms % 1000) * 1000;
-
-  size_t read_total = 0;
-  size_t len_read = 0;
-
-  while (len_read < len) {
-
-    /* set exceptfds as well to return when a child exited/closed the pipe. */
-    int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
-
-    if (!sret) {
-
-      // printf("Timeout in sret.");
-      return timeout_ms + 1;
-
-    } else if (sret < 0) {
-
-      /* Retry select for all signals other than than ctrl+c */
-      if (errno == EINTR && !*stop_soon_p) { continue; }
-      return 0;
-
-    }
-
-    len_read = read(fd, ((u8 *)buf) + len_read, len - len_read);
-    if (!len_read) { return 0; }
-    read_total += len_read;
-
-  }
-
-  s32 exec_ms =
-      MIN(timeout_ms,
-          ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
-  return exec_ms > 0 ? exec_ms
-                     : 1;  // at least 1 milli must have passed (0 is an error)
-
-}
-
+/* Reads the map size from ENV */
 u32 get_map_size(void) {
 
   uint32_t map_size = MAP_SIZE;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 137a4f99..a5e2db54 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -119,7 +119,55 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
 
 }
 
-/* Internal forkserver for dumb_mode=1 and non-forkserver mode runs.
+/* Wrapper for select() and read(), reading a 32 bit var.
+  Returns the time passed to read.
+  If the wait times out, returns timeout_ms + 1;
+  Returns 0 if an error occurred (fd closed, signal, ...); */
+static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
+                          volatile u8 *stop_soon_p) {
+
+  fd_set readfds;
+  FD_ZERO(&readfds);
+  FD_SET(fd, &readfds);
+  struct timeval timeout;
+  size_t         len = 4;
+
+  timeout.tv_sec = (timeout_ms / 1000);
+  timeout.tv_usec = (timeout_ms % 1000) * 1000;
+#if !defined(__linux__)
+  u64 read_start = get_cur_time_us();
+#endif
+
+  /* set exceptfds as well to return when a child exited/closed the pipe. */
+  int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
+
+  if (!sret) {
+
+    return timeout_ms + 1;
+
+  } else if (sret < 0) {
+
+    return 0;
+
+  }
+
+  ssize_t len_read = read(fd, ((u8 *)buf), len);
+  if (len_read < len) { return 0; }
+
+#if defined(__linux__)
+  u32 exec_ms =
+      MIN(timeout_ms,
+          ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
+#else
+  u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
+#endif
+
+  // ensure to report 1 ms has passed (0 is an error)
+  return exec_ms > 0 ? exec_ms : 1;
+
+}
+
+/* Internal forkserver for non_instrumented_mode=1 and non-forkserver mode runs.
   It execvs for each fork, forwarding exit codes and child pids to afl. */
 
 static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
@@ -238,7 +286,7 @@ static void report_error_and_exit(int error) {
 
 }
 
-/* Spins up fork server (instrumented mode only). The idea is explained here:
+/* Spins up fork server. The idea is explained here:
 
    http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html
 
@@ -250,14 +298,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
                     volatile u8 *stop_soon_p, u8 debug_child_output) {
 
   int st_pipe[2], ctl_pipe[2];
-  int status;
+  s32 status;
   s32 rlen;
 
   if (!be_quiet) { ACTF("Spinning up the fork server..."); }
 
   if (fsrv->use_fauxsrv) {
 
-    /* TODO: Come up with sone nice way to initalize this all */
+    /* TODO: Come up with sone nice way to initialize this all */
 
     if (fsrv->init_child_func != fsrv_exec_child) {
 
@@ -406,14 +454,15 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
   rlen = 0;
   if (fsrv->exec_tmout) {
 
-    u32 time = read_timed(fsrv->fsrv_st_fd, &status, 4,
-                          fsrv->exec_tmout * FORK_WAIT_MULT, stop_soon_p);
+    u32 time_ms =
+        read_s32_timed(fsrv->fsrv_st_fd, &status,
+                       fsrv->exec_tmout * FORK_WAIT_MULT, stop_soon_p);
 
-    if (!time) {
+    if (!time_ms) {
 
       kill(fsrv->fsrv_pid, SIGKILL);
 
-    } else if (time > fsrv->exec_tmout * FORK_WAIT_MULT) {
+    } else if (time_ms > fsrv->exec_tmout * FORK_WAIT_MULT) {
 
       fsrv->last_run_timed_out = 1;
       kill(fsrv->fsrv_pid, SIGKILL);
@@ -457,7 +506,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
       if ((status & FS_OPT_SHDMEM_FUZZ) == FS_OPT_SHDMEM_FUZZ) {
 
-        if (fsrv->support_shdmen_fuzz) {
+        if (fsrv->support_shmem_fuzz) {
 
           fsrv->use_shdmen_fuzz = 1;
           if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); }
@@ -473,6 +522,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
           }
 
+        } else {
+
+          FATAL(
+              "Target requested sharedmem fuzzing, but we failed to enable "
+              "it.");
+
         }
 
       }
@@ -774,10 +829,11 @@ static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
 
 void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
 
-  if (fsrv->shdmem_fuzz) {
+  if (fsrv->shmem_fuzz) {
 
-    memcpy(fsrv->shdmem_fuzz, buf, len);
-    fsrv->shdmem_fuzz_len = len;
+    *fsrv->shmem_fuzz_len = len;
+    memcpy(fsrv->shmem_fuzz, buf, len);
+    // fprintf(stderr, "test case len: %u\n", *fsrv->shmem_fuzz_len);
 
   } else {
 
@@ -839,8 +895,6 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
 
   MEM_BARRIER();
 
-  if (fsrv->shdmem_fuzz_len) write_value += (fsrv->shdmem_fuzz_len << 8);
-
   /* we have the fork server (or faux server) up and running
   First, tell it if the previous run timed out. */
 
@@ -862,8 +916,8 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
 
   if (fsrv->child_pid <= 0) { FATAL("Fork server is misbehaving (OOM?)"); }
 
-  exec_ms = read_timed(fsrv->fsrv_st_fd, &fsrv->child_status, 4, timeout,
-                       stop_soon_p);
+  exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout,
+                           stop_soon_p);
 
   if (exec_ms > timeout) {
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index ff078319..5b98be9e 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -623,14 +623,14 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       /* Timeouts are not very interesting, but we're still obliged to keep
          a handful of samples. We use the presence of new bits in the
-         hang-specific bitmap as a signal of uniqueness. In "dumb" mode, we
-         just keep everything. */
+         hang-specific bitmap as a signal of uniqueness. In "non-instrumented"
+         mode, we just keep everything. */
 
       ++afl->total_tmouts;
 
       if (afl->unique_hangs >= KEEP_UNIQUE_HANG) { return keeping; }
 
-      if (likely(!afl->dumb_mode)) {
+      if (likely(!afl->non_instrumented_mode)) {
 
 #ifdef WORD_SIZE_64
         simplify_trace(afl, (u64 *)afl->fsrv.trace_bits);
@@ -698,7 +698,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       if (afl->unique_crashes >= KEEP_UNIQUE_CRASH) { return keeping; }
 
-      if (likely(!afl->dumb_mode)) {
+      if (likely(!afl->non_instrumented_mode)) {
 
 #ifdef WORD_SIZE_64
         simplify_trace(afl, (u64 *)afl->fsrv.trace_bits);
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 9349fefe..96d4fc46 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1315,10 +1315,10 @@ dir_cleanup_failed:
 
 }
 
-/* If this is a -S slave, ensure a -M master is running, if a master is
-   running when another master is started then warn */
+/* If this is a -S secondary node, ensure a -M main node is running,
+  if a main node is running when another main is started, then warn */
 
-int check_master_exists(afl_state_t *afl) {
+int check_main_node_exists(afl_state_t *afl) {
 
   DIR *          sd;
   struct dirent *sd_ent;
@@ -1337,7 +1337,7 @@ int check_master_exists(afl_state_t *afl) {
 
     }
 
-    fn = alloc_printf("%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
+    fn = alloc_printf("%s/%s/is_main_node", afl->sync_dir, sd_ent->d_name);
     int res = access(fn, F_OK);
     free(fn);
     if (res == 0) return 1;
@@ -1392,9 +1392,9 @@ void setup_dirs_fds(afl_state_t *afl) {
 
   }
 
-  if (afl->is_master) {
+  if (afl->is_main_node) {
 
-    u8 *x = alloc_printf("%s/is_master", afl->out_dir);
+    u8 *x = alloc_printf("%s/is_main_node", afl->out_dir);
     int fd = open(x, O_CREAT | O_RDWR, 0644);
     if (fd < 0) FATAL("cannot create %s", x);
     free(x);
@@ -1859,7 +1859,11 @@ void fix_up_sync(afl_state_t *afl) {
 
   u8 *x = afl->sync_id;
 
-  if (afl->dumb_mode) { FATAL("-S / -M and -n are mutually exclusive"); }
+  if (afl->non_instrumented_mode) {
+
+    FATAL("-S / -M and -n are mutually exclusive");
+
+  }
 
   while (*x) {
 
@@ -1949,6 +1953,36 @@ static void handle_skipreq(int sig) {
 
 }
 
+/* Setup shared map for fuzzing with input via sharedmem */
+
+void setup_testcase_shmem(afl_state_t *afl) {
+
+  afl->shm_fuzz = ck_alloc(sizeof(sharedmem_t));
+
+  // we need to set the non-instrumented mode to not overwrite the SHM_ENV_VAR
+  if ((afl->fsrv.shmem_fuzz_len =
+           (u32 *)afl_shm_init(afl->shm_fuzz, MAX_FILE + sizeof(int), 1))) {
+
+#ifdef USEMMAP
+    setenv(SHM_FUZZ_ENV_VAR, afl->shm_fuzz->g_shm_file_path, 1);
+#else
+    u8 *shm_str;
+    shm_str = alloc_printf("%d", afl->shm_fuzz->shm_id);
+    setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
+    ck_free(shm_str);
+#endif
+    afl->fsrv.support_shmem_fuzz = 1;
+    afl->fsrv.shmem_fuzz = (u8 *)(afl->fsrv.shmem_fuzz_len + sizeof(int));
+
+  } else {
+
+    ck_free(afl->shm_fuzz);
+    afl->shm_fuzz = NULL;
+
+  }
+
+}
+
 /* Do a PATH search and find target binary to see that it exists and
    isn't a shell script - a common and painful mistake. We also check for
    a valid ELF header and for evidence of AFL instrumentation. */
@@ -2098,7 +2132,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
 
 #endif                                                       /* ^!__APPLE__ */
 
-  if (!afl->fsrv.qemu_mode && !afl->unicorn_mode && !afl->dumb_mode &&
+  if (!afl->fsrv.qemu_mode && !afl->unicorn_mode &&
+      !afl->non_instrumented_mode &&
       !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
 
     SAYF("\n" cLRD "[-] " cRST
@@ -2115,8 +2150,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
          "    mode support. Consult the README.md for tips on how to enable "
          "this.\n"
 
-         "    (It is also possible to use afl-fuzz as a traditional, \"dumb\" "
-         "fuzzer.\n"
+         "    (It is also possible to use afl-fuzz as a traditional, "
+         "non-instrumented fuzzer.\n"
          "    For that, you can use the -n option - but expect much worse "
          "results.)\n",
          doc_path);
@@ -2153,30 +2188,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
     OKF(cPIN "Persistent mode binary detected.");
     setenv(PERSIST_ENV_VAR, "1", 1);
     afl->persistent_mode = 1;
-    // do not fail if we can not get the fuzzing shared mem
-    if ((afl->shm_fuzz = calloc(1, sizeof(sharedmem_t)))) {
-
-      // we need to set the dumb mode to not overwrite the SHM_ENV_VAR
-      if ((afl->fsrv.shdmem_fuzz = afl_shm_init(afl->shm_fuzz, MAX_FILE, 1))) {
-
-#ifdef USEMMAP
-        setenv(SHM_FUZZ_ENV_VAR, afl->shm_fuzz->g_shm_file_path, 1);
-#else
-        u8 *shm_str;
-        shm_str = alloc_printf("%d", afl->shm_fuzz->shm_id);
-        setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
-        ck_free(shm_str);
-#endif
-        afl->fsrv.support_shdmen_fuzz = 1;
-
-      } else {
-
-        free(afl->shm_fuzz);
-        afl->shm_fuzz = NULL;
 
-      }
-
-    }
+    afl->shmem_testcase_mode = 1;
 
   } else if (getenv("AFL_PERSISTENT")) {
 
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 56f16b4c..578ac584 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -415,7 +415,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
 
     }
 
-  } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
+  } else if (!afl->non_instrumented_mode && !afl->queue_cur->favored &&
 
              afl->queued_paths > 10) {
 
@@ -512,7 +512,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
    * TRIMMING *
    ************/
 
-  if (!afl->dumb_mode && !afl->queue_cur->trim_done && !afl->disable_trim) {
+  if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done &&
+      !afl->disable_trim) {
 
     u8 res = trim_case(afl, afl->queue_cur, in_buf);
 
@@ -577,10 +578,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
   }
 
   /* Skip deterministic fuzzing if exec path checksum puts this out of scope
-     for this master instance. */
+     for this main instance. */
 
-  if (afl->master_max &&
-      (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) {
+  if (afl->main_node_max && (afl->queue_cur->exec_cksum % afl->main_node_max) !=
+                                afl->main_node_id - 1) {
 
     goto custom_mutator_stage;
 
@@ -650,7 +651,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
 
       */
 
-    if (!afl->dumb_mode && (afl->stage_cur & 7) == 7) {
+    if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
 
       u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
@@ -822,10 +823,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
 
       u32 cksum;
 
-      /* If in dumb mode or if the file is very short, just flag everything
-         without wasting time on checksums. */
+      /* If in non-instrumented mode or if the file is very short, just flag
+         everything without wasting time on checksums. */
 
-      if (!afl->dumb_mode && len >= EFF_MIN_LEN) {
+      if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
 
         cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
@@ -2568,7 +2569,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
     }
 
-  } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
+  } else if (!afl->non_instrumented_mode && !afl->queue_cur->favored &&
 
              afl->queued_paths > 10) {
 
@@ -2660,7 +2661,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
    * TRIMMING *
    ************/
 
-  if (!afl->dumb_mode && !afl->queue_cur->trim_done) {
+  if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done) {
 
     u8 res = trim_case(afl, afl->queue_cur, in_buf);
 
@@ -2730,10 +2731,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
   }
 
   /* Skip deterministic fuzzing if exec path checksum puts this out of scope
-     for this master instance. */
+     for this main instance. */
 
-  if (afl->master_max &&
-      (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) {
+  if (afl->main_node_max && (afl->queue_cur->exec_cksum % afl->main_node_max) !=
+                                afl->main_node_id - 1) {
 
     goto havoc_stage;
 
@@ -2803,7 +2804,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
       */
 
-    if (!afl->dumb_mode && (afl->stage_cur & 7) == 7) {
+    if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
 
       u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
@@ -2975,10 +2976,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
       u32 cksum;
 
-      /* If in dumb mode or if the file is very short, just flag everything
-         without wasting time on checksums. */
+      /* If in non-instrumented mode or if the file is very short, just flag
+         everything without wasting time on checksums. */
 
-      if (!afl->dumb_mode && len >= EFF_MIN_LEN) {
+      if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
 
         cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index cfeb6c5e..ea7f57e2 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -303,7 +303,7 @@ void cull_queue(afl_state_t *afl) {
   u32                 i;
   u8 *                temp_v = afl->map_tmp_buf;
 
-  if (afl->dumb_mode || !afl->score_changed) { return; }
+  if (afl->non_instrumented_mode || !afl->score_changed) { return; }
 
   afl->score_changed = 0;
 
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 04450363..91a64fba 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -27,6 +27,7 @@
 #include "afl-fuzz.h"
 #include <sys/time.h>
 #include <signal.h>
+#include <limits.h>
 
 #include "cmplog.h"
 
@@ -231,13 +232,13 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
     afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon,
                    afl->afl_env.afl_debug_child_output);
 
-    if (afl->fsrv.support_shdmen_fuzz && !afl->fsrv.use_shdmen_fuzz) {
+    if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shdmen_fuzz) {
 
       afl_shm_deinit(afl->shm_fuzz);
-      free(afl->shm_fuzz);
+      ck_free(afl->shm_fuzz);
       afl->shm_fuzz = NULL;
-      afl->fsrv.support_shdmen_fuzz = 0;
-      afl->fsrv.shdmem_fuzz = NULL;
+      afl->fsrv.support_shmem_fuzz = 0;
+      afl->fsrv.shmem_fuzz = NULL;
 
     }
 
@@ -272,7 +273,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
 
     if (afl->stop_soon || fault != afl->crash_mode) { goto abort_calibration; }
 
-    if (!afl->dumb_mode && !afl->stage_cur &&
+    if (!afl->non_instrumented_mode && !afl->stage_cur &&
         !count_bytes(afl, afl->fsrv.trace_bits)) {
 
       fault = FSRV_RUN_NOINST;
@@ -337,7 +338,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
      parent. This is a non-critical problem, but something to warn the user
      about. */
 
-  if (!afl->dumb_mode && first_run && !fault && !new_bits) {
+  if (!afl->non_instrumented_mode && first_run && !fault && !new_bits) {
 
     fault = FSRV_RUN_NOBITS;
 
@@ -412,17 +413,17 @@ void sync_fuzzers(afl_state_t *afl) {
 
     entries++;
 
-    // a slave only syncs from a master, a master syncs from everyone
-    if (likely(afl->is_slave)) {
+    // secondary nodes only syncs from main, the main node syncs from everyone
+    if (likely(afl->is_secondary_node)) {
 
-      sprintf(qd_path, "%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
+      sprintf(qd_path, "%s/%s/is_main_node", afl->sync_dir, sd_ent->d_name);
       int res = access(qd_path, F_OK);
-      if (unlikely(afl->is_master)) {  // an elected temporary master
+      if (unlikely(afl->is_main_node)) {  // an elected temporary main node
 
-        if (likely(res == 0)) {  // there is another master? downgrade.
+        if (likely(res == 0)) {  // there is another main node? downgrade.
 
-          afl->is_master = 0;
-          sprintf(qd_path, "%s/is_master", afl->out_dir);
+          afl->is_main_node = 0;
+          sprintf(qd_path, "%s/is_main_node", afl->out_dir);
           unlink(qd_path);
 
         }
@@ -561,16 +562,17 @@ void sync_fuzzers(afl_state_t *afl) {
 
   closedir(sd);
 
-  // If we are a slave and no master was found to sync then become the master
-  if (unlikely(synced == 0) && likely(entries) && likely(afl->is_slave)) {
+  // If we are a secondary and no main was found to sync then become the main
+  if (unlikely(synced == 0) && likely(entries) &&
+      likely(afl->is_secondary_node)) {
 
-    // there is a small race condition here that another slave runs at the same
-    // time. If so, the first temporary master running again will demote
+    // there is a small race condition here that another secondary runs at the
+    // same time. If so, the first temporary main node running again will demote
     // themselves so this is not an issue
 
     u8 path[PATH_MAX];
-    afl->is_master = 1;
-    sprintf(path, "%s/is_master", afl->out_dir);
+    afl->is_main_node = 1;
+    sprintf(path, "%s/is_main_node", afl->out_dir);
     int fd = open(path, O_CREAT | O_RDWR, 0644);
     if (fd >= 0) { close(fd); }
 
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 014ed34d..1f5552e0 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -103,7 +103,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
       "afl_banner        : %s\n"
       "afl_version       : " VERSION
       "\n"
-      "target_mode       : %s%s%s%s%s%s%s%s\n"
+      "target_mode       : %s%s%s%s%s%s%s%s%s\n"
       "command_line      : %s\n",
       afl->start_time / 1000, cur_time / 1000,
       (cur_time - afl->start_time) / 1000, (u32)getpid(),
@@ -125,11 +125,12 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
 #endif
       t_bytes, afl->var_byte_count, afl->use_banner,
       afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
-      afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "",
-      afl->crash_mode ? "crash " : "",
+      afl->non_instrumented_mode ? " non_instrumented " : "",
+      afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
       afl->persistent_mode ? "persistent " : "",
+      afl->shmem_testcase_mode ? "shmem_testcase " : "",
       afl->deferred_mode ? "deferred " : "",
-      (afl->unicorn_mode || afl->fsrv.qemu_mode || afl->dumb_mode ||
+      (afl->unicorn_mode || afl->fsrv.qemu_mode || afl->non_instrumented_mode ||
        afl->no_forkserver || afl->crash_mode || afl->persistent_mode ||
        afl->deferred_mode)
           ? ""
@@ -137,6 +138,20 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
       afl->orig_cmdline);
   /* ignore errors */
 
+  if (afl->debug) {
+
+    fprintf(f, "virgin_bytes     :");
+    for (uint32_t i = 0; i < afl->fsrv.map_size; i++)
+      if (afl->virgin_bits[i] != 0xff)
+        fprintf(f, " %d[%02x]", i, afl->virgin_bits[i]);
+    fprintf(f, "\n");
+    fprintf(f, "var_bytes        :");
+    for (uint32_t i = 0; i < afl->fsrv.map_size; i++)
+      if (afl->var_bytes[i]) fprintf(f, " %d", i);
+    fprintf(f, "\n");
+
+  }
+
   fclose(f);
 
 }
@@ -326,7 +341,7 @@ void show_stats(afl_state_t *afl) {
 
   /* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
 
-  if (!afl->dumb_mode && afl->cycles_wo_finds > 100 &&
+  if (!afl->non_instrumented_mode && afl->cycles_wo_finds > 100 &&
       !afl->pending_not_fuzzed && afl->afl_env.afl_exit_when_done) {
 
     afl->stop_soon = 2;
@@ -414,7 +429,7 @@ void show_stats(afl_state_t *afl) {
        " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
        " overall results " bSTG bH2 bH2                 bRT "\n");
 
-  if (afl->dumb_mode) {
+  if (afl->non_instrumented_mode) {
 
     strcpy(tmp, cRST);
 
@@ -460,7 +475,7 @@ void show_stats(afl_state_t *afl) {
   /* We want to warn people about not seeing new paths after a full cycle,
      except when resuming fuzzing or running in non-instrumented mode. */
 
-  if (!afl->dumb_mode &&
+  if (!afl->non_instrumented_mode &&
       (afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
        afl->in_bitmap || afl->crash_mode)) {
 
@@ -469,7 +484,7 @@ void show_stats(afl_state_t *afl) {
 
   } else {
 
-    if (afl->dumb_mode) {
+    if (afl->non_instrumented_mode) {
 
       SAYF(bV bSTOP "   last new path : " cPIN "n/a" cRST
                     " (non-instrumented mode)       ");
@@ -524,8 +539,9 @@ void show_stats(afl_state_t *afl) {
           t_byte_ratio);
 
   SAYF("    map density : %s%-21s" bSTG bV "\n",
-       t_byte_ratio > 70 ? cLRD
-                         : ((t_bytes < 200 && !afl->dumb_mode) ? cPIN : cRST),
+       t_byte_ratio > 70
+           ? cLRD
+           : ((t_bytes < 200 && !afl->non_instrumented_mode) ? cPIN : cRST),
        tmp);
 
   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_paths),
@@ -1020,10 +1036,11 @@ void show_init_stats(afl_state_t *afl) {
 
   }
 
-  /* In dumb mode, re-running every timing out test case with a generous time
+  /* In non-instrumented mode, re-running every timing out test case with a
+     generous time
      limit is very expensive, so let's select a more conservative default. */
 
-  if (afl->dumb_mode && !(afl->afl_env.afl_hang_tmout)) {
+  if (afl->non_instrumented_mode && !(afl->afl_env.afl_hang_tmout)) {
 
     afl->hang_tmout = MIN(EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100);
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e024e9a4..44b91877 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -130,7 +130,7 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
       "  -N            - do not unlink the fuzzing input file (only for "
       "devices etc.!)\n"
       "  -d            - quick & dirty mode (skips deterministic steps)\n"
-      "  -n            - fuzz without instrumentation (dumb mode)\n"
+      "  -n            - fuzz without instrumentation (non-instrumented mode)\n"
       "  -x dir        - optional fuzzer dictionary (see README.md, its really "
       "good!)\n\n"
 
@@ -246,7 +246,7 @@ int main(int argc, char **argv_orig, char **envp) {
   u64    prev_queued = 0;
   u32    sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE;
   u8 *   extras_dir = 0;
-  u8     mem_limit_given = 0, exit_1 = 0;
+  u8     mem_limit_given = 0, exit_1 = 0, debug = 0;
   char **use_argv;
 
   struct timeval  tv;
@@ -257,10 +257,11 @@ int main(int argc, char **argv_orig, char **envp) {
   afl_state_t *afl = calloc(1, sizeof(afl_state_t));
   if (!afl) { FATAL("Could not create afl state"); }
 
-  if (get_afl_env("AFL_DEBUG")) { afl->debug = 1; }
+  if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; }
 
   map_size = get_map_size();
   afl_state_init(afl, map_size);
+  afl->debug = debug;
   afl_fsrv_init(&afl->fsrv);
 
   read_afl_environment(afl, envp);
@@ -379,17 +380,19 @@ int main(int argc, char **argv_orig, char **envp) {
 
           *c = 0;
 
-          if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 ||
-              !afl->master_id || !afl->master_max ||
-              afl->master_id > afl->master_max || afl->master_max > 1000000) {
+          if (sscanf(c + 1, "%u/%u", &afl->main_node_id, &afl->main_node_max) !=
+                  2 ||
+              !afl->main_node_id || !afl->main_node_max ||
+              afl->main_node_id > afl->main_node_max ||
+              afl->main_node_max > 1000000) {
 
-            FATAL("Bogus master ID passed to -M");
+            FATAL("Bogus main node ID passed to -M");
 
           }
 
         }
 
-        afl->is_master = 1;
+        afl->is_main_node = 1;
 
       }
 
@@ -399,7 +402,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
         if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
         afl->sync_id = ck_strdup(optarg);
-        afl->is_slave = 1;
+        afl->is_secondary_node = 1;
         afl->skip_deterministic = 1;
         afl->use_splicing = 1;
         break;
@@ -533,14 +536,19 @@ int main(int argc, char **argv_orig, char **envp) {
 
       case 'n':                                                /* dumb mode */
 
-        if (afl->dumb_mode) { FATAL("Multiple -n options not supported"); }
+        if (afl->non_instrumented_mode) {
+
+          FATAL("Multiple -n options not supported");
+
+        }
+
         if (afl->afl_env.afl_dumb_forksrv) {
 
-          afl->dumb_mode = 2;
+          afl->non_instrumented_mode = 2;
 
         } else {
 
-          afl->dumb_mode = 1;
+          afl->non_instrumented_mode = 1;
 
         }
 
@@ -556,6 +564,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
         if (afl->fsrv.qemu_mode) { FATAL("Multiple -Q options not supported"); }
         afl->fsrv.qemu_mode = 1;
+        afl->shmem_testcase_mode = 1;
 
         if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; }
 
@@ -572,6 +581,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
         if (afl->unicorn_mode) { FATAL("Multiple -U options not supported"); }
         afl->unicorn_mode = 1;
+        afl->shmem_testcase_mode = 1;
 
         if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_UNICORN; }
 
@@ -582,6 +592,7 @@ int main(int argc, char **argv_orig, char **envp) {
         if (afl->use_wine) { FATAL("Multiple -W options not supported"); }
         afl->fsrv.qemu_mode = 1;
         afl->use_wine = 1;
+        afl->shmem_testcase_mode = 1;
 
         if (!mem_limit_given) { afl->fsrv.mem_limit = 0; }
 
@@ -790,10 +801,12 @@ int main(int argc, char **argv_orig, char **envp) {
   OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL");
   OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL");
 
-  if (afl->sync_id && afl->is_master && afl->afl_env.afl_custom_mutator_only) {
+  if (afl->sync_id && afl->is_main_node &&
+      afl->afl_env.afl_custom_mutator_only) {
 
     WARNF(
-        "Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will "
+        "Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
+        "will "
         "result in no deterministic mutations being done!");
 
   }
@@ -841,7 +854,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
     }
 
-    /* randamsa_init installs some signal hadlers, call it before
+    /* radamsa_init installs some signal handlers, call it before
        setup_signal_handlers so that AFL++ can then replace those signal
        handlers */
     radamsa_init_ptr();
@@ -871,7 +884,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  if (afl->dumb_mode) {
+  if (afl->non_instrumented_mode) {
 
     if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); }
     if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); }
@@ -954,13 +967,13 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  if (afl->dumb_mode == 2 && afl->no_forkserver) {
+  if (afl->non_instrumented_mode == 2 && afl->no_forkserver) {
 
     FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
 
   }
 
-  afl->fsrv.use_fauxsrv = afl->dumb_mode == 1 || afl->no_forkserver;
+  afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
 
   if (getenv("LD_PRELOAD")) {
 
@@ -1057,7 +1070,7 @@ int main(int argc, char **argv_orig, char **envp) {
   check_cpu_governor(afl);
 
   afl->fsrv.trace_bits =
-      afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->dumb_mode);
+      afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode);
 
   if (!afl->in_bitmap) { memset(afl->virgin_bits, 255, afl->fsrv.map_size); }
   memset(afl->virgin_tmout, 255, afl->fsrv.map_size);
@@ -1065,7 +1078,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   init_count_class16();
 
-  if (afl->is_master && check_master_exists(afl) == 1) {
+  if (afl->is_main_node && check_main_node_exists(afl) == 1) {
 
     WARNF("it is wasteful to run more than one master!");
     sleep(1);
@@ -1074,9 +1087,9 @@ int main(int argc, char **argv_orig, char **envp) {
 
   setup_dirs_fds(afl);
 
-  if (afl->is_slave && check_master_exists(afl) == 0) {
+  if (afl->is_secondary_node && check_main_node_exists(afl) == 0) {
 
-    WARNF("no -M master found. You need to run one master!");
+    WARNF("no -M main node found. You need to run one main instance!");
     sleep(5);
 
   }
@@ -1178,6 +1191,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   check_binary(afl, argv[optind]);
 
+  if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); }
+
   afl->start_time = get_cur_time();
 
   if (afl->fsrv.qemu_mode) {
@@ -1366,10 +1381,10 @@ stop_fuzzing:
        time_spent_working / afl->fsrv.total_execs);
   #endif
 
-  if (afl->is_master) {
+  if (afl->is_main_node) {
 
     u8 path[PATH_MAX];
-    sprintf(path, "%s/is_master", afl->out_dir);
+    sprintf(path, "%s/is_main_node", afl->out_dir);
     unlink(path);
 
   }
@@ -1383,7 +1398,7 @@ stop_fuzzing:
   if (afl->shm_fuzz) {
 
     afl_shm_deinit(afl->shm_fuzz);
-    free(afl->shm_fuzz);
+    ck_free(afl->shm_fuzz);
 
   }
 
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index f5817293..63013435 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -96,7 +96,8 @@ void afl_shm_deinit(sharedmem_t *shm) {
    Returns a pointer to shm->map for ease of use.
 */
 
-u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
+u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
+                 unsigned char non_instrumented_mode) {
 
   shm->map_size = map_size;
 
@@ -137,12 +138,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
 
   }
 
-  /* If somebody is asking us to fuzz instrumented binaries in dumb mode,
-     we don't want them to detect instrumentation, since we won't be sending
-     fork server commands. This should be replaced with better auto-detection
-     later on, perhaps? */
+  /* If somebody is asking us to fuzz instrumented binaries in non-instrumented
+     mode, we don't want them to detect instrumentation, since we won't be
+     sending fork server commands. This should be replaced with better
+     auto-detection later on, perhaps? */
 
-  if (!dumb_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
+  if (!non_instrumented_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
 
   if (shm->map == -1 || !shm->map) PFATAL("mmap() failed");
 
@@ -164,12 +165,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
 
   shm_str = alloc_printf("%d", shm->shm_id);
 
-  /* If somebody is asking us to fuzz instrumented binaries in dumb mode,
-     we don't want them to detect instrumentation, since we won't be sending
-     fork server commands. This should be replaced with better auto-detection
-     later on, perhaps? */
+  /* If somebody is asking us to fuzz instrumented binaries in non-instrumented
+     mode, we don't want them to detect instrumentation, since we won't be
+     sending fork server commands. This should be replaced with better
+     auto-detection later on, perhaps? */
 
-  if (!dumb_mode) { setenv(SHM_ENV_VAR, shm_str, 1); }
+  if (!non_instrumented_mode) { setenv(SHM_ENV_VAR, shm_str, 1); }
 
   ck_free(shm_str);
 
@@ -177,7 +178,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
 
     shm_str = alloc_printf("%d", shm->cmplog_shm_id);
 
-    if (!dumb_mode) { setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1); }
+    if (!non_instrumented_mode) { setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1); }
 
     ck_free(shm_str);
 
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index bb3959ea..8c009a33 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-5833117
+d1b23ed
diff --git a/unicorn_mode/samples/c/harness.c b/unicorn_mode/samples/c/harness.c
index 18c59c3f..4bda6e2d 100644
--- a/unicorn_mode/samples/c/harness.c
+++ b/unicorn_mode/samples/c/harness.c
@@ -184,7 +184,7 @@ int main(int argc, char **argv, char **envp) {
 
     // Map memory.
     mem_map_checked(uc, BASE_ADDRESS, len, UC_PROT_ALL);
-    printf("Len: %lx", len);
+    printf("Len: %lx\n", len);
     fflush(stdout);
 
     // write machine code to be emulated to memory
diff --git a/unicorn_mode/samples/persistent/Makefile b/unicorn_mode/samples/persistent/Makefile
index 9596facc..cd43bf02 100644
--- a/unicorn_mode/samples/persistent/Makefile
+++ b/unicorn_mode/samples/persistent/Makefile
@@ -44,7 +44,7 @@ harness: harness.o
 	${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@
 
 debug: harness-debug.o
-	${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
+	${MYCC} -L${LIBDIR} harness-debug.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
 
 fuzz: harness
 	../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
diff --git a/unicorn_mode/samples/persistent/harness.c b/unicorn_mode/samples/persistent/harness.c
index 3d379f46..2a27e39b 100644
--- a/unicorn_mode/samples/persistent/harness.c
+++ b/unicorn_mode/samples/persistent/harness.c
@@ -68,7 +68,7 @@ static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user
 
 /*
 The sample uses strlen, since we don't have a loader or libc, we'll fake it.
-We know the strlen will return the lenght of argv[1] that we just planted.
+We know the strlen will return the length of argv[1] that we just planted.
 It will be a lot faster than an actual strlen for this specific purpose.
 */
 static void hook_strlen(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
@@ -86,7 +86,7 @@ static void hook_strlen(uc_engine *uc, uint64_t address, uint32_t size, void *us
 static uint64_t pad(uint64_t size) {
     if (size % ALIGNMENT == 0) return size;
     return ((size / ALIGNMENT) + 1) * ALIGNMENT;
-} 
+}
 
 /* returns the filesize in bytes, -1 or error. */
 static off_t afl_mmap_file(char *filename, char **buf_ptr) {
@@ -100,9 +100,9 @@ static off_t afl_mmap_file(char *filename, char **buf_ptr) {
 
     off_t in_len = st.st_size;
     if (in_len == -1) {
-	/* This can only ever happen on 32 bit if the file is exactly 4gb. */
-	fprintf(stderr, "Filesize of %s too large\n", filename);
-	goto exit;
+    /* This can only ever happen on 32 bit if the file is exactly 4gb. */
+    fprintf(stderr, "Filesize of %s too large\n", filename);
+    goto exit;
     }
 
     *buf_ptr = mmap(0, in_len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
@@ -117,10 +117,10 @@ exit:
 
 /* Place the input at the right spot inside unicorn */
 static bool place_input_callback(
-    uc_engine *uc, 
-    char *input, 
-    size_t input_len, 
-    uint32_t persistent_round, 
+    uc_engine *uc,
+    char *input,
+    size_t input_len,
+    uint32_t persistent_round,
     void *data
 ){
     // printf("Placing input with len %ld to %x\n", input_len, DATA_ADDRESS);
@@ -134,7 +134,7 @@ static bool place_input_callback(
     // Set up the function parameters accordingly RSI, RDI (see calling convention/disassembly)
     uc_reg_write(uc, UC_X86_REG_RSI, &INPUT_LOCATION); // argv
     uc_reg_write(uc, UC_X86_REG_RDI, &EMULATED_ARGC);  // argc == 2
-   
+
     // We need a valid c string, make sure it never goes out of bounds.
     input[input_len-1] = '\0';
     // Write the testcase to unicorn.
@@ -188,13 +188,13 @@ int main(int argc, char **argv, char **envp) {
         return -2;
     }
     if (len == 0) {
-	fprintf(stderr, "File at '%s' is empty\n", BINARY_FILE);
-	return -3;
+    fprintf(stderr, "File at '%s' is empty\n", BINARY_FILE);
+    return -3;
     }
 
     // Map memory.
     mem_map_checked(uc, BASE_ADDRESS, len, UC_PROT_ALL);
-    printf("Len: %lx", len);
+    printf("Len: %lx\n", len);
     fflush(stdout);
 
     // write machine code to be emulated to memory
@@ -209,7 +209,7 @@ int main(int argc, char **argv, char **envp) {
     uint64_t start_address = CODE_ADDRESS;      // address of entry point of main()
     uint64_t end_address = END_ADDRESS; // Address of last instruction in main()
     uc_reg_write(uc, UC_X86_REG_RIP, &start_address); // address of entry point of main()
-    
+
     // Setup the Stack
     mem_map_checked(uc, STACK_ADDRESS - STACK_SIZE, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE);
     uint64_t stack_val = STACK_ADDRESS;
@@ -219,7 +219,7 @@ int main(int argc, char **argv, char **envp) {
     // reserve some space for our input data
     mem_map_checked(uc, INPUT_LOCATION, INPUT_SIZE_MAX, UC_PROT_READ);
 
-    // build a "dummy" argv with lenth 2 at 0x10000: 
+    // build a "dummy" argv with lenth 2 at 0x10000:
     // 0x10000 argv[0]  NULL
     // 0x10008 argv[1]  (char *)0x10016 --. points to the next offset.
     // 0x10016 argv[1][0], ...          <-^ contains the acutal input data. (INPUT_LOCATION + INPUT_OFFSET)
@@ -264,6 +264,6 @@ int main(int argc, char **argv, char **envp) {
             break;
         default:
             break;
-    } 
+    }
     return 0;
 }
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
-Subproject 5833117abf55d54c4191ead81312764df03a48b
+Subproject d1b23ed28b380b735bceafdb1d4ea234317d77a