about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rw-r--r--GNUmakefile11
-rw-r--r--GNUmakefile.gcc_plugin8
-rw-r--r--GNUmakefile.llvm14
-rw-r--r--README.md4
-rw-r--r--TODO.md3
-rw-r--r--custom_mutators/libfuzzer/FuzzerDriver.cpp19
-rw-r--r--custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp4
-rw-r--r--custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp7
-rw-r--r--custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp23
-rw-r--r--custom_mutators/libfuzzer/FuzzerFlags.def5
-rw-r--r--custom_mutators/libfuzzer/FuzzerInterceptors.cpp290
-rw-r--r--custom_mutators/libfuzzer/FuzzerLoop.cpp2
-rw-r--r--custom_mutators/libfuzzer/FuzzerMain.cpp26
-rw-r--r--custom_mutators/libfuzzer/FuzzerMutate.cpp19
-rw-r--r--custom_mutators/libfuzzer/FuzzerMutate.h5
-rw-r--r--custom_mutators/libfuzzer/FuzzerOptions.h2
-rw-r--r--custom_mutators/libfuzzer/Makefile54
-rw-r--r--custom_mutators/libfuzzer/README.md2
-rw-r--r--custom_mutators/libfuzzer/libfuzzer.cpp2
-rw-r--r--docs/Changelog.md4
-rw-r--r--examples/custom_mutators/README.md2
-rw-r--r--examples/persistent_demo/persistent_demo_new.c3
-rw-r--r--include/afl-fuzz.h27
-rw-r--r--include/config.h32
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc2
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc20
-rw-r--r--instrumentation/afl-llvm-lto-instrumentation.so.cc2
-rw-r--r--instrumentation/cmplog-instructions-pass.cc6
-rw-r--r--instrumentation/cmplog-routines-pass.cc11
-rw-r--r--instrumentation/compare-transform-pass.so.cc24
-rw-r--r--instrumentation/split-compares-pass.so.cc47
-rw-r--r--instrumentation/split-switches-pass.so.cc21
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-cc.c2
-rw-r--r--src/afl-fuzz-bitmap.c25
-rw-r--r--src/afl-fuzz-init.c8
-rw-r--r--src/afl-fuzz-one.c58
-rw-r--r--src/afl-fuzz-queue.c92
-rw-r--r--src/afl-fuzz-state.c55
-rw-r--r--src/afl-fuzz-stats.c2
-rw-r--r--src/afl-fuzz.c33
-rwxr-xr-xtest/test-performance.sh15
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
45 files changed, 699 insertions, 302 deletions
diff --git a/.travis.yml b/.travis.yml
index 5dc4ab39..b8b36e6b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,9 +9,9 @@ branches:
 
 matrix:
   include:
-  - os: linux
-    dist: focal
-    env: NAME="focal-amd64" MODERN="yes" GCC="9"
+  #- os: linux # again disabled because fetching packages times out very often :(
+  #  dist: focal
+  #  env: NAME="focal-amd64" MODERN="yes" GCC="9"
   - os: linux
     dist: bionic
     env: NAME="bionic-amd64" MODERN="yes" GCC="7"
diff --git a/GNUmakefile b/GNUmakefile
index d47f8247..c885a935 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -205,7 +205,7 @@ endif
 
 ifneq "$(filter Linux GNU%,$(shell uname))" ""
   override CFLAGS += -D_FORTIFY_SOURCE=2
-  LDFLAGS += -ldl -lrt
+  LDFLAGS += -ldl -lrt -lm
 endif
 
 ifneq "$(findstring FreeBSD, $(shell uname))" ""
@@ -218,6 +218,11 @@ ifneq "$(findstring NetBSD, $(shell uname))" ""
   LDFLAGS += -lpthread
 endif
 
+ifneq "$(findstring OpenBSD, $(shell uname))" ""
+  override CFLAGS  += -pthread
+  LDFLAGS += -lpthread
+endif
+
 TEST_CC = afl-gcc
 
 COMM_HDR    = include/alloc-inl.h include/config.h include/debug.h include/types.h
@@ -465,8 +470,8 @@ code-format:
 	./.custom-format.py -i instrumentation/*.h
 	./.custom-format.py -i instrumentation/*.cc
 	./.custom-format.py -i instrumentation/*.c
-	./.custom-format.py -i custom_mutators/*/*.c*
-	@#./.custom-format.py -i custom_mutators/*/*.h # destroys input.h :-(
+	@#./.custom-format.py -i custom_mutators/*/*.c* # destroys libfuzzer :-(
+	@#./.custom-format.py -i custom_mutators/*/*.h # destroys honggfuzz :-(
 	./.custom-format.py -i examples/*/*.c*
 	./.custom-format.py -i examples/*/*.h
 	./.custom-format.py -i test/*.c
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 55b79182..e3108511 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -75,11 +75,19 @@ ifeq "$(TEST_MMAP)" "1"
 endif
 
 ifneq "$(shell uname -s)" "Haiku"
+ifneq "$(shell uname -s)" "OpenBSD"
   	LDFLAGS += -lrt
+endif
 else
 	CFLAGS_SAFE += -DUSEMMAP=1
 endif
 
+ifeq "$(shell uname -s)" "OpenBSD"
+    CC  = egcc
+    CXX = eg++
+    PLUGIN_FLAGS += -I/usr/local/include
+endif
+
 ifeq "$(shell uname -s)" "SunOS"
   	PLUGIN_FLAGS += -I/usr/include/gmp
 endif
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 11ed0bd6..e0dc793e 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -34,7 +34,7 @@ ifeq "$(shell uname)" "OpenBSD"
   LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
   HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
   ifeq "$(HAS_OPT)" "1"
-    $(error llvm_mode needs a complete llvm installation (versions 3.4 up to 12) -> e.g. "pkg_add llvm-7.0.1p9")
+    $(warn llvm_mode needs a complete llvm installation (versions 3.4 up to 12) -> e.g. "pkg_add llvm-7.0.1p9")
   endif
 else
   LLVM_CONFIG ?= llvm-config
@@ -237,7 +237,7 @@ else
 endif
 
 CFLAGS          ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
-CFLAGS_SAFE     := -Wall -g -Wno-pointer-sign -I ./include/ -I ./instrumentation/ \
+CFLAGS_SAFE     := -Wall -g -Wno-cast-qual -Wno-variadic-macros -Wno-pointer-sign -I ./include/ -I ./instrumentation/ \
                    -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
                    -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
                    -DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
@@ -279,7 +279,7 @@ ifeq "$(shell uname)" "OpenBSD"
   CLANG_CPPFL += -mno-retpoline
   CFLAGS += -mno-retpoline
   # Needed for unwind symbols
-  LDFLAGS += -lc++abi
+  LDFLAGS += -lc++abi -lpthread
 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,7 +354,7 @@ endif
 instrumentation/afl-common.o: ./src/afl-common.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ $(LDFLAGS)
 
-./afl-cc: src/afl-cc.c instrumentation/afl-common.o | test_deps
+./afl-cc: src/afl-cc.c instrumentation/afl-common.o
 	$(CC) $(CLANG_CFL) $(CFLAGS) $(CPPFLAGS) $< instrumentation/afl-common.o -o $@ -DLLVM_MAJOR=$(LLVM_MAJOR) $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
 	@ln -sf afl-cc ./afl-c++
 	@ln -sf afl-cc ./afl-gcc
@@ -429,14 +429,14 @@ document:
 	@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -m32 -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-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_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -m64 -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
 
-./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c | test_deps
+./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c
 	$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -fPIC -c $< -o $@
 
-./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c | test_deps
+./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c
 	@printf "[*] Building 32-bit variant of the runtime (-m32)... "
 	@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi
 
-./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c | test_deps
+./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c
 	@printf "[*] Building 64-bit variant of the runtime (-m64)... "
 	@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi
 
diff --git a/README.md b/README.md
index c2108e93..f63b0c1e 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,9 @@
   afl++ is a superior fork to Google's afl - more speed, more and better
   mutations, more and better instrumentation, custom module support, etc.
 
+  If you want to use afl++ for you academic work, check the [papers page](https://aflplus.plus/papers/)
+  in the website.
+
 ## Major changes in afl++ 3.0
 
 With afl++ 3.0 we introduced changes that break some previous afl and afl++
@@ -1078,6 +1081,7 @@ without feedback, bug reports, or patches from:
   Andrea Biondo                         Vincent Le Garrec
   Khaled Yakdan                         Kuang-che Wu
   Josephine Calliotte                   Konrad Welc
+  David Carlier
 ```
 
 Thank you!
diff --git a/TODO.md b/TODO.md
index bb420518..0f60f267 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,12 +1,13 @@
 # TODO list for AFL++
 
-## Roadmap 2.68+
+## Roadmap 3.00+
 
  - AFL_MAP_SIZE for qemu_mode and unicorn_mode
  - CPU affinity for many cores? There seems to be an issue > 96 cores
  - afl-plot to support multiple plot_data
  - afl_custom_fuzz_splice_optin()
  - intel-pt tracer
+ - https://github.com/zyingp/desockmulti ?
 
 ## Further down the road
 
diff --git a/custom_mutators/libfuzzer/FuzzerDriver.cpp b/custom_mutators/libfuzzer/FuzzerDriver.cpp
index 6468a02e..c79278bd 100644
--- a/custom_mutators/libfuzzer/FuzzerDriver.cpp
+++ b/custom_mutators/libfuzzer/FuzzerDriver.cpp
@@ -77,7 +77,7 @@ struct {
 } Flags;
 
 static const FlagDescription FlagDescriptions[]{
-
+\
 #define FUZZER_DEPRECATED_FLAG(Name) \
   {#Name, "Deprecated; don't use", 0, nullptr, nullptr, nullptr},
 #define FUZZER_FLAG_INT(Name, Default, Description) \
@@ -941,23 +941,12 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
   Options.EntropicNumberOfRarestFeatures =
       (size_t)Flags.entropic_number_of_rarest_features;
   Options.EntropicScalePerExecTime = Flags.entropic_scale_per_exec_time;
-  if (Options.Entropic) {
-
-    if (!Options.FocusFunction.empty()) {
-
-      Printf(
-          "ERROR: The parameters `--entropic` and `--focus_function` cannot "
-          "be used together.\n");
-      exit(1);
-
-    }
-
+  if (!Options.FocusFunction.empty())
+    Options.Entropic = false;  // FocusFunction overrides entropic scheduling.
+  if (Options.Entropic)
     Printf("INFO: Running with entropic power schedule (0x%X, %d).\n",
            Options.EntropicFeatureFrequencyThreshold,
            Options.EntropicNumberOfRarestFeatures);
-
-  }
-
   struct EntropicOptions Entropic;
   Entropic.Enabled = Options.Entropic;
   Entropic.FeatureFrequencyThreshold =
diff --git a/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp b/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp
index 4a4d58fc..8009b237 100644
--- a/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp
+++ b/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp
@@ -45,8 +45,8 @@ namespace fuzzer {
 
 ExternalFunctions::ExternalFunctions() {
 \
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME =
-      GetFnPtr < decltype(ExternalFunctions::NAME)>(#NAME, WARN)
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
+    this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)
 
   #include "FuzzerExtFunctions.def"
 
diff --git a/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp b/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp
index caf1a7ef..c7a1d05e 100644
--- a/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp
+++ b/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp
@@ -46,9 +46,10 @@ namespace fuzzer {
 
 ExternalFunctions::ExternalFunctions() {
 \
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME = ::NAME;
-  CheckFnPtr(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(::NAME)),
-  #NAME, WARN);
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                         \
+    this->NAME = ::NAME;                                                      \
+    CheckFnPtr(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(::NAME)), \
+               #NAME, WARN);
 
   #include "FuzzerExtFunctions.def"
 
diff --git a/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp b/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp
index 630f352d..a727220a 100644
--- a/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp
+++ b/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp
@@ -45,16 +45,15 @@ using namespace fuzzer;
   #endif  // LIBFUZZER_MSVC
 
 extern "C" {
-
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)
-RETURN_TYPE NAME##Def FUNC_SIG {
-
-  Printf("ERROR: Function \"%s\" not defined.\n", #NAME);
-  exit(1);
-
-}
-
-EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
+\
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)         \
+    RETURN_TYPE NAME##Def FUNC_SIG {                          \
+                                                              \
+      Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
+      exit(1);                                                \
+                                                              \
+    }                                                         \
+    EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
 
   #include "FuzzerExtFunctions.def"
 
@@ -81,8 +80,8 @@ namespace fuzzer {
 
 ExternalFunctions::ExternalFunctions() {
 \
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME =
-      GetFnPtr < decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
+    this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
 
   #include "FuzzerExtFunctions.def"
 
diff --git a/custom_mutators/libfuzzer/FuzzerFlags.def b/custom_mutators/libfuzzer/FuzzerFlags.def
index c9a787e0..4d4841b1 100644
--- a/custom_mutators/libfuzzer/FuzzerFlags.def
+++ b/custom_mutators/libfuzzer/FuzzerFlags.def
@@ -171,8 +171,9 @@ FUZZER_FLAG_INT(ignore_remaining_args, 0, "If 1, ignore all arguments passed "
 FUZZER_FLAG_STRING(focus_function, "Experimental. "
      "Fuzzing will focus on inputs that trigger calls to this function. "
      "If -focus_function=auto and -data_flow_trace is used, libFuzzer "
-     "will choose the focus functions automatically.")
-FUZZER_FLAG_INT(entropic, 0, "Experimental. Enables entropic power schedule.")
+     "will choose the focus functions automatically. Disables -entropic when "
+     "specified.")
+FUZZER_FLAG_INT(entropic, 1, "Enables entropic power schedule.")
 FUZZER_FLAG_INT(entropic_feature_frequency_threshold, 0xFF, "Experimental. If "
      "entropic is enabled, all features which are observed less often than "
      "the specified value are considered as rare.")
diff --git a/custom_mutators/libfuzzer/FuzzerInterceptors.cpp b/custom_mutators/libfuzzer/FuzzerInterceptors.cpp
new file mode 100644
index 00000000..442ab79a
--- /dev/null
+++ b/custom_mutators/libfuzzer/FuzzerInterceptors.cpp
@@ -0,0 +1,290 @@
+//===-- FuzzerInterceptors.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Intercept certain libc functions to aid fuzzing.
+// Linked only when other RTs that define their own interceptors are not linked.
+//===----------------------------------------------------------------------===//
+
+#include "FuzzerPlatform.h"
+
+#if LIBFUZZER_LINUX
+
+  #define GET_CALLER_PC() __builtin_return_address(0)
+
+  #define PTR_TO_REAL(x) real_##x
+  #define REAL(x) __interception::PTR_TO_REAL(x)
+  #define FUNC_TYPE(x) x##_type
+  #define DEFINE_REAL(ret_type, func, ...)            \
+    typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
+    namespace __interception {                        \
+                                                      \
+    FUNC_TYPE(func) PTR_TO_REAL(func);                \
+                                                      \
+    }
+
+  #include <cassert>
+  #include <cstdint>
+  #include <dlfcn.h>  // for dlsym()
+
+static void *getFuncAddr(const char *name, uintptr_t wrapper_addr) {
+
+  void *addr = dlsym(RTLD_NEXT, name);
+  if (!addr) {
+
+    // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
+    // later in the library search order than the DSO that we are trying to
+    // intercept, which means that we cannot intercept this function. We still
+    // want the address of the real definition, though, so look it up using
+    // RTLD_DEFAULT.
+    addr = dlsym(RTLD_DEFAULT, name);
+
+    // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
+    // We don't want to intercept the wrapper and have it point to itself.
+    if (reinterpret_cast<uintptr_t>(addr) == wrapper_addr) addr = nullptr;
+
+  }
+
+  return addr;
+
+}
+
+static int  FuzzerInited = 0;
+static bool FuzzerInitIsRunning;
+
+static void fuzzerInit();
+
+static void ensureFuzzerInited() {
+
+  assert(!FuzzerInitIsRunning);
+  if (!FuzzerInited) { fuzzerInit(); }
+
+}
+
+static int internal_strcmp_strncmp(const char *s1, const char *s2, bool strncmp,
+                                   size_t n) {
+
+  size_t i = 0;
+  while (true) {
+
+    if (strncmp) {
+
+      if (i == n) break;
+      i++;
+
+    }
+
+    unsigned c1 = *s1;
+    unsigned c2 = *s2;
+    if (c1 != c2) return (c1 < c2) ? -1 : 1;
+    if (c1 == 0) break;
+    s1++;
+    s2++;
+
+  }
+
+  return 0;
+
+}
+
+static int internal_strncmp(const char *s1, const char *s2, size_t n) {
+
+  return internal_strcmp_strncmp(s1, s2, true, n);
+
+}
+
+static int internal_strcmp(const char *s1, const char *s2) {
+
+  return internal_strcmp_strncmp(s1, s2, false, 0);
+
+}
+
+static int internal_memcmp(const void *s1, const void *s2, size_t n) {
+
+  const uint8_t *t1 = static_cast<const uint8_t *>(s1);
+  const uint8_t *t2 = static_cast<const uint8_t *>(s2);
+  for (size_t i = 0; i < n; ++i, ++t1, ++t2)
+    if (*t1 != *t2) return *t1 < *t2 ? -1 : 1;
+  return 0;
+
+}
+
+static size_t internal_strlen(const char *s) {
+
+  size_t i = 0;
+  while (s[i])
+    i++;
+  return i;
+
+}
+
+static char *internal_strstr(const char *haystack, const char *needle) {
+
+  // This is O(N^2), but we are not using it in hot places.
+  size_t len1 = internal_strlen(haystack);
+  size_t len2 = internal_strlen(needle);
+  if (len1 < len2) return nullptr;
+  for (size_t pos = 0; pos <= len1 - len2; pos++) {
+
+    if (internal_memcmp(haystack + pos, needle, len2) == 0)
+      return const_cast<char *>(haystack) + pos;
+
+  }
+
+  return nullptr;
+
+}
+
+extern "C" {
+
+// Weak hooks forward-declared to avoid dependency on
+// <sanitizer/common_interface_defs.h>.
+void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
+                                  const void *s2, size_t n, int result);
+void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
+                                   const char *s2, size_t n, int result);
+void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+                                       const char *s2, size_t n, int result);
+void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
+                                  const char *s2, int result);
+void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+                                      const char *s2, int result);
+void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+                                  const char *s2, char *result);
+void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+                                      const char *s2, char *result);
+void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
+                                  const void *s2, size_t len2, void *result);
+
+DEFINE_REAL(int, bcmp, const void *, const void *, size_t)
+DEFINE_REAL(int, memcmp, const void *, const void *, size_t)
+DEFINE_REAL(int, strncmp, const char *, const char *, size_t)
+DEFINE_REAL(int, strcmp, const char *, const char *)
+DEFINE_REAL(int, strncasecmp, const char *, const char *, size_t)
+DEFINE_REAL(int, strcasecmp, const char *, const char *)
+DEFINE_REAL(char *, strstr, const char *, const char *)
+DEFINE_REAL(char *, strcasestr, const char *, const char *)
+DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
+
+ATTRIBUTE_INTERFACE int bcmp(const char *s1, const char *s2, size_t n) {
+
+  if (!FuzzerInited) return internal_memcmp(s1, s2, n);
+  int result = REAL(bcmp)(s1, s2, n);
+  __sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int memcmp(const void *s1, const void *s2, size_t n) {
+
+  if (!FuzzerInited) return internal_memcmp(s1, s2, n);
+  int result = REAL(memcmp)(s1, s2, n);
+  __sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strncmp(const char *s1, const char *s2, size_t n) {
+
+  if (!FuzzerInited) return internal_strncmp(s1, s2, n);
+  int result = REAL(strncmp)(s1, s2, n);
+  __sanitizer_weak_hook_strncmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strcmp(const char *s1, const char *s2) {
+
+  if (!FuzzerInited) return internal_strcmp(s1, s2);
+  int result = REAL(strcmp)(s1, s2);
+  __sanitizer_weak_hook_strcmp(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strncasecmp(const char *s1, const char *s2, size_t n) {
+
+  ensureFuzzerInited();
+  int result = REAL(strncasecmp)(s1, s2, n);
+  __sanitizer_weak_hook_strncasecmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strcasecmp(const char *s1, const char *s2) {
+
+  ensureFuzzerInited();
+  int result = REAL(strcasecmp)(s1, s2);
+  __sanitizer_weak_hook_strcasecmp(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE char *strstr(const char *s1, const char *s2) {
+
+  if (!FuzzerInited) return internal_strstr(s1, s2);
+  char *result = REAL(strstr)(s1, s2);
+  __sanitizer_weak_hook_strstr(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE char *strcasestr(const char *s1, const char *s2) {
+
+  ensureFuzzerInited();
+  char *result = REAL(strcasestr)(s1, s2);
+  __sanitizer_weak_hook_strcasestr(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE
+void *memmem(const void *s1, size_t len1, const void *s2, size_t len2) {
+
+  ensureFuzzerInited();
+  void *result = REAL(memmem)(s1, len1, s2, len2);
+  __sanitizer_weak_hook_memmem(GET_CALLER_PC(), s1, len1, s2, len2, result);
+  return result;
+
+}
+
+__attribute__((section(".preinit_array"),
+               used)) static void (*__local_fuzzer_preinit)(void) = fuzzerInit;
+
+}  // extern "C"
+
+static void fuzzerInit() {
+
+  assert(!FuzzerInitIsRunning);
+  if (FuzzerInited) return;
+  FuzzerInitIsRunning = true;
+
+  REAL(bcmp) = reinterpret_cast<memcmp_type>(
+      getFuncAddr("bcmp", reinterpret_cast<uintptr_t>(&bcmp)));
+  REAL(memcmp) = reinterpret_cast<memcmp_type>(
+      getFuncAddr("memcmp", reinterpret_cast<uintptr_t>(&memcmp)));
+  REAL(strncmp) = reinterpret_cast<strncmp_type>(
+      getFuncAddr("strncmp", reinterpret_cast<uintptr_t>(&strncmp)));
+  REAL(strcmp) = reinterpret_cast<strcmp_type>(
+      getFuncAddr("strcmp", reinterpret_cast<uintptr_t>(&strcmp)));
+  REAL(strncasecmp) = reinterpret_cast<strncasecmp_type>(
+      getFuncAddr("strncasecmp", reinterpret_cast<uintptr_t>(&strncasecmp)));
+  REAL(strcasecmp) = reinterpret_cast<strcasecmp_type>(
+      getFuncAddr("strcasecmp", reinterpret_cast<uintptr_t>(&strcasecmp)));
+  REAL(strstr) = reinterpret_cast<strstr_type>(
+      getFuncAddr("strstr", reinterpret_cast<uintptr_t>(&strstr)));
+  REAL(strcasestr) = reinterpret_cast<strcasestr_type>(
+      getFuncAddr("strcasestr", reinterpret_cast<uintptr_t>(&strcasestr)));
+  REAL(memmem) = reinterpret_cast<memmem_type>(
+      getFuncAddr("memmem", reinterpret_cast<uintptr_t>(&memmem)));
+
+  FuzzerInitIsRunning = false;
+  FuzzerInited = 1;
+
+}
+
+#endif
+
diff --git a/custom_mutators/libfuzzer/FuzzerLoop.cpp b/custom_mutators/libfuzzer/FuzzerLoop.cpp
index 49187b30..201883f0 100644
--- a/custom_mutators/libfuzzer/FuzzerLoop.cpp
+++ b/custom_mutators/libfuzzer/FuzzerLoop.cpp
@@ -752,7 +752,7 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U, const char *Text) {
   if (Options.Verbosity) {
 
     Printf(" L: %zd/%zd ", U.size(), Corpus.MaxInputSize());
-    MD.PrintMutationSequence();
+    MD.PrintMutationSequence(Options.Verbosity >= 2);
     Printf("\n");
 
   }
diff --git a/custom_mutators/libfuzzer/FuzzerMain.cpp b/custom_mutators/libfuzzer/FuzzerMain.cpp
new file mode 100644
index 00000000..b02c88e9
--- /dev/null
+++ b/custom_mutators/libfuzzer/FuzzerMain.cpp
@@ -0,0 +1,26 @@
+//===- FuzzerMain.cpp - main() function and flags -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// main() and flags.
+//===----------------------------------------------------------------------===//
+
+#include "FuzzerDefs.h"
+#include "FuzzerPlatform.h"
+
+extern "C" {
+
+// This function should be defined by the user.
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+
+}  // extern "C"
+
+ATTRIBUTE_INTERFACE int main(int argc, char **argv) {
+
+  return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
+
+}
+
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.cpp b/custom_mutators/libfuzzer/FuzzerMutate.cpp
index 8faf6918..eebae39b 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.cpp
+++ b/custom_mutators/libfuzzer/FuzzerMutate.cpp
@@ -17,7 +17,8 @@
 
 namespace fuzzer {
 
-const size_t Dictionary::kMaxDictSize;
+const size_t        Dictionary::kMaxDictSize;
+static const size_t kMaxMutationsToPrint = 10;
 
 static void PrintASCII(const Word &W, const char *PrintAfter) {
 
@@ -608,18 +609,24 @@ void MutationDispatcher::PrintRecommendedDictionary() {
 
 }
 
-void MutationDispatcher::PrintMutationSequence() {
+void MutationDispatcher::PrintMutationSequence(bool Verbose) {
 
   Printf("MS: %zd ", CurrentMutatorSequence.size());
-  for (auto M : CurrentMutatorSequence)
-    Printf("%s-", M.Name);
+  size_t EntriesToPrint =
+      Verbose ? CurrentMutatorSequence.size()
+              : std::min(kMaxMutationsToPrint, CurrentMutatorSequence.size());
+  for (size_t i = 0; i < EntriesToPrint; i++)
+    Printf("%s-", CurrentMutatorSequence[i].Name);
   if (!CurrentDictionaryEntrySequence.empty()) {
 
     Printf(" DE: ");
-    for (auto DE : CurrentDictionaryEntrySequence) {
+    EntriesToPrint = Verbose ? CurrentDictionaryEntrySequence.size()
+                             : std::min(kMaxMutationsToPrint,
+                                        CurrentDictionaryEntrySequence.size());
+    for (size_t i = 0; i < EntriesToPrint; i++) {
 
       Printf("\"");
-      PrintASCII(DE->GetW(), "\"-");
+      PrintASCII(CurrentDictionaryEntrySequence[i]->GetW(), "\"-");
 
     }
 
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.h b/custom_mutators/libfuzzer/FuzzerMutate.h
index 3ce3159f..37fd6100 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.h
+++ b/custom_mutators/libfuzzer/FuzzerMutate.h
@@ -24,8 +24,9 @@ public:
   ~MutationDispatcher() {}
   /// Indicate that we are about to start a new sequence of mutations.
   void StartMutationSequence();
-  /// Print the current sequence of mutations.
-  void PrintMutationSequence();
+  /// Print the current sequence of mutations. Only prints the full sequence
+  /// when Verbose is true.
+  void PrintMutationSequence(bool Verbose = true);
   /// Return the current sequence of mutations.
   std::string MutationSequence();
   /// Indicate that the current sequence of mutations was successful.
diff --git a/custom_mutators/libfuzzer/FuzzerOptions.h b/custom_mutators/libfuzzer/FuzzerOptions.h
index 706e1c64..20b810b2 100644
--- a/custom_mutators/libfuzzer/FuzzerOptions.h
+++ b/custom_mutators/libfuzzer/FuzzerOptions.h
@@ -46,7 +46,7 @@ struct FuzzingOptions {
   size_t MaxNumberOfRuns = -1L;
   int ReportSlowUnits = 10;
   bool OnlyASCII = false;
-  bool Entropic = false;
+  bool Entropic = true;
   size_t EntropicFeatureFrequencyThreshold = 0xFF;
   size_t EntropicNumberOfRarestFeatures = 100;
   bool EntropicScalePerExecTime = false;
diff --git a/custom_mutators/libfuzzer/Makefile b/custom_mutators/libfuzzer/Makefile
index f0c80392..95402f6c 100644
--- a/custom_mutators/libfuzzer/Makefile
+++ b/custom_mutators/libfuzzer/Makefile
@@ -1,81 +1,81 @@
 
-#CFLAGS = -O3 -funroll-loops -fPIC -fpermissive -std=c++11
-CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
-CC := clang++
+CFLAGS = -g -O3 -funroll-loops -fPIC -fpermissive -std=c++11
+#CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
+CXX ?= clang++
 
 all: libfuzzer-mutator.so
 
 FuzzerCrossOver.o:	FuzzerCrossOver.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerDataFlowTrace.o:	FuzzerDataFlowTrace.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerDriver.o:	FuzzerDriver.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtFunctionsDlsym.o:	FuzzerExtFunctionsDlsym.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtFunctionsWeak.o:	FuzzerExtFunctionsWeak.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtFunctionsWindows.o:	FuzzerExtFunctionsWindows.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtraCounters.o:	FuzzerExtraCounters.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerFork.o:	FuzzerFork.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerIO.o:	FuzzerIO.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerIOPosix.o:	FuzzerIOPosix.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerIOWindows.o:	FuzzerIOWindows.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerLoop.o:	FuzzerLoop.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerMerge.o:	FuzzerMerge.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerMutate.o:	FuzzerMutate.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerSHA1.o:	FuzzerSHA1.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerTracePC.o:	FuzzerTracePC.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtil.o:	FuzzerUtil.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilDarwin.o:	FuzzerUtilDarwin.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilFuchsia.o:	FuzzerUtilFuchsia.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilLinux.o:	FuzzerUtilLinux.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilPosix.o:	FuzzerUtilPosix.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilWindows.o:	FuzzerUtilWindows.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 libfuzzer.o:	libfuzzer.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 libfuzzer-mutator.so:	FuzzerCrossOver.o FuzzerDataFlowTrace.o FuzzerDriver.o FuzzerExtFunctionsDlsym.o FuzzerExtFunctionsWeak.o FuzzerExtFunctionsWindows.o FuzzerExtraCounters.o FuzzerFork.o FuzzerIO.o FuzzerIOPosix.o FuzzerIOWindows.o FuzzerLoop.o FuzzerMerge.o FuzzerMutate.o FuzzerSHA1.o FuzzerTracePC.o FuzzerUtil.o FuzzerUtilDarwin.o FuzzerUtilFuchsia.o FuzzerUtilLinux.o FuzzerUtilPosix.o FuzzerUtilWindows.o libfuzzer.o
-	$(CC) $(CFLAGS) -I../../include -I. -shared -o libfuzzer-mutator.so *.o
+	$(CXX) $(CFLAGS) -I../../include -I. -shared -o libfuzzer-mutator.so *.o
 
 clean:
 	rm -f *.o *~ *.so core
diff --git a/custom_mutators/libfuzzer/README.md b/custom_mutators/libfuzzer/README.md
index a773da02..4783f2ca 100644
--- a/custom_mutators/libfuzzer/README.md
+++ b/custom_mutators/libfuzzer/README.md
@@ -21,4 +21,4 @@ are done.
 
 > Original repository: https://github.com/llvm/llvm-project
 > Path: compiler-rt/lib/fuzzer/*.{h|cpp}
-> Source commit: d4b88ac1658d681e143482336cac27c6a74b8b24
+> Source commit: df3e903655e2499968fc7af64fb5fa52b2ee79bb
diff --git a/custom_mutators/libfuzzer/libfuzzer.cpp b/custom_mutators/libfuzzer/libfuzzer.cpp
index cf41af2d..5e37df66 100644
--- a/custom_mutators/libfuzzer/libfuzzer.cpp
+++ b/custom_mutators/libfuzzer/libfuzzer.cpp
@@ -72,7 +72,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
 /* When a new queue entry is added we check if there are new dictionary
    entries to add to honggfuzz structure */
-#if ß
+#if 0
 extern "C" void afl_custom_queue_new_entry(my_mutator_t * data,
                                            const uint8_t *filename_new_queue,
                                            const uint8_t *filename_orig_queue) {
diff --git a/docs/Changelog.md b/docs/Changelog.md
index af52b955..ba7028df 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -14,6 +14,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - all compilers combined to afl-cc which emulates the previous ones
   - afl-llvm/gcc-rt.o merged into afl-compiler-rt.o
   - afl-fuzz
+    - memory limits are now disabled by default, set them with -m if required
+    - Marcel Boehme submitted a patch that improves all AFFast schedules :)
     - reading testcases from -i now descends into subdirectories
     - allow up to 4 -x command line options
     - loaded extras now have a duplicate protection
@@ -32,6 +34,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
       -x dictionary of string comparisons found during compilation
     - LTO autodict now also collects interesting cmp comparisons,
       std::string compare + find + ==, bcmp
+    - fix crash in dict2file for integers > 64 bit
+  - unicornafl synced with upstream (arm64 fix, better rust bindings)
   - added a new custom mutator: symcc -> https://github.com/eurecom-s3/symcc/
   - added a new custom mutator: libfuzzer that integrates libfuzzer mutations
   - Our afl++ Grammar-Mutator is now better integrated into custom_mutators/
diff --git a/examples/custom_mutators/README.md b/examples/custom_mutators/README.md
index a81538e6..655f7a5e 100644
--- a/examples/custom_mutators/README.md
+++ b/examples/custom_mutators/README.md
@@ -1,7 +1,7 @@
 # Examples for the custom mutator
 
 These are example and helper files for the custom mutator feature.
-See [docs/custom_mutators.md](../docs/custom_mutators.md) for more information
+See [docs/custom_mutators.md](../../docs/custom_mutators.md) for more information
 
 Note that if you compile with python3.7 you must use python3 scripts, and if
 you use python2.7 to compile python2 scripts!
diff --git a/examples/persistent_demo/persistent_demo_new.c b/examples/persistent_demo/persistent_demo_new.c
index 7f878c0c..b8b4cda0 100644
--- a/examples/persistent_demo/persistent_demo_new.c
+++ b/examples/persistent_demo/persistent_demo_new.c
@@ -37,7 +37,8 @@ unsigned char fuzz_buf[1024000];
   #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
   #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
   #define __AFL_FUZZ_INIT() void sync(void);
-  #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ?
+  #define __AFL_LOOP(x) \
+    ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0)
   #define __AFL_INIT() sync()
 
 #endif
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 8ad0ced1..e9d148e9 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -154,11 +154,11 @@ struct queue_entry {
       is_ascii;                         /* Is the input just ascii text?    */
 
   u32 bitmap_size,                      /* Number of bits set in bitmap     */
-      fuzz_level;                       /* Number of fuzzing iterations     */
+      fuzz_level,                       /* Number of fuzzing iterations     */
+      n_fuzz_entry;                     /* offset in n_fuzz                 */
 
   u64 exec_us,                          /* Execution time (us)              */
       handicap,                         /* Number of queue cycles behind    */
-      n_fuzz,                           /* Number of fuzz, does not overflow*/
       depth,                            /* Path depth                       */
       exec_cksum;                       /* Checksum of the execution trace  */
 
@@ -246,13 +246,13 @@ enum {
 enum {
 
   /* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
-  /* 01 */ EXPLOIT, /* AFL's exploitation-based const.  */
-  /* 02 */ FAST,    /* Exponential schedule             */
-  /* 03 */ COE,     /* Cut-Off Exponential schedule     */
-  /* 04 */ LIN,     /* Linear schedule                  */
-  /* 05 */ QUAD,    /* Quadratic schedule               */
-  /* 06 */ RARE,    /* Rare edges                       */
-  /* 07 */ MMOPT,   /* Modified MOPT schedule           */
+  /* 01 */ MMOPT,   /* Modified MOPT schedule           */
+  /* 02 */ EXPLOIT, /* AFL's exploitation-based const.  */
+  /* 03 */ FAST,    /* Exponential schedule             */
+  /* 04 */ COE,     /* Cut-Off Exponential schedule     */
+  /* 05 */ LIN,     /* Linear schedule                  */
+  /* 06 */ QUAD,    /* Quadratic schedule               */
+  /* 07 */ RARE,    /* Rare edges                       */
   /* 08 */ SEEK,    /* EXPLORE that ignores timings     */
 
   POWER_SCHEDULES_NUM
@@ -447,6 +447,7 @@ typedef struct afl_state {
 
   u8 cal_cycles,                        /* Calibration cycles defaults      */
       cal_cycles_long,                  /* Calibration cycles defaults      */
+      havoc_stack_pow2,                 /* HAVOC_STACK_POW2                 */
       no_unlink,                        /* do not unlink cur_input          */
       debug,                            /* Debug mode                       */
       custom_only,                      /* Custom mutator only mode         */
@@ -487,7 +488,7 @@ typedef struct afl_state {
       disable_trim,                     /* Never trim in fuzz_one           */
       shmem_testcase_mode,              /* If sharedmem testcases are used  */
       expand_havoc,                /* perform expensive havoc after no find */
-      cycle_schedules;                  /* cycle power schedules ?          */
+      cycle_schedules;                  /* cycle power schedules?           */
 
   u8 *virgin_bits,                      /* Regions yet untouched by fuzzing */
       *virgin_tmout,                    /* Bits we haven't seen in tmouts   */
@@ -495,6 +496,9 @@ typedef struct afl_state {
 
   u8 *var_bytes;                        /* Bytes that appear to be variable */
 
+#define N_FUZZ_SIZE (1 << 21)
+  u32 *n_fuzz;
+
   volatile u8 stop_soon,                /* Ctrl-C pressed?                  */
       clear_screen;                     /* Window resized?                  */
 
@@ -671,6 +675,9 @@ typedef struct afl_state {
    * they do not call another function */
   u8 *map_tmp_buf;
 
+  /* queue entries ready for splicing count (len > 4) */
+  u32 ready_for_splicing_count;
+
 } afl_state_t;
 
 struct custom_mutator {
diff --git a/include/config.h b/include/config.h
index 405c2712..7dd045e3 100644
--- a/include/config.h
+++ b/include/config.h
@@ -74,25 +74,17 @@
   #define WORD_SIZE_64 1
 #endif
 
-/* Default memory limit for child process (MB): */
-
-#ifndef __NetBSD__
-  #ifndef WORD_SIZE_64
-    #define MEM_LIMIT 50
-  #else
-    #define MEM_LIMIT 75
-  #endif                                                  /* ^!WORD_SIZE_64 */
-#else /* NetBSD's kernel needs more space for stack, see discussion for issue \
-         #165 */
-  #define MEM_LIMIT 250
-#endif
-/* Default memory limit when running in QEMU mode (MB): */
+/* Default memory limit for child process (MB) 0 = disabled : */
+
+#define MEM_LIMIT 0
+
+/* Default memory limit when running in QEMU mode (MB) 0 = disabled : */
 
-#define MEM_LIMIT_QEMU 250
+#define MEM_LIMIT_QEMU 0
 
-/* Default memory limit when running in Unicorn mode (MB): */
+/* Default memory limit when running in Unicorn mode (MB) 0 = disabled : */
 
-#define MEM_LIMIT_UNICORN 250
+#define MEM_LIMIT_UNICORN 0
 
 /* Number of calibration cycles per every new test case (and for test
    cases that show variable behavior): */
@@ -117,8 +109,8 @@
 /* Maximum multiplier for the above (should be a power of two, beware
    of 32-bit int overflows): */
 
-#define HAVOC_MAX_MULT 32
-#define HAVOC_MAX_MULT_MOPT 32
+#define HAVOC_MAX_MULT 64
+#define HAVOC_MAX_MULT_MOPT 64
 
 /* Absolute minimum number of havoc cycles (after all adjustments): */
 
@@ -134,10 +126,10 @@
    n = random between 1 and HAVOC_STACK_POW2
    stacking = 2^n
 
-   In other words, the default (n = 6) produces 2, 4, 8, 16, 32, or 64
+   In other words, the default (n = 4) produces 2, 4, 8, 16
    stacked tweaks: */
 
-#define HAVOC_STACK_POW2 6
+#define HAVOC_STACK_POW2 4
 
 /* Caps on block sizes for cloning and deletion operations. Each of these
    ranges has a 33% probability of getting picked, except for the first
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 64162145..82e55218 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -526,7 +526,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
             Value *      op = cmpInst->getOperand(1);
             ConstantInt *ilen = dyn_cast<ConstantInt>(op);
 
-            if (ilen) {
+            if (ilen && ilen->uge(0xffffffffffffffff) == false) {
 
               u64 val2 = 0, val = ilen->getZExtValue();
               u32 len = 0;
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index 15accc88..bd8eb27a 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -195,7 +195,11 @@ bool AFLdict2filePass::runOnModule(Module &M) {
           Value *      op = cmpInst->getOperand(1);
           ConstantInt *ilen = dyn_cast<ConstantInt>(op);
 
-          if (ilen) {
+          /* We skip > 64 bit integers. why? first because their value is
+             difficult to obtain, and second because clang does not support
+             literals > 64 bit (as of llvm 12) */
+
+          if (ilen && ilen->uge(0xffffffffffffffff) == false) {
 
             u64 val2 = 0, val = ilen->getZExtValue();
             u32 len = 0;
@@ -377,8 +381,9 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
           if (debug)
             fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n",
-                    FuncName.c_str(), Str1P, Str1P->getName().str().c_str(),
-                    Str1.c_str(), HasStr1 == true ? "true" : "false", Str2P,
+                    FuncName.c_str(), (void *)Str1P,
+                    Str1P->getName().str().c_str(), Str1.c_str(),
+                    HasStr1 == true ? "true" : "false", (void *)Str2P,
                     Str2P->getName().str().c_str(), Str2.c_str(),
                     HasStr2 == true ? "true" : "false");
 
@@ -432,7 +437,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
               valueMap[Str1P] = new std::string(Str2);
 
               if (debug)
-                fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), Str1P);
+                fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(),
+                        (void *)Str1P);
               continue;
 
             }
@@ -451,7 +457,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
               Str2 = *strng;
               HasStr2 = true;
               if (debug)
-                fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), Str2P);
+                fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(),
+                        (void *)Str2P);
 
             }
 
@@ -493,7 +500,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
               Str1 = *strng;
               HasStr1 = true;
               if (debug)
-                fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), Str1P);
+                fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(),
+                        (void *)Str1P);
 
             }
 
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index 2f936c29..9e026e57 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -293,7 +293,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
             Value *      op = cmpInst->getOperand(1);
             ConstantInt *ilen = dyn_cast<ConstantInt>(op);
 
-            if (ilen) {
+            if (ilen && ilen->uge(0xffffffffffffffff) == false) {
 
               u64 val2 = 0, val = ilen->getZExtValue();
               u32 len = 0;
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index d5de3dbb..9921de0c 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -210,7 +210,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
   }
 
   if (!icomps.size()) return false;
-  if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp instructions\n";
+  // if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp
+  // instructions\n";
 
   for (auto &selectcmpInst : icomps) {
 
@@ -259,8 +260,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 bool CmpLogInstructions::runOnModule(Module &M) {
 
   if (getenv("AFL_QUIET") == NULL)
-    llvm::errs()
-        << "Running cmplog-instructions-pass by andreafioraldi@gmail.com\n";
+    printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n");
   else
     be_quiet = 1;
   hookInstrs(M);
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index c44f38c4..e92883ae 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -149,9 +149,11 @@ bool CmpLogRoutines::hookRtns(Module &M) {
   }
 
   if (!calls.size()) return false;
-  if (!be_quiet)
-    errs() << "Hooking " << calls.size()
-           << " calls with pointers as arguments\n";
+  /*
+    if (!be_quiet)
+      errs() << "Hooking " << calls.size()
+             << " calls with pointers as arguments\n";
+  */
 
   for (auto &callInst : calls) {
 
@@ -179,8 +181,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
 bool CmpLogRoutines::runOnModule(Module &M) {
 
   if (getenv("AFL_QUIET") == NULL)
-    llvm::errs()
-        << "Running cmplog-routines-pass by andreafioraldi@gmail.com\n";
+    printf("Running cmplog-routines-pass by andreafioraldi@gmail.com\n");
   else
     be_quiet = 1;
   hookRtns(M);
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index 9d2f4a92..de8b97f0 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -339,8 +339,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 
   if (!calls.size()) return false;
   if (!be_quiet)
-    errs() << "Replacing " << calls.size()
-           << " calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n";
+    printf(
+        "Replacing %zu calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n",
+        calls.size());
 
   for (auto &callInst : calls) {
 
@@ -426,11 +427,14 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
     else
       unrollLen = constStrLen;
 
-    if (!be_quiet)
-      errs() << callInst->getCalledFunction()->getName() << ": unroll len "
-             << unrollLen
-             << ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ": "
-             << ConstStr << "\n";
+    /*
+        if (!be_quiet)
+          errs() << callInst->getCalledFunction()->getName() << ": unroll len "
+                 << unrollLen
+                 << ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ":
+       "
+                 << ConstStr << "\n";
+    */
 
     /* split before the call instruction */
     BasicBlock *bb = callInst->getParent();
@@ -556,10 +560,12 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 bool CompareTransform::runOnModule(Module &M) {
 
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
-    llvm::errs() << "Running compare-transform-pass by laf.intel@gmail.com, "
-                    "extended by heiko@hexco.de\n";
+    printf(
+        "Running compare-transform-pass by laf.intel@gmail.com, extended by "
+        "heiko@hexco.de\n");
   else
     be_quiet = 1;
+
   transformCmps(M, true, true, true, true, true);
   verifyModule(M);
 
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 2fb90e5e..6d0c52a4 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -1262,8 +1262,9 @@ bool SplitComparesTransform::runOnModule(Module &M) {
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
       getenv("AFL_DEBUG") != NULL) {
 
-    errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
-              "heiko@hexco.de\n";
+    printf(
+        "Split-compare-pass by laf.intel@gmail.com, extended by "
+        "heiko@hexco.de\n");
 
   } else {
 
@@ -1275,13 +1276,15 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
     count = splitFPCompares(M);
 
-    if (!be_quiet) {
+    /*
+        if (!be_quiet) {
 
-      errs() << "Split-floatingpoint-compare-pass: " << count
-             << " FP comparisons split\n";
+          errs() << "Split-floatingpoint-compare-pass: " << count
+                 << " FP comparisons split\n";
 
-    }
+        }
 
+    */
     simplifyFPCompares(M);
 
   }
@@ -1294,10 +1297,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
     case 64:
       count = splitIntCompares(M, bitw);
-      if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
-               << " split\n";
-
+      /*
+            if (!be_quiet)
+              errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
+         count
+                     << " split\n";
+      */
       bitw >>= 1;
 #if LLVM_VERSION_MAJOR > 3 || \
     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7)
@@ -1305,10 +1310,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 #endif
     case 32:
       count = splitIntCompares(M, bitw);
-      if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
-               << " split\n";
-
+      /*
+            if (!be_quiet)
+              errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
+         count
+                     << " split\n";
+      */
       bitw >>= 1;
 #if LLVM_VERSION_MAJOR > 3 || \
     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7)
@@ -1316,15 +1323,17 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 #endif
     case 16:
       count = splitIntCompares(M, bitw);
-      if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
-               << " split\n";
-
+      /*
+            if (!be_quiet)
+              errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
+         count
+                     << " split\n";
+      */
       bitw >>= 1;
       break;
 
     default:
-      if (!be_quiet) errs() << "NOT Running split-compare-pass \n";
+      // if (!be_quiet) errs() << "NOT Running split-compare-pass \n";
       return false;
       break;
 
diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc
index a79d4114..97ab04a4 100644
--- a/instrumentation/split-switches-pass.so.cc
+++ b/instrumentation/split-switches-pass.so.cc
@@ -327,10 +327,11 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
   }
 
   if (!switches.size()) return false;
-  if (!be_quiet)
-    errs() << "Rewriting " << switches.size() << " switch statements "
-           << "\n";
-
+  /*
+    if (!be_quiet)
+      errs() << "Rewriting " << switches.size() << " switch statements "
+             << "\n";
+  */
   for (auto &SI : switches) {
 
     BasicBlock *CurBlock = SI->getParent();
@@ -341,15 +342,17 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
     BasicBlock *Default = SI->getDefaultDest();
     unsigned    bitw = Val->getType()->getIntegerBitWidth();
 
-    if (!be_quiet)
-      errs() << "switch: " << SI->getNumCases() << " cases " << bitw
-             << " bit\n";
+    /*
+        if (!be_quiet)
+          errs() << "switch: " << SI->getNumCases() << " cases " << bitw
+                 << " bit\n";
+    */
 
     /* If there is only the default destination or the condition checks 8 bit or
      * less, don't bother with the code below. */
     if (!SI->getNumCases() || bitw <= 8) {
 
-      if (!be_quiet) errs() << "skip trivial switch..\n";
+      // if (!be_quiet) errs() << "skip trivial switch..\n";
       continue;
 
     }
@@ -415,7 +418,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
 bool SplitSwitchesTransform::runOnModule(Module &M) {
 
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
-    llvm::errs() << "Running split-switches-pass by laf.intel@gmail.com\n";
+    printf("Running split-switches-pass by laf.intel@gmail.com\n");
   else
     be_quiet = 1;
   splitSwitches(M);
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 5d5800ad..75883247 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-41ce1c3542
+21ff343837
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject 41ce1c35429b15b5af6d4ae249a60b4c97c7159
+Subproject 21ff34383764a8c6f66509b3b8d5282468c721e
diff --git a/src/afl-cc.c b/src/afl-cc.c
index c3b8959d..c516dc4c 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1537,7 +1537,7 @@ int main(int argc, char **argv, char **envp) {
   if (debug) {
 
     SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd());
-    for (i = 0; i < cc_par_cnt; i++)
+    for (i = 0; i < (s32)cc_par_cnt; i++)
       SAYF(" '%s'", cc_params[i]);
     SAYF("\n");
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 1b9df624..a22223b9 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -555,19 +555,9 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
     cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
-    struct queue_entry *q = afl->queue;
-    while (q) {
-
-      if (q->exec_cksum == cksum) {
-
-        ++q->n_fuzz;
-        break;
-
-      }
-
-      q = q->next;
-
-    }
+    /* Saturated increment */
+    if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF)
+      afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
 
   }
 
@@ -607,9 +597,16 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
     if (cksum)
       afl->queue_top->exec_cksum = cksum;
     else
-      afl->queue_top->exec_cksum =
+      cksum = afl->queue_top->exec_cksum =
           hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
+    if (afl->schedule >= FAST && afl->schedule <= RARE) {
+
+      afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
+      afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
+
+    }
+
     /* Try to calibrate inline; this also calls update_bitmap_score() when
        successful. */
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index cbac3822..65478a78 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -729,6 +729,14 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
     add_to_queue(afl, fn2, st.st_size >= MAX_FILE ? MAX_FILE : st.st_size,
                  passed_det);
 
+    if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
+
+      u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+      afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
+      afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
+
+    }
+
   }
 
   free(nl);                                                  /* not tracked */
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 5737c1f5..c04b492b 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1696,50 +1696,47 @@ custom_mutator_stage:
 
           struct queue_entry *target;
           u32                 tid;
-          u8 *                new_buf;
+          u8 *                new_buf = NULL;
+          u32                 target_len = 0;
 
-        retry_external_pick:
-          /* Pick a random other queue entry for passing to external API */
+          /* check if splicing makes sense yet (enough entries) */
+          if (likely(afl->ready_for_splicing_count > 1)) {
 
-          do {
+            /* Pick a random other queue entry for passing to external API
+               that has the necessary length */
 
-            tid = rand_below(afl, afl->queued_paths);
+            do {
 
-          } while (tid == afl->current_entry && afl->queued_paths > 1);
-
-          afl->splicing_with = tid;
-          target = afl->queue_buf[tid];
+              tid = rand_below(afl, afl->queued_paths);
 
-          /* Make sure that the target has a reasonable length. */
+            } while (unlikely(tid == afl->current_entry &&
 
-          while (target && (target->len < 2 || target == afl->queue_cur) &&
-                 afl->queued_paths > 3) {
+                              afl->queue_buf[tid]->len >= 4));
 
-            target = target->next;
-            ++afl->splicing_with;
+            target = afl->queue_buf[tid];
+            afl->splicing_with = tid;
 
-          }
+            /* Read the additional testcase into a new buffer. */
+            fd = open(target->fname, O_RDONLY);
+            if (unlikely(fd < 0)) {
 
-          if (!target) { goto retry_external_pick; }
+              PFATAL("Unable to open '%s'", target->fname);
 
-          /* Read the additional testcase into a new buffer. */
-          fd = open(target->fname, O_RDONLY);
-          if (unlikely(fd < 0)) {
+            }
 
-            PFATAL("Unable to open '%s'", target->fname);
+            new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len);
+            if (unlikely(!new_buf)) { PFATAL("alloc"); }
+            ck_read(fd, new_buf, target->len, target->fname);
+            close(fd);
+            target_len = target->len;
 
           }
 
-          new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len);
-          if (unlikely(!new_buf)) { PFATAL("alloc"); }
-          ck_read(fd, new_buf, target->len, target->fname);
-          close(fd);
-
           u8 *mutated_buf = NULL;
 
           size_t mutated_size =
               el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf,
-                                  target->len, max_seed_size);
+                                  target_len, max_seed_size);
 
           if (unlikely(!mutated_buf)) {
 
@@ -1887,7 +1884,7 @@ havoc_stage:
 
   for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
 
-    u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2));
+    u32 use_stacking = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2));
 
     afl->stage_cur_val = use_stacking;
 
@@ -2738,6 +2735,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
   if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done) {
 
+    u32 old_len = afl->queue_cur->len;
+
     u8 res = trim_case(afl, afl->queue_cur, in_buf);
 
     if (res == FSRV_RUN_ERROR) {
@@ -2759,6 +2758,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
     len = afl->queue_cur->len;
 
+    /* maybe current entry is not ready for splicing anymore */
+    if (unlikely(len <= 4 && old_len > 4)) afl->ready_for_splicing_count--;
+
   }
 
   memcpy(out_buf, in_buf, len);
@@ -3968,7 +3970,7 @@ pacemaker_fuzzing:
       for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
            ++afl->stage_cur) {
 
-        u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2));
+        u32 use_stacking = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2));
 
         afl->stage_cur_val = use_stacking;
 
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 336b7f4f..0d7d0314 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -25,6 +25,7 @@
 #include "afl-fuzz.h"
 #include <limits.h>
 #include <ctype.h>
+#include <math.h>
 
 /* Mark deterministic checks as done for a particular queue entry. We use the
    .state file to avoid repeating deterministic fuzzing when resuming aborted
@@ -218,7 +219,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
   q->len = len;
   q->depth = afl->cur_depth + 1;
   q->passed_det = passed_det;
-  q->n_fuzz = 1;
   q->trace_mini = NULL;
 
   if (q->depth > afl->max_depth) { afl->max_depth = q->depth; }
@@ -234,6 +234,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
 
   }
 
+  if (likely(q->len > 4)) afl->ready_for_splicing_count++;
+
   ++afl->queued_paths;
   ++afl->pending_not_fuzzed;
 
@@ -305,8 +307,10 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
   u64 fav_factor;
   u64 fuzz_p2;
 
-  if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
-    fuzz_p2 = next_pow2(q->n_fuzz);
+  if (unlikely(afl->schedule >= FAST && afl->schedule < RARE))
+    fuzz_p2 = 0;  // Skip the fuzz_p2 comparison
+  else if (unlikely(afl->schedule == RARE))
+    fuzz_p2 = next_pow2(afl->n_fuzz[q->n_fuzz_entry]);
   else
     fuzz_p2 = q->fuzz_level;
 
@@ -332,7 +336,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
         u64 top_rated_fav_factor;
         u64 top_rated_fuzz_p2;
         if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
-          top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
+          top_rated_fuzz_p2 =
+              next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]);
         else
           top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
 
@@ -603,11 +608,9 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
 
   }
 
-  u64 fuzz = q->n_fuzz;
-  u64 fuzz_total;
-
-  u32 n_paths, fuzz_mu;
-  u32 factor = 1;
+  u32         n_paths;
+  double      factor = 1.0;
+  long double fuzz_mu;
 
   switch (afl->schedule) {
 
@@ -622,60 +625,83 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
       break;
 
     case COE:
-      fuzz_total = 0;
+      fuzz_mu = 0.0;
       n_paths = 0;
 
+      // Don't modify perf_score for unfuzzed seeds
+      if (q->fuzz_level == 0) break;
+
       struct queue_entry *queue_it = afl->queue;
       while (queue_it) {
 
-        fuzz_total += queue_it->n_fuzz;
+        fuzz_mu += log2(afl->n_fuzz[q->n_fuzz_entry]);
         n_paths++;
+
         queue_it = queue_it->next;
 
       }
 
       if (unlikely(!n_paths)) { FATAL("Queue state corrupt"); }
 
-      fuzz_mu = fuzz_total / n_paths;
-      if (fuzz <= fuzz_mu) {
+      fuzz_mu = fuzz_mu / n_paths;
 
-        if (q->fuzz_level < 16) {
+      if (log2(afl->n_fuzz[q->n_fuzz_entry]) > fuzz_mu) {
 
-          factor = ((u32)(1 << q->fuzz_level));
+        /* Never skip favourites */
+        if (!q->favored) factor = 0;
 
-        } else {
+        break;
 
-          factor = MAX_FACTOR;
+      }
 
-        }
+    // Fall through
+    case FAST:
 
-      } else {
+      // Don't modify unfuzzed seeds
+      if (q->fuzz_level == 0) break;
 
-        factor = 0;
+      switch ((u32)log2(afl->n_fuzz[q->n_fuzz_entry])) {
 
-      }
+        case 0 ... 1:
+          factor = 4;
+          break;
 
-      break;
+        case 2 ... 3:
+          factor = 3;
+          break;
 
-    case FAST:
-      if (q->fuzz_level < 16) {
+        case 4:
+          factor = 2;
+          break;
+
+        case 5:
+          break;
 
-        factor = ((u32)(1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz);
+        case 6:
+          if (!q->favored) factor = 0.8;
+          break;
 
-      } else {
+        case 7:
+          if (!q->favored) factor = 0.6;
+          break;
 
-        factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_pow2(fuzz));
+        default:
+          if (!q->favored) factor = 0.4;
+          break;
 
       }
 
+      if (q->favored) factor *= 1.15;
+
       break;
 
     case LIN:
-      factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
+      factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
       break;
 
     case QUAD:
-      factor = q->fuzz_level * q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
+      factor =
+          q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
       break;
 
     case MMOPT:
@@ -700,8 +726,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
       perf_score += (q->tc_ref * 10);
       // the more often fuzz result paths are equal to this queue entry,
       // reduce its value
-      perf_score *=
-          (1 - (double)((double)q->n_fuzz / (double)afl->fsrv.total_execs));
+      perf_score *= (1 - (double)((double)afl->n_fuzz[q->n_fuzz_entry] /
+                                  (double)afl->fsrv.total_execs));
 
       break;
 
@@ -710,7 +736,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
 
   }
 
-  if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
+  if (unlikely(afl->schedule >= EXPLOIT && afl->schedule <= QUAD)) {
 
     if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
     perf_score *= factor / POWER_BETA;
@@ -722,7 +748,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
 
     perf_score *= 2;
 
-  } else if (perf_score < 1) {
+  } else if (afl->schedule != COE && perf_score < 1) {
 
     // Add a lower bound to AFLFast's energy assignment strategies
     perf_score = 1;
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index a7c7aff9..b7d44dbf 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -30,9 +30,9 @@ s8  interesting_8[] = {INTERESTING_8};
 s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
 s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
 
-char *power_names[POWER_SCHEDULES_NUM] = {"explore", "exploit", "fast",
-                                          "coe",     "lin",     "quad",
-                                          "rare",    "mmopt",   "seek"};
+char *power_names[POWER_SCHEDULES_NUM] = {"explore", "mmopt", "exploit",
+                                          "fast",    "coe",   "lin",
+                                          "quad",    "rare",  "seek"};
 
 /* Initialize MOpt "globals" for this afl state */
 
@@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
   afl->w_end = 0.3;
   afl->g_max = 5000;
   afl->period_pilot_tmp = 5000.0;
-  afl->schedule = SEEK;                   /* Power schedule (default: SEEK) */
+  afl->schedule = EXPLORE;             /* Power schedule (default: EXPLORE) */
   afl->havoc_max_mult = HAVOC_MAX_MULT;
 
   afl->clear_screen = 1;                /* Window resized?                  */
@@ -95,6 +95,12 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
   afl->stage_name = "init";             /* Name of the current fuzz stage   */
   afl->splicing_with = -1;              /* Splicing with which test case?   */
   afl->cpu_to_bind = -1;
+  afl->havoc_stack_pow2 = HAVOC_STACK_POW2;
+  afl->cal_cycles = CAL_CYCLES;
+  afl->cal_cycles_long = CAL_CYCLES_LONG;
+  afl->hang_tmout = EXEC_TIMEOUT;
+  afl->stats_update_freq = 1;
+  afl->stats_avg_exec = -1;
 
 #ifdef HAVE_AFFINITY
   afl->cpu_aff = -1;                    /* Selected CPU core                */
@@ -115,46 +121,13 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
   // afl_state_t is not available in forkserver.c
   afl->fsrv.afl_ptr = (void *)afl;
   afl->fsrv.add_extra_func = (void (*)(void *, u8 *, u32)) & add_extra;
-
-  afl->cal_cycles = CAL_CYCLES;
-  afl->cal_cycles_long = CAL_CYCLES_LONG;
-
   afl->fsrv.exec_tmout = EXEC_TIMEOUT;
-  afl->hang_tmout = EXEC_TIMEOUT;
-
   afl->fsrv.mem_limit = MEM_LIMIT;
-
-  afl->stats_update_freq = 1;
-
   afl->fsrv.dev_urandom_fd = -1;
   afl->fsrv.dev_null_fd = -1;
-
   afl->fsrv.child_pid = -1;
   afl->fsrv.out_dir_fd = -1;
 
-  afl->cmplog_prev_timed_out = 0;
-
-  /* statis file */
-  afl->last_bitmap_cvg = 0;
-  afl->last_stability = 0;
-  afl->last_eps = 0;
-
-  /* plot file saves from last run */
-  afl->plot_prev_qp = 0;
-  afl->plot_prev_pf = 0;
-  afl->plot_prev_pnf = 0;
-  afl->plot_prev_ce = 0;
-  afl->plot_prev_md = 0;
-  afl->plot_prev_qc = 0;
-  afl->plot_prev_uc = 0;
-  afl->plot_prev_uh = 0;
-
-  afl->stats_last_stats_ms = 0;
-  afl->stats_last_plot_ms = 0;
-  afl->stats_last_ms = 0;
-  afl->stats_last_execs = 0;
-  afl->stats_avg_exec = -1;
-
   init_mopt_globals(afl);
 
   list_append(&afl_states, afl);
@@ -175,6 +148,14 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
       WARNF("Potentially mistyped AFL environment variable: %s", env);
       issue_detected = 1;
 
+    } else if (strncmp(env, "USE_", 4) == 0) {
+
+      WARNF(
+          "Potentially mistyped AFL environment variable: %s, did you mean "
+          "AFL_%s?",
+          env, env);
+      issue_detected = 1;
+
     } else if (strncmp(env, "AFL_", 4) == 0) {
 
       int i = 0, match = 0;
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 8a1c2cc6..0cd6f399 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -967,7 +967,7 @@ void show_stats(afl_state_t *afl) {
 #else
 
     SAYF("%s" cGRA "   [cpu:%s%3u%%" cGRA "]\r" cRST, spacing, cpu_color,
-         MIN(cur_utilization, 999));
+         MIN(cur_utilization, (u32)999));
 
 #endif                                                    /* ^HAVE_AFFINITY */
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index aa36a6c6..dc0eb4a7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -90,13 +90,13 @@ static void usage(u8 *argv0, int more_help) {
 
       "Execution control settings:\n"
       "  -p schedule   - power schedules compute a seed's performance score:\n"
-      "                  <seek (default), explore, rare, exploit, mmopt, coe, "
+      "                  <explore(default), rare, exploit, seek, mmopt, coe, "
       "fast,\n"
       "                  lin, quad> -- see docs/power_schedules.md\n"
       "  -f file       - location read by the fuzzed program (default: stdin "
       "or @@)\n"
       "  -t msec       - timeout for each run (auto-scaled, 50-%d ms)\n"
-      "  -m megs       - memory limit for child process (%d MB)\n"
+      "  -m megs       - memory limit for child process (%d MB, 0 = no limit)\n"
       "  -Q            - use binary-only instrumentation (QEMU mode)\n"
       "  -U            - use unicorn-based instrumentation (Unicorn mode)\n"
       "  -W            - use qemu-based instrumentation with Wine (Wine "
@@ -251,7 +251,8 @@ 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[4];
-  u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0, have_p = 0;
+  u8  mem_limit_given = 0, exit_1 = 0, debug = 0,
+     extras_dir_cnt = 0 /*, have_p = 0*/;
   char **use_argv;
 
   struct timeval  tv;
@@ -369,7 +370,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
         }
 
-        have_p = 1;
+        // have_p = 1;
 
         break;
 
@@ -934,7 +935,7 @@ int main(int argc, char **argv_orig, char **envp) {
       OKF("Using seek power schedule (SEEK)");
       break;
     case EXPLORE:
-      OKF("Using exploration-based constant power schedule (EXPLORE, default)");
+      OKF("Using exploration-based constant power schedule (EXPLORE)");
       break;
     default:
       FATAL("Unknown power schedule");
@@ -942,6 +943,13 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  /* Dynamically allocate memory for AFLFast schedules */
+  if (afl->schedule >= FAST && afl->schedule <= RARE) {
+
+    afl->n_fuzz = ck_alloc(N_FUZZ_SIZE * sizeof(u32));
+
+  }
+
   if (get_afl_env("AFL_NO_FORKSRV")) { afl->no_forkserver = 1; }
   if (get_afl_env("AFL_NO_CPU_RED")) { afl->no_cpu_meter_red = 1; }
   if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
@@ -1330,11 +1338,11 @@ int main(int argc, char **argv_orig, char **envp) {
       afl->cur_skipped_paths = 0;
       afl->queue_cur = afl->queue;
 
-      while (seek_to) {
+      if (seek_to) {
 
-        ++afl->current_entry;
-        --seek_to;
-        afl->queue_cur = afl->queue_cur->next;
+        afl->current_entry = seek_to;
+        afl->queue_cur = afl->queue_buf[seek_to];
+        seek_to = 0;
 
       }
 
@@ -1373,10 +1381,15 @@ int main(int argc, char **argv_orig, char **envp) {
               afl->expand_havoc = 2;
               break;
             case 2:
-              if (!have_p) afl->schedule = EXPLOIT;
+              // if (!have_p) afl->schedule = EXPLOIT;
+              afl->havoc_stack_pow2++;
               afl->expand_havoc = 3;
               break;
             case 3:
+              afl->havoc_stack_pow2++;
+              afl->expand_havoc = 4;
+              break;
+            case 4:
               // nothing else currently
               break;
 
diff --git a/test/test-performance.sh b/test/test-performance.sh
index cd6eea64..61ec1e28 100755
--- a/test/test-performance.sh
+++ b/test/test-performance.sh
@@ -4,7 +4,7 @@
 # you can set the AFL_PERFORMANCE_FILE environment variable:
 FILE=$AFL_PERFORMANCE_FILE
 # otherwise we use ~/.afl_performance
-test -z "$FILE" && FILE=~/.afl_performance
+test -z "$FILE" && FILE=.afl_performance
 
 test -e $FILE || {
   echo Warning: This script measure the performance of afl++ and saves the result for future comparisons into $FILE
@@ -12,7 +12,11 @@ test -e $FILE || {
   read IN
 }
 
+test -e ./test-performance.sh || { echo Error: this script must be run from the directory in which it lies. ; exit 1 ; }
+
 export AFL_QUIET=1
+export AFL_PATH=`pwd`/..
+
 unset AFL_EXIT_WHEN_DONE
 unset AFL_SKIP_CPUFREQ
 unset AFL_DEBUG
@@ -36,8 +40,10 @@ test -e /usr/local/bin/opt && {
 # afl-gcc does not work there
 test `uname -s` = 'Darwin' -o `uname -s` = 'FreeBSD' && {
   AFL_GCC=afl-clang
+  CC=clang
 } || {
   AFL_GCC=afl-gcc
+  CC=gcc
 }
 
 ECHO="printf %b\\n"
@@ -57,9 +63,9 @@ RED="\\033[0;31m"
 YELLOW="\\033[1;93m"
 RESET="\\033[0m"
 
-MEM_LIMIT=150
+MEM_LIMIT=500
 
->> $FILE || { echo Error: can not write to $FILE ; exit 1 ; }
+touch $FILE || { echo Error: can not write to $FILE ; exit 1 ; }
 
 echo Warning: this script is setting performance parameters with afl-system-config
 sleep 1
@@ -144,7 +150,7 @@ test -e ../afl-gcc-fast -a -e ../afl-fuzz && {
 $ECHO "$BLUE[*] Testing: qemu_mode"
 QEMU=x
 test -e ../afl-qemu-trace -a -e ../afl-fuzz && {
-  cc -o test-instr.qemu ../test-instr.c > /dev/null 2>&1
+  $CC -o test-instr.qemu ../test-instr.c > /dev/null 2>&1
   test -e test-instr.qemu && {
     $ECHO "$GREEN[+] native compilation with cc succeeded"
     mkdir -p in
@@ -157,6 +163,7 @@ test -e ../afl-qemu-trace -a -e ../afl-fuzz && {
       QEMU=`grep execs_done out-qemu/fuzzer_stats | awk '{print$3}'`
     } || {
         echo CUT----------------------------------------------------------------
+        echo ../afl-fuzz -Q -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-qemu -- ./test-instr.qemu
         cat errors
         echo CUT----------------------------------------------------------------
       $ECHO "$RED[!] afl-fuzz is not working correctly with qemu_mode"
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 02736b77..87c5f419 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-c6d66471
+0bf26f6c