about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--GNUmakefile70
-rw-r--r--README.md2
-rw-r--r--docs/Changelog.md9
-rw-r--r--docs/env_variables.md4
-rw-r--r--gcc_plugin/Makefile3
-rw-r--r--gcc_plugin/afl-gcc-fast.c8
-rw-r--r--include/afl-fuzz.h13
-rw-r--r--include/common.h2
-rw-r--r--include/config.h9
-rw-r--r--include/types.h27
-rw-r--r--libdislocator/Makefile2
-rw-r--r--libdislocator/libdislocator.so.c7
-rw-r--r--llvm_mode/GNUmakefile45
-rw-r--r--llvm_mode/LLVMInsTrim.so.cc177
-rw-r--r--llvm_mode/NOTES88
-rw-r--r--llvm_mode/README.lto.md25
-rw-r--r--llvm_mode/afl-llvm-common.cc202
-rw-r--r--llvm_mode/afl-llvm-common.h41
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc164
-rw-r--r--llvm_mode/afl-llvm-lto-whitelist.so.cc21
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc212
-rw-r--r--llvm_mode/afl-llvm-rt.o.c141
-rw-r--r--llvm_mode/cmplog-instructions-pass.cc134
-rw-r--r--llvm_mode/cmplog-routines-pass.cc134
-rw-r--r--llvm_mode/compare-transform-pass.so.cc134
-rw-r--r--llvm_mode/split-compares-pass.so.cc152
-rw-r--r--llvm_mode/split-switches-pass.so.cc151
-rw-r--r--src/afl-common.c14
-rw-r--r--src/afl-forkserver.c53
-rw-r--r--src/afl-fuzz-bitmap.c2
-rw-r--r--src/afl-fuzz-init.c13
-rw-r--r--src/afl-fuzz-state.c35
-rw-r--r--src/afl-gcc.c32
-rw-r--r--src/afl-sharedmem.c10
-rw-r--r--test/test-compcov.c3
-rwxr-xr-xtest/test.sh10
-rw-r--r--test/travis/bionic/Dockerfile43
-rw-r--r--test/travis/trusty/Dockerfile48
-rw-r--r--test/travis/xenial/Dockerfile45
-rw-r--r--test/unittests/unit_list.c2
-rwxr-xr-xunicorn_mode/build_unicorn_support.sh7
42 files changed, 927 insertions, 1369 deletions
diff --git a/.travis.yml b/.travis.yml
index 89d72c34..a360bd42 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,7 +32,7 @@ jobs:
     - arch: arm64
 
 env:
-  - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_STOP_MANUALLY=1
+  - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1
  # - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_EXIT_WHEN_DONE=1
  # TODO: test AFL_BENCH_UNTIL_CRASH once we have a target that crashes
  # - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_BENCH_JUST_ONE=1
diff --git a/GNUmakefile b/GNUmakefile
index 2337b9e0..8811da03 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -88,24 +88,50 @@ ifneq "$(shell command -v python3m 2>/dev/null)" ""
   endif
 endif
 
-ifneq "$(shell command -v python3 2>/dev/null)" ""
-  ifneq "$(shell command -v python3-config 2>/dev/null)" ""
-    PYTHON_INCLUDE  ?= $(shell python3-config --includes)
-    PYTHON_VERSION  ?= $(strip $(shell python3 --version 2>&1))
-    # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag.
-    ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1"
-      PYTHON_LIB      ?= $(shell python3-config --libs --embed --ldflags)
-    else
-      PYTHON_LIB      ?= $(shell python3-config --ldflags)
+ifeq "$(PYTHON_INCLUDE)" ""
+  ifneq "$(shell command -v python3 2>/dev/null)" ""
+    ifneq "$(shell command -v python3-config 2>/dev/null)" ""
+      PYTHON_INCLUDE  ?= $(shell python3-config --includes)
+      PYTHON_VERSION  ?= $(strip $(shell python3 --version 2>&1))
+      # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag.
+      ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1"
+        PYTHON_LIB      ?= $(shell python3-config --libs --embed --ldflags)
+      else
+        PYTHON_LIB      ?= $(shell python3-config --ldflags)
+      endif
+    endif
+  endif
+endif
+
+ifeq "$(PYTHON_INCLUDE)" ""
+  ifneq "$(shell command -v python 2>/dev/null)" ""
+    ifneq "$(shell command -v python-config 2>/dev/null)" ""
+      PYTHON_INCLUDE  ?= $(shell python-config --includes)
+      PYTHON_LIB      ?= $(shell python-config --ldflags)
+      PYTHON_VERSION  ?= $(strip $(shell python --version 2>&1))
     endif
   endif
 endif
 
-ifneq "$(shell command -v python 2>/dev/null)" ""
-  ifneq "$(shell command -v python-config 2>/dev/null)" ""
-    PYTHON_INCLUDE  ?= $(shell python-config --includes)
-    PYTHON_LIB      ?= $(shell python-config --ldflags)
-    PYTHON_VERSION  ?= $(strip $(shell python --version 2>&1))
+# Old Ubuntu and others dont have python/python3-config so we hardcode 3.7
+ifeq "$(PYTHON_INCLUDE)" ""
+  ifneq "$(shell command -v python3.7 2>/dev/null)" ""
+    ifneq "$(shell command -v python3.7-config 2>/dev/null)" ""
+      PYTHON_INCLUDE  ?= $(shell python3.7-config --includes)
+      PYTHON_LIB      ?= $(shell python3.7-config --ldflags)
+      PYTHON_VERSION  ?= $(strip $(shell python3.7 --version 2>&1))
+    endif
+  endif
+endif
+
+# Old Ubuntu and others dont have python/python2-config so we hardcode 2.7
+ifeq "$(PYTHON_INCLUDE)" ""
+  ifneq "$(shell command -v python2.7 2>/dev/null)" ""
+    ifneq "$(shell command -v python2.7-config 2>/dev/null)" ""
+      PYTHON_INCLUDE  ?= $(shell python2.7-config --includes)
+      PYTHON_LIB      ?= $(shell python2.7-config --ldflags)
+      PYTHON_VERSION  ?= $(strip $(shell python2.7 --version 2>&1))
+    endif
   endif
 endif
 
@@ -333,27 +359,27 @@ document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/
 	$(CC) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
 
 test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES)
-	$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o
+	@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o
 
 test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
-	$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
+	@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
 
 unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
-	$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
+	@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
 	./test/unittests/unit_maybe_alloc
 
 test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES)
-	$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
+	@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
 
 unit_list: test/unittests/unit_list.o
-	$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list  $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
+	@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list  $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
 	./test/unittests/unit_list
 
 test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES)
-	$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o
+	@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o
 
 unit_preallocable: test/unittests/unit_preallocable.o
-	$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
+	@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
 	./test/unittests/unit_preallocable
 
 unit_clean:
@@ -426,7 +452,7 @@ clean:
 	$(MAKE) -C src/third_party/libradamsa/ clean
 	rm -rf qemu_mode/qemu-3.1.1
 ifeq "$(IN_REPO)" "1"
-	$(MAKE) -C unicorn_mode/unicornafl clean || true
+	test -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true
 else
 	rm -rf qemu_mode/qemu-3.1.1.tar.xz
 	rm -rf unicorn_mode/unicornafl
diff --git a/README.md b/README.md
index 9ec7b6e7..222afab7 100644
--- a/README.md
+++ b/README.md
@@ -137,7 +137,7 @@ afl++ has many build options.
 The easiest is to build and install everything:
 
 ```shell
-$ sudo apt install build-essential libtool-bin python3 automake bison libglib2.0-dev libpixman-1-dev clang python-setuptools
+$ sudo apt install build-essential libtool-bin python3 automake bison libglib2.0-dev libpixman-1-dev clang python-setuptools llvm
 $ make distrib
 $ sudo make install
 ```
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 8f584393..71de0984 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -10,6 +10,14 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 
 ### Version ++2.64d (develop):
+  - afl-fuzz:
+     - AFL_MAP_SIZE was not working correctly
+     - better python detection
+  - llvm_mode:
+     - if LLVM 11 is installed the posix shm_open+mmap is used and a fixed
+       address for the shared memory map is used as this increases the
+       fuzzing speed
+     - fixes to LTO mode if instrumented edges > MAP_SIZE
   - qemu_mode:
     - add information on PIE/PIC load addresses for 32 bit
     - better dependency checks
@@ -18,6 +26,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - unicorn_mode:
     - better submodule handling
   - all:
+    - forkserver communication now also used for error reporting
     - fix 32 bit build options
     - make clean now leaves qemu-3.1.1.tar.xz and the unicornafl directory
       intact if in a git/svn checkout - unless "deepclean" is used
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 21bf9fad..41c8f12a 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -123,6 +123,10 @@ Then there are a few specific features that are only available in llvm_mode:
     These are used if several seperated instrumentation are performed which
     are then later combined.
 
+   - AFL_LLVM_MAP_ADDR sets the fixed map address to a different address than
+     the default 0x10000. A value of 0 or empty sets the map address to be
+     dynamic (the original afl way, which is slower)
+   - AFL_LLVM_MAP_DYNAMIC sets the shared memory address to be dynamic
    - AFL_LLVM_LTO_STARTID sets the starting location ID for the instrumentation.
      This defaults to 1
    - AFL_LLVM_LTO_DONTWRITEID prevents that the highest location ID written
diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile
index 3da2e4f6..e81924e0 100644
--- a/gcc_plugin/Makefile
+++ b/gcc_plugin/Makefile
@@ -68,8 +68,7 @@ LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-lrt)
 CFLAGS += $(CFLAGS_ADD)
 LDFLAGS += $(LDFLAGS_ADD)
 
-PROGS        = ../afl-gcc-fast ../afl-gcc-pass.so ../afl-gcc-rt.o
-
+PROGS        = ../afl-gcc-pass.so ../afl-gcc-fast ../afl-gcc-rt.o
 
 all: test_shm test_deps $(PROGS) afl-gcc-fast.8 test_build all_done
 
diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c
index 0e51ee62..164c72c2 100644
--- a/gcc_plugin/afl-gcc-fast.c
+++ b/gcc_plugin/afl-gcc-fast.c
@@ -123,11 +123,17 @@ static void edit_params(u32 argc, char **argv) {
     u8 *alt_cxx = getenv("AFL_CXX");
     cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)AFL_GCC_CXX;
 
-  } else {
+  } else if (!strcmp(name, "afl-gcc-fast")) {
 
     u8 *alt_cc = getenv("AFL_CC");
     cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)AFL_GCC_CC;
 
+  } else {
+
+    fprintf(stderr, "Name of the binary: %s\n", argv[0]);
+    FATAL(
+        "Name of the binary is not a known name, expected afl-(gcc|g++)-fast");
+
   }
 
   char *fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path);
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 428bfa8e..2203cfdf 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -614,11 +614,6 @@ typedef struct afl_state {
 
 } afl_state_t;
 
-/* A global pointer to all instances is needed (for now) for signals to arrive
- */
-
-extern list_t afl_states;
-
 struct custom_mutator {
 
   const char *name;
@@ -800,6 +795,14 @@ struct custom_mutator {
 
 void afl_state_init(afl_state_t *, uint32_t map_size);
 void afl_state_deinit(afl_state_t *);
+
+/* Set stop_soon flag on all childs, kill all childs */
+void afl_states_stop(void);
+/* Set clear_screen flag on all states */
+void afl_states_clear_screen(void);
+/* Sets the skip flag on all states */
+void afl_states_request_skip(void);
+
 void read_afl_environment(afl_state_t *, char **);
 
 /**** Prototypes ****/
diff --git a/include/common.h b/include/common.h
index 70ff0744..4aed9572 100644
--- a/include/common.h
+++ b/include/common.h
@@ -115,7 +115,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms);
 u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms,
                volatile u8 *stop_soon_p);
 
-u32 get_map_size();
+u32 get_map_size(void);
 
 #endif
 
diff --git a/include/config.h b/include/config.h
index f11ac919..c21d775a 100644
--- a/include/config.h
+++ b/include/config.h
@@ -400,14 +400,5 @@
 #endif
 #endif                           /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
 
-/* Extended forkserver option values */
-
-#define FS_OPT_ENABLED 0x8f000001
-#define FS_OPT_MAPSIZE 0x40000000
-#define FS_OPT_SNAPSHOT 0x20000000
-#define FS_OPT_AUTODICT 0x10000000
-#define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1)
-#define FS_OPT_SET_MAPSIZE(x) (x <= 1 || x > 0x1000000 ? 0 : ((x - 1) << 1))
-
 #endif                                                  /* ! _HAVE_CONFIG_H */
 
diff --git a/include/types.h b/include/types.h
index f2a12953..e7ff131d 100644
--- a/include/types.h
+++ b/include/types.h
@@ -30,6 +30,29 @@ typedef uint8_t  u8;
 typedef uint16_t u16;
 typedef uint32_t u32;
 
+/* Extended forkserver option values */
+
+/* Reporting errors */
+#define FS_OPT_ERROR 0xf800008f
+#define FS_OPT_GET_ERROR(x) ((x & 0x00ffff00) >> 8)
+#define FS_OPT_SET_ERROR(x) ((x & 0x0000ffff) << 8)
+#define FS_ERROR_MAP_SIZE 1
+#define FS_ERROR_MAP_ADDR 2
+#define FS_ERROR_SHM_OPEN 4
+#define FS_ERROR_SHMAT 8
+#define FS_ERROR_MMAP 16
+
+/* Reporting options */
+#define FS_OPT_ENABLED 0x8f000001
+#define FS_OPT_MAPSIZE 0x40000000
+#define FS_OPT_SNAPSHOT 0x20000000
+#define FS_OPT_AUTODICT 0x10000000
+// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22
+#define FS_OPT_MAX_MAPSIZE ((0x00fffffe >> 1) + 1)
+#define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1)
+#define FS_OPT_SET_MAPSIZE(x) \
+  (x <= 1 || x > FS_OPT_MAX_MAPSIZE ? 0 : ((x - 1) << 1))
+
 /*
 
    Ugh. There is an unintended compiler / glibc #include glitch caused by
@@ -108,7 +131,7 @@ typedef int64_t s64;
   })
 
 #ifdef AFL_LLVM_PASS
-#if defined(__linux__)
+#if defined(__linux__) || !defined(__ANDROID__)
 #define AFL_SR(s) (srandom(s))
 #define AFL_R(x) (random() % (x))
 #else
@@ -116,7 +139,7 @@ typedef int64_t s64;
 #define AFL_R(x) (arc4random_uniform(x))
 #endif
 #else
-#if defined(__linux__)
+#if defined(__linux__) || !defined(__ANDROID__)
 #define SR(s) (srandom(s))
 #define R(x) (random() % (x))
 #else
diff --git a/libdislocator/Makefile b/libdislocator/Makefile
index 37fd4fd6..f9c4cb65 100644
--- a/libdislocator/Makefile
+++ b/libdislocator/Makefile
@@ -39,5 +39,5 @@ clean:
 install: all
 	install -m 755 -d $${DESTDIR}$(HELPER_PATH)
 	install -m 755 ../libdislocator.so $${DESTDIR}$(HELPER_PATH)
-	install -m 644 README.dislocator.md $${DESTDIR}$(HELPER_PATH)
+	install -m 644 -T README.md $${DESTDIR}$(HELPER_PATH)/README.dislocator.md
 
diff --git a/libdislocator/libdislocator.so.c b/libdislocator/libdislocator.so.c
index 8098de91..73ddc292 100644
--- a/libdislocator/libdislocator.so.c
+++ b/libdislocator/libdislocator.so.c
@@ -37,7 +37,7 @@
 #include <sys/param.h>
 #endif
 
-#ifdef __linux__
+#if defined(__linux__) && !defined(__ANDROID__)
 #include <unistd.h>
 #include <sys/syscall.h>
 #ifdef __NR_getrandom
@@ -466,11 +466,13 @@ void *reallocarray(void *ptr, size_t elem_len, size_t elem_cnt) {
 
 #if !defined(__ANDROID__)
 size_t malloc_usable_size(void *ptr) {
+
 #else
 size_t malloc_usable_size(const void *ptr) {
+
 #endif
 
-   return ptr ? PTR_L(ptr) : 0;
+  return ptr ? PTR_L(ptr) : 0;
 
 }
 
@@ -498,3 +500,4 @@ __attribute__((constructor)) void __dislocator_init(void) {
   align_allocations = !!getenv("AFL_ALIGNED_ALLOC");
 
 }
+
diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile
index 67c31f14..69b0875e 100644
--- a/llvm_mode/GNUmakefile
+++ b/llvm_mode/GNUmakefile
@@ -1,4 +1,3 @@
-#
 # american fuzzy lop++ - LLVM instrumentation
 # -----------------------------------------
 #
@@ -68,6 +67,7 @@ endif
 ifeq "$(LLVM_MAJOR)" "11"
   $(info [+] llvm_mode detected llvm 11, enabling afl-clang-lto LTO implementation)
   LLVM_LTO = 1
+  TEST_MMAP = 1
 endif
 
 ifeq "$(LLVM_LTO)" "0"
@@ -193,13 +193,13 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
 else
         SHMAT_OK=0
         CFLAGS+=-DUSEMMAP=1
-        LDFLAGS += -lrt
+        LDFLAGS += -Wno-deprecated-declarations
 endif
 
 ifeq "$(TEST_MMAP)" "1"
         SHMAT_OK=0
         CFLAGS+=-DUSEMMAP=1
-        LDFLAGS += -lrt
+        LDFLAGS += -Wno-deprecated-declarations
 endif
 
   PROGS      = ../afl-clang-fast ../afl-llvm-pass.so ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so
@@ -270,42 +270,45 @@ ifeq "$(LLVM_LTO)" "1"
 endif
 endif
 
-../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps
-	-$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL)
+afl-llvm-common.o: afl-llvm-common.cc afl-llvm-common.h
+	$(CXX) $(CFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@ 
+
+../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc afl-llvm-common.o | test_deps
+	-$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
 
-../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps
+../afl-llvm-pass.so: afl-llvm-pass.so.cc afl-llvm-common.o | test_deps
 ifeq "$(LLVM_MIN_4_0_1)" "0"
 	$(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER))
 endif
-	$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL)
+	$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
 
-../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc
+../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o
 ifeq "$(LLVM_LTO)" "1"
-	$(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL)
+	$(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
 endif
 
-../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc
+../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc afl-llvm-common.o
 ifeq "$(LLVM_LTO)" "1"
-	$(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL)
+	$(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
 	$(CC) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto.o
 	@$(CC) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
 	@$(CC) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
 endif
 
 # laf
-../split-switches-pass.so:	split-switches-pass.so.cc | test_deps
-	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
-../compare-transform-pass.so:	compare-transform-pass.so.cc | test_deps
-	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
-../split-compares-pass.so:	split-compares-pass.so.cc | test_deps
-	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+../split-switches-pass.so:	split-switches-pass.so.cc afl-llvm-common.o | test_deps
+	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
+../compare-transform-pass.so:	compare-transform-pass.so.cc afl-llvm-common.o | test_deps
+	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
+../split-compares-pass.so:	split-compares-pass.so.cc afl-llvm-common.o | test_deps
+	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
 # /laf
 
-../cmplog-routines-pass.so:	cmplog-routines-pass.cc | test_deps
-	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+../cmplog-routines-pass.so:	cmplog-routines-pass.cc afl-llvm-common.o | test_deps
+	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
 
-../cmplog-instructions-pass.so:	cmplog-instructions-pass.cc | test_deps
-	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+../cmplog-instructions-pass.so:	cmplog-instructions-pass.cc afl-llvm-common.o | test_deps
+	$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
 
 ../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
 	$(CC) $(CFLAGS) -Wno-unused-result -fPIC -c $< -o $@
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc
index 8b23942c..98263ef1 100644
--- a/llvm_mode/LLVMInsTrim.so.cc
+++ b/llvm_mode/LLVMInsTrim.so.cc
@@ -40,6 +40,7 @@ typedef long double max_align_t;
 #include "debug.h"
 
 #include "MarkNodes.h"
+#include "afl-llvm-common.h"
 
 using namespace llvm;
 
@@ -53,9 +54,8 @@ namespace {
 struct InsTrim : public ModulePass {
 
  protected:
-  std::list<std::string> myWhitelist;
-  uint32_t               function_minimum_size = 1;
-  uint32_t               debug = 0;
+  uint32_t function_minimum_size = 1;
+  uint32_t debug = 0;
 
  private:
   std::mt19937 generator;
@@ -69,24 +69,10 @@ struct InsTrim : public ModulePass {
 
  public:
   static char ID;
-  InsTrim() : ModulePass(ID), generator(0) {
-
-    char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
-    if (instWhiteListFilename) {
-
-      std::string   line;
-      std::ifstream fileStream;
-      fileStream.open(instWhiteListFilename);
-      if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
-      getline(fileStream, line);
-      while (fileStream) {
 
-        myWhitelist.push_back(line);
-        getline(fileStream, line);
+  InsTrim() : ModulePass(ID), generator(0) {
 
-      }
-
-    }
+    initWhitelist();
 
   }
 
@@ -107,28 +93,6 @@ struct InsTrim : public ModulePass {
 
   }
 
-  // ripped from aflgo
-  static bool isBlacklisted(const Function *F) {
-
-    static const char *Blacklist[] = {
-
-        "asan.",
-        "llvm.",
-        "sancov.",
-        "__ubsan_handle_",
-
-    };
-
-    for (auto const &BlacklistFunc : Blacklist) {
-
-      if (F->getName().startswith(BlacklistFunc)) { return true; }
-
-    }
-
-    return false;
-
-  }
-
   bool runOnModule(Module &M) override {
 
     char be_quiet = 0;
@@ -194,138 +158,11 @@ struct InsTrim : public ModulePass {
 
       }
 
+      if (!isInWhitelist(&F)) continue;
+
       // if the function below our minimum size skip it (1 or 2)
       if (F.size() < function_minimum_size) { continue; }
 
-      if (!myWhitelist.empty()) {
-
-        bool         instrumentBlock = false;
-        DebugLoc     Loc;
-        StringRef    instFilename;
-        unsigned int instLine = 0;
-
-#if LLVM_VERSION_MAJOR >= 4 || \
-    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
-        for (auto &BB : F) {
-
-          BasicBlock::iterator IP = BB.getFirstInsertionPt();
-          IRBuilder<>          IRB(&(*IP));
-          if (!Loc) Loc = IP->getDebugLoc();
-
-        }
-
-        if (Loc) {
-
-          DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
-
-          instLine = cDILoc->getLine();
-          instFilename = cDILoc->getFilename();
-
-          if (instFilename.str().empty()) {
-
-            /* If the original location is empty, try using the inlined location
-             */
-            DILocation *oDILoc = cDILoc->getInlinedAt();
-            if (oDILoc) {
-
-              instFilename = oDILoc->getFilename();
-              instLine = oDILoc->getLine();
-
-            }
-
-          }
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#else
-        for (auto &BB : F) {
-
-          BasicBlock::iterator IP = BB.getFirstInsertionPt();
-          IRBuilder<>          IRB(&(*IP));
-          if (Loc.isUnknown()) Loc = IP->getDebugLoc();
-
-        }
-
-        if (!Loc.isUnknown()) {
-
-          DILocation cDILoc(Loc.getAsMDNode(C));
-
-          instLine = cDILoc.getLineNumber();
-          instFilename = cDILoc.getFilename();
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#endif
-        /* Either we couldn't figure out our location or the location is
-         * not whitelisted, so we skip instrumentation. */
-        if (!instrumentBlock) {
-
-          if (!be_quiet) {
-
-            if (!instFilename.str().empty())
-              SAYF(cYEL "[!] " cBRI
-                        "Not in whitelist, skipping %s line %u...\n",
-                   instFilename.str().c_str(), instLine);
-            else
-              SAYF(cYEL "[!] " cBRI
-                        "No filename information found, skipping it");
-
-          }
-
-          continue;
-
-        }
-
-      }
-
-      if (isBlacklisted(&F)) continue;
-
       std::unordered_set<BasicBlock *> MS;
       if (!MarkSetOpt) {
 
diff --git a/llvm_mode/NOTES b/llvm_mode/NOTES
deleted file mode 100644
index 9aee7f46..00000000
--- a/llvm_mode/NOTES
+++ /dev/null
@@ -1,88 +0,0 @@
-
-markNodes
- ->
-
-whitelist:
-  set meta information/context to functions? ask llvm-dev
-    setAttribute/hasAttribute?
-
-afl-ld:
-  handle(=instrument) .a archives on the cmdline
-
-afl-pass-lto-instrument.so:
-  either a or b:
-  a) use instrim
-  b) start in main() or _init() and first otherwise (warn!)
-     keep list of done functions
-     final: go through function list and instrument those missing
-
-
-
----------------------------
-
-
-
-for (auto &module : Ctx.getModules()) {
-  auto &functionList = module->getModule()->getFunctionList();
-  for (auto &function : functionList) {
-    for (auto &bb : function) {
-      for (auto &instruction : bb) {
-        if (CallInst *callInst = dyn_cast<CallInst>(&instruction)) {
-          if (Function *calledFunction = callInst->getCalledFunction()) {
-            if (calledFunction->getName().startswith("llvm.dbg.declare")) {
-
-
-for (auto &U : F.getUsers()) { <- unbekannt
-  if (auto CS = CallSite(U)) {
-    if (CS->getCalledFunction() == F)
-
-getCalledValue()->stripPointerCasts()
- -> for indirect calls
-
-
-CallGraph(M)
-
-
-
-#include "llvm/IR/CallSite.h"
-
-unsigned int indirect_call_cnt = 0;
- 
-  printf("Function: %s\n", F.getName().str().c_str());
-  int cnt=0;
-  for (auto *U : F.users()) {
-//    auto *I = dyn_cast<Instruction>(U);
-//    if (I) {
-//      if (cast<CallInst>(I)->getCalledFunction()->getName() == F.getName()) {
-//       printf("DIRECT CALL %s->%s->%s\n", cast<CallInst>(I)->getParent()->getParent()->getName().str().c_str(), cast<CallInst>(I)->getCalledFunction()->getName().str().c_str(), F.getName().str().c_str());
-//     }
-printf("Callsite #%d\n", ++cnt);
-    CallSite CS(U);
-    auto *I = CS.getInstruction();
-    if (I) {
-      Value *called = CS.getCalledValue()->stripPointerCasts();
-      Function* f = dyn_cast<Function>(called);
-      if (f->getName().size() > 0) {
-        printf("test %s->%s->%s\n", cast<CallInst>(I)->getParent()->getParent()->getName().str().c_str(), f->getName().str().c_str(), F.getName().str().c_str());
-        if (f->getName() == F.getName()) {
-          printf("CALL %s->%s->%s\n", cast<CallInst>(I)->getParent()->getParent()->getName().str().c_str(), f->getName().str().c_str(), F.getName().str().c_str());
-        }
-      } else
-        printf("FOO  %s->...->%s\n", cast<CallInst>(I)->getParent()->getParent()->getName().str().c_str(), F.getName().str().c_str());
-      if (cast<CallInst>(I)->getCalledFunction()->getName() == F.getName()) {
-        printf("DIRECT %s->%s->%s\n", cast<CallInst>(I)->getParent()->getParent()->getName().str().c_str(), cast<CallInst>(I)->getCalledFunction()->getName().str().c_str(), F.getName().str().c_str());
-      }
-    } else {
-      printf("WE MISSED SOMETHING HERE!!\n");
-      indirect_call_cnt++;
-    }
-  }
-
-oder:
-  for (auto *U : F.users()) {
-    if (auto CS = CallSite(U->getUser())) {
-      if (CS->isCallee(&U)) {
-        // foo
-      }
-    }
-  }
diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md
index 9af9ffff..bb66b5e7 100644
--- a/llvm_mode/README.lto.md
+++ b/llvm_mode/README.lto.md
@@ -95,6 +95,17 @@ target binary based on string compare and memory compare functions.
 afl-fuzz will automatically get these transmitted when starting to fuzz.
 This improves coverage on a lot of targets.
 
+## Fixed memory map
+
+To speed up fuzzing, the shared memory map is hard set to a specific address,
+by default 0x10000. In most cases this will work without any problems.
+On unusual operating systems/processors/kernels or weird libraries this might
+fail so to change the fixed address at compile time set
+AFL_LLVM_MAP_ADDR with a better value (a value of 0 or empty sets the map address
+to be dynamic - the original afl way, which is slower).
+AFL_LLVM_MAP_DYNAMIC can be set so the shared memory address is dynamic (which
+is safer but also slower).
+
 ## Potential issues
 
 ### compiling libraries fails
@@ -110,12 +121,22 @@ Solution:
 ```
 AR=llvm-ar RANLIB=llvm-ranlib CC=afl-clang-lto CXX=afl-clang-lto++ ./configure --disable-shared
 ```
-and on some target you have to to AR=/RANLIB= even for make as the configure script does not save it ...
+and on some target you have to to AR=/RANLIB= even for make as the configure script does not save it.
+Other targets ignore environment variables and need the parameters set via
+`./configure --cc=... --cxx= --ranlib= ...` etc. (I am looking at you ffmpeg!).
 
 ### compiling programs still fail
 
 afl-clang-lto is still work in progress.
-Please report issues at:
+
+Known issues:
+  * Anything that llvm11 cannot compile, afl-clang-lto can not compile either - obviously
+  * Anything that does not compile with LTO, afl-clang-lto can not compile either - obviously
+
+Hence if building a target with afl-clang-lto fails try to build it with llvm11
+and LTO enabled (`CC=clang-11` `CXX=clang++-11` `CFLAGS=-flto=full` and
+`CXXFLAGS=-flto=full`).
+If this succeeeds then there is an issue with afl-clang-lto. Please report at
 [https://github.com/AFLplusplus/AFLplusplus/issues/226](https://github.com/AFLplusplus/AFLplusplus/issues/226)
 
 ## Upcoming Work
diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc
new file mode 100644
index 00000000..9b7a444a
--- /dev/null
+++ b/llvm_mode/afl-llvm-common.cc
@@ -0,0 +1,202 @@
+#define AFL_LLVM_PASS
+
+#include "config.h"
+#include "debug.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <list>
+#include <string>
+#include <fstream>
+
+#include "afl-llvm-common.h"
+
+using namespace llvm;
+
+static std::list<std::string> myWhitelist;
+
+char *getBBName(const llvm::BasicBlock *BB) {
+
+  static char *name;
+
+  if (!BB->getName().empty()) {
+
+    name = strdup(BB->getName().str().c_str());
+    return name;
+
+  }
+
+  std::string        Str;
+  raw_string_ostream OS(Str);
+
+  BB->printAsOperand(OS, false);
+  name = strdup(OS.str().c_str());
+  return name;
+
+}
+
+/* Function that we never instrument or analyze */
+/* Note: this blacklist check is also called in isInWhitelist() */
+bool isBlacklisted(const llvm::Function *F) {
+
+  static const char *Blacklist[] = {
+
+      "asan.", "llvm.",      "sancov.", "__ubsan_handle_", "ign.", "__afl_",
+      "_fini", "__libc_csu", "__asan",  "__msan",          "msan."
+
+  };
+
+  for (auto const &BlacklistFunc : Blacklist) {
+
+    if (F->getName().startswith(BlacklistFunc)) { return true; }
+
+  }
+
+  return false;
+
+}
+
+void initWhitelist() {
+
+  char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
+  if (instWhiteListFilename) {
+
+    std::string   line;
+    std::ifstream fileStream;
+    fileStream.open(instWhiteListFilename);
+    if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
+    getline(fileStream, line);
+    while (fileStream) {
+
+      myWhitelist.push_back(line);
+      getline(fileStream, line);
+
+    }
+
+  }
+
+}
+
+bool isInWhitelist(llvm::Function *F) {
+
+  // is this a function with code? If it is external we dont instrument it
+  // anyway and cant be in the whitelist. Or if it is blacklisted.
+  if (!F->size() || isBlacklisted(F)) return false;
+
+  // if we do not have a whitelist return true
+  if (myWhitelist.empty()) return true;
+
+  // let's try to get the filename for the function
+  auto                 bb = &F->getEntryBlock();
+  BasicBlock::iterator IP = bb->getFirstInsertionPt();
+  IRBuilder<>          IRB(&(*IP));
+  DebugLoc             Loc = IP->getDebugLoc();
+
+#if LLVM_VERSION_MAJOR >= 4 || \
+    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
+  if (Loc) {
+
+    DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
+
+    unsigned int instLine = cDILoc->getLine();
+    StringRef    instFilename = cDILoc->getFilename();
+
+    if (instFilename.str().empty()) {
+
+      /* If the original location is empty, try using the inlined location
+       */
+      DILocation *oDILoc = cDILoc->getInlinedAt();
+      if (oDILoc) {
+
+        instFilename = oDILoc->getFilename();
+        instLine = oDILoc->getLine();
+
+      }
+
+    }
+
+    (void)instLine;
+
+    /* Continue only if we know where we actually are */
+    if (!instFilename.str().empty()) {
+
+      for (std::list<std::string>::iterator it = myWhitelist.begin();
+           it != myWhitelist.end(); ++it) {
+
+        /* We don't check for filename equality here because
+         * filenames might actually be full paths. Instead we
+         * check that the actual filename ends in the filename
+         * specified in the list. */
+        if (instFilename.str().length() >= it->length()) {
+
+          if (instFilename.str().compare(
+                  instFilename.str().length() - it->length(), it->length(),
+                  *it) == 0) {
+
+            return true;
+
+          }
+
+        }
+
+      }
+
+    }
+
+  }
+
+#else
+  if (!Loc.isUnknown()) {
+
+    DILocation cDILoc(Loc.getAsMDNode(C));
+
+    unsigned int instLine = cDILoc.getLineNumber();
+    StringRef    instFilename = cDILoc.getFilename();
+
+    (void)instLine;
+    /* Continue only if we know where we actually are */
+    if (!instFilename.str().empty()) {
+
+      for (std::list<std::string>::iterator it = myWhitelist.begin();
+           it != myWhitelist.end(); ++it) {
+
+        /* We don't check for filename equality here because
+         * filenames might actually be full paths. Instead we
+         * check that the actual filename ends in the filename
+         * specified in the list. */
+        if (instFilename.str().length() >= it->length()) {
+
+          if (instFilename.str().compare(
+                  instFilename.str().length() - it->length(), it->length(),
+                  *it) == 0) {
+
+            return true;
+
+          }
+
+        }
+
+      }
+
+    }
+
+  }
+
+#endif
+  else {
+
+    // we could not find out the location. in this case we say it is not
+    // in the whitelist
+
+    return false;
+
+  }
+
+  //
+  return false;
+
+}
+
diff --git a/llvm_mode/afl-llvm-common.h b/llvm_mode/afl-llvm-common.h
new file mode 100644
index 00000000..5b5e08d0
--- /dev/null
+++ b/llvm_mode/afl-llvm-common.h
@@ -0,0 +1,41 @@
+#ifndef __AFLLLVMCOMMON_H
+#define __AFLLLVMCOMMON_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <list>
+#include <string>
+#include <fstream>
+#include <sys/time.h>
+
+#include "llvm/Config/llvm-config.h"
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5
+typedef long double max_align_t;
+#endif
+
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+
+#if LLVM_VERSION_MAJOR > 3 || \
+    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/CFG.h"
+#else
+#include "llvm/DebugInfo.h"
+#include "llvm/Support/CFG.h"
+#endif
+
+char *getBBName(const llvm::BasicBlock *BB);
+bool  isBlacklisted(const llvm::Function *F);
+void  initWhitelist();
+bool  isInWhitelist(llvm::Function *F);
+
+#endif
+
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index ece3201f..118ada52 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 
 #include <list>
 #include <string>
@@ -56,6 +57,7 @@
 #include "llvm/Pass.h"
 
 #include <set>
+#include "afl-llvm-common.h"
 
 using namespace llvm;
 
@@ -103,57 +105,12 @@ class AFLLTOPass : public ModulePass {
 
   }
 
-  // Get the internal llvm name of a basic block
-  // This is an ugly debug support so it is commented out :-)
-  /*
-    static char *getBBName(const BasicBlock *BB) {
-
-      static char *name;
-
-      if (!BB->getName().empty()) {
-
-        name = strdup(BB->getName().str().c_str());
-        return name;
-
-      }
-
-      std::string        Str;
-      raw_string_ostream OS(Str);
-
-      BB->printAsOperand(OS, false);
-
-      name = strdup(OS.str().c_str());
-
-      return name;
-
-    }
-
-  */
-
-  static bool isBlacklisted(const Function *F) {
-
-    static const char *Blacklist[] = {
-
-        "asan.",  "llvm.", "sancov.",   "__ubsan_handle_", "ign.",
-        "__afl_", "_fini", "__libc_csu"
-
-    };
-
-    for (auto const &BlacklistFunc : Blacklist) {
-
-      if (F->getName().startswith(BlacklistFunc)) { return true; }
-
-    }
-
-    return false;
-
-  }
-
   bool runOnModule(Module &M) override;
 
  protected:
   int      afl_global_id = 1, debug = 0, autodictionary = 0;
   uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0, total_instr = 0;
+  uint64_t map_addr = 0x10000;
 
 };
 
@@ -165,9 +122,11 @@ bool AFLLTOPass::runOnModule(Module &M) {
   std::vector<std::string>         dictionary;
   std::vector<CallInst *>          calls;
   DenseMap<Value *, std::string *> valueMap;
+  char *                           ptr;
 
   IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
   IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
+  IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
 
   if (getenv("AFL_DEBUG")) debug = 1;
 
@@ -186,12 +145,63 @@ bool AFLLTOPass::runOnModule(Module &M) {
       getenv("AFL_LLVM_LTO_AUTODICTIONARY"))
     autodictionary = 1;
 
+  if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
+
+  if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
+
+    uint64_t val;
+    if (!*ptr || !strcmp(ptr, "0") || !strcmp(ptr, "0x0")) {
+
+      map_addr = 0;
+
+    } else if (map_addr == 0) {
+
+      FATAL(
+          "AFL_LLVM_MAP_ADDR and AFL_LLVM_MAP_DYNAMIC cannot be used together");
+
+    } else if (strncmp(ptr, "0x", 2) != 0) {
+
+      map_addr = 0x10000;  // the default
+
+    } else {
+
+      val = strtoull(ptr, NULL, 16);
+      if (val < 0x100 || val > 0xffffffff00000000) {
+
+        FATAL(
+            "AFL_LLVM_MAP_ADDR must be a value between 0x100 and "
+            "0xffffffff00000000");
+
+      }
+
+      map_addr = val;
+
+    }
+
+  }
+
+  if (debug) { fprintf(stderr, "map address is %lu\n", map_addr); }
+
   /* Get globals for the SHM region and the previous location. Note that
      __afl_prev_loc is thread-local. */
 
-  GlobalVariable *AFLMapPtr =
-      new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
-                         GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
+  GlobalVariable *AFLMapPtr = NULL;
+  ;
+  Value *MapPtrFixed = NULL;
+
+  if (!map_addr) {
+
+    AFLMapPtr =
+        new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
+                           GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
+
+  } else {
+
+    ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr);
+    MapPtrFixed =
+        ConstantExpr::getIntToPtr(MapAddr, PointerType::getUnqual(Int8Ty));
+
+  }
 
   ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
   ConstantInt *One = ConstantInt::get(Int8Ty, 1);
@@ -202,6 +212,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   for (auto &F : M) {
 
+    // fprintf(stderr, "DEBUG: Function %s\n", F.getName().str().c_str());
+
     if (F.size() < 2) continue;
     if (isBlacklisted(&F)) continue;
 
@@ -579,10 +591,20 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
           /* Load SHM pointer */
 
-          LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
-          MapPtr->setMetadata(M.getMDKindID("nosanitize"),
-                              MDNode::get(C, None));
-          Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
+          Value *MapPtrIdx;
+
+          if (map_addr) {
+
+            MapPtrIdx = IRB.CreateGEP(MapPtrFixed, CurLoc);
+
+          } else {
+
+            LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+            MapPtr->setMetadata(M.getMDKindID("nosanitize"),
+                                MDNode::get(C, None));
+            MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
+
+          }
 
           /* Update bitmap */
 
@@ -612,7 +634,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   // save highest location ID to global variable
   // do this after each function to fail faster
-  if (!be_quiet && afl_global_id > MAP_SIZE) {
+  if (!be_quiet && afl_global_id > MAP_SIZE &&
+      afl_global_id > FS_OPT_MAX_MAPSIZE) {
 
     uint32_t pow2map = 1, map = afl_global_id;
     while ((map = map >> 1))
@@ -627,7 +650,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   }
 
-  if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL || dictionary.size()) {
+  if (!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr) {
 
     // yes we could create our own function, insert it into ctors ...
     // but this would be a pain in the butt ... so we use afl-llvm-rt-lto.o
@@ -656,24 +679,31 @@ bool AFLLTOPass::runOnModule(Module &M) {
     BasicBlock::iterator IP = bb->getFirstInsertionPt();
     IRBuilder<>          IRB(&(*IP));
 
+    if (map_addr) {
+
+      GlobalVariable *AFLMapAddrFixed = new GlobalVariable(
+          M, Int64Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr",
+          0, GlobalVariable::GeneralDynamicTLSModel, 0, false);
+      ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr);
+      StoreInst *  StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed);
+      StoreMapAddr->setMetadata(M.getMDKindID("nosanitize"),
+                                MDNode::get(C, None));
+
+    }
+
     if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL) {
 
       uint32_t write_loc = afl_global_id;
 
       if (afl_global_id % 8) write_loc = (((afl_global_id + 8) >> 3) << 3);
 
-      if (write_loc <= MAP_SIZE && write_loc <= 0x800000) {
-
-        GlobalVariable *AFLFinalLoc = new GlobalVariable(
-            M, Int32Ty, true, GlobalValue::ExternalLinkage, 0,
-            "__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0,
-            false);
-        ConstantInt *const_loc = ConstantInt::get(Int32Ty, write_loc);
-        StoreInst *  StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
-        StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"),
-                                   MDNode::get(C, None));
-
-      }
+      GlobalVariable *AFLFinalLoc = new GlobalVariable(
+          M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc",
+          0, GlobalVariable::GeneralDynamicTLSModel, 0, false);
+      ConstantInt *const_loc = ConstantInt::get(Int32Ty, write_loc);
+      StoreInst *  StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
+      StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"),
+                                 MDNode::get(C, None));
 
     }
 
diff --git a/llvm_mode/afl-llvm-lto-whitelist.so.cc b/llvm_mode/afl-llvm-lto-whitelist.so.cc
index 48df76c3..5e157472 100644
--- a/llvm_mode/afl-llvm-lto-whitelist.so.cc
+++ b/llvm_mode/afl-llvm-lto-whitelist.so.cc
@@ -46,6 +46,8 @@
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/IR/CFG.h"
 
+#include "afl-llvm-common.h"
+
 using namespace llvm;
 
 namespace {
@@ -86,25 +88,6 @@ class AFLwhitelist : public ModulePass {
 
   }
 
-  // ripped from aflgo
-  static bool isBlacklisted(const Function *F) {
-
-    static const SmallVector<std::string, 5> Blacklist = {
-
-        "asan.", "llvm.", "sancov.", "__ubsan_handle_", "ign."
-
-    };
-
-    for (auto const &BlacklistFunc : Blacklist) {
-
-      if (F->getName().startswith(BlacklistFunc)) { return true; }
-
-    }
-
-    return false;
-
-  }
-
   bool runOnModule(Module &M) override;
 
   // StringRef getPassName() const override {
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index 71abcd05..9314c3d1 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -61,6 +61,7 @@ typedef long double max_align_t;
 #include "llvm/Support/CFG.h"
 #endif
 
+#include "afl-llvm-common.h"
 #include "llvm-ngram-coverage.h"
 
 using namespace llvm;
@@ -73,60 +74,17 @@ class AFLCoverage : public ModulePass {
   static char ID;
   AFLCoverage() : ModulePass(ID) {
 
-    char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
-    if (instWhiteListFilename) {
-
-      std::string   line;
-      std::ifstream fileStream;
-      fileStream.open(instWhiteListFilename);
-      if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
-      getline(fileStream, line);
-      while (fileStream) {
-
-        myWhitelist.push_back(line);
-        getline(fileStream, line);
-
-      }
-
-    }
-
-  }
-
-  // ripped from aflgo
-  static bool isBlacklisted(const Function *F) {
-
-    static const char *Blacklist[] = {
-
-        "asan.",
-        "llvm.",
-        "sancov.",
-        "__ubsan_handle_",
-
-    };
-
-    for (auto const &BlacklistFunc : Blacklist) {
-
-      if (F->getName().startswith(BlacklistFunc)) { return true; }
-
-    }
-
-    return false;
+    initWhitelist();
 
   }
 
   bool runOnModule(Module &M) override;
 
-  // StringRef getPassName() const override {
-
-  //  return "American Fuzzy Lop Instrumentation";
-  // }
-
  protected:
-  std::list<std::string> myWhitelist;
-  uint32_t               ngram_size = 0;
-  uint32_t               debug = 0;
-  uint32_t               map_size = MAP_SIZE;
-  char *                 ctx_str = NULL;
+  uint32_t ngram_size = 0;
+  uint32_t debug = 0;
+  uint32_t map_size = MAP_SIZE;
+  char *   ctx_str = NULL;
 
 };
 
@@ -336,9 +294,7 @@ bool AFLCoverage::runOnModule(Module &M) {
       fprintf(stderr, "FUNCTION: %s (%zu)\n", F.getName().str().c_str(),
               F.size());
 
-    if (isBlacklisted(&F)) continue;
-
-    // AllocaInst *CallingContext = nullptr;
+    if (!isInWhitelist(&F)) continue;
 
     if (ctx_str && F.size() > 1) {  // Context sensitive coverage
       // load the context ID of the previous function and write to to a local
@@ -393,115 +349,6 @@ bool AFLCoverage::runOnModule(Module &M) {
       BasicBlock::iterator IP = BB.getFirstInsertionPt();
       IRBuilder<>          IRB(&(*IP));
 
-      if (!myWhitelist.empty()) {
-
-        bool instrumentBlock = false;
-
-        /* Get the current location using debug information.
-         * For now, just instrument the block if we are not able
-         * to determine our location. */
-        DebugLoc Loc = IP->getDebugLoc();
-#if LLVM_VERSION_MAJOR >= 4 || \
-    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
-        if (Loc) {
-
-          DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
-
-          unsigned int instLine = cDILoc->getLine();
-          StringRef    instFilename = cDILoc->getFilename();
-
-          if (instFilename.str().empty()) {
-
-            /* If the original location is empty, try using the inlined location
-             */
-            DILocation *oDILoc = cDILoc->getInlinedAt();
-            if (oDILoc) {
-
-              instFilename = oDILoc->getFilename();
-              instLine = oDILoc->getLine();
-
-            }
-
-          }
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#else
-        if (!Loc.isUnknown()) {
-
-          DILocation cDILoc(Loc.getAsMDNode(C));
-
-          unsigned int instLine = cDILoc.getLineNumber();
-          StringRef    instFilename = cDILoc.getFilename();
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#endif
-
-        /* Either we couldn't figure out our location or the location is
-         * not whitelisted, so we skip instrumentation. */
-        if (!instrumentBlock) continue;
-
-      }
-
       // in CTX mode we have to restore the original context for the caller -
       // she might be calling other functions which need the correct CTX
       if (ctx_str && has_calls) {
@@ -630,54 +477,11 @@ bool AFLCoverage::runOnModule(Module &M) {
          * Counter + 1 -> {Counter, OverflowFlag}
          * Counter + OverflowFlag -> Counter
          */
-        /*       // we keep the old solutions just in case
-                 // Solution #1
-                 if (neverZero_counters_str[0] == '1') {
-
-                   CallInst *AddOv =
-           IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter,
-           ConstantInt::get(Int8Ty, 1));
-                   AddOv->setMetadata(M.getMDKindID("nosanitize"),
-           MDNode::get(C, None)); Value *SumWithOverflowBit = AddOv; Incr =
-           IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0),  // sum
-                                        IRB.CreateZExt( // convert from one bit
-           type to 8 bits type IRB.CreateExtractValue(SumWithOverflowBit, 1), //
-           overflow Int8Ty));
-                  // Solution #2
-
-                  } else if (neverZero_counters_str[0] == '2') {
-
-                     auto cf = IRB.CreateICmpEQ(Counter,
-           ConstantInt::get(Int8Ty, 255)); Value *HowMuch =
-           IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf); Incr =
-           IRB.CreateAdd(Counter, HowMuch);
-                  // Solution #3
-
-                  } else if (neverZero_counters_str[0] == '3') {
-
-        */
-        // this is the solution we choose because llvm9 should do the right
-        // thing here
+
         auto cf = IRB.CreateICmpEQ(Incr, Zero);
         auto carry = IRB.CreateZExt(cf, Int8Ty);
         Incr = IRB.CreateAdd(Incr, carry);
-/*
-         // Solution #4
-
-         } else if (neverZero_counters_str[0] == '4') {
-
-            auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
-            auto carry = IRB.CreateZExt(cf, Int8Ty);
-            Incr = IRB.CreateAdd(Incr, carry);
-
-         } else {
-
-            fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s
-   (valid is 1-4)\n", neverZero_counters_str); exit(-1);
-
-         }
 
-*/
 #if LLVM_VERSION_MAJOR < 9
 
       }
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index f286e66a..8867ae36 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -52,6 +52,10 @@
 
 #define CONST_PRIO 5
 
+#ifndef MAP_FIXED_NOREPLACE
+#define MAP_FIXED_NOREPLACE MAP_FIXED
+#endif
+
 #include <sys/mman.h>
 #include <fcntl.h>
 
@@ -69,12 +73,16 @@ u32        __afl_final_loc;
 u32        __afl_prev_ctx;
 u32        __afl_cmp_counter;
 u32        __afl_dictionary_len;
+u32        __afl_map_size = MAP_SIZE;
+u64        __afl_map_addr;
 #else
 __thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX];
 __thread u32        __afl_final_loc;
 __thread u32        __afl_prev_ctx;
 __thread u32        __afl_cmp_counter;
 __thread u32        __afl_dictionary_len;
+__thread u32        __afl_map_size = MAP_SIZE;
+__thread u64        __afl_map_addr;
 #endif
 
 struct cmp_map *__afl_cmp_map;
@@ -83,44 +91,113 @@ struct cmp_map *__afl_cmp_map;
 
 static u8 is_persistent;
 
+/* Error reporting to forkserver controller */
+
+void send_forkserver_error(int error) {
+
+  u32 status;
+  if (!error || error > 0xffff) return;
+  status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error));
+  if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return;
+
+}
+
 /* SHM setup. */
 
 static void __afl_map_shm(void) {
 
-  u8 *id_str = getenv(SHM_ENV_VAR);
+  char *id_str = getenv(SHM_ENV_VAR);
+
+  if (__afl_final_loc) {
+
+    __afl_map_size = __afl_final_loc;
+    if (__afl_final_loc > MAP_SIZE) {
+
+      char *ptr;
+      u32   val = 0;
+      if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) val = atoi(ptr);
+      if (val < __afl_final_loc) {
+
+        if (__afl_final_loc > FS_OPT_MAX_MAPSIZE) {
+
+          fprintf(stderr,
+                  "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to "
+                  "be able to run this instrumented program!\n",
+                  __afl_final_loc);
+          if (id_str) {
+
+            send_forkserver_error(FS_ERROR_MAP_SIZE);
+            exit(-1);
+
+          }
+
+        } else {
+
+          fprintf(stderr,
+                  "Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to "
+                  "be able to run this instrumented program!\n",
+                  __afl_final_loc);
+
+        }
+
+      }
+
+    }
+
+  }
 
   /* If we're running under AFL, attach to the appropriate region, replacing the
      early-stage __afl_area_initial region that is needed to allow some really
      hacky .init code to work correctly in projects such as OpenSSL. */
 
+  if (getenv("AFL_DEBUG"))
+    fprintf(stderr,
+            "DEBUG: id_str %s, __afl_map_addr 0x%x, MAP_SIZE %u, "
+            "__afl_final_loc %u, max_size_forkserver %u/0x%x\n",
+            id_str == NULL ? "<null>" : id_str, __afl_map_addr, MAP_SIZE,
+            __afl_final_loc, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE);
+
   if (id_str) {
 
 #ifdef USEMMAP
     const char *   shm_file_path = id_str;
     int            shm_fd = -1;
     unsigned char *shm_base = NULL;
-    unsigned int   map_size = MAP_SIZE
-
-        if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE) map_size =
-            __afl_final_loc;
 
     /* create the shared memory segment as if it was a file */
     shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
     if (shm_fd == -1) {
 
       fprintf(stderr, "shm_open() failed\n");
+      send_forkserver_error(FS_ERROR_SHM_OPEN);
       exit(1);
 
     }
 
     /* map the shared memory segment to the address space of the process */
-    shm_base = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+    if (__afl_map_addr) {
+
+      shm_base =
+          mmap((void *)__afl_map_addr, __afl_map_size, PROT_READ | PROT_WRITE,
+               MAP_FIXED_NOREPLACE | MAP_SHARED, shm_fd, 0);
+
+    } else {
+
+      shm_base = mmap(0, __afl_map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+                      shm_fd, 0);
+
+    }
+
     if (shm_base == MAP_FAILED) {
 
       close(shm_fd);
       shm_fd = -1;
 
       fprintf(stderr, "mmap() failed\n");
+      if (__afl_map_addr)
+        send_forkserver_error(FS_ERROR_MAP_ADDR);
+      else
+        send_forkserver_error(FS_ERROR_MMAP);
       exit(2);
 
     }
@@ -129,18 +206,40 @@ static void __afl_map_shm(void) {
 #else
     u32 shm_id = atoi(id_str);
 
-    __afl_area_ptr = shmat(shm_id, NULL, 0);
+    __afl_area_ptr = shmat(shm_id, (void *)__afl_map_addr, 0);
+
 #endif
 
     /* Whooooops. */
 
-    if (__afl_area_ptr == (void *)-1) _exit(1);
+    if (__afl_area_ptr == (void *)-1) {
+
+      if (__afl_map_addr)
+        send_forkserver_error(FS_ERROR_MAP_ADDR);
+      else
+        send_forkserver_error(FS_ERROR_SHMAT);
+      _exit(1);
+
+    }
 
     /* Write something into the bitmap so that even with low AFL_INST_RATIO,
        our parent doesn't give up on us. */
 
     __afl_area_ptr[0] = 1;
 
+  } else if (__afl_map_addr) {
+
+    __afl_area_ptr =
+        mmap((void *)__afl_map_addr, __afl_map_size, PROT_READ | PROT_WRITE,
+             MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+    if (__afl_area_ptr == MAP_FAILED) {
+
+      fprintf(stderr, "can not aquire mmap for address %p\n",
+              (void *)__afl_map_addr);
+      exit(1);
+
+    }
+
   }
 
   id_str = getenv(CMPLOG_SHM_ENV_VAR);
@@ -193,13 +292,9 @@ static void __afl_start_snapshots(void) {
   static u8 tmp[4] = {0, 0, 0, 0};
   s32       child_pid;
   u32       status = 0;
-  u32       map_size = MAP_SIZE;
   u32       already_read_first = 0;
   u32       was_killed;
 
-  if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE)
-    map_size = __afl_final_loc;
-
   u8 child_stopped = 0;
 
   void (*old_sigchld_handler)(int) = 0;  // = signal(SIGCHLD, SIG_DFL);
@@ -208,8 +303,8 @@ static void __afl_start_snapshots(void) {
      assume we're not running in forkserver mode and just execute program. */
 
   status |= (FS_OPT_ENABLED | FS_OPT_SNAPSHOT);
-  if (map_size <= 0x800000)
-    status |= (FS_OPT_SET_MAPSIZE(map_size) | FS_OPT_MAPSIZE);
+  if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
+    status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
   if (__afl_dictionary_len > 0 && __afl_dictionary) status |= FS_OPT_AUTODICT;
   memcpy(tmp, &status, 4);
 
@@ -362,19 +457,15 @@ static void __afl_start_forkserver(void) {
   u8  tmp[4] = {0, 0, 0, 0};
   s32 child_pid;
   u32 status = 0;
-  u32 map_size = MAP_SIZE;
   u32 already_read_first = 0;
   u32 was_killed;
 
-  if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE)
-    map_size = __afl_final_loc;
-
   u8 child_stopped = 0;
 
   void (*old_sigchld_handler)(int) = 0;  // = signal(SIGCHLD, SIG_DFL);
 
-  if (map_size <= 0x800000)
-    status |= (FS_OPT_SET_MAPSIZE(map_size) | FS_OPT_MAPSIZE);
+  if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
+    status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
   if (__afl_dictionary_len > 0 && __afl_dictionary) status |= FS_OPT_AUTODICT;
   if (status) status |= (FS_OPT_ENABLED);
   memcpy(tmp, &status, 4);
@@ -512,12 +603,8 @@ static void __afl_start_forkserver(void) {
 
 int __afl_persistent_loop(unsigned int max_cnt) {
 
-  static u8    first_pass = 1;
-  static u32   cycle_cnt;
-  unsigned int map_size = MAP_SIZE;
-
-  if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE)
-    map_size = __afl_final_loc;
+  static u8  first_pass = 1;
+  static u32 cycle_cnt;
 
   if (first_pass) {
 
@@ -528,7 +615,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
 
     if (is_persistent) {
 
-      memset(__afl_area_ptr, 0, map_size);
+      memset(__afl_area_ptr, 0, __afl_map_size);
       __afl_area_ptr[0] = 1;
       memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
 
diff --git a/llvm_mode/cmplog-instructions-pass.cc b/llvm_mode/cmplog-instructions-pass.cc
index b0ab475d..628151c6 100644
--- a/llvm_mode/cmplog-instructions-pass.cc
+++ b/llvm_mode/cmplog-instructions-pass.cc
@@ -47,6 +47,7 @@
 #endif
 
 #include <set>
+#include "afl-llvm-common.h"
 
 using namespace llvm;
 
@@ -58,22 +59,7 @@ class CmpLogInstructions : public ModulePass {
   static char ID;
   CmpLogInstructions() : ModulePass(ID) {
 
-    char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
-    if (instWhiteListFilename) {
-
-      std::string   line;
-      std::ifstream fileStream;
-      fileStream.open(instWhiteListFilename);
-      if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
-      getline(fileStream, line);
-      while (fileStream) {
-
-        myWhitelist.push_back(line);
-        getline(fileStream, line);
-
-      }
-
-    }
+    initWhitelist();
 
   }
 
@@ -91,8 +77,7 @@ class CmpLogInstructions : public ModulePass {
   }
 
  protected:
-  std::list<std::string> myWhitelist;
-  int                    be_quiet = 0;
+  int be_quiet = 0;
 
  private:
   bool hookInstrs(Module &M);
@@ -185,118 +170,9 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
   /* iterate over all functions, bbs and instruction and add suitable calls */
   for (auto &F : M) {
 
-    for (auto &BB : F) {
-
-      if (!myWhitelist.empty()) {
-
-        BasicBlock::iterator IP = BB.getFirstInsertionPt();
-
-        bool instrumentBlock = false;
-
-        /* Get the current location using debug information.
-         * For now, just instrument the block if we are not able
-         * to determine our location. */
-        DebugLoc Loc = IP->getDebugLoc();
-#if LLVM_VERSION_MAJOR >= 4 || \
-    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
-        if (Loc) {
-
-          DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
-
-          unsigned int instLine = cDILoc->getLine();
-          StringRef    instFilename = cDILoc->getFilename();
-
-          if (instFilename.str().empty()) {
-
-            /* If the original location is empty, try using the inlined location
-             */
-            DILocation *oDILoc = cDILoc->getInlinedAt();
-            if (oDILoc) {
-
-              instFilename = oDILoc->getFilename();
-              instLine = oDILoc->getLine();
-
-            }
-
-          }
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
+    if (!isInWhitelist(&F)) continue;
 
-            }
-
-          }
-
-        }
-
-#else
-        if (!Loc.isUnknown()) {
-
-          DILocation cDILoc(Loc.getAsMDNode(C));
-
-          unsigned int instLine = cDILoc.getLineNumber();
-          StringRef    instFilename = cDILoc.getFilename();
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#endif
-
-        /* Either we couldn't figure out our location or the location is
-         * not whitelisted, so we skip instrumentation. */
-        if (!instrumentBlock) continue;
-
-      }
+    for (auto &BB : F) {
 
       for (auto &IN : BB) {
 
diff --git a/llvm_mode/cmplog-routines-pass.cc b/llvm_mode/cmplog-routines-pass.cc
index f58e351c..b74fb712 100644
--- a/llvm_mode/cmplog-routines-pass.cc
+++ b/llvm_mode/cmplog-routines-pass.cc
@@ -47,6 +47,7 @@
 #endif
 
 #include <set>
+#include "afl-llvm-common.h"
 
 using namespace llvm;
 
@@ -58,22 +59,7 @@ class CmpLogRoutines : public ModulePass {
   static char ID;
   CmpLogRoutines() : ModulePass(ID) {
 
-    char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
-    if (instWhiteListFilename) {
-
-      std::string   line;
-      std::ifstream fileStream;
-      fileStream.open(instWhiteListFilename);
-      if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
-      getline(fileStream, line);
-      while (fileStream) {
-
-        myWhitelist.push_back(line);
-        getline(fileStream, line);
-
-      }
-
-    }
+    initWhitelist();
 
   }
 
@@ -91,8 +77,7 @@ class CmpLogRoutines : public ModulePass {
   }
 
  protected:
-  std::list<std::string> myWhitelist;
-  int                    be_quiet = 0;
+  int be_quiet = 0;
 
  private:
   bool hookRtns(Module &M);
@@ -132,118 +117,9 @@ bool CmpLogRoutines::hookRtns(Module &M) {
   /* iterate over all functions, bbs and instruction and add suitable calls */
   for (auto &F : M) {
 
-    for (auto &BB : F) {
-
-      if (!myWhitelist.empty()) {
-
-        BasicBlock::iterator IP = BB.getFirstInsertionPt();
-
-        bool instrumentBlock = false;
-
-        /* Get the current location using debug information.
-         * For now, just instrument the block if we are not able
-         * to determine our location. */
-        DebugLoc Loc = IP->getDebugLoc();
-#if LLVM_VERSION_MAJOR >= 4 || \
-    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
-        if (Loc) {
-
-          DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
-
-          unsigned int instLine = cDILoc->getLine();
-          StringRef    instFilename = cDILoc->getFilename();
-
-          if (instFilename.str().empty()) {
-
-            /* If the original location is empty, try using the inlined location
-             */
-            DILocation *oDILoc = cDILoc->getInlinedAt();
-            if (oDILoc) {
-
-              instFilename = oDILoc->getFilename();
-              instLine = oDILoc->getLine();
-
-            }
-
-          }
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
+    if (!isInWhitelist(&F)) continue;
 
-            }
-
-          }
-
-        }
-
-#else
-        if (!Loc.isUnknown()) {
-
-          DILocation cDILoc(Loc.getAsMDNode(C));
-
-          unsigned int instLine = cDILoc.getLineNumber();
-          StringRef    instFilename = cDILoc.getFilename();
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#endif
-
-        /* Either we couldn't figure out our location or the location is
-         * not whitelisted, so we skip instrumentation. */
-        if (!instrumentBlock) continue;
-
-      }
+    for (auto &BB : F) {
 
       for (auto &IN : BB) {
 
diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc
index 84a9b8d9..c871c1c4 100644
--- a/llvm_mode/compare-transform-pass.so.cc
+++ b/llvm_mode/compare-transform-pass.so.cc
@@ -47,6 +47,7 @@
 #endif
 
 #include <set>
+#include "afl-llvm-common.h"
 
 using namespace llvm;
 
@@ -58,22 +59,7 @@ class CompareTransform : public ModulePass {
   static char ID;
   CompareTransform() : ModulePass(ID) {
 
-    char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
-    if (instWhiteListFilename) {
-
-      std::string   line;
-      std::ifstream fileStream;
-      fileStream.open(instWhiteListFilename);
-      if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
-      getline(fileStream, line);
-      while (fileStream) {
-
-        myWhitelist.push_back(line);
-        getline(fileStream, line);
-
-      }
-
-    }
+    initWhitelist();
 
   }
 
@@ -91,8 +77,7 @@ class CompareTransform : public ModulePass {
   }
 
  protected:
-  std::list<std::string> myWhitelist;
-  int                    be_quiet = 0;
+  int be_quiet = 0;
 
  private:
   bool transformCmps(Module &M, const bool processStrcmp,
@@ -140,118 +125,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
    * strcmp/memcmp/strncmp/strcasecmp/strncasecmp */
   for (auto &F : M) {
 
-    for (auto &BB : F) {
-
-      if (!myWhitelist.empty()) {
-
-        BasicBlock::iterator IP = BB.getFirstInsertionPt();
-
-        bool instrumentBlock = false;
-
-        /* Get the current location using debug information.
-         * For now, just instrument the block if we are not able
-         * to determine our location. */
-        DebugLoc Loc = IP->getDebugLoc();
-#if LLVM_VERSION_MAJOR >= 4 || \
-    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
-        if (Loc) {
-
-          DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
-
-          unsigned int instLine = cDILoc->getLine();
-          StringRef    instFilename = cDILoc->getFilename();
-
-          if (instFilename.str().empty()) {
-
-            /* If the original location is empty, try using the inlined location
-             */
-            DILocation *oDILoc = cDILoc->getInlinedAt();
-            if (oDILoc) {
-
-              instFilename = oDILoc->getFilename();
-              instLine = oDILoc->getLine();
+    if (!isInWhitelist(&F)) continue;
 
-            }
-
-          }
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#else
-        if (!Loc.isUnknown()) {
-
-          DILocation cDILoc(Loc.getAsMDNode(C));
-
-          unsigned int instLine = cDILoc.getLineNumber();
-          StringRef    instFilename = cDILoc.getFilename();
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#endif
-
-        /* Either we couldn't figure out our location or the location is
-         * not whitelisted, so we skip instrumentation. */
-        if (!instrumentBlock) continue;
-
-      }
+    for (auto &BB : F) {
 
       for (auto &IN : BB) {
 
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index 7c657ebf..9c91e44f 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -46,6 +46,7 @@
 #endif
 
 using namespace llvm;
+#include "afl-llvm-common.h"
 
 namespace {
 
@@ -55,40 +56,7 @@ class SplitComparesTransform : public ModulePass {
   static char ID;
   SplitComparesTransform() : ModulePass(ID) {
 
-    char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
-    if (instWhiteListFilename) {
-
-      std::string   line;
-      std::ifstream fileStream;
-      fileStream.open(instWhiteListFilename);
-      if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
-      getline(fileStream, line);
-      while (fileStream) {
-
-        myWhitelist.push_back(line);
-        getline(fileStream, line);
-
-      }
-
-    }
-
-  }
-
-  static bool isBlacklisted(const Function *F) {
-
-    static const char *Blacklist[] = {
-
-        "asan.", "llvm.", "sancov.", "__ubsan_handle_", "ign."
-
-    };
-
-    for (auto const &BlacklistFunc : Blacklist) {
-
-      if (F->getName().startswith(BlacklistFunc)) { return true; }
-
-    }
-
-    return false;
+    initWhitelist();
 
   }
 
@@ -105,8 +73,7 @@ class SplitComparesTransform : public ModulePass {
   }
 
  protected:
-  std::list<std::string> myWhitelist;
-  int                    be_quiet = 0;
+  int be_quiet = 0;
 
  private:
   int enableFPSplit;
@@ -136,121 +103,10 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
    * all integer comparisons with >= and <= predicates to the icomps vector */
   for (auto &F : M) {
 
-    if (isBlacklisted(&F)) continue;
+    if (!isInWhitelist(&F)) continue;
 
     for (auto &BB : F) {
 
-      if (!myWhitelist.empty()) {
-
-        bool instrumentBlock = false;
-
-        BasicBlock::iterator IP = BB.getFirstInsertionPt();
-
-        /* Get the current location using debug information.
-         * For now, just instrument the block if we are not able
-         * to determine our location. */
-        DebugLoc Loc = IP->getDebugLoc();
-#if LLVM_VERSION_MAJOR >= 4 || \
-    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
-        if (Loc) {
-
-          DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
-
-          unsigned int instLine = cDILoc->getLine();
-          StringRef    instFilename = cDILoc->getFilename();
-
-          if (instFilename.str().empty()) {
-
-            /* If the original location is empty, try using the inlined location
-             */
-            DILocation *oDILoc = cDILoc->getInlinedAt();
-            if (oDILoc) {
-
-              instFilename = oDILoc->getFilename();
-              instLine = oDILoc->getLine();
-
-            }
-
-          }
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#else
-        if (!Loc.isUnknown()) {
-
-          DILocation cDILoc(Loc.getAsMDNode(C));
-
-          unsigned int instLine = cDILoc.getLineNumber();
-          StringRef    instFilename = cDILoc.getFilename();
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#endif
-
-        /* Either we couldn't figure out our location or the location is
-         * not whitelisted, so we skip instrumentation. */
-        if (!instrumentBlock) continue;
-
-      }
-
       for (auto &IN : BB) {
 
         CmpInst *selectcmpInst = nullptr;
diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc
index 980dcb12..3444d6a1 100644
--- a/llvm_mode/split-switches-pass.so.cc
+++ b/llvm_mode/split-switches-pass.so.cc
@@ -49,6 +49,7 @@
 #endif
 
 #include <set>
+#include "afl-llvm-common.h"
 
 using namespace llvm;
 
@@ -60,40 +61,7 @@ class SplitSwitchesTransform : public ModulePass {
   static char ID;
   SplitSwitchesTransform() : ModulePass(ID) {
 
-    char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
-    if (instWhiteListFilename) {
-
-      std::string   line;
-      std::ifstream fileStream;
-      fileStream.open(instWhiteListFilename);
-      if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
-      getline(fileStream, line);
-      while (fileStream) {
-
-        myWhitelist.push_back(line);
-        getline(fileStream, line);
-
-      }
-
-    }
-
-  }
-
-  static bool isBlacklisted(const Function *F) {
-
-    static const char *Blacklist[] = {
-
-        "asan.", "llvm.", "sancov.", "__ubsan_handle_", "ign."
-
-    };
-
-    for (auto const &BlacklistFunc : Blacklist) {
-
-      if (F->getName().startswith(BlacklistFunc)) { return true; }
-
-    }
-
-    return false;
+    initWhitelist();
 
   }
 
@@ -125,8 +93,7 @@ class SplitSwitchesTransform : public ModulePass {
   typedef std::vector<CaseExpr> CaseVector;
 
  protected:
-  std::list<std::string> myWhitelist;
-  int                    be_quiet = 0;
+  int be_quiet = 0;
 
  private:
   bool        splitSwitches(Module &M);
@@ -346,122 +313,12 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
    * all switches to switches vector for later processing */
   for (auto &F : M) {
 
-    if (isBlacklisted(&F)) continue;
+    if (!isInWhitelist(&F)) continue;
 
     for (auto &BB : F) {
 
       SwitchInst *switchInst = nullptr;
 
-      if (!myWhitelist.empty()) {
-
-        bool                 instrumentBlock = false;
-        BasicBlock::iterator IP = BB.getFirstInsertionPt();
-
-        /* Get the current location using debug information.
-         * For now, just instrument the block if we are not able
-         * to determine our location. */
-        DebugLoc Loc = IP->getDebugLoc();
-#if LLVM_VERSION_MAJOR >= 4 || \
-    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
-        if (Loc) {
-
-          DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
-
-          unsigned int instLine = cDILoc->getLine();
-          StringRef    instFilename = cDILoc->getFilename();
-
-          if (instFilename.str().empty()) {
-
-            /* If the original location is empty, try using the inlined location
-             */
-            DILocation *oDILoc = cDILoc->getInlinedAt();
-            if (oDILoc) {
-
-              instFilename = oDILoc->getFilename();
-              instLine = oDILoc->getLine();
-
-            }
-
-          }
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#else
-        if (!Loc.isUnknown()) {
-
-          DILocation cDILoc(Loc.getAsMDNode(C));
-
-          unsigned int instLine = cDILoc.getLineNumber();
-          StringRef    instFilename = cDILoc.getFilename();
-
-          (void)instLine;
-
-          /* Continue only if we know where we actually are */
-          if (!instFilename.str().empty()) {
-
-            for (std::list<std::string>::iterator it = myWhitelist.begin();
-                 it != myWhitelist.end(); ++it) {
-
-              /* We don't check for filename equality here because
-               * filenames might actually be full paths. Instead we
-               * check that the actual filename ends in the filename
-               * specified in the list. */
-              if (instFilename.str().length() >= it->length()) {
-
-                if (instFilename.str().compare(
-                        instFilename.str().length() - it->length(),
-                        it->length(), *it) == 0) {
-
-                  instrumentBlock = true;
-                  break;
-
-                }
-
-              }
-
-            }
-
-          }
-
-        }
-
-#endif
-
-        /* Either we couldn't figure out our location or the location is
-         * not whitelisted, so we skip instrumentation. */
-        if (!instrumentBlock) continue;
-
-      }
-
       if ((switchInst = dyn_cast<SwitchInst>(BB.getTerminator()))) {
 
         if (switchInst->getNumCases() < 1) continue;
diff --git a/src/afl-common.c b/src/afl-common.c
index 1dae8509..dda62219 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -67,10 +67,11 @@ char *afl_environment_variables[] = {
     "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES",
     "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS",
     "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES",
-    "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", "AFL_LLVM_NOT_ZERO",
-    "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID",
-    "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
-    "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
+    "AFL_LLVM_MAP_ADDR", "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE",
+    "AFL_NGRAM_SIZE", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST",
+    "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID",
+    "AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV",
+    "AFL_NO_UI", "AFL_NO_PYTHON",
     "AFL_NO_X86",  // not really an env but we dont want to warn on it
     "AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE",
     //"AFL_PERSISTENT", // not implemented anymore, so warn additionally
@@ -917,7 +918,7 @@ u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms,
 
 }
 
-u32 get_map_size() {
+u32 get_map_size(void) {
 
   uint32_t map_size = MAP_SIZE;
   char *   ptr;
@@ -927,7 +928,8 @@ u32 get_map_size() {
     map_size = atoi(ptr);
     if (map_size < 8 || map_size > (1 << 29)) {
 
-      FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size);
+      FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8,
+            1 << 29);
 
     }
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 0c795f9c..d5a60077 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -53,7 +53,7 @@
 
 /* Describe integer as memory size. */
 
-list_t fsrv_list = {.element_prealloc_count = 0};
+static list_t fsrv_list = {.element_prealloc_count = 0};
 
 static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) {
 
@@ -67,7 +67,6 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
 
   // this structure needs default so we initialize it if this was not done
   // already
-
   fsrv->out_fd = -1;
   fsrv->out_dir_fd = -1;
   fsrv->dev_null_fd = -1;
@@ -83,7 +82,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
 
   /* exec related stuff */
   fsrv->child_pid = -1;
-  fsrv->map_size = MAP_SIZE;
+  fsrv->map_size = get_map_size();
   fsrv->use_fauxsrv = 0;
   fsrv->last_run_timed_out = 0;
 
@@ -201,6 +200,44 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
 
 }
 
+/* Report on the error received via the forkserver controller and exit */
+static void report_error_and_exit(int error) {
+
+  switch (error) {
+
+    case FS_ERROR_MAP_SIZE:
+      FATAL(
+          "AFL_MAP_SIZE is not set and fuzzing target reports that the "
+          "required size is very large. Solution: Run the fuzzing target "
+          "stand-alone with the environment variable AFL_DEBUG=1 set and set "
+          "the value for __afl_final_loc in the AFL_MAP_SIZE environment "
+          "variable for afl-fuzz.");
+      break;
+    case FS_ERROR_MAP_ADDR:
+      FATAL(
+          "the fuzzing target reports that hardcoded map address might be the "
+          "reason the mmap of the shared memory failed. Solution: recompile "
+          "the target with either afl-clang-lto and the environment variable "
+          "AFL_LLVM_MAP_DYNAMIC set or recompile with afl-clang-fast.");
+      break;
+    case FS_ERROR_SHM_OPEN:
+      FATAL("the fuzzing target reports that the shm_open() call failed.");
+      break;
+    case FS_ERROR_SHMAT:
+      FATAL("the fuzzing target reports that the shmat() call failed.");
+      break;
+    case FS_ERROR_MMAP:
+      FATAL(
+          "the fuzzing target reports that the mmap() call to the share memory "
+          "failed.");
+      break;
+    default:
+      FATAL("unknown error code %u from fuzzing target!", error);
+
+  }
+
+}
+
 /* Spins up fork server (instrumented mode only). The idea is explained here:
 
    http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html
@@ -400,6 +437,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     if (!be_quiet) { OKF("All right - fork server is up."); }
 
+    if ((status & FS_OPT_ERROR) == FS_OPT_ERROR)
+      report_error_and_exit(FS_OPT_GET_ERROR(status));
+
     if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
 
       if (!be_quiet && getenv("AFL_DEBUG")) {
@@ -434,9 +474,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
           FATAL(
               "Target's coverage map size of %u is larger than the one this "
-              "afl++ is set with (%u) (change MAP_SIZE_POW2 in config.h and "
-              "recompile or set AFL_MAP_SIZE)\n",
-              tmp_map_size, fsrv->map_size);
+              "afl++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
+              " afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile "
+              "afl-fuzz",
+              tmp_map_size, fsrv->map_size, tmp_map_size);
 
         }
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 69fe6562..2289183c 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -721,7 +721,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 #else
 
       snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir,
-               afl->unique_crashes, afl->kill_signal);
+               afl->unique_crashes, afl->last_kill_signal);
 
 #endif                                                    /* ^!SIMPLE_FILES */
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 4dd31ac9..32481887 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1903,7 +1903,7 @@ void fix_up_sync(afl_state_t *afl) {
 
 static void handle_resize(int sig) {
 
-  LIST_FOREACH(&afl_states, afl_state_t, { el->clear_screen = 1; });
+  afl_states_clear_screen();
 
 }
 
@@ -1954,14 +1954,7 @@ void check_asan_opts(void) {
 
 static void handle_stop_sig(int sig) {
 
-  LIST_FOREACH(&afl_states, afl_state_t, {
-
-    el->stop_soon = 1;
-
-    if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, SIGKILL);
-    if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, SIGKILL);
-
-  });
+  afl_states_stop();
 
 }
 
@@ -1969,7 +1962,7 @@ static void handle_stop_sig(int sig) {
 
 static void handle_skipreq(int sig) {
 
-  LIST_FOREACH(&afl_states, afl_state_t, { el->skip_requested = 1; });
+  afl_states_request_skip();
 
 }
 
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index b38c9ec5..4f5389e3 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -71,7 +71,7 @@ static void init_mopt_globals(afl_state_t *afl) {
 /* A global pointer to all instances is needed (for now) for signals to arrive
  */
 
-list_t afl_states = {.element_prealloc_count = 0};
+static list_t afl_states = {.element_prealloc_count = 0};
 
 /* Initializes an afl_state_t. */
 
@@ -81,7 +81,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
   and out_size are NULL/0 by default. */
   memset(afl, 0, sizeof(afl_state_t));
 
-  if (!map_size) { afl->shm.map_size = MAP_SIZE; }
+  afl->shm.map_size = map_size ? map_size : MAP_SIZE;
 
   afl->w_init = 0.9;
   afl->w_end = 0.3;
@@ -398,3 +398,34 @@ void afl_state_deinit(afl_state_t *afl) {
 
 }
 
+void afl_states_stop(void) {
+
+  /* We may be inside a signal handler.
+   Set flags first, send kill signals to child proceses later. */
+  LIST_FOREACH(&afl_states, afl_state_t, {
+
+    el->stop_soon = 1;
+
+  });
+
+  LIST_FOREACH(&afl_states, afl_state_t, {
+
+    if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, SIGKILL);
+    if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, SIGKILL);
+
+  });
+
+}
+
+void afl_states_clear_screen(void) {
+
+  LIST_FOREACH(&afl_states, afl_state_t, { el->clear_screen = 1; });
+
+}
+
+void afl_states_request_skip(void) {
+
+  LIST_FOREACH(&afl_states, afl_state_t, { el->skip_requested = 1; });
+
+}
+
diff --git a/src/afl-gcc.c b/src/afl-gcc.c
index 6c6bd1f1..7eb01c0c 100644
--- a/src/afl-gcc.c
+++ b/src/afl-gcc.c
@@ -149,11 +149,16 @@ static void edit_params(u32 argc, char **argv) {
       u8 *alt_cxx = getenv("AFL_CXX");
       cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)"clang++";
 
-    } else {
+    } else if (!strcmp(name, "afl-clang")) {
 
       u8 *alt_cc = getenv("AFL_CC");
       cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"clang";
 
+    } else {
+
+      fprintf(stderr, "Name of the binary: %s\n", argv[0]);
+      FATAL("Name of the binary is not a known name, expected afl-clang(++)");
+
     }
 
   } else {
@@ -166,13 +171,25 @@ static void edit_params(u32 argc, char **argv) {
 
 #ifdef __APPLE__
 
-    if (!strcmp(name, "afl-g++"))
+    if (!strcmp(name, "afl-g++")) {
+
       cc_params[0] = getenv("AFL_CXX");
-    else if (!strcmp(name, "afl-gcj"))
+
+    } else if (!strcmp(name, "afl-gcj")) {
+
       cc_params[0] = getenv("AFL_GCJ");
-    else
+
+    } else if (!strcmp(name, "afl-gcc")) {
+
       cc_params[0] = getenv("AFL_CC");
 
+    } else {
+
+      fprintf(stderr, "Name of the binary: %s\n", argv[0]);
+      FATAL("Name of the binary is not a known name, expected afl-gcc/g++/gcj");
+
+    }
+
     if (!cc_params[0]) {
 
       SAYF("\n" cLRD "[-] " cRST
@@ -199,11 +216,16 @@ static void edit_params(u32 argc, char **argv) {
       u8 *alt_cc = getenv("AFL_GCJ");
       cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"gcj";
 
-    } else {
+    } else if (!strcmp(name, "afl-gcc")) {
 
       u8 *alt_cc = getenv("AFL_CC");
       cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"gcc";
 
+    } else {
+
+      fprintf(stderr, "Name of the binary: %s\n", argv[0]);
+      FATAL("Name of the binary is not a known name, expected afl-gcc/g++/gcj");
+
     }
 
 #endif                                                         /* __APPLE__ */
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index 90754b75..e024eb18 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -127,12 +127,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
   }
 
   /* map the shared memory segment to the address space of the process */
-  shm->map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
-                  map_size->g_shm_fd, 0);
-  if (map_size->map == MAP_FAILED) {
+  shm->map =
+      mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->g_shm_fd, 0);
+  if (shm->map == MAP_FAILED) {
 
-    close(map_size->g_shm_fd);
-    map_size->g_shm_fd = -1;
+    close(shm->g_shm_fd);
+    shm->g_shm_fd = -1;
     PFATAL("mmap() failed");
 
   }
diff --git a/test/test-compcov.c b/test/test-compcov.c
index f1743265..c8dd674e 100644
--- a/test/test-compcov.c
+++ b/test/test-compcov.c
@@ -25,11 +25,10 @@ int main(int argc, char **argv) {
     printf("your string was bugmenot\n");
   else if (strcmp(input, "BUFFEROVERFLOW") == 0) {
 
-    buf = malloc(16);
+    buf = (char *)malloc(16);
     strcpy(buf, "TEST");
     strcat(buf, input);
     printf("This will only crash with libdislocator: %s\n", buf);
-    return 0;
 
   } else if (*(unsigned int *)input == 0xabadcafe)
 
diff --git a/test/test.sh b/test/test.sh
index 5af35ec3..b8d4208f 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -951,7 +951,15 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
   test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.py && {
     unset AFL_CC
     # Compile the vulnerable program
-    ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
+    test -e ../afl-clang-fast && {
+      ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
+    } || {
+      test -e ../afl-gcc-fast && {
+        ../afl-gcc-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
+      } || {
+        ../afl-gcc -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
+      }
+    }
     # Compile the custom mutator
     make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1
     test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && {
diff --git a/test/travis/bionic/Dockerfile b/test/travis/bionic/Dockerfile
new file mode 100644
index 00000000..3883f775
--- /dev/null
+++ b/test/travis/bionic/Dockerfile
@@ -0,0 +1,43 @@
+# 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 \
+    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
+
+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
new file mode 100644
index 00000000..7b86f3e7
--- /dev/null
+++ b/test/travis/trusty/Dockerfile
@@ -0,0 +1,48 @@
+# 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 \
+    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
new file mode 100644
index 00000000..a5f8d359
--- /dev/null
+++ b/test/travis/xenial/Dockerfile
@@ -0,0 +1,45 @@
+# 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 \
+    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/test/unittests/unit_list.c b/test/unittests/unit_list.c
index 90700a11..df4864e4 100644
--- a/test/unittests/unit_list.c
+++ b/test/unittests/unit_list.c
@@ -40,7 +40,7 @@ int __wrap_printf(const char *format, ...) {
     return 1;
 }
 
-list_t testlist;
+static list_t testlist = {.element_prealloc_count = 0};
 
 static void test_contains(void **state) {
 
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index b2ac48f9..965d7614 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -107,7 +107,7 @@ for i in $PYTHONBIN automake autoconf git $MAKECMD $TARCMD; do
 
 done
 
-if ! type $EASY_INSTALL > /dev/null; then
+if ! command -v $EASY_INSTALL >/dev/null; then
 
   # work around for installs with executable easy_install
   EASY_INSTALL_FOUND=0
@@ -123,7 +123,7 @@ if ! type $EASY_INSTALL > /dev/null; then
 
     fi
   done
-  if [ '!' $EASY_INSTALL_FOUND ]; then
+  if [ "0" = $EASY_INSTALL_FOUND ]; then
 
     echo "[-] Error: Python setup-tools not found. Run 'sudo apt-get install python-setuptools'."
     PREREQ_NOTFOUND=1
@@ -182,7 +182,8 @@ echo "[+] Configuration complete."
 echo "[*] Attempting to build unicornafl (fingers crossed!)..."
 
 $MAKECMD clean  # make doesn't seem to work for unicorn
-UNICORN_QEMU_FLAGS="--python=$PYTHONBIN" $MAKECMD -j$CORES || exit 1
+# Fixed to 1 core for now as there is a race condition in the makefile
+UNICORN_QEMU_FLAGS="--python=$PYTHONBIN" $MAKECMD -j1 || exit 1
 
 echo "[+] Build process successful!"