about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2021-03-24 11:25:33 +0100
committerGitHub <noreply@github.com>2021-03-24 11:25:33 +0100
commitf0e08e648609e57732a76e285e57714c6d5fd2cd (patch)
tree9d35021985e2b6ea2b2988f318195d238e6fabc3
parent37829765282421d9e3cb9448bceedcb58256e76a (diff)
parent2dac4e785fa9f27e8c59bb504cfa8942eba938be (diff)
downloadafl++-f0e08e648609e57732a76e285e57714c6d5fd2cd.tar.gz
Merge pull request #842 from AFLplusplus/stable
3.12c release
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--.github/workflows/codeql-analysis.yml4
-rw-r--r--.gitignore1
-rw-r--r--GNUmakefile5
-rw-r--r--GNUmakefile.llvm2
-rw-r--r--README.md13
-rw-r--r--TODO.md1
-rw-r--r--docs/Changelog.md24
-rw-r--r--docs/env_variables.md13
-rw-r--r--dynamic_list.txt37
-rw-r--r--include/afl-fuzz.h2
-rw-r--r--include/common.h9
-rw-r--r--include/config.h14
-rw-r--r--include/envs.h4
-rw-r--r--instrumentation/README.lto.md2
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc10
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc238
-rw-r--r--instrumentation/afl-compiler-rt.o.c46
-rw-r--r--instrumentation/afl-llvm-common.cc21
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
-rw-r--r--qemu_mode/libqasan/hooks.c2
-rw-r--r--qemu_mode/libqasan/malloc.c6
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-analyze.c60
-rw-r--r--src/afl-as.c2
-rw-r--r--src/afl-cc.c81
-rw-r--r--src/afl-common.c391
-rw-r--r--src/afl-forkserver.c104
-rw-r--r--src/afl-fuzz-bitmap.c8
-rw-r--r--src/afl-fuzz-extras.c2
-rw-r--r--src/afl-fuzz-init.c57
-rw-r--r--src/afl-fuzz-mutators.c2
-rw-r--r--src/afl-fuzz-one.c21
-rw-r--r--src/afl-fuzz-queue.c20
-rw-r--r--src/afl-fuzz-run.c18
-rw-r--r--src/afl-fuzz-state.c7
-rw-r--r--src/afl-fuzz-stats.c9
-rw-r--r--src/afl-fuzz.c99
-rw-r--r--src/afl-sharedmem.c12
-rw-r--r--src/afl-showmap.c63
-rw-r--r--src/afl-tmin.c62
-rw-r--r--test-instr.c4
-rw-r--r--test/test-dlopen.c23
-rwxr-xr-xtest/test-llvm.sh42
-rw-r--r--test/travis/bionic/Dockerfile45
-rw-r--r--test/travis/focal/Dockerfile45
-rw-r--r--test/travis/trusty/Dockerfile49
-rw-r--r--test/travis/xenial/Dockerfile46
-rw-r--r--unicorn_mode/helper_scripts/ida_context_loader.py197
m---------unicorn_mode/unicornafl0
-rw-r--r--utils/afl_network_proxy/afl-network-server.c33
-rw-r--r--utils/aflpp_driver/aflpp_driver.c12
-rwxr-xr-xutils/crash_triage/triage_crashes.sh4
-rw-r--r--utils/libdislocator/libdislocator.so.c12
54 files changed, 963 insertions, 1027 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8412fcbb..31cfceaf 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,8 +3,8 @@ name: CI
 on:
   push:
     branches: [ stable, dev ]
-#  pull_request:
-#    branches: [ stable, dev ]
+  pull_request:
+    branches: [ stable, dev ]
 
 jobs:
   build:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index e6c166f2..eda8dfd0 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -3,8 +3,8 @@ name: "CodeQL"
 on:
   push:
     branches: [ stable, dev ]
-#  pull_request:
-#    branches: [ stable, dev ]
+  pull_request:
+    branches: [ stable, dev ]
 
 jobs:
   analyze:
diff --git a/.gitignore b/.gitignore
index fa820833..3f440730 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,7 +65,6 @@ qemu_mode/qemu-*
 qemu_mode/qemuafl
 unicorn_mode/samples/*/\.test-*
 unicorn_mode/samples/*/output/
-unicorn_mode/unicornafl
 test/unittests/unit_maybe_alloc
 test/unittests/unit_preallocable
 test/unittests/unit_list
diff --git a/GNUmakefile b/GNUmakefile
index 6c89bc6f..ac8fe796 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -558,6 +558,7 @@ clean:
 	-$(MAKE) -f GNUmakefile.gcc_plugin clean
 	$(MAKE) -C utils/libdislocator clean
 	$(MAKE) -C utils/libtokencap clean
+	$(MAKE) -C utils/aflpp_driver clean
 	$(MAKE) -C utils/afl_network_proxy clean
 	$(MAKE) -C utils/socket_fuzzing clean
 	$(MAKE) -C utils/argv_fuzzing clean
@@ -576,7 +577,11 @@ endif
 deepclean:	clean
 	rm -rf unicorn_mode/unicornafl
 	rm -rf qemu_mode/qemuafl
+ifeq "$(IN_REPO)" "1"
 # NEVER EVER ACTIVATE THAT!!!!! git reset --hard >/dev/null 2>&1 || true
+	git checkout unicorn_mode/unicornafl
+	git checkout qemu_mode/qemuafl
+endif
 
 .PHONY: distrib
 distrib: all
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index cc332f6c..111a847d 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -507,6 +507,8 @@ install: all
 	@echo .SH LICENSE >> ./$@
 	@echo Apache License Version 2.0, January 2004 >> ./$@
 	@ln -sf afl-cc.8 ./afl-c++.8
+	@ln -sf afl-cc.8 ./afl-clang-fast.8
+	@ln -sf afl-cc.8 ./afl-clang-fast++.8
 ifneq "$(AFL_CLANG_FLTO)" ""
 ifeq "$(LLVM_LTO)" "1"
 	@ln -sf afl-cc.8 ./afl-clang-lto.8
diff --git a/README.md b/README.md
index 69e5bb74..084971f3 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
 
   <img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ Logo">
 
-  Release Version: [3.11c](https://github.com/AFLplusplus/AFLplusplus/releases)
+  Release Version: [3.12c](https://github.com/AFLplusplus/AFLplusplus/releases)
 
-  Github Version: 3.12a
+  Github Version: 3.13a
 
   Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
 
@@ -175,7 +175,13 @@ If you want to build afl++ yourself you have many options.
 The easiest choice is to build and install everything:
 
 ```shell
-sudo apt install build-essential python3-dev automake flex bison libglib2.0-dev libpixman-1-dev python3-setuptools clang lld llvm llvm-dev libstdc++-dev
+sudo apt-get update
+sudo apt-get install -y build-essential python3-dev automake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools
+# try to install llvm 11 and install the distro default if that fails
+sudo apt-get install -y lld-11 llvm-11 llvm-11-dev clang-11 || sudo apt-get install -y lld llvm llvm-dev clang 
+sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-dev
+git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus
+cd AFLplusplus
 make distrib
 sudo make install
 ```
@@ -1178,6 +1184,7 @@ without feedback, bug reports, or patches from:
   Josephine Calliotte                   Konrad Welc
   Thomas Rooijakkers                    David Carlier
   Ruben ten Hove                        Joey Jiao
+  fuzzah
 ```
 
 Thank you!
diff --git a/TODO.md b/TODO.md
index e5a678cf..b8a091ff 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,6 +2,7 @@
 
 ## Roadmap 3.00+
 
+ - Update afl->pending_not_fuzzed for MOpt
  - 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()
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 1c735a70..5b7d6ab6 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,6 +8,29 @@
 Want to stay in the loop on major new features? Join our mailing list by
 sending a mail to <afl-users+subscribe@googlegroups.com>.
 
+### Version ++3.12c (release)
+  - afl-fuzz:
+    - added AFL_TARGET_ENV variable to pass extra env vars to the target
+      (for things like LD_LIBRARY_PATH)
+    - fix map detection, AFL_MAP_SIZE not needed anymore for most cases
+    - fix counting favorites (just a display thing)
+  - afl-cc:
+    - fix cmplog rtn (rare crash and not being able to gather ptr data)
+    - fix our own PCGUARD implementation to compile with llvm 10.0.1
+    - link runtime not to shared libs
+    - ensure shared libraries are properly built and instrumented
+    - AFL_LLVM_INSTRUMENT_ALLOW/DENY were not implemented for LTO, added
+    - show correct LLVM PCGUARD NATIVE mode when auto switching to it
+      and keep fsanitize-coverage-*list=...
+      Short mnemnonic NATIVE is now also accepted.
+  - qemu_mode (thanks @realmadsci):
+    - move AFL_PRELOAD and AFL_USE_QASAN logic inside afl-qemu-trace
+    - add AFL_QEMU_CUSTOM_BIN
+  - unicorn_mode
+    - accidently removed the subfolder from github, re-added
+  - added DEFAULT_PERMISSION to config.h for all files created, default
+    to 0600
+
 ### Version ++3.11c (release)
   - afl-fuzz:
     - better auto detection of map size
@@ -38,7 +61,6 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
     - we no longer perform a "git drop"
   - afl-cmin: support filenames with spaces
 
-
 ### Version ++3.10c (release)
   - Mac OS ARM64 support
   - Android support fixed and updated by Joey Jiaojg - thanks!
diff --git a/docs/env_variables.md b/docs/env_variables.md
index a20f1e42..409425f1 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -393,6 +393,10 @@ checks or alter some of the more exotic semantics of the tool:
 
   - In QEMU mode (-Q), `AFL_PATH` will be searched for afl-qemu-trace.
 
+  - In QEMU mode (-Q), setting `AFL_QEMU_CUSTOM_BIN` cause afl-fuzz to skip
+    prepending `afl-qemu-trace` to your command line. Use this if you wish to use a
+    custom afl-qemu-trace or if you need to modify the afl-qemu-trace arguments.
+
   - Setting `AFL_CYCLE_SCHEDULES` will switch to a different schedule everytime
     a cycle is finished.
 
@@ -404,6 +408,12 @@ checks or alter some of the more exotic semantics of the tool:
     without disrupting the afl-fuzz process itself. This is useful, among other
     things, for bootstrapping libdislocator.so.
 
+  - Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables
+    for the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz ... `
+    This exists mostly for things like `LD_LIBRARY_PATH` but it would theoretically
+    allow fuzzing of AFL++ itself (with 'target' AFL++ using some AFL_ vars that
+    would disrupt work of 'fuzzer' AFL++).
+
   - Setting `AFL_NO_UI` inhibits the UI altogether, and just periodically prints
     some basic stats. This behavior is also automatically triggered when the
     output from afl-fuzz is redirected to a file or to a pipe.
@@ -415,7 +425,8 @@ checks or alter some of the more exotic semantics of the tool:
     no valid terminal was detected (for virtual consoles)
 
   - If you are Jakub, you may need `AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES`.
-    Others need not apply.
+    Others need not apply, unless they also want to disable the
+    `/proc/sys/kernel/core_pattern` check.
 
   - Benchmarking only: `AFL_BENCH_JUST_ONE` causes the fuzzer to exit after
     processing the first queue entry; and `AFL_BENCH_UNTIL_CRASH` causes it to
diff --git a/dynamic_list.txt b/dynamic_list.txt
index 3c0b054f..f0e54d92 100644
--- a/dynamic_list.txt
+++ b/dynamic_list.txt
@@ -5,6 +5,43 @@
   "__afl_auto_init";
   "__afl_area_initial";
   "__afl_prev_loc";
+  "__afl_prev_caller";
+  "__afl_prev_ctx";
+  "__afl_final_loc";
+  "__afl_map_addr";
+  "__afl_dictionary";
+  "__afl_dictionary_len";
+  "__afl_selective_coverage";
+  "__afl_selective_coverage_start_off";
+  "__afl_selective_coverage_temp";
+  "__afl_coverage_discard";
+  "__afl_coverage_skip";
+  "__afl_coverage_on";
+  "__afl_coverage_off";
+  "__afl_coverage_interesting";
+  "__afl_fuzz_len";
+  "__afl_fuzz_ptr";
   "__sanitizer_cov_trace_pc_guard";
   "__sanitizer_cov_trace_pc_guard_init";
+  "__cmplog_ins_hook1";
+  "__cmplog_ins_hook2";
+  "__cmplog_ins_hook4";
+  "__cmplog_ins_hookN";
+  "__cmplog_ins_hook16";
+  "__sanitizer_cov_trace_cmp1";
+  "__sanitizer_cov_trace_const_cmp1";
+  "__sanitizer_cov_trace_cmp2";
+  "__sanitizer_cov_trace_const_cmp2";
+  "__sanitizer_cov_trace_cmp4";
+  "__sanitizer_cov_trace_const_cmp4";
+  "__sanitizer_cov_trace_cmp8";
+  "__sanitizer_cov_trace_const_cmp8";
+  "__sanitizer_cov_trace_cmp16";
+  "__sanitizer_cov_trace_const_cmp16";
+  "__sanitizer_cov_trace_switch";
+  "__cmplog_rtn_hook";
+  "__cmplog_rtn_gcc_stdstring_cstring";
+  "__cmplog_rtn_gcc_stdstring_stdstring";
+  "__cmplog_rtn_llvm_stdstring_cstring";
+  "__cmplog_rtn_llvm_stdstring_stdstring";
 };
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 5003b563..565e9afd 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -390,7 +390,7 @@ typedef struct afl_env_vars {
       *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload,
       *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
       *afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
-      *afl_testcache_entries, *afl_kill_signal;
+      *afl_testcache_entries, *afl_kill_signal, *afl_target_env;
 
 } afl_env_vars_t;
 
diff --git a/include/common.h b/include/common.h
index cd728536..7bba9e91 100644
--- a/include/common.h
+++ b/include/common.h
@@ -48,7 +48,10 @@ void   argv_cpy_free(char **argv);
 char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
 char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
 char * get_afl_env(char *env);
-u8 *   get_libqasan_path(u8 *own_loc);
+
+/* Extract env vars from input string and set them using setenv()
+   For use with AFL_TARGET_ENV, ... */
+bool extract_and_set_env(u8 *env_str);
 
 extern u8  be_quiet;
 extern u8 *doc_path;                    /* path to documentation dir        */
@@ -58,6 +61,10 @@ extern u8 *doc_path;                    /* path to documentation dir        */
 
 u8 *find_binary(u8 *fname);
 
+/* find an afl binary */
+
+u8 *find_afl_binary(u8 *own_loc, u8 *fname);
+
 /* Parses the kill signal environment variable, FATALs on error.
   If the env is not set, sets the env to default_signal for the signal handlers
   and returns the default_signal. */
diff --git a/include/config.h b/include/config.h
index cc8024ea..c93a6d51 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
 /* Version string: */
 
 // c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++3.11c"
+#define VERSION "++3.12c"
 
 /******************************************************
  *                                                    *
@@ -34,6 +34,18 @@
  *                                                    *
  ******************************************************/
 
+/* Default shared memory map size. Most targets just need a coverage map
+   between 20-250kb. Plus there is an auto-detection feature in afl-fuzz.
+   However if a target has problematic constructors and init arrays then
+   this can fail. Hence afl-fuzz deploys a larger default map. The largest
+   map seen so far is the xlsx fuzzer for libreoffice which is 5MB.
+   At runtime this value can be overriden via AFL_MAP_SIZE.
+   Default: 8MB (defined in bytes) */
+#define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024)
+
+/* Default file permission umode when creating files (default: 0600) */
+#define DEFAULT_PERMISSION 0600
+
 /* CMPLOG/REDQUEEN TUNING
  *
  * Here you can modify tuning and solving options for CMPLOG.
diff --git a/include/envs.h b/include/envs.h
index 4d4d6b0e..d7578045 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -42,6 +42,7 @@ static char *afl_environment_variables[] = {
     "AFL_DEBUG_CHILD",
     "AFL_DEBUG_GDB",
     "AFL_DISABLE_TRIM",
+    "AFL_DISABLE_LLVM_INSTRUMENTATION",
     "AFL_DONT_OPTIMIZE",
     "AFL_DRIVER_STDERR_DUPLICATE_FILENAME",
     "AFL_DUMB_FORKSRV",
@@ -50,6 +51,7 @@ static char *afl_environment_variables[] = {
     "AFL_FAST_CAL",
     "AFL_FORCE_UI",
     "AFL_FUZZER_ARGS",  // oss-fuzz
+    "AFL_GDB",
     "AFL_GCC_ALLOWLIST",
     "AFL_GCC_DENYLIST",
     "AFL_GCC_BLOCKLIST",
@@ -129,7 +131,9 @@ static char *afl_environment_variables[] = {
     "AFL_PATH",
     "AFL_PERFORMANCE_FILE",
     "AFL_PRELOAD",
+    "AFL_TARGET_ENV",
     "AFL_PYTHON_MODULE",
+    "AFL_QEMU_CUSTOM_BIN",
     "AFL_QEMU_COMPCOV",
     "AFL_QEMU_COMPCOV_DEBUG",
     "AFL_QEMU_DEBUG_MAPS",
diff --git a/instrumentation/README.lto.md b/instrumentation/README.lto.md
index 81c82c4b..39f6465a 100644
--- a/instrumentation/README.lto.md
+++ b/instrumentation/README.lto.md
@@ -113,7 +113,7 @@ cmake \
     -DLLVM_LINK_LLVM_DYLIB="ON" \
     -DLLVM_TARGETS_TO_BUILD="host" \
     ../llvm/
-cmake --build . --parallel
+cmake --build . -j4
 export PATH="$(pwd)/bin:$PATH"
 export LLVM_CONFIG="$(pwd)/bin/llvm-config"
 export LD_LIBRARY_PATH="$(llvm-config --libdir)${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 13a5e5fd..6dd390e6 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -507,6 +507,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
   Zero = ConstantInt::get(Int8Tyi, 0);
   One = ConstantInt::get(Int8Tyi, 1);
 
+  initInstrumentList();
   scanForDangerousFunctions(&M);
   Mo = &M;
 
@@ -1229,7 +1230,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
 
   // afl++ START
   if (!F.size()) return;
-  if (isIgnoreFunction(&F)) return;
+  if (!isInInstrumentList(&F)) return;
   // afl++ END
 
   if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
@@ -1291,10 +1292,17 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
       *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
       Constant::getNullValue(ArrayTy), "__sancov_gen_");
 
+#if LLVM_VERSION_MAJOR > 12
+  if (TargetTriple.supportsCOMDAT() &&
+      (TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
+    if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
+      Array->setComdat(Comdat);
+#else
   if (TargetTriple.supportsCOMDAT() && !F.isInterposable())
     if (auto Comdat =
             GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
       Array->setComdat(Comdat);
+#endif
   Array->setSection(getSectionName(Section));
   Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
   GlobalsToAppendToUsed.push_back(Array);
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 9b1351b0..09cda9e2 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/EHPersonalities.h"
@@ -34,11 +35,11 @@
 #include "llvm/InitializePasses.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SpecialCaseList.h"
 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
   #include "llvm/Support/VirtualFileSystem.h"
 #endif
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -47,65 +48,6 @@
 #include "debug.h"
 #include "afl-llvm-common.h"
 
-namespace llvm {
-
-/// This is the ModuleSanitizerCoverage pass used in the new pass manager. The
-/// pass instruments functions for coverage, adds initialization calls to the
-/// module for trace PC guards and 8bit counters if they are requested, and
-/// appends globals to llvm.compiler.used.
-class ModuleSanitizerCoveragePass
-    : public PassInfoMixin<ModuleSanitizerCoveragePass> {
-
- public:
-  explicit ModuleSanitizerCoveragePass(
-      SanitizerCoverageOptions        Options = SanitizerCoverageOptions(),
-      const std::vector<std::string> &AllowlistFiles =
-          std::vector<std::string>(),
-      const std::vector<std::string> &BlocklistFiles =
-          std::vector<std::string>())
-      : Options(Options) {
-
-    if (AllowlistFiles.size() > 0)
-      Allowlist = SpecialCaseList::createOrDie(AllowlistFiles
-#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
-                                               ,
-                                               *vfs::getRealFileSystem()
-#endif
-      );
-    if (BlocklistFiles.size() > 0)
-      Blocklist = SpecialCaseList::createOrDie(BlocklistFiles
-#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
-                                               ,
-                                               *vfs::getRealFileSystem()
-#endif
-      );
-
-  }
-
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-  static bool       isRequired() {
-
-    return true;
-
-  }
-
- private:
-  SanitizerCoverageOptions Options;
-
-  std::unique_ptr<SpecialCaseList> Allowlist;
-  std::unique_ptr<SpecialCaseList> Blocklist;
-
-};
-
-// Insert SanitizerCoverage instrumentation.
-ModulePass *createModuleSanitizerCoverageLegacyPassPass(
-    const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(),
-    const std::vector<std::string> &AllowlistFiles = std::vector<std::string>(),
-    const std::vector<std::string> &BlocklistFiles =
-        std::vector<std::string>());
-
-}  // namespace llvm
-
 using namespace llvm;
 
 #define DEBUG_TYPE "sancov"
@@ -156,96 +98,8 @@ static const char *const SanCovLowestStackName = "__sancov_lowest_stack";
 
 static char *skip_nozero;
 
-/*
-static cl::opt<int> ClCoverageLevel(
-    "sanitizer-coverage-level",
-    cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
-             "3: all blocks and critical edges"),
-    cl::Hidden, cl::init(3));
-
-static cl::opt<bool> ClTracePC("sanitizer-coverage-trace-pc",
-                               cl::desc("Experimental pc tracing"), cl::Hidden,
-                               cl::init(false));
-
-static cl::opt<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
-                                    cl::desc("pc tracing with a guard"),
-                                    cl::Hidden, cl::init(true));
-
-// If true, we create a global variable that contains PCs of all instrumented
-// BBs, put this global into a named section, and pass this section's bounds
-// to __sanitizer_cov_pcs_init.
-// This way the coverage instrumentation does not need to acquire the PCs
-// at run-time. Works with trace-pc-guard, inline-8bit-counters, and
-// inline-bool-flag.
-static cl::opt<bool> ClCreatePCTable("sanitizer-coverage-pc-table",
-                                     cl::desc("create a static PC table"),
-                                     cl::Hidden, cl::init(false));
-
-static cl::opt<bool> ClInline8bitCounters(
-    "sanitizer-coverage-inline-8bit-counters",
-    cl::desc("increments 8-bit counter for every edge"), cl::Hidden,
-    cl::init(false));
-
-static cl::opt<bool> ClInlineBoolFlag(
-    "sanitizer-coverage-inline-bool-flag",
-    cl::desc("sets a boolean flag for every edge"), cl::Hidden,
-    cl::init(false));
-
-static cl::opt<bool> ClCMPTracing(
-    "sanitizer-coverage-trace-compares",
-    cl::desc("Tracing of CMP and similar instructions"), cl::Hidden,
-    cl::init(false));
-
-static cl::opt<bool> ClDIVTracing("sanitizer-coverage-trace-divs",
-                                  cl::desc("Tracing of DIV instructions"),
-                                  cl::Hidden, cl::init(false));
-
-static cl::opt<bool> ClGEPTracing("sanitizer-coverage-trace-geps",
-                                  cl::desc("Tracing of GEP instructions"),
-                                  cl::Hidden, cl::init(false));
-
-static cl::opt<bool> ClPruneBlocks(
-    "sanitizer-coverage-prune-blocks",
-    cl::desc("Reduce the number of instrumented blocks"), cl::Hidden,
-    cl::init(true));
-
-static cl::opt<bool> ClStackDepth("sanitizer-coverage-stack-depth",
-                                  cl::desc("max stack depth tracing"),
-                                  cl::Hidden, cl::init(false));
-*/
 namespace {
 
-/*
-SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
-
-  SanitizerCoverageOptions Res;
-  switch (LegacyCoverageLevel) {
-
-    case 0:
-      Res.CoverageType = SanitizerCoverageOptions::SCK_None;
-      break;
-    case 1:
-      Res.CoverageType = SanitizerCoverageOptions::SCK_Function;
-      break;
-    case 2:
-      Res.CoverageType = SanitizerCoverageOptions::SCK_BB;
-      break;
-    case 3:
-      Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
-      break;
-    case 4:
-      Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
-      Res.IndirectCalls = true;
-      break;
-
-  }
-
-  return Res;
-
-}
-
-*/
-
 SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
 
   // Sets CoverageType and IndirectCalls.
@@ -281,12 +135,14 @@ class ModuleSanitizerCoverage {
 
  public:
   ModuleSanitizerCoverage(
-      const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(),
-      const SpecialCaseList *         Allowlist = nullptr,
-      const SpecialCaseList *         Blocklist = nullptr)
-      : Options(OverrideFromCL(Options)),
-        Allowlist(Allowlist),
-        Blocklist(Blocklist) {
+      const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()
+#if LLVM_MAJOR > 10
+          ,
+      const SpecialCaseList *Allowlist = nullptr,
+      const SpecialCaseList *Blocklist = nullptr
+#endif
+      )
+      : Options(OverrideFromCL(Options)) {
 
   }
 
@@ -356,9 +212,6 @@ class ModuleSanitizerCoverage {
 
   SanitizerCoverageOptions Options;
 
-  const SpecialCaseList *Allowlist;
-  const SpecialCaseList *Blocklist;
-
   uint32_t        instr = 0;
   GlobalVariable *AFLMapPtr = NULL;
   ConstantInt *   One = NULL;
@@ -370,27 +223,17 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
 
  public:
   ModuleSanitizerCoverageLegacyPass(
-      const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(),
+      const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()
+#if LLVM_VERSION_MAJOR > 10
+          ,
       const std::vector<std::string> &AllowlistFiles =
           std::vector<std::string>(),
       const std::vector<std::string> &BlocklistFiles =
-          std::vector<std::string>())
+          std::vector<std::string>()
+#endif
+          )
       : ModulePass(ID), Options(Options) {
 
-    if (AllowlistFiles.size() > 0)
-      Allowlist = SpecialCaseList::createOrDie(AllowlistFiles
-#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
-                                               ,
-                                               *vfs::getRealFileSystem()
-#endif
-      );
-    if (BlocklistFiles.size() > 0)
-      Blocklist = SpecialCaseList::createOrDie(BlocklistFiles
-#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
-                                               ,
-                                               *vfs::getRealFileSystem()
-#endif
-      );
     initializeModuleSanitizerCoverageLegacyPassPass(
         *PassRegistry::getPassRegistry());
 
@@ -398,8 +241,12 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
 
   bool runOnModule(Module &M) override {
 
-    ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(),
-                                         Blocklist.get());
+    ModuleSanitizerCoverage ModuleSancov(Options
+#if LLVM_MAJOR > 10
+                                         ,
+                                         Allowlist.get(), Blocklist.get()
+#endif
+    );
     auto DTCallback = [this](Function &F) -> const DominatorTree * {
 
       return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
@@ -444,8 +291,12 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
 PreservedAnalyses ModuleSanitizerCoveragePass::run(Module &               M,
                                                    ModuleAnalysisManager &MAM) {
 
-  ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(),
-                                       Blocklist.get());
+  ModuleSanitizerCoverage ModuleSancov(Options
+#if LLVM_MAJOR > 10
+                                       ,
+                                       Allowlist.get(), Blocklist.get()
+#endif
+  );
   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
   auto  DTCallback = [&FAM](Function &F) -> const DominatorTree * {
 
@@ -564,12 +415,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
   }
 
   if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false;
-  if (Allowlist &&
-      !Allowlist->inSection("coverage", "src", M.getSourceFileName()))
-    return false;
-  if (Blocklist &&
-      Blocklist->inSection("coverage", "src", M.getSourceFileName()))
-    return false;
   C = &(M.getContext());
   DL = &M.getDataLayout();
   CurModule = &M;
@@ -842,9 +687,6 @@ void ModuleSanitizerCoverage::instrumentFunction(
   if (F.hasPersonalityFn() &&
       isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
     return;
-  if (Allowlist && !Allowlist->inSection("coverage", "fun", F.getName()))
-    return;
-  if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName())) return;
   if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
     SplitAllCriticalEdges(
         F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
@@ -915,10 +757,18 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
       *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
       Constant::getNullValue(ArrayTy), "__sancov_gen_");
 
+#if LLVM_VERSION_MAJOR > 12
+  if (TargetTriple.supportsCOMDAT() &&
+      (TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
+    if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
+      Array->setComdat(Comdat);
+#else
   if (TargetTriple.supportsCOMDAT() && !F.isInterposable())
     if (auto Comdat =
             GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
       Array->setComdat(Comdat);
+#endif
+
   Array->setSection(getSectionName(Section));
 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
   Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
@@ -1354,12 +1204,20 @@ INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov",
                     false)
 
 ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
-    const SanitizerCoverageOptions &Options,
+    const SanitizerCoverageOptions &Options
+#if LLVM_MAJOR > 10
+    ,
     const std::vector<std::string> &AllowlistFiles,
-    const std::vector<std::string> &BlocklistFiles) {
+    const std::vector<std::string> &BlocklistFiles
+#endif
+) {
 
-  return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles,
-                                               BlocklistFiles);
+  return new ModuleSanitizerCoverageLegacyPass(Options
+#if LLVM_MAJOR > 10
+                                               ,
+                                               AllowlistFiles, BlocklistFiles
+#endif
+  );
 
 }
 
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index cca38cd0..f241447a 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -204,7 +204,7 @@ static void __afl_map_shm_fuzz() {
     int         shm_fd = -1;
 
     /* create the shared memory segment as if it was a file */
-    shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
+    shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
     if (shm_fd == -1) {
 
       fprintf(stderr, "shm_open() failed for fuzz\n");
@@ -353,7 +353,7 @@ static void __afl_map_shm(void) {
     unsigned char *shm_base = NULL;
 
     /* create the shared memory segment as if it was a file */
-    shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
+    shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
     if (shm_fd == -1) {
 
       fprintf(stderr, "shm_open() failed\n");
@@ -528,7 +528,7 @@ static void __afl_map_shm(void) {
     struct cmp_map *shm_base = NULL;
 
     /* create the shared memory segment as if it was a file */
-    shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
+    shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
     if (shm_fd == -1) {
 
       perror("shm_open() failed\n");
@@ -729,7 +729,7 @@ static void __afl_start_snapshots(void) {
       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);
+      s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
       if (fd_doc >= 0) {
 
         if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) {
@@ -960,7 +960,7 @@ static void __afl_start_forkserver(void) {
       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);
+      s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
       if (fd_doc >= 0) {
 
         if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) {
@@ -1676,6 +1676,12 @@ void __sanitizer_cov_trace_cmp16(uint128_t arg1, uint128_t arg2) {
 
 }
 
+void __sanitizer_cov_trace_const_cmp16(uint128_t arg1, uint128_t arg2) {
+
+  __cmplog_ins_hook16(arg1, arg2, 0);
+
+}
+
 #endif
 
 void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
@@ -1730,29 +1736,30 @@ __attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size) {
 // to avoid to call it on .text addresses
 static int area_is_valid(void *ptr, size_t len) {
 
-  if (unlikely(__asan_region_is_poisoned(ptr, len))) { return 0; }
+  if (unlikely(!ptr || __asan_region_is_poisoned(ptr, len))) { return 0; }
 
-  long r = syscall(__afl_dummy_fd[1], SYS_write, ptr, len);
+  long r = syscall(SYS_write, __afl_dummy_fd[1], ptr, len);
 
-  if (unlikely(r <= 0 || r > len)) {  // fail - maybe hitting asan boundary?
+  if (r <= 0 || r > len) return 0;
 
-    char *p = (char *)ptr;
-    long  page_size = sysconf(_SC_PAGE_SIZE);
-    char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size;
-    if (page < p + len) { return 0; }  // no isnt, return fail
-    len -= (p + len - page);
-    r = syscall(__afl_dummy_fd[1], SYS_write, p, len);
+  // even if the write succeed this can be a false positive if we cross
+  // a page boundary. who knows why.
 
-  }
+  char *p = (char *)ptr;
+  long  page_size = sysconf(_SC_PAGE_SIZE);
+  char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size;
 
-  // partial writes - we return what was written.
-  if (likely(r >= 0 && r <= len)) {
+  if (page > p + len) {
 
+    // no, not crossing a page boundary
     return (int)r;
 
   } else {
 
-    return 0;
+    // yes it crosses a boundary, hence we can only return the length of
+    // rest of the first page, we cannot detect if the next page is valid
+    // or not, neither by SYS_write nor msync() :-(
+    return (int)(page - p);
 
   }
 
@@ -1773,12 +1780,14 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
   */
 
   if (unlikely(!__afl_cmp_map)) return;
+  // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
   int l1, l2;
   if ((l1 = area_is_valid(ptr1, 32)) <= 0 ||
       (l2 = area_is_valid(ptr2, 32)) <= 0)
     return;
   int len = MIN(l1, l2);
 
+  // fprintf(stderr, "RTN2 %u\n", len);
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (k >> 4) ^ (k << 8);
   k &= CMP_MAP_W - 1;
@@ -1809,6 +1818,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
                    ptr1, len);
   __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1,
                    ptr2, len);
+  // fprintf(stderr, "RTN3\n");
 
 }
 
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index 0fd3a011..74943fb2 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -60,7 +60,7 @@ bool isIgnoreFunction(const llvm::Function *F) {
       "asan.",
       "llvm.",
       "sancov.",
-      "__ubsan_",
+      "__ubsan",
       "ign.",
       "__afl",
       "_fini",
@@ -69,13 +69,16 @@ bool isIgnoreFunction(const llvm::Function *F) {
       "__msan",
       "__cmplog",
       "__sancov",
+      "__san",
       "__cxx_",
+      "__decide_deferred",
       "_GLOBAL",
+      "_ZZN6__asan",
+      "_ZZN6__lsan",
       "msan.",
       "LLVMFuzzerM",
       "LLVMFuzzerC",
       "LLVMFuzzerI",
-      "__decide_deferred",
       "maybe_duplicate_stderr",
       "discard_output",
       "close_stdout",
@@ -91,6 +94,20 @@ bool isIgnoreFunction(const llvm::Function *F) {
 
   }
 
+  static const char *ignoreSubstringList[] = {
+
+      "__asan",       "__msan",     "__ubsan", "__lsan",
+      "__san",        "__sanitize", "__cxx",   "_GLOBAL__",
+      "DebugCounter", "DwarfDebug", "DebugLoc"
+
+  };
+
+  for (auto const &ignoreListFunc : ignoreSubstringList) {
+
+    if (F->getName().contains(ignoreListFunc)) { return true; }
+
+  }
+
   return false;
 
 }
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index a7f25da3..8d95c359 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-d1ca56b84e
+ddc4a9748d
diff --git a/qemu_mode/libqasan/hooks.c b/qemu_mode/libqasan/hooks.c
index 9c406c74..0e6c3e08 100644
--- a/qemu_mode/libqasan/hooks.c
+++ b/qemu_mode/libqasan/hooks.c
@@ -51,6 +51,7 @@ ssize_t write(int fd, const void *buf, size_t count) {
   void *rtv = __builtin_return_address(0);
 
   QASAN_DEBUG("%14p: write(%d, %p, %zu)\n", rtv, fd, buf, count);
+  QASAN_LOAD(buf, count);
   ssize_t r = __lq_libc_write(fd, buf, count);
   QASAN_DEBUG("\t\t = %zd\n", r);
 
@@ -63,6 +64,7 @@ ssize_t read(int fd, void *buf, size_t count) {
   void *rtv = __builtin_return_address(0);
 
   QASAN_DEBUG("%14p: read(%d, %p, %zu)\n", rtv, fd, buf, count);
+  QASAN_STORE(buf, count);
   ssize_t r = __lq_libc_read(fd, buf, count);
   QASAN_DEBUG("\t\t = %zd\n", r);
 
diff --git a/qemu_mode/libqasan/malloc.c b/qemu_mode/libqasan/malloc.c
index 5a2d2a0c..6fe6fc8c 100644
--- a/qemu_mode/libqasan/malloc.c
+++ b/qemu_mode/libqasan/malloc.c
@@ -159,6 +159,9 @@ size_t __libqasan_malloc_usable_size(void *ptr) {
   char *p = ptr;
   p -= sizeof(struct chunk_begin);
 
+  // Validate that the chunk marker is readable (a crude check
+  // to verify that ptr is a valid malloc region before we dereference it)
+  QASAN_LOAD(p, sizeof(struct chunk_begin) - REDZONE_SIZE);
   return ((struct chunk_begin *)p)->requested_size;
 
 }
@@ -225,6 +228,9 @@ void __libqasan_free(void *ptr) {
   struct chunk_begin *p = ptr;
   p -= 1;
 
+  // Validate that the chunk marker is readable (a crude check
+  // to verify that ptr is a valid malloc region before we dereference it)
+  QASAN_LOAD(p, sizeof(struct chunk_begin) - REDZONE_SIZE);
   size_t n = p->requested_size;
 
   QASAN_STORE(ptr, n);
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject d1ca56b84e78f821406eef28d836918edfc8d61
+Subproject 0fb212daab492411b3e323bc18a3074c1aecfd3
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index d46ecb8d..e106cd31 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -212,7 +212,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
 
   unlink(path);                                            /* Ignore errors */
 
-  ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
+  ret = open(path, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
 
   if (ret < 0) { PFATAL("Unable to create '%s'", path); }
 
@@ -822,38 +822,7 @@ static void set_up_environment(void) {
 
     if (qemu_mode) {
 
-      u8 *qemu_preload = getenv("QEMU_SET_ENV");
-      u8 *afl_preload = getenv("AFL_PRELOAD");
-      u8 *buf;
-
-      s32 i, afl_preload_size = strlen(afl_preload);
-      for (i = 0; i < afl_preload_size; ++i) {
-
-        if (afl_preload[i] == ',') {
-
-          PFATAL(
-              "Comma (',') is not allowed in AFL_PRELOAD when -Q is "
-              "specified!");
-
-        }
-
-      }
-
-      if (qemu_preload) {
-
-        buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           qemu_preload, afl_preload, afl_preload);
-
-      } else {
-
-        buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           afl_preload, afl_preload);
-
-      }
-
-      setenv("QEMU_SET_ENV", buf, 1);
-
-      ck_free(buf);
+      /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
 
     } else {
 
@@ -1079,31 +1048,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (optind == argc || !in_file) { usage(argv[0]); }
 
-  if (qemu_mode && getenv("AFL_USE_QASAN")) {
-
-    u8 *preload = getenv("AFL_PRELOAD");
-    u8 *libqasan = get_libqasan_path(argv_orig[0]);
-
-    if (!preload) {
-
-      setenv("AFL_PRELOAD", libqasan, 0);
-
-    } else {
-
-      u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
-      strcpy(result, libqasan);
-      strcat(result, " ");
-      strcat(result, preload);
-
-      setenv("AFL_PRELOAD", result, 1);
-      ck_free(result);
-
-    }
-
-    ck_free(libqasan);
-
-  }
-
   map_size = get_map_size();
 
   use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
diff --git a/src/afl-as.c b/src/afl-as.c
index 7de267a3..aebd0ac8 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -280,7 +280,7 @@ static void add_instrumentation(void) {
 
   }
 
-  outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600);
+  outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, DEFAULT_PERMISSION);
 
   if (outfd < 0) { PFATAL("Unable to write to '%s'", modified_file); }
 
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 44654de0..80fc0742 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -590,6 +590,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
   #ifdef __ANDROID__
         cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+        instrument_mode != INSTRUMENT_LLVMNATIVE;
   #else
         if (have_instr_list) {
 
@@ -599,6 +600,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
                 "-fsanitize-coverage-allow/denylist, you can use "
                 "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n");
           cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+          instrument_mode = INSTRUMENT_LLVMNATIVE;
 
         } else {
 
@@ -618,6 +620,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
               "Using unoptimized trace-pc-guard, upgrade to llvm 10.0.1+ for "
               "enhanced version.\n");
         cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+        instrument_mode = INSTRUMENT_LLVMNATIVE;
   #else
         FATAL("pcguard instrumentation requires llvm 4.0.1+");
   #endif
@@ -682,19 +685,49 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   /* Detect stray -v calls from ./configure scripts. */
 
+  u8 skip_next = 0;
   while (--argc) {
 
     u8 *cur = *(++argv);
 
+    if (skip_next) {
+
+      skip_next = 0;
+      continue;
+
+    }
+
     if (!strncmp(cur, "--afl", 5)) continue;
     if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
     if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
     if (!strncmp(cur, "-fno-unroll", 11)) continue;
     if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
-    if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined"))
+    if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
+        !strcmp(cur, "--no-undefined")) {
+
       continue;
-    if (!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) ||
-        !strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) {
+
+    }
+
+    if (!strcmp(cur, "-z")) {
+
+      u8 *param = *(argv + 1);
+      if (!strcmp(param, "defs")) {
+
+        skip_next = 1;
+        continue;
+
+      }
+
+    }
+
+    if ((!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) ||
+         !strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) &&
+        (strncmp(cur, "sanitize-coverage-allow",
+                 strlen("sanitize-coverage-allow")) &&
+         strncmp(cur, "sanitize-coverage-deny",
+                 strlen("sanitize-coverage-deny")) &&
+         instrument_mode != INSTRUMENT_LLVMNATIVE)) {
 
       if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
       continue;
@@ -962,18 +995,24 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     switch (bit_mode) {
 
       case 0:
-        cc_params[cc_par_cnt++] =
-            alloc_printf("%s/afl-compiler-rt.o", obj_path);
+        if (!shared_linking)
+          cc_params[cc_par_cnt++] =
+              alloc_printf("%s/afl-compiler-rt.o", obj_path);
         if (lto_mode)
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/afl-llvm-rt-lto.o", obj_path);
         break;
 
       case 32:
-        cc_params[cc_par_cnt++] =
-            alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
-        if (access(cc_params[cc_par_cnt - 1], R_OK))
-          FATAL("-m32 is not supported by your compiler");
+        if (!shared_linking) {
+
+          cc_params[cc_par_cnt++] =
+              alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
+          if (access(cc_params[cc_par_cnt - 1], R_OK))
+            FATAL("-m32 is not supported by your compiler");
+
+        }
+
         if (lto_mode) {
 
           cc_params[cc_par_cnt++] =
@@ -986,10 +1025,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         break;
 
       case 64:
-        cc_params[cc_par_cnt++] =
-            alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
-        if (access(cc_params[cc_par_cnt - 1], R_OK))
-          FATAL("-m64 is not supported by your compiler");
+        if (!shared_linking) {
+
+          cc_params[cc_par_cnt++] =
+              alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
+          if (access(cc_params[cc_par_cnt - 1], R_OK))
+            FATAL("-m64 is not supported by your compiler");
+
+        }
+
         if (lto_mode) {
 
           cc_params[cc_par_cnt++] =
@@ -1009,12 +1053,12 @@ static void edit_params(u32 argc, char **argv, char **envp) {
           alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
   #endif
 
+  }
+
   #if defined(USEMMAP) && !defined(__HAIKU__)
-    cc_params[cc_par_cnt++] = "-lrt";
+  cc_params[cc_par_cnt++] = "-lrt";
   #endif
 
-  }
-
 #endif
 
   cc_params[cc_par_cnt] = NULL;
@@ -1220,6 +1264,7 @@ int main(int argc, char **argv, char **envp) {
 
       } else if (strcasecmp(ptr, "LLVMNATIVE") == 0 ||
 
+                 strcasecmp(ptr, "NATIVE") == 0 ||
                  strcasecmp(ptr, "LLVM-NATIVE") == 0) {
 
         compiler_mode = LLVM;
@@ -1632,8 +1677,8 @@ int main(int argc, char **argv, char **envp) {
         "of afl-cc.\n\n");
 
 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
-  #define NATIVE_MSG                                              \
-    "  NATIVE:  use llvm's native PCGUARD instrumentation (less " \
+  #define NATIVE_MSG                                                   \
+    "  LLVM-NATIVE:  use llvm's native PCGUARD instrumentation (less " \
     "performant)\n"
 #else
   #define NATIVE_MSG ""
diff --git a/src/afl-common.c b/src/afl-common.c
index 9f6eb564..37b4788c 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -149,9 +149,14 @@ void argv_cpy_free(char **argv) {
 
 char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
 
-  if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); }
+  if (unlikely(getenv("AFL_QEMU_CUSTOM_BIN"))) {
 
-  u8 *tmp, *cp = NULL, *rsl, *own_copy;
+    WARNF(
+        "AFL_QEMU_CUSTOM_BIN is enabled. "
+        "You must run your target under afl-qemu-trace on your own!");
+    return argv;
+
+  }
 
   char **new_argv = ck_alloc(sizeof(char *) * (argc + 4));
   if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
@@ -164,70 +169,8 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
 
   /* Now we need to actually find the QEMU binary to put in argv[0]. */
 
-  tmp = getenv("AFL_PATH");
-
-  if (tmp) {
-
-    cp = alloc_printf("%s/afl-qemu-trace", tmp);
-
-    if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
-
-    *target_path_p = new_argv[0] = cp;
-    return new_argv;
-
-  }
-
-  own_copy = ck_strdup(own_loc);
-  rsl = strrchr(own_copy, '/');
-
-  if (rsl) {
-
-    *rsl = 0;
-
-    cp = alloc_printf("%s/afl-qemu-trace", own_copy);
-    ck_free(own_copy);
-
-    if (!access(cp, X_OK)) {
-
-      *target_path_p = new_argv[0] = cp;
-      return new_argv;
-
-    }
-
-  } else {
-
-    ck_free(own_copy);
-
-  }
-
-  if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
-
-    if (cp) { ck_free(cp); }
-    *target_path_p = new_argv[0] = ck_strdup(BIN_PATH "/afl-qemu-trace");
-
-    return new_argv;
-
-  }
-
-  SAYF("\n" cLRD "[-] " cRST
-       "Oops, unable to find the 'afl-qemu-trace' binary. The binary must be "
-       "built\n"
-       "    separately by following the instructions in "
-       "qemu_mode/README.md. "
-       "If you\n"
-       "    already have the binary installed, you may need to specify "
-       "AFL_PATH in the\n"
-       "    environment.\n\n"
-
-       "    Of course, even without QEMU, afl-fuzz can still work with "
-       "binaries that are\n"
-       "    instrumented at compile time with afl-gcc. It is also possible to "
-       "use it as a\n"
-       "    traditional non-instrumented fuzzer by specifying '-n' in the "
-       "command "
-       "line.\n");
-
-  FATAL("Failed to locate 'afl-qemu-trace'.");
+  *target_path_p = new_argv[0] = find_afl_binary(own_loc, "afl-qemu-trace");
+  return new_argv;
 
 }
 
@@ -235,10 +178,6 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
 
 char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
 
-  if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); }
-
-  u8 *tmp, *cp = NULL, *rsl, *own_copy;
-
   char **new_argv = ck_alloc(sizeof(char *) * (argc + 3));
   if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
 
@@ -249,152 +188,10 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
 
   /* Now we need to actually find the QEMU binary to put in argv[0]. */
 
-  tmp = getenv("AFL_PATH");
-
-  if (tmp) {
-
-    cp = alloc_printf("%s/afl-qemu-trace", tmp);
-
-    if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
-
-    ck_free(cp);
-
-    cp = alloc_printf("%s/afl-wine-trace", tmp);
-
-    if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
-
-    *target_path_p = new_argv[0] = cp;
-    return new_argv;
-
-  }
-
-  own_copy = ck_strdup(own_loc);
-  rsl = strrchr(own_copy, '/');
-
-  if (rsl) {
-
-    *rsl = 0;
-
-    cp = alloc_printf("%s/afl-qemu-trace", own_copy);
-
-    if (cp && !access(cp, X_OK)) {
-
-      ck_free(cp);
-
-      cp = alloc_printf("%s/afl-wine-trace", own_copy);
-
-      if (!access(cp, X_OK)) {
-
-        *target_path_p = new_argv[0] = cp;
-        return new_argv;
-
-      }
-
-    }
-
-    ck_free(own_copy);
-
-  } else {
-
-    ck_free(own_copy);
-
-  }
-
-  u8 *ncp = BIN_PATH "/afl-qemu-trace";
-
-  if (!access(ncp, X_OK)) {
-
-    ncp = BIN_PATH "/afl-wine-trace";
-
-    if (!access(ncp, X_OK)) {
-
-      *target_path_p = new_argv[0] = ck_strdup(ncp);
-      return new_argv;
-
-    }
-
-  }
-
-  SAYF("\n" cLRD "[-] " cRST
-       "Oops, unable to find the '%s' binary. The binary must be "
-       "built\n"
-       "    separately by following the instructions in "
-       "qemu_mode/README.md. "
-       "If you\n"
-       "    already have the binary installed, you may need to specify "
-       "AFL_PATH in the\n"
-       "    environment.\n\n"
-
-       "    Of course, even without QEMU, afl-fuzz can still work with "
-       "binaries that are\n"
-       "    instrumented at compile time with afl-gcc. It is also possible to "
-       "use it as a\n"
-       "    traditional non-instrumented fuzzer by specifying '-n' in the "
-       "command "
-       "line.\n",
-       ncp);
-
-  FATAL("Failed to locate '%s'.", ncp);
-
-}
-
-/* Get libqasan path. */
-
-u8 *get_libqasan_path(u8 *own_loc) {
-
-  if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); }
-
-  u8 *tmp, *cp = NULL, *rsl, *own_copy;
-
-  tmp = getenv("AFL_PATH");
-
-  if (tmp) {
-
-    cp = alloc_printf("%s/libqasan.so", tmp);
-
-    if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
-
-    return cp;
-
-  }
-
-  own_copy = ck_strdup(own_loc);
-  rsl = strrchr(own_copy, '/');
-
-  if (rsl) {
-
-    *rsl = 0;
-
-    cp = alloc_printf("%s/libqasan.so", own_copy);
-    ck_free(own_copy);
-
-    if (!access(cp, X_OK)) { return cp; }
-
-  } else {
-
-    ck_free(own_copy);
-
-  }
-
-  if (!access(AFL_PATH "/libqasan.so", X_OK)) {
-
-    if (cp) { ck_free(cp); }
-
-    return ck_strdup(AFL_PATH "/libqasan.so");
-
-  }
-
-  SAYF("\n" cLRD "[-] " cRST
-       "Oops, unable to find the 'libqasan.so' binary. The binary must be "
-       "built\n"
-       "    separately by following the instructions in "
-       "qemu_mode/libqasan/README.md. "
-       "If you\n"
-       "    already have the binary installed, you may need to specify "
-       "AFL_PATH in the\n"
-       "    environment.\n");
-
-  FATAL("Failed to locate 'libqasan.so'.");
+  u8 *tmp = find_afl_binary(own_loc, "afl-qemu-trace");
+  ck_free(tmp);
+  *target_path_p = new_argv[0] = find_afl_binary(own_loc, "afl-wine-trace");
+  return new_argv;
 
 }
 
@@ -488,6 +285,70 @@ u8 *find_binary(u8 *fname) {
 
 }
 
+u8 *find_afl_binary(u8 *own_loc, u8 *fname) {
+
+  u8 *afl_path = NULL, *target_path, *own_copy;
+
+  if ((afl_path = getenv("AFL_PATH"))) {
+
+    target_path = alloc_printf("%s/%s", afl_path, fname);
+    if (!access(target_path, X_OK)) {
+
+      return target_path;
+
+    } else {
+
+      ck_free(target_path);
+
+    }
+
+  }
+
+  if (own_loc) {
+
+    own_copy = ck_strdup(own_loc);
+    u8 *rsl = strrchr(own_copy, '/');
+
+    if (rsl) {
+
+      *rsl = 0;
+
+      target_path = alloc_printf("%s/%s", own_copy, fname);
+      ck_free(own_copy);
+
+      if (!access(target_path, X_OK)) {
+
+        return target_path;
+
+      } else {
+
+        ck_free(target_path);
+
+      }
+
+    } else {
+
+      ck_free(own_copy);
+
+    }
+
+  }
+
+  target_path = alloc_printf("%s/%s", BIN_PATH, fname);
+  if (!access(target_path, X_OK)) {
+
+    return target_path;
+
+  } else {
+
+    ck_free(target_path);
+
+  }
+
+  return find_binary(fname);
+
+}
+
 /* Parses the kill signal environment variable, FATALs on error.
   If the env is not set, sets the env to default_signal for the signal handlers
   and returns the default_signal. */
@@ -757,6 +618,98 @@ char *get_afl_env(char *env) {
 
 }
 
+bool extract_and_set_env(u8 *env_str) {
+
+  if (!env_str) { return false; }
+
+  bool ret = false;  // return false by default
+
+  u8 *p = ck_strdup(env_str);
+  u8 *end = p + strlen((char *)p);
+  u8 *rest = p;
+
+  u8 closing_sym = ' ';
+  u8 c;
+
+  size_t num_pairs = 0;
+
+  while (rest < end) {
+
+    while (*rest == ' ') {
+
+      rest++;
+
+    }
+
+    if (rest + 1 >= end) break;
+
+    u8 *key = rest;
+    // env variable names may not start with numbers or '='
+    if (*key == '=' || (*key >= '0' && *key <= '9')) { goto free_and_return; }
+
+    while (rest < end && *rest != '=' && *rest != ' ') {
+
+      c = *rest;
+      // lowercase is bad but we may still allow it
+      if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
+          (c < '0' || c > '9') && c != '_') {
+
+        goto free_and_return;
+
+      }
+
+      rest++;
+
+    }
+
+    if (*rest != '=') { goto free_and_return; }
+
+    *rest = '\0';  // done with variable name
+
+    rest += 1;
+    if (rest >= end || *rest == ' ') { goto free_and_return; }
+
+    u8 *val = rest;
+    if (*val == '\'' || *val == '"') {
+
+      closing_sym = *val;
+      val += 1;
+      rest += 1;
+      if (rest >= end) { goto free_and_return; }
+
+    } else {
+
+      closing_sym = ' ';
+
+    }
+
+    while (rest < end && *rest != closing_sym) {
+
+      rest++;
+
+    }
+
+    if (closing_sym != ' ' && *rest != closing_sym) { goto free_and_return; }
+
+    *rest = '\0';  // done with variable value
+
+    rest += 1;
+    if (rest < end && *rest != ' ') { goto free_and_return; }
+
+    num_pairs++;
+
+    setenv(key, val, 1);
+
+  }
+
+  if (num_pairs) { ret = true; }
+
+free_and_return:
+  ck_free(p);
+  return ret;
+
+}
+
 /* Read mask bitmap from file. This is for the -B option. */
 
 void read_bitmap(u8 *fname, u8 *map, size_t len) {
@@ -1123,7 +1076,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
 /* Reads the map size from ENV */
 u32 get_map_size(void) {
 
-  uint32_t map_size = 8000000;  // a very large default map
+  uint32_t map_size = DEFAULT_SHMEM_SIZE;
   char *   ptr;
 
   if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
@@ -1151,7 +1104,7 @@ FILE *create_ffile(u8 *fn) {
   s32   fd;
   FILE *f;
 
-  fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+  fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
 
   if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
 
@@ -1169,7 +1122,7 @@ s32 create_file(u8 *fn) {
 
   s32 fd;
 
-  fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+  fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
 
   if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 68995388..c2d552cd 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -809,7 +809,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
            "have a\n"
            "    restrictive memory limit configured, this is expected; please "
            "read\n"
-           "    %s/notes_for_asan.md for help.\n",
+           "    %s/notes_for_asan.md for help and run with '-m 0'.\n",
            doc_path);
 
     } else if (!fsrv->mem_limit) {
@@ -817,18 +817,21 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
       SAYF("\n" cLRD "[-] " cRST
            "Whoops, the target binary crashed suddenly, "
            "before receiving any input\n"
-           "    from the fuzzer! There are several probable explanations:\n\n"
-
-           "    - The target binary requires a large map and crashes before "
-           "reporting.\n"
-           "      Set a high value (e.g. AFL_MAP_SIZE=8000000) or use "
-           "AFL_DEBUG=1 to see the\n"
-           "      message from the target binary\n\n"
-
-           "    - The binary is just buggy and explodes entirely on its own. "
-           "If so, you\n"
-           "      need to fix the underlying problem or find a better "
-           "replacement.\n\n"
+           "    from the fuzzer! You can try the following:\n\n"
+
+           "    - The target binary crashes because necessary runtime "
+           "conditions it needs\n"
+           "      are not met. Try to:\n"
+           "      1. Run again with AFL_DEBUG=1 set and check the output of "
+           "the target\n"
+           "         binary for clues.\n"
+           "      2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
+           "analyze the\n"
+           "         generated core dump.\n\n"
+
+           "    - Possibly the target requires a huge coverage map and has "
+           "CTORS.\n"
+           "      Retry with setting AFL_MAP_SIZE=10000000.\n\n"
 
            MSG_FORK_ON_APPLE
 
@@ -844,13 +847,17 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
       SAYF("\n" cLRD "[-] " cRST
            "Whoops, the target binary crashed suddenly, "
            "before receiving any input\n"
-           "    from the fuzzer! There are several probable explanations:\n\n"
-
-           "    - The target binary requires a large map and crashes before "
-           "reporting.\n"
-           "      Set a high value (e.g. AFL_MAP_SIZE=8000000) or use "
-           "AFL_DEBUG=1 to see the\n"
-           "      message from the target binary\n\n"
+           "    from the fuzzer! You can try the following:\n\n"
+
+           "    - The target binary crashes because necessary runtime "
+           "conditions it needs\n"
+           "      are not met. Try to:\n"
+           "      1. Run again with AFL_DEBUG=1 set and check the output of "
+           "the target\n"
+           "         binary for clues.\n"
+           "      2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
+           "analyze the\n"
+           "         generated core dump.\n\n"
 
            "    - The current memory limit (%s) is too restrictive, causing "
            "the\n"
@@ -868,13 +875,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
            "      estimate the required amount of virtual memory for the "
            "binary.\n\n"
 
-           "    - The binary is just buggy and explodes entirely on its own. "
-           "If so, you\n"
-           "      need to fix the underlying problem or find a better "
-           "replacement.\n\n"
-
            MSG_FORK_ON_APPLE
 
+           "    - Possibly the target requires a huge coverage map and has "
+           "CTORS.\n"
+           "      Retry with setting AFL_MAP_SIZE=10000000.\n\n"
+
            "    - Less likely, there is a horrible bug in the fuzzer. If other "
            "options\n"
            "      fail, poke <afl-users@googlegroups.com> for troubleshooting "
@@ -903,7 +909,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
          "with ASAN and\n"
          "    you have a restrictive memory limit configured, this is "
          "expected; please\n"
-         "    read %s/notes_for_asan.md for help.\n",
+         "    read %s/notes_for_asan.md for help and run with '-m 0'.\n",
          doc_path);
 
   } else if (!fsrv->mem_limit) {
@@ -911,10 +917,22 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
     SAYF("\n" cLRD "[-] " cRST
          "Hmm, looks like the target binary terminated before we could complete"
          " a\n"
-         "handshake with the injected code.\n"
-         "Most likely the target has a huge coverage map, retry with setting"
-         " the\n"
-         "environment variable AFL_MAP_SIZE=8000000\n"
+         "handshake with the injected code. You can try the following:\n\n"
+
+         "    - The target binary crashes because necessary runtime conditions "
+         "it needs\n"
+         "      are not met. Try to:\n"
+         "      1. Run again with AFL_DEBUG=1 set and check the output of the "
+         "target\n"
+         "         binary for clues.\n"
+         "      2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
+         "analyze the\n"
+         "         generated core dump.\n\n"
+
+         "    - Possibly the target requires a huge coverage map and has "
+         "CTORS.\n"
+         "      Retry with setting AFL_MAP_SIZE=10000000.\n\n"
+
          "Otherwise there is a horrible bug in the fuzzer.\n"
          "Poke <afl-users@googlegroups.com> for troubleshooting tips.\n");
 
@@ -926,14 +944,23 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
         "\n" cLRD "[-] " cRST
         "Hmm, looks like the target binary terminated "
         "before we could complete a\n"
-        "    handshake with the injected code. There are %s probable "
-        "explanations:\n\n"
+        "    handshake with the injected code. You can try the following:\n\n"
 
         "%s"
 
-        "    - Most likely the target has a huge coverage map, retry with "
-        "setting the\n"
-        "      environment variable AFL_MAP_SIZE=8000000\n\n"
+        "    - The target binary crashes because necessary runtime conditions "
+        "it needs\n"
+        "      are not met. Try to:\n"
+        "      1. Run again with AFL_DEBUG=1 set and check the output of the "
+        "target\n"
+        "         binary for clues.\n"
+        "      2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
+        "analyze the\n"
+        "         generated core dump.\n\n"
+
+        "    - Possibly the target requires a huge coverage map and has "
+        "CTORS.\n"
+        "      Retry with setting AFL_MAP_SIZE=10000000.\n\n"
 
         "    - The current memory limit (%s) is too restrictive, causing an "
         "OOM\n"
@@ -958,7 +985,6 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
         "options\n"
         "      fail, poke <afl-users@googlegroups.com> for troubleshooting "
         "tips.\n",
-        getenv(DEFER_ENV_VAR) ? "three" : "two",
         getenv(DEFER_ENV_VAR)
             ? "    - You are using deferred forkserver, but __AFL_INIT() is "
               "never\n"
@@ -1038,12 +1064,14 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
 
       if (unlikely(fsrv->no_unlink)) {
 
-        fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+        fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC,
+                  DEFAULT_PERMISSION);
 
       } else {
 
         unlink(fsrv->out_file);                           /* Ignore errors. */
-        fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
+        fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL,
+                  DEFAULT_PERMISSION);
 
       }
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 4ed59364..3d0228db 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -42,7 +42,7 @@ void write_bitmap(afl_state_t *afl) {
   afl->bitmap_changed = 0;
 
   snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir);
-  fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+  fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
 
   if (fd < 0) { PFATAL("Unable to open '%s'", fname); }
 
@@ -407,7 +407,7 @@ static void write_crash_readme(afl_state_t *afl) {
 
   sprintf(fn, "%s/crashes/README.txt", afl->out_dir);
 
-  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
 
   /* Do not die on errors here - that would be impolite. */
 
@@ -509,7 +509,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
         alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths);
 
 #endif                                                    /* ^!SIMPLE_FILES */
-    fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+    fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
     if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); }
     ck_write(fd, mem, len, queue_fn);
     close(fd);
@@ -783,7 +783,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
   /* If we're here, we apparently want to save the crash or hang
      test case, too. */
 
-  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
   if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn); }
   ck_write(fd, mem, len, fn);
   close(fd);
diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c
index 52100fa1..6091db15 100644
--- a/src/afl-fuzz-extras.c
+++ b/src/afl-fuzz-extras.c
@@ -731,7 +731,7 @@ void save_auto(afl_state_t *afl) {
         alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
     s32 fd;
 
-    fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+    fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
 
     if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index ca2f75f1..70a49a6b 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -152,7 +152,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
 
     do {
 
-      if ((lockfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
+      if ((lockfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL,
+                         DEFAULT_PERMISSION)) < 0) {
 
         if (first) {
 
@@ -1219,7 +1220,7 @@ static void link_or_copy(u8 *old_path, u8 *new_path) {
   sfd = open(old_path, O_RDONLY);
   if (sfd < 0) { PFATAL("Unable to open '%s'", old_path); }
 
-  dfd = open(new_path, O_WRONLY | O_CREAT | O_EXCL, 0600);
+  dfd = open(new_path, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
   if (dfd < 0) { PFATAL("Unable to create '%s'", new_path); }
 
   tmp = ck_alloc(64 * 1024);
@@ -1812,9 +1813,13 @@ static void handle_existing_out_dir(afl_state_t *afl) {
 
   }
 
-  fn = alloc_printf("%s/plot_data", afl->out_dir);
-  if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
-  ck_free(fn);
+  if (!afl->in_place_resume) {
+
+    fn = alloc_printf("%s/plot_data", afl->out_dir);
+    if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
+    ck_free(fn);
+
+  }
 
   fn = alloc_printf("%s/cmdline", afl->out_dir);
   if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
@@ -2008,17 +2013,35 @@ void setup_dirs_fds(afl_state_t *afl) {
   /* Gnuplot output file. */
 
   tmp = alloc_printf("%s/plot_data", afl->out_dir);
-  int fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600);
-  if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
-  ck_free(tmp);
 
-  afl->fsrv.plot_file = fdopen(fd, "w");
-  if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); }
+  if (!afl->in_place_resume) {
+
+    int fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+    if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
+    ck_free(tmp);
+
+    afl->fsrv.plot_file = fdopen(fd, "w");
+    if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); }
+
+    fprintf(
+        afl->fsrv.plot_file,
+        "# unix_time, cycles_done, cur_path, paths_total, "
+        "pending_total, pending_favs, map_size, unique_crashes, "
+        "unique_hangs, max_depth, execs_per_sec, total_execs, edges_found\n");
+
+  } else {
+
+    int fd = open(tmp, O_WRONLY | O_CREAT, DEFAULT_PERMISSION);
+    if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
+    ck_free(tmp);
+
+    afl->fsrv.plot_file = fdopen(fd, "w");
+    if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); }
+
+    fseek(afl->fsrv.plot_file, 0, SEEK_END);
+
+  }
 
-  fprintf(afl->fsrv.plot_file,
-          "# unix_time, cycles_done, cur_path, paths_total, "
-          "pending_total, pending_favs, map_size, unique_crashes, "
-          "unique_hangs, max_depth, execs_per_sec, total_execs, edges_found\n");
   fflush(afl->fsrv.plot_file);
 
   /* ignore errors */
@@ -2035,7 +2058,7 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) {
 
   /* Store the command line to reproduce our findings */
   tmp = alloc_printf("%s/cmdline", afl->out_dir);
-  fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600);
+  fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
   if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
   ck_free(tmp);
 
@@ -2070,7 +2093,8 @@ void setup_stdio_file(afl_state_t *afl) {
 
   unlink(afl->fsrv.out_file);                              /* Ignore errors */
 
-  afl->fsrv.out_fd = open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
+  afl->fsrv.out_fd =
+      open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
 
   if (afl->fsrv.out_fd < 0) {
 
@@ -2592,6 +2616,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
   }
 
   if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode ||
+      (afl->fsrv.qemu_mode && getenv("AFL_QEMU_CUSTOM_BIN")) ||
       afl->non_instrumented_mode) {
 
     return;
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 80df6d08..a47b4f5f 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -465,7 +465,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
 
     unlink(q->fname);                                      /* ignore errors */
 
-    fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
+    fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
 
     if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
 
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index c73e394a..4e8154cd 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -5119,14 +5119,23 @@ pacemaker_fuzzing:
 
       /* Update afl->pending_not_fuzzed count if we made it through the
          calibration cycle and have not seen this entry before. */
+      /*
+        // TODO FIXME: I think we need this plus need an -L -1 check
+        if (!afl->stop_soon && !afl->queue_cur->cal_failed &&
+            (afl->queue_cur->was_fuzzed == 0 || afl->queue_cur->fuzz_level == 0)
+        && !afl->queue_cur->disabled) {
 
-      // if (!afl->stop_soon && !afl->queue_cur->cal_failed &&
-      // !afl->queue_cur->was_fuzzed) {
+          if (!afl->queue_cur->was_fuzzed) {
 
-      //   afl->queue_cur->was_fuzzed = 1;
-      //   --afl->pending_not_fuzzed;
-      //   if (afl->queue_cur->favored) --afl->pending_favored;
-      // }
+            --afl->pending_not_fuzzed;
+            afl->queue_cur->was_fuzzed = 1;
+            if (afl->queue_cur->favored) { --afl->pending_favored; }
+
+          }
+
+        }
+
+      */
 
       orig_in = NULL;
 
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index b2f88205..e5f51a6c 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -249,7 +249,7 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
   snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir,
            strrchr(q->fname, '/') + 1);
 
-  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
   if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
   close(fd);
 
@@ -272,7 +272,7 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
 
   if (symlink(ldest, fn)) {
 
-    s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+    s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
     if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
     close(fd);
 
@@ -300,7 +300,7 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
 
     s32 fd;
 
-    fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+    fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
     if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
     close(fd);
 
@@ -680,13 +680,17 @@ void cull_queue(afl_state_t *afl) {
 
       }
 
-      afl->top_rated[i]->favored = 1;
-      ++afl->queued_favored;
+      if (!afl->top_rated[i]->favored) {
 
-      if (afl->top_rated[i]->fuzz_level == 0 ||
-          !afl->top_rated[i]->was_fuzzed) {
+        afl->top_rated[i]->favored = 1;
+        ++afl->queued_favored;
 
-        ++afl->pending_favored;
+        if (afl->top_rated[i]->fuzz_level == 0 ||
+            !afl->top_rated[i]->was_fuzzed) {
+
+          ++afl->pending_favored;
+
+        }
 
       }
 
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 0b84a542..83133dad 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -83,7 +83,8 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
            afl->document_counter++,
            describe_op(afl, 0, NAME_MAX - strlen("000000000:")));
 
-  if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
+  if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION)) >=
+      0) {
 
     if (write(doc_fd, mem, len) != len)
       PFATAL("write to mutation file failed: %s", fn);
@@ -247,12 +248,14 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
 
     if (unlikely(afl->no_unlink)) {
 
-      fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+      fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_TRUNC,
+                DEFAULT_PERMISSION);
 
     } else {
 
       unlink(afl->fsrv.out_file);                         /* Ignore errors. */
-      fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
+      fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL,
+                DEFAULT_PERMISSION);
 
     }
 
@@ -564,7 +567,8 @@ void sync_fuzzers(afl_state_t *afl) {
     /* document the attempt to sync to this instance */
 
     sprintf(qd_synced_path, "%s/.synced/%s.last", afl->out_dir, sd_ent->d_name);
-    id_fd = open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, 0600);
+    id_fd =
+        open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
     if (id_fd >= 0) close(id_fd);
 
     /* Skip anything that doesn't have a queue/ subdirectory. */
@@ -587,7 +591,7 @@ void sync_fuzzers(afl_state_t *afl) {
 
     sprintf(qd_synced_path, "%s/.synced/%s", afl->out_dir, sd_ent->d_name);
 
-    id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);
+    id_fd = open(qd_synced_path, O_RDWR | O_CREAT, DEFAULT_PERMISSION);
 
     if (id_fd < 0) { PFATAL("Unable to create '%s'", qd_synced_path); }
 
@@ -851,7 +855,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
     if (unlikely(afl->no_unlink)) {
 
-      fd = open(q->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+      fd = open(q->fname, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
 
       if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
 
@@ -866,7 +870,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
     } else {
 
       unlink(q->fname);                                    /* ignore errors */
-      fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
+      fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
 
       if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
 
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 3d36e712..0ddf8cf3 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -433,6 +433,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
             afl->afl_env.afl_kill_signal =
                 (u8 *)get_afl_env(afl_environment_variables[i]);
 
+          } else if (!strncmp(env, "AFL_TARGET_ENV",
+
+                              afl_environment_variable_len)) {
+
+            afl->afl_env.afl_target_env =
+                (u8 *)get_afl_env(afl_environment_variables[i]);
+
           }
 
         } else {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 99059a2d..2c814d90 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -391,10 +391,11 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
   fprintf(afl->fsrv.plot_file,
           "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, "
           "%u\n",
-          get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry,
-          afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored,
-          bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth,
-          eps, afl->plot_prev_ed, t_bytes);                /* ignore errors */
+          (afl->prev_run_time + get_cur_time() - afl->start_time),
+          afl->queue_cycle - 1, afl->current_entry, afl->queued_paths,
+          afl->pending_not_fuzzed, afl->pending_favored, bitmap_cvg,
+          afl->unique_crashes, afl->unique_hangs, afl->max_depth, eps,
+          afl->plot_prev_ed, t_bytes);                     /* ignore errors */
 
   fflush(afl->fsrv.plot_file);
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 64e4b869..d70ffd31 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -223,6 +223,7 @@ static void usage(u8 *argv0, int more_help) {
       "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
       "AFL_QUIET: suppress forkserver status messages\n"
       "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
+      "AFL_TARGET_ENV: pass extra environment variables to target\n"
       "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
       "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n"
       "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
@@ -1022,32 +1023,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  if (afl->fsrv.qemu_mode && getenv("AFL_USE_QASAN")) {
-
-    u8 *preload = getenv("AFL_PRELOAD");
-    u8 *libqasan = get_libqasan_path(argv_orig[0]);
-
-    if (!preload) {
-
-      setenv("AFL_PRELOAD", libqasan, 0);
-
-    } else {
-
-      u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
-      strcpy(result, libqasan);
-      strcat(result, " ");
-      strcat(result, preload);
-
-      setenv("AFL_PRELOAD", result, 1);
-      ck_free(result);
-
-    }
-
-    afl->afl_env.afl_preload = (u8 *)getenv("AFL_PRELOAD");
-    ck_free(libqasan);
-
-  }
-
   if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
 
   OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
@@ -1312,38 +1287,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
     if (afl->fsrv.qemu_mode) {
 
-      u8 *qemu_preload = getenv("QEMU_SET_ENV");
-      u8 *afl_preload = getenv("AFL_PRELOAD");
-      u8 *buf;
-
-      s32 j, afl_preload_size = strlen(afl_preload);
-      for (j = 0; j < afl_preload_size; ++j) {
-
-        if (afl_preload[j] == ',') {
-
-          PFATAL(
-              "Comma (',') is not allowed in AFL_PRELOAD when -Q is "
-              "specified!");
-
-        }
-
-      }
-
-      if (qemu_preload) {
-
-        buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           qemu_preload, afl_preload, afl_preload);
-
-      } else {
-
-        buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           afl_preload, afl_preload);
-
-      }
-
-      setenv("QEMU_SET_ENV", buf, 1);
-
-      ck_free(buf);
+      /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
 
     } else {
 
@@ -1360,6 +1304,13 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  if (afl->afl_env.afl_target_env &&
+      !extract_and_set_env(afl->afl_env.afl_target_env)) {
+
+    FATAL("Bad value of AFL_TARGET_ENV");
+
+  }
+
   save_cmdline(afl, argc, argv);
 
   fix_up_banner(afl, argv[optind]);
@@ -1584,21 +1535,21 @@ int main(int argc, char **argv_orig, char **envp) {
   if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
       !afl->unicorn_mode) {
 
-    if (map_size <= 8000000 && !afl->non_instrumented_mode &&
+    if (map_size <= DEFAULT_SHMEM_SIZE && !afl->non_instrumented_mode &&
         !afl->fsrv.qemu_mode && !afl->unicorn_mode) {
 
-      afl->fsrv.map_size = 8000000;  // dummy temporary value
-      setenv("AFL_MAP_SIZE", "8000000", 1);
+      afl->fsrv.map_size = DEFAULT_SHMEM_SIZE;  // dummy temporary value
+      char vbuf[16];
+      snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE);
+      setenv("AFL_MAP_SIZE", vbuf, 1);
 
     }
 
     u32 new_map_size = afl_fsrv_get_mapsize(
         &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child);
 
-    // only reinitialize when it makes sense
-    if ((map_size < new_map_size ||
-         (new_map_size != MAP_SIZE && new_map_size < map_size &&
-          map_size - new_map_size > MAP_SIZE))) {
+    // only reinitialize if the map needs to be larger than what we have.
+    if (map_size < new_map_size) {
 
       OKF("Re-initializing maps to %u bytes", new_map_size);
 
@@ -1627,8 +1578,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
     }
 
-    afl->fsrv.map_size = map_size;
-
   }
 
   if (afl->cmplog_binary) {
@@ -1641,11 +1590,15 @@ int main(int argc, char **argv_orig, char **envp) {
     afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
     afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
 
-    if (map_size <= 8000000 && !afl->non_instrumented_mode &&
-        !afl->fsrv.qemu_mode && !afl->unicorn_mode) {
+    if ((map_size <= DEFAULT_SHMEM_SIZE ||
+         afl->cmplog_fsrv.map_size < map_size) &&
+        !afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
+        !afl->unicorn_mode) {
 
-      afl->cmplog_fsrv.map_size = 8000000;  // dummy temporary value
-      setenv("AFL_MAP_SIZE", "8000000", 1);
+      afl->cmplog_fsrv.map_size = MAX(map_size, (u32)DEFAULT_SHMEM_SIZE);
+      char vbuf[16];
+      snprintf(vbuf, sizeof(vbuf), "%u", afl->cmplog_fsrv.map_size);
+      setenv("AFL_MAP_SIZE", vbuf, 1);
 
     }
 
@@ -1686,10 +1639,6 @@ int main(int argc, char **argv_orig, char **envp) {
       afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon,
                      afl->afl_env.afl_debug_child);
 
-    } else {
-
-      afl->cmplog_fsrv.map_size = new_map_size;
-
     }
 
     OKF("Cmplog forkserver successfully started");
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index 3241a130..fbb8e65d 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -162,8 +162,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
   snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random());
 
   /* create the shared memory segment as if it was a file */
-  shm->g_shm_fd =
-      shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
+  shm->g_shm_fd = shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL,
+                           DEFAULT_PERMISSION);
   if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); }
 
   /* configure the size of the shared memory segment */
@@ -202,7 +202,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
 
     /* create the shared memory segment as if it was a file */
     shm->cmplog_g_shm_fd =
-        shm_open(shm->cmplog_g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
+        shm_open(shm->cmplog_g_shm_file_path, O_CREAT | O_RDWR | O_EXCL,
+                 DEFAULT_PERMISSION);
     if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
 
     /* configure the size of the shared memory segment */
@@ -241,13 +242,14 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
 #else
   u8 *shm_str;
 
-  shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
+  shm->shm_id =
+      shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | DEFAULT_PERMISSION);
   if (shm->shm_id < 0) { PFATAL("shmget() failed"); }
 
   if (shm->cmplog_mode) {
 
     shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
-                                IPC_CREAT | IPC_EXCL | 0600);
+                                IPC_CREAT | IPC_EXCL | DEFAULT_PERMISSION);
 
     if (shm->cmplog_shm_id < 0) {
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 0fc76193..077c9248 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -252,7 +252,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
   } else {
 
     unlink(outfile);                                       /* Ignore errors */
-    fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
+    fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
     if (fd < 0) { PFATAL("Unable to create '%s'", outfile); }
 
   }
@@ -599,38 +599,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
 
     if (fsrv->qemu_mode) {
 
-      u8 *qemu_preload = getenv("QEMU_SET_ENV");
-      u8 *afl_preload = getenv("AFL_PRELOAD");
-      u8 *buf;
-
-      s32 i, afl_preload_size = strlen(afl_preload);
-      for (i = 0; i < afl_preload_size; ++i) {
-
-        if (afl_preload[i] == ',') {
-
-          PFATAL(
-              "Comma (',') is not allowed in AFL_PRELOAD when -Q is "
-              "specified!");
-
-        }
-
-      }
-
-      if (qemu_preload) {
-
-        buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           qemu_preload, afl_preload, afl_preload);
-
-      } else {
-
-        buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           afl_preload, afl_preload);
-
-      }
-
-      setenv("QEMU_SET_ENV", buf, 1);
-
-      ck_free(buf);
+      /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
 
     } else {
 
@@ -946,31 +915,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (optind == argc || !out_file) { usage(argv[0]); }
 
-  if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) {
-
-    u8 *preload = getenv("AFL_PRELOAD");
-    u8 *libqasan = get_libqasan_path(argv_orig[0]);
-
-    if (!preload) {
-
-      setenv("AFL_PRELOAD", libqasan, 0);
-
-    } else {
-
-      u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
-      strcpy(result, libqasan);
-      strcat(result, " ");
-      strcat(result, preload);
-
-      setenv("AFL_PRELOAD", result, 1);
-      ck_free(result);
-
-    }
-
-    ck_free(libqasan);
-
-  }
-
   if (in_dir) {
 
     if (!out_file && !collect_coverage)
@@ -1175,7 +1119,8 @@ int main(int argc, char **argv_orig, char **envp) {
     unlink(stdin_file);
     atexit(at_exit_handler);
     fsrv->out_file = stdin_file;
-    fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
+    fsrv->out_fd =
+        open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
     if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
 
     if (arg_offset && use_argv[arg_offset] != stdin_file) {
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 6d04c652..fc974262 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -244,7 +244,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
 
   unlink(path);                                            /* Ignore errors */
 
-  ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
+  ret = open(path, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
 
   if (ret < 0) { PFATAL("Unable to create '%s'", path); }
 
@@ -666,7 +666,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
   unlink(out_file);
 
   fsrv->out_file = out_file;
-  fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
+  fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
 
   if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
 
@@ -753,38 +753,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
 
     if (fsrv->qemu_mode) {
 
-      u8 *qemu_preload = getenv("QEMU_SET_ENV");
-      u8 *afl_preload = getenv("AFL_PRELOAD");
-      u8 *buf;
-
-      s32 i, afl_preload_size = strlen(afl_preload);
-      for (i = 0; i < afl_preload_size; ++i) {
-
-        if (afl_preload[i] == ',') {
-
-          PFATAL(
-              "Comma (',') is not allowed in AFL_PRELOAD when -Q is "
-              "specified!");
-
-        }
-
-      }
-
-      if (qemu_preload) {
-
-        buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           qemu_preload, afl_preload, afl_preload);
-
-      } else {
-
-        buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           afl_preload, afl_preload);
-
-      }
-
-      setenv("QEMU_SET_ENV", buf, 1);
-
-      ck_free(buf);
+      /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
 
     } else {
 
@@ -1079,31 +1048,6 @@ int main(int argc, char **argv_orig, char **envp) {
   check_environment_vars(envp);
   setenv("AFL_NO_AUTODICT", "1", 1);
 
-  if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) {
-
-    u8 *preload = getenv("AFL_PRELOAD");
-    u8 *libqasan = get_libqasan_path(argv_orig[0]);
-
-    if (!preload) {
-
-      setenv("AFL_PRELOAD", libqasan, 0);
-
-    } else {
-
-      u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
-      strcpy(result, libqasan);
-      strcat(result, " ");
-      strcat(result, preload);
-
-      setenv("AFL_PRELOAD", result, 1);
-      ck_free(result);
-
-    }
-
-    ck_free(libqasan);
-
-  }
-
   /* initialize cmplog_mode */
   shm.cmplog_mode = 0;
 
diff --git a/test-instr.c b/test-instr.c
index 00799103..13d4eb93 100644
--- a/test-instr.c
+++ b/test-instr.c
@@ -18,6 +18,10 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#ifdef TEST_SHARED_OBJECT
+  #define main main_exported
+#endif
+
 int main(int argc, char **argv) {
 
   int   fd = 0;
diff --git a/test/test-dlopen.c b/test/test-dlopen.c
new file mode 100644
index 00000000..d08d9092
--- /dev/null
+++ b/test/test-dlopen.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+
+  if (!getenv("TEST_DLOPEN_TARGET")) return 1;
+  void *lib = dlopen(getenv("TEST_DLOPEN_TARGET"), RTLD_LAZY);
+  if (!lib) {
+
+    perror(dlerror());
+    return 2;
+
+  }
+
+  int (*func)(int, char **) = dlsym(lib, "main_exported");
+  if (!func) return 3;
+
+  return func(argc, argv);
+
+}
+
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index aa36af1b..3ef36b37 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -43,6 +43,48 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
     $ECHO "$RED[!] llvm_mode failed"
     CODE=1
   }
+  ../afl-clang-fast -DTEST_SHARED_OBJECT=1 -z defs -fPIC -shared -o test-instr.so ../test-instr.c > /dev/null 2>&1
+  test -e test-instr.so && {
+    $ECHO "$GREEN[+] llvm_mode shared object with -z defs compilation succeeded"
+    ../afl-clang-fast -o test-dlopen.plain test-dlopen.c -ldl > /dev/null 2>&1
+    test -e test-dlopen.plain && {
+      $ECHO "$GREEN[+] llvm_mode test-dlopen compilation succeeded"
+      echo 0 | TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ./test-dlopen.plain > /dev/null 2>&1
+      if [ $? -ne 0 ]; then
+        $ECHO "$RED[!] llvm_mode test-dlopen exits with an error"
+        CODE=1
+      fi
+      echo 0 | TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-dlopen.plain.0 -r -- ./test-dlopen.plain > /dev/null 2>&1
+      TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-dlopen.plain.1 -r -- ./test-dlopen.plain < /dev/null > /dev/null 2>&1
+      test -e test-dlopen.plain.0 -a -e test-dlopen.plain.1 && {
+        diff test-dlopen.plain.0 test-dlopen.plain.1 > /dev/null 2>&1 && {
+          $ECHO "$RED[!] llvm_mode test-dlopen instrumentation should be different on different input but is not"
+          CODE=1
+        } || {
+          $ECHO "$GREEN[+] llvm_mode test-dlopen instrumentation present and working correctly"
+          TUPLES=`echo 0|TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-dlopen.plain 2>&1 | grep Captur | awk '{print$3}'`
+          test "$TUPLES" -gt 3 -a "$TUPLES" -lt 12 && {
+            $ECHO "$GREEN[+] llvm_mode test-dlopen run reported $TUPLES instrumented locations which is fine"
+          } || {
+            $ECHO "$RED[!] llvm_mode test-dlopen instrumentation produces weird numbers: $TUPLES"
+            CODE=1
+          }
+          test "$TUPLES" -lt 3 && SKIP=1
+          true
+        }
+      } || {
+        $ECHO "$RED[!] llvm_mode test-dlopen instrumentation failed"
+        CODE=1
+      }
+    } || {
+      $ECHO "$RED[!] llvm_mode test-dlopen compilation failed"
+      CODE=1
+    }
+    rm -f test-dlopen.plain test-dlopen.plain.0 test-dlopen.plain.1 test-instr.so
+  } || {
+    $ECHO "$RED[!] llvm_mode shared object with -z defs compilation failed"
+    CODE=1
+  }
   test -e test-compcov.harden && test_compcov_binary_functionality ./test-compcov.harden && {
     grep -Eq$GREPAOPTION 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && {
       $ECHO "$GREEN[+] llvm_mode hardened mode succeeded and is working"
diff --git a/test/travis/bionic/Dockerfile b/test/travis/bionic/Dockerfile
deleted file mode 100644
index 00ab96f9..00000000
--- a/test/travis/bionic/Dockerfile
+++ /dev/null
@@ -1,45 +0,0 @@
-# This is the Dockerfile for testing problems in Travis build
-# configuration #1.
-# This needs not to be rebuild everytime, most of the time it needs just to
-# be build once and then started when debugging issues and execute:
-#   cd /AFLplusplus/
-#   git pull
-#   make distrib
-#
-FROM ubuntu:bionic
-LABEL "about"="travis image 1"
-RUN apt-get update && apt-get -y install \
-    automake \
-    bison \
-    build-essential \
-    clang \
-    flex \
-    git \
-    python3.7 python3.7-dev \
-    python3-setuptools \
-    libtool libtool-bin \
-    libglib2.0-dev \
-    python-setuptools \
-    wget \
-    ca-certificates \
-    libpixman-1-dev \
-    gcc-7 gcc-7-plugin-dev libc++-7-dev \
-    findutils \
-    libcmocka-dev \
-    joe nano vim locate \
-    && rm -rf /var/lib/apt/lists/*
-
-ENV AFL_NO_UI=1
-ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
-ENV LLVM_CONFIG=llvm-config-6.0
-
-RUN cd / && \
-    git clone https://github.com/AFLplusplus/AFLplusplus && \
-    cd AFLplusplus && \
-    git checkout dev && \
-    cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
-    cd ../unicorn_mode && git submodule init && git submodule update || true && \
-    cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
-
-WORKDIR /AFLplusplus
-CMD ["/bin/bash"]
diff --git a/test/travis/focal/Dockerfile b/test/travis/focal/Dockerfile
deleted file mode 100644
index 27d994f2..00000000
--- a/test/travis/focal/Dockerfile
+++ /dev/null
@@ -1,45 +0,0 @@
-# This is the Dockerfile for testing problems in Travis build
-# configuration #1.
-# This needs not to be rebuild everytime, most of the time it needs just to
-# be build once and then started when debugging issues and execute:
-#   cd /AFLplusplus/
-#   git pull
-#   make distrib
-#
-FROM ubuntu:focal
-LABEL "about"="travis image 4"
-ARG DEBIAN_FRONTEND=noninteractive
-RUN apt-get update && apt-get -y install \
-    automake \
-    bison \
-    build-essential \
-    clang \
-    flex \
-    git \
-    python3 python3-dev \
-    python3-setuptools \
-    libtool libtool-bin \
-    libglib2.0-dev \
-    python-setuptools \
-    wget \
-    ca-certificates \
-    libpixman-1-dev \
-    gcc-9 gcc-9-plugin-dev libc++-9-dev \
-    findutils \
-    libcmocka-dev \
-    joe nano vim locate \
-    && rm -rf /var/lib/apt/lists/*
-
-ENV AFL_NO_UI=1
-ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
-
-RUN cd / && \
-    git clone https://github.com/AFLplusplus/AFLplusplus && \
-    cd AFLplusplus && \
-    git checkout dev && \
-    cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
-    cd ../unicorn_mode && git submodule init && git submodule update || true && \
-    cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
-
-WORKDIR /AFLplusplus
-CMD ["/bin/bash"]
diff --git a/test/travis/trusty/Dockerfile b/test/travis/trusty/Dockerfile
deleted file mode 100644
index 0a6f1804..00000000
--- a/test/travis/trusty/Dockerfile
+++ /dev/null
@@ -1,49 +0,0 @@
-# This is the Dockerfile for testing problems in Travis builds
-# configuration #3.
-# This needs not to be rebuild everytime, most of the time it needs just to
-# be build once and then started when debugging issues and execute:
-#   cd /AFLplusplus/
-#   git pull
-#   make distrib
-#
-FROM ubuntu:trusty
-LABEL "about"="travis image 3"
-RUN apt-get update && apt-get -y install \
-    automake \
-    bison \
-    build-essential \
-    clang \
-    flex \
-    git \
-    python2.7 python2.7-dev \
-    python3-setuptools \
-    libtool \
-    libglib2.0-dev \
-    python-setuptools \
-    wget \
-    ca-certificates \
-    libpixman-1-dev \
-    gcc-4.8 gcc-4.8-plugin-dev \
-    libc++-dev \
-    findutils \
-    libcmocka-dev \
-    joe nano vim locate \
-    && rm -rf /var/lib/apt/lists/*
-
-ENV TERM linux
-ENV DEBIAN_FRONTEND noninteractive
-ENV LLVM_CONFIG=llvm-config-3.4
-ENV AFL_NO_UI=1
-ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
-
-RUN cd / && \
-    git clone https://github.com/AFLplusplus/AFLplusplus && \
-    cd AFLplusplus && \
-    git checkout dev && \
-    cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
-    cd ../unicorn_mode && git submodule init && git submodule update || true && \
-    cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
-
-WORKDIR /AFLplusplus
-CMD ["/bin/bash"]
-
diff --git a/test/travis/xenial/Dockerfile b/test/travis/xenial/Dockerfile
deleted file mode 100644
index 6aa4b1d1..00000000
--- a/test/travis/xenial/Dockerfile
+++ /dev/null
@@ -1,46 +0,0 @@
-# This is the Dockerfile for testing problems in Travis builds
-# configuration #2.
-# This needs not to be rebuild everytime, most of the time it needs just to
-# be build once and then started when debugging issues and execute:
-#   cd /AFLplusplus/
-#   git pull
-#   make distrib
-#
-FROM ubuntu:xenial
-LABEL "about"="travis image 2"
-RUN apt-get update && apt-get -y install \
-    automake \
-    bison \
-    build-essential \
-    clang-6.0 \
-    flex \
-    git \
-    python3 python3-dev \
-    python3-setuptools \
-    libtool libtool-bin \
-    libglib2.0-dev \
-    python-setuptools \
-    wget \
-    ca-certificates \
-    libpixman-1-dev \
-    gcc-5 gcc-5-plugin-dev \
-    libc++-dev \
-    findutils \
-    libcmocka-dev \
-    joe nano vim locate \
-    && rm -rf /var/lib/apt/lists/*
-
-ENV LLVM_CONFIG=llvm-config-6.0
-ENV AFL_NO_UI=1
-ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
-
-RUN cd / && \
-    git clone https://github.com/AFLplusplus/AFLplusplus && \
-    cd AFLplusplus && \
-    git checkout dev && \
-    cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
-    cd ../unicorn_mode && git submodule init && git submodule update || true && \
-    cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
-
-WORKDIR /AFLplusplus
-CMD ["/bin/bash"]
diff --git a/unicorn_mode/helper_scripts/ida_context_loader.py b/unicorn_mode/helper_scripts/ida_context_loader.py
new file mode 100644
index 00000000..31d47a90
--- /dev/null
+++ b/unicorn_mode/helper_scripts/ida_context_loader.py
@@ -0,0 +1,197 @@
+# Copyright (c) 2021 Brandon Miller (zznop)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+"""IDA script for loading state that was dumped from a running process using unicorn AFL's GDB
+plugin (unicorn_dumper_gdb.py). The dumper script can be found in the AFL++ repository at:
+https://github.com/AFLplusplus/AFLplusplus/blob/stable/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py
+"""
+
+import json
+from pathlib import Path, PurePath
+import zlib
+import idaapi
+import ida_bytes
+import ida_kernwin
+import ida_nalt
+import ida_segment
+
+
+class ContextLoaderError(Exception):
+    """Base "catch all" exception for this script
+    """
+
+
+class ArchNotSupportedError(ContextLoaderError):
+    """Exception raised if the input file CPU architecture isn't supported fully
+    """
+
+
+def parse_mapping_index(filepath: str):
+    """Open and unmarshal the _index.json file
+
+    :param filepath: Path to the JSON file
+    :return: Dict representing index file contents
+    """
+
+    if filepath is None:
+        raise ContextLoaderError('_index.json file was not selected')
+
+    try:
+        with open(filepath, 'rb') as _file:
+            return json.load(_file)
+    except Exception as ex:
+        raise ContextLoaderError('Failed to parse json file {}'.format(filepath)) from ex
+
+def get_input_name():
+    """Get the name of the input file
+
+    :retrun: Name of the input file
+    """
+
+    input_filepath = ida_nalt.get_input_file_path()
+    return Path(input_filepath).name
+
+def write_segment_bytes(start: int, filepath: str):
+    """"Read data from context file and write it to the IDA segment
+
+    :param start: Start address
+    :param filepath: Path to context file
+    """
+
+    with open(filepath, 'rb') as _file:
+        data = _file.read()
+
+    decompressed_data = zlib.decompress(data)
+    ida_bytes.put_bytes(start, decompressed_data)
+
+def create_segment(context_dir: str, segment: dict, is_be: bool):
+    """Create segment in IDA and map in the data from the file
+
+    :param context_dir: Parent directory of the context files
+    :param segment: Segment information from _index.json
+    :param is_be: True if processor is big endian, otherwise False
+    """
+
+    input_name = get_input_name()
+    if Path(segment['name']).name != input_name:
+        ida_seg = idaapi.segment_t()
+        ida_seg.start_ea = segment['start']
+        ida_seg.end_ea = segment['end']
+        ida_seg.bitness = 1 if is_be else 0
+        if segment['permissions']['r']:
+            ida_seg.perm |= ida_segment.SEGPERM_READ
+        if segment['permissions']['w']:
+            ida_seg.perm |= ida_segment.SEGPERM_WRITE
+        if segment['permissions']['x']:
+            ida_seg.perm |= ida_segment.SEGPERM_EXEC
+            idaapi.add_segm_ex(ida_seg, Path(segment['name']).name, 'CODE', idaapi.ADDSEG_OR_DIE)
+        else:
+            idaapi.add_segm_ex(ida_seg, Path(segment['name']).name, 'DATA', idaapi.ADDSEG_OR_DIE)
+
+    if segment['content_file']:
+        write_segment_bytes(segment['start'], PurePath(context_dir, segment['content_file']))
+
+def create_segments(index: dict, context_dir: str):
+    """Iterate segments in index JSON, create the segment in IDA, and map in the data from the file
+
+    :param index: _index.json JSON data
+    :param context_dir: Parent directory of the context files
+    """
+
+    info = idaapi.get_inf_structure()
+    is_be = info.is_be()
+    for segment in index['segments']:
+        create_segment(context_dir, segment, is_be)
+
+def rebase_program(index: dict):
+    """Rebase the program to the offset specified in the context _index.json
+
+    :param index: _index.json JSON data
+    """
+
+    input_name = get_input_name()
+    new_base = None
+    for segment in index['segments']:
+        if not segment['name']:
+            continue
+
+        segment_name = Path(segment['name']).name
+        if input_name == segment_name:
+            new_base = segment['start']
+            break
+
+    if not new_base:
+        raise ContextLoaderError('Input file is not in _index.json')
+
+    current_base = idaapi.get_imagebase()
+    ida_segment.rebase_program(new_base-current_base, 8)
+
+def get_pc_by_arch(index: dict) -> int:
+    """Queries the input file CPU architecture and attempts to lookup the address of the program
+    counter in the _index.json by register name
+
+    :param index: _index.json JSON data
+    :return: Program counter value or None
+    """
+
+    progctr = None
+    info = idaapi.get_inf_structure()
+    if info.procname == 'metapc':
+        if info.is_64bit():
+            progctr = index['regs']['rax']
+        elif info.is_32bit():
+            progctr = index['regs']['eax']
+    return progctr
+
+def write_reg_info(index: dict):
+    """Write register info as line comment at instruction pointed to by the program counter and
+    change focus to that location
+
+    :param index: _index.json JSON data
+    """
+
+    cmt = ''
+    for reg, val in index['regs'].items():
+        cmt += f"{reg.ljust(6)} : {hex(val)}\n"
+
+    progctr = get_pc_by_arch(index)
+    if progctr is None:
+        raise ArchNotSupportedError(
+            'Architecture not fully supported, skipping register status comment')
+    ida_bytes.set_cmt(progctr, cmt, 0)
+    ida_kernwin.jumpto(progctr)
+
+def main(filepath):
+    """Main - parse _index.json input and map context files into the database
+
+    :param filepath: Path to the _index.json file
+    """
+
+    try:
+        index = parse_mapping_index(filepath)
+        context_dir = Path(filepath).parent
+        rebase_program(index)
+        create_segments(index, context_dir)
+        write_reg_info(index)
+    except ContextLoaderError as ex:
+        print(ex)
+
+if __name__ == '__main__':
+    main(ida_kernwin.ask_file(1, '*.json', 'Import file name'))
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
new file mode 160000
+Subproject fb2fc9f25df32f17f6b6b859e4dbd70f9a857e0
diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c
index fe225416..0dfae658 100644
--- a/utils/afl_network_proxy/afl-network-server.c
+++ b/utils/afl_network_proxy/afl-network-server.c
@@ -237,38 +237,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
 
     if (fsrv->qemu_mode) {
 
-      u8 *qemu_preload = getenv("QEMU_SET_ENV");
-      u8 *afl_preload = getenv("AFL_PRELOAD");
-      u8 *buf;
-
-      s32 i, afl_preload_size = strlen(afl_preload);
-      for (i = 0; i < afl_preload_size; ++i) {
-
-        if (afl_preload[i] == ',') {
-
-          PFATAL(
-              "Comma (',') is not allowed in AFL_PRELOAD when -Q is "
-              "specified!");
-
-        }
-
-      }
-
-      if (qemu_preload) {
-
-        buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           qemu_preload, afl_preload, afl_preload);
-
-      } else {
-
-        buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
-                           afl_preload, afl_preload);
-
-      }
-
-      setenv("QEMU_SET_ENV", buf, 1);
-
-      afl_free(buf);
+      /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
 
     } else {
 
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index 9c97607c..ad781e64 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -187,6 +187,8 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
 
     }
 
+    close(fd);
+
   }
 
   free(buf);
@@ -208,6 +210,16 @@ int main(int argc, char **argv) {
       "======================================================\n",
       argv[0], argv[0]);
 
+  if (getenv("AFL_GDB")) {
+
+    char cmd[64];
+    snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
+    system(cmd);
+    fprintf(stderr, "DEBUG: aflpp_driver pid is %d\n", getpid());
+    sleep(1);
+
+  }
+
   output_file = stderr;
   maybe_duplicate_stderr();
   maybe_close_fd_mask();
diff --git a/utils/crash_triage/triage_crashes.sh b/utils/crash_triage/triage_crashes.sh
index bf763cba..a752458d 100755
--- a/utils/crash_triage/triage_crashes.sh
+++ b/utils/crash_triage/triage_crashes.sh
@@ -60,12 +60,12 @@ if
 fi
 
 if [ ! -f "$BIN" -o ! -x "$BIN" ]; then
-  echo "[-] Error: binary '$2' not found or is not executable." 1>&2
+  echo "[-] Error: binary '$BIN' not found or is not executable." 1>&2
   exit 1
 fi
 
 if [ ! -d "$DIR/queue" ]; then
-  echo "[-] Error: directory '$1' not found or not created by afl-fuzz." 1>&2
+  echo "[-] Error: directory '$DIR' not found or not created by afl-fuzz." 1>&2
   exit 1
 fi
 
diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c
index c041fec6..1b247c86 100644
--- a/utils/libdislocator/libdislocator.so.c
+++ b/utils/libdislocator/libdislocator.so.c
@@ -168,7 +168,7 @@ static void *__dislocator_alloc(size_t len) {
 
   u8 *   ret, *base;
   size_t tlen;
-  int    flags, fd, sp;
+  int    flags, protflags, fd, sp;
 
   if (total_mem + len > max_mem || total_mem + len < total_mem) {
 
@@ -191,8 +191,14 @@ static void *__dislocator_alloc(size_t len) {
 
   base = NULL;
   tlen = (1 + PG_COUNT(rlen + 8)) * PAGE_SIZE;
+  protflags = PROT_READ | PROT_WRITE;
   flags = MAP_PRIVATE | MAP_ANONYMOUS;
   fd = -1;
+#if defined(PROT_MAX)
+  // apply when sysctl vm.imply_prot_max is set to 1
+  // no-op otherwise
+  protflags |= PROT_MAX(PROT_READ | PROT_WRITE);
+#endif
 #if defined(USEHUGEPAGE)
   sp = (rlen >= SUPER_PAGE_SIZE && !(rlen % SUPER_PAGE_SIZE));
 
@@ -215,7 +221,7 @@ static void *__dislocator_alloc(size_t len) {
   (void)sp;
 #endif
 
-  ret = (u8 *)mmap(base, tlen, PROT_READ | PROT_WRITE, flags, fd, 0);
+  ret = (u8 *)mmap(base, tlen, protflags, flags, fd, 0);
 #if defined(USEHUGEPAGE)
   /* We try one more time with regular call */
   if (ret == MAP_FAILED) {
@@ -229,7 +235,7 @@ static void *__dislocator_alloc(size_t len) {
   #elif defined(__sun)
     flags &= -MAP_ALIGN;
   #endif
-    ret = (u8 *)mmap(NULL, tlen, PROT_READ | PROT_WRITE, flags, fd, 0);
+    ret = (u8 *)mmap(NULL, tlen, protflags, flags, fd, 0);
 
   }