about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--.github/workflows/codeql-analysis.yml4
-rw-r--r--.gitignore1
-rw-r--r--GNUmakefile4
-rw-r--r--README.md8
-rw-r--r--docs/Changelog.md4
-rw-r--r--dynamic_list.txt37
-rw-r--r--include/common.h4
-rw-r--r--include/config.h9
-rw-r--r--include/envs.h1
-rw-r--r--instrumentation/README.lto.md2
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc7
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc158
-rw-r--r--instrumentation/afl-compiler-rt.o.c12
-rw-r--r--instrumentation/afl-llvm-common.cc18
-rw-r--r--src/afl-cc.c93
-rw-r--r--src/afl-common.c230
-rw-r--r--src/afl-fuzz-init.c39
-rw-r--r--src/afl-fuzz-stats.c2
-rw-r--r--src/afl-fuzz.c32
-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
m---------unicorn_mode/unicornafl0
-rwxr-xr-xutils/crash_triage/triage_crashes.sh2
-rw-r--r--utils/libdislocator/libdislocator.so.c12
30 files changed, 361 insertions, 576 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..f885f998 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -576,7 +576,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/README.md b/README.md
index 700fe818..627e1b0f 100644
--- a/README.md
+++ b/README.md
@@ -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
 ```
diff --git a/docs/Changelog.md b/docs/Changelog.md
index fdb1cf5c..ab0312f8 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -12,12 +12,16 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - afl-fuzz:
     - added AFL_TARGET_ENV variable to pass extra env vars to the target
       (for things like LD_LIBRARY_PATH)
+    - better map detection, AFL_MAP_SIZE not needed anymore for most cases
   - afl-cc:
     - fix cmplog rtn (rare crash and not being able to gather ptr data)
     - link runtime not to shared libs
+    - ensure shared libraries are properly built and instrumented
   - 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
 
 ### Version ++3.11c (release)
   - afl-fuzz:
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/common.h b/include/common.h
index 06453b8e..05137fb6 100644
--- a/include/common.h
+++ b/include/common.h
@@ -61,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 b049fee0..29225f6b 100644
--- a/include/config.h
+++ b/include/config.h
@@ -34,6 +34,15 @@
  *                                                    *
  ******************************************************/
 
+/* 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)
+
 /* CMPLOG/REDQUEEN TUNING
  *
  * Here you can modify tuning and solving options for CMPLOG.
diff --git a/include/envs.h b/include/envs.h
index fda4ab55..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",
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..28d905a3 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1291,10 +1291,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..99ead3d6 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.
@@ -915,10 +769,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()));
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 3bd019ac..ab1bfb31 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -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) {
@@ -1774,14 +1780,14 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
   */
 
   if (unlikely(!__afl_cmp_map)) return;
-  fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
+  // 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);
+  // 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;
@@ -1812,7 +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");
+  // fprintf(stderr, "RTN3\n");
 
 }
 
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index 17780143..74943fb2 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -96,19 +96,11 @@ bool isIgnoreFunction(const llvm::Function *F) {
 
   static const char *ignoreSubstringList[] = {
 
-      "__asan",
-      "__msan",
-      "__ubsan",
-      "__lsan",
-      "__san",
-      "__sanitize",
-      "__cxx",
-      "_GLOBAL__",
-      "DebugCounter",
-      "DwarfDebug",
-      "DebugLoc"
-
- };
+      "__asan",       "__msan",     "__ubsan", "__lsan",
+      "__san",        "__sanitize", "__cxx",   "_GLOBAL__",
+      "DebugCounter", "DwarfDebug", "DebugLoc"
+
+  };
 
   for (auto const &ignoreListFunc : ignoreSubstringList) {
 
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 18401d0d..5251465b 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -682,17 +682,42 @@ 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 (!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"))) {
 
@@ -959,65 +984,73 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   if (compiler_mode != GCC && compiler_mode != CLANG) {
 
-    if (!shared_linking) {
+    switch (bit_mode) {
 
-      switch (bit_mode) {
-
-        case 0:
+      case 0:
+        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;
+        if (lto_mode)
+          cc_params[cc_par_cnt++] =
+              alloc_printf("%s/afl-llvm-rt-lto.o", obj_path);
+        break;
+
+      case 32:
+        if (!shared_linking) {
 
-        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 (lto_mode) {
 
-            cc_params[cc_par_cnt++] =
-                alloc_printf("%s/afl-llvm-rt-lto-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) {
 
-          break;
+          cc_params[cc_par_cnt++] =
+              alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path);
+          if (access(cc_params[cc_par_cnt - 1], R_OK))
+            FATAL("-m32 is not supported by your compiler");
+
+        }
+
+        break;
+
+      case 64:
+        if (!shared_linking) {
 
-        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 (lto_mode) {
 
-            cc_params[cc_par_cnt++] =
-                alloc_printf("%s/afl-llvm-rt-lto-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) {
 
-          break;
+          cc_params[cc_par_cnt++] =
+              alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path);
+          if (access(cc_params[cc_par_cnt - 1], R_OK))
+            FATAL("-m64 is not supported by your compiler");
 
-      }
+        }
+
+        break;
+
+    }
 
   #if !defined(__APPLE__) && !defined(__sun)
+    if (!shared_linking)
       cc_params[cc_par_cnt++] =
           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;
diff --git a/src/afl-common.c b/src/afl-common.c
index 72a95fbc..6e485117 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -158,10 +158,6 @@ 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"); }
-
-  u8 *tmp, *cp = NULL, *rsl, *own_copy;
-
   char **new_argv = ck_alloc(sizeof(char *) * (argc + 4));
   if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
 
@@ -173,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;
 
 }
 
@@ -244,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"); }
 
@@ -258,92 +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);
+  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;
 
 }
 
@@ -437,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. */
@@ -1168,7 +1080,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"))) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 82c1799e..91076bf7 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1812,9 +1812,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 +2012,34 @@ 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) {
 
-  fprintf(afl->fsrv.plot_file,
+    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"); }
+
+    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, 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"); }
+
+    fseek(afl->fsrv.plot_file, 0, SEEK_END);
+
+  } 
+
   fflush(afl->fsrv.plot_file);
 
   /* ignore errors */
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 99059a2d..3e237003 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -391,7 +391,7 @@ 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->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 */
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9ea1fb34..b1d01959 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1535,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);
 
@@ -1578,8 +1578,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
     }
 
-    afl->fsrv.map_size = map_size;
-
   }
 
   if (afl->cmplog_binary) {
@@ -1592,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);
 
     }
 
@@ -1637,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/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/unicornafl b/unicorn_mode/unicornafl
new file mode 160000
+Subproject fb2fc9f25df32f17f6b6b859e4dbd70f9a857e0
diff --git a/utils/crash_triage/triage_crashes.sh b/utils/crash_triage/triage_crashes.sh
index 4e8f09a0..a752458d 100755
--- a/utils/crash_triage/triage_crashes.sh
+++ b/utils/crash_triage/triage_crashes.sh
@@ -65,7 +65,7 @@ if [ ! -f "$BIN" -o ! -x "$BIN" ]; then
 fi
 
 if [ ! -d "$DIR/queue" ]; then
-  echo "[-] Error: directory '$DIR/queue' 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);
 
   }