about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile13
-rw-r--r--README.md11
-rwxr-xr-xafl-cmin65
-rwxr-xr-xafl-cmin.bash3
-rw-r--r--docs/Changelog.md4
-rw-r--r--include/alloc-inl.h3
-rw-r--r--llvm_mode/afl-clang-fast.c4
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc4
-rw-r--r--llvm_mode/compare-transform-pass.so.cc2
-rw-r--r--llvm_mode/split-compares-pass.so.cc11
-rw-r--r--llvm_mode/split-switches-pass.so.cc5
-rw-r--r--qemu_mode/patches/afl-qemu-tcg-runtime-inl.h4
-rw-r--r--src/afl-as.c2
-rw-r--r--src/afl-fuzz-init.c12
-rw-r--r--src/afl-fuzz.c54
-rw-r--r--src/afl-gcc.c54
-rw-r--r--src/afl-showmap.c16
-rwxr-xr-xtest/test.sh62
-rw-r--r--unicorn_mode/samples/c/harness.c2
19 files changed, 222 insertions, 109 deletions
diff --git a/Makefile b/Makefile
index 1e8a894b..b9d4bf5a 100644
--- a/Makefile
+++ b/Makefile
@@ -64,7 +64,7 @@ endif
 CFLAGS     ?= -O3 -funroll-loops $(CFLAGS_OPT)
 override CFLAGS     += -Wall -g -Wno-pointer-sign -I include/ \
               -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-              -DDOC_PATH=\"$(DOC_PATH)\" -Wno-unused-function
+              -DDOC_PATH=\"$(DOC_PATH)\" -Wno-unused-function -fcommon
 
 AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
 
@@ -200,7 +200,14 @@ help:
 	@echo "help: shows these build options :-)"
 	@echo "=========================================="
 	@echo "Recommended: \"distrib\" or \"source-only\", then \"install\""
-
+	@echo
+	@echo Known build environment options:
+	@echo "=========================================="
+	@echo STATIC - compile AFL++ static
+	@echo ASAN_BUILD - compiles with memory sanitizer for debug purposes
+	@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
+	@echo "=========================================="
+	@echo e.g.: make ASAN_BUILD=1
 
 ifndef AFL_NO_X86
 
@@ -321,7 +328,7 @@ ifndef AFL_NO_X86
 
 test_build: afl-gcc afl-as afl-showmap
 	@echo "[*] Testing the CC wrapper and instrumentation output..."
-	@unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 )
+	@unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 )
 	./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
 	echo 1 | ./afl-showmap -m none -q -o .test-instr1 ./test-instr
 	@rm -f test-instr
diff --git a/README.md b/README.md
index 8c759779..ec1d5ba9 100644
--- a/README.md
+++ b/README.md
@@ -109,7 +109,7 @@ $ make source-only
 ```
 is what you should choose.
 
-These build options exist:
+These build targets exist:
 
 * all: just the main afl++ binaries
 * binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa
@@ -128,6 +128,15 @@ afl++ binaries by passing the STATIC=1 argument to make:
 $ make all STATIC=1
 ```
 
+These build options exist:
+
+* STATIC - compile AFL++ static
+* ASAN_BUILD - compiles with memory sanitizer for debug purposes
+* AFL_NO_X86 - if compiling on non-intel/amd platforms
+
+e.g.: make ASAN_BUILD=1
+
+
 Note that afl++ is faster and better the newer the compilers used are.
 Hence gcc-9 and especially llvm-9 should be the compilers of choice.
 If your distribution does not have them, you can use the Dockerfile:
diff --git a/afl-cmin b/afl-cmin
index 44a84735..9570bc93 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -287,7 +287,8 @@ BEGIN {
   system("rm -rf "trace_dir" 2>/dev/null");
   system("rm "out_dir"/id[:_]* 2>/dev/null")
 
-  if (0 == system( "test -d "out_dir" -a -e "out_dir"/*" )) {
+  "ls "out_dir"/* 2>/dev/null | wc -l" | getline noofentries
+  if (0 == system( "test -d "out_dir" -a "noofentries" -gt 0" )) {
     print "[-] Error: directory '"out_dir"' exists and is not empty - delete it first." > "/dev/stderr"
     exit 1
   }
@@ -318,7 +319,7 @@ BEGIN {
     print "[-] Error: can't find 'afl-showmap' - please set AFL_PATH." > "/dev/stderr"
     exit 1
   }
-  
+
   # get list of input filenames sorted by size
   i = 0
   # yuck, gnu stat is option incompatible to bsd stat
@@ -330,8 +331,10 @@ BEGIN {
   } else {
     stat_format = "-f '%z %N'" # *BSD, MacOS
   }
-  cmdline = "cd "in_dir" && find . \\( ! -name . -a -type d -prune \\) -o -type f -exec stat "stat_format" \\{\\} \\; | sort -n | cut -d' ' -f2-"
+  cmdline = "cd "in_dir" && find . \\( ! -name . -a -type d -prune \\) -o -type f -exec stat "stat_format" \\{\\} \\; | sort -k1n -k2r"
+  cmdline = "ls "in_dir" | (cd "in_dir" && xargs stat "stat_format") | sort -k1n -k2r"
   while (cmdline | getline) {
+    sub(/^[0-9]+ (\.\/)?/,"",$0)
     infilesSmallToBig[i++] = $0
   }
   in_count = i
@@ -390,10 +393,10 @@ BEGIN {
 
   cur = 0;
   if (!stdin_file) {
-    printf "    Processing "in_count" files (forkserver mode)..."
+    print "    Processing "in_count" files (forkserver mode)..."
     system( "AFL_CMIN_ALLOW_ANY=1 \""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string)
   } else {
-    printf "    Processing "in_count" files (forkserver mode)..."
+    print "    Processing "in_count" files (forkserver mode)..."
     system( "AFL_CMIN_ALLOW_ANY=1 \""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string" </dev/null")
   }
 
@@ -410,6 +413,9 @@ BEGIN {
   out_count = 0
   tuple_count = 0
 
+  # from rare to frequent new tuples
+  # get the best (smallest) file for it
+  # and copy it
   while (cur < in_count) {
     fn = infilesSmallToBig[cur]
     ++cur
@@ -426,17 +432,54 @@ BEGIN {
         if (! (key in best_file)) {
             # this is the best file for this key
             best_file[key] = fn
-            # copy file unless already done
-            if (! (fn in file_already_copied)) {
-                system(cp_tool" "in_dir"/"fn" "out_dir"/"fn)
-                file_already_copied[fn] = ""
-                ++out_count
-            }
+#printf "BEST_FILE[%d]=\"%s\"\n",key,fn | "sort -t'[' -k2 > "trace_dir"/.candidate_script"
         }
+#printf "%d %s\n",key,fn > trace_dir"/.candidate_list"
     }
     close(tracefile_path)
   }
+  print ""
+
+  # sort keys
+  sortedKeys = trace_dir"/.all_uniq"
+  sortKeysCmd = "sort -k1n > "sortedKeys
+  for (key in key_count) {
+     printf "%7d %s\n",key_count[key],key | sortKeysCmd
+  }
+  close(sortKeysCmd)
+
+  # iterate over keys from rare to frequent and
+  # copy best file
+  while ((getline < sortedKeys) > 0) {
+
+    # split
+    nrFields = split($0, field, / +/)
+#print nrFields" Felder: '"field[0]"',  '"field[1]"',  '"field[2]"',  '"field[3]"'"
+    key = field[nrFields]
 
+    ++tcnt;
+    printf "\r    Processing tuple "tcnt"/"tuple_count" with count "key_count[key]"..."
+    if (key in keyAlreadyKnown) {
+      continue
+    }
+
+    fn = best_file[key]
+    # gather all tuples from the best file for this key
+    tracedfn = trace_dir"/"fn
+    while ((getline < tracedfn) > 0) {
+      keyAlreadyKnown[$0] = ""
+    }
+    close(tracedfn)
+
+    # copy file unless already done
+    if (! (fn in file_already_copied)) {
+      system(cp_tool" "in_dir"/"fn" "out_dir"/"fn)
+      file_already_copied[fn] = ""
+      ++out_count
+      #printf "tuple nr %d (%d cnt=%d) -> %s\n",tcnt,key,key_count[key],fn > trace_dir"/.log"
+    }
+  }
+  close(sortedKeys)
   print ""
   print "[+] Found "tuple_count" unique tuples across "in_count" files."
 
diff --git a/afl-cmin.bash b/afl-cmin.bash
index 1dd782d8..94c02fda 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -435,7 +435,7 @@ touch "$TRACE_DIR/.already_have"
 while read -r cnt tuple; do
 
   CUR=$((CUR+1))
-  printf "\\r    Processing tuple $CUR/$TUPLE_COUNT... "
+  printf "\\r    Processing tuple $CUR/$TUPLE_COUNT with count $cnt... "
 
   # If we already have this tuple, skip it.
 
@@ -443,6 +443,7 @@ while read -r cnt tuple; do
 
   FN=${BEST_FILE[tuple]}
 
+#  echo "tuple nr $CUR ($tuple cnt=$cnt) -> $FN" >> "$TRACE_DIR/.log"
   $CP_TOOL "$IN_DIR/$FN" "$OUT_DIR/$FN"
 
   if [ "$((CUR % 5))" = "0" ]; then
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 4ee83ecd..5d781545 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -13,6 +13,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
 
   - use -march=native if available
   - most tools now check for mistyped environment variables
+  - gcc 10 is now supported
   - the memory safety checks are now disabled for a little more speed during
     fuzzing (only affects creating queue entries), can be toggled in config.h
   - afl-fuzz:
@@ -26,6 +27,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
        (which is pointless) to total execs per second
      - bugfix for dictionary insert stage count (fix via Google repo PR)
      - added warning if -M is used together with custom mutators with _ONLY option
+     - AFL_TMPDIR checks are now later and better explained if they fail
   - llvm_mode InsTrim: no pointless instrumentation of 1 block functions
   - afl-clang-fast:
      - show in the help output for which llvm version it was compiled for
@@ -37,6 +39,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
      - experimental support for undefined behaviour sanitizer UBSAN
        (set AFL_USE_UBSAN=1)
      - the instrumentation summary output now also lists activated sanitizers
+     - afl-as: added isatty(2) check back in
+     - added AFL_DEBUG (for upcoming merge)
   - qemu_mode:
      - persistent mode is now also available for arm and aarch64
      - CmpLog instrumentation for QEMU (-c afl-fuzz command line option)
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index ada08b69..5764e30b 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -141,8 +141,7 @@ static inline void* DFL_ck_realloc(void* orig, u32 size) {
 
 static inline void* DFL_ck_realloc_block(void* orig, u32 size) {
 
-  if (orig)
-    size += ALLOC_BLK_INC;
+  if (orig) size += ALLOC_BLK_INC;
 
   return DFL_ck_realloc(orig, size);
 
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index 0ec68ab5..683b6bee 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -494,7 +494,9 @@ int main(int argc, char** argv, char** envp) {
 
     exit(1);
 
-  } else if (isatty(2) && !getenv("AFL_QUIET")) {
+  } else if ((isatty(2) && !getenv("AFL_QUIET")) ||
+
+             getenv("AFL_DEBUG") != NULL) {
 
 #ifdef USE_TRACE_PC
     SAYF(cCYA "afl-clang-fast" VERSION cRST
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index 555510cc..133c64b4 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -145,11 +145,11 @@ bool AFLCoverage::runOnModule(Module &M) {
 
   char be_quiet = 0;
 
-  if (isatty(2) && !getenv("AFL_QUIET")) {
+  if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
 
     SAYF(cCYA "afl-llvm-pass" VERSION cRST " by <lszekeres@google.com>\n");
 
-  } else if (getenv("AFL_QUIET"))
+  } else
 
     be_quiet = 1;
 
diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc
index e1332a9d..94b256f7 100644
--- a/llvm_mode/compare-transform-pass.so.cc
+++ b/llvm_mode/compare-transform-pass.so.cc
@@ -496,7 +496,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 
 bool CompareTransform::runOnModule(Module &M) {
 
-  if (getenv("AFL_QUIET") == NULL)
+  if (isatty(2) && getenv("AFL_QUIET") == NULL)
     llvm::errs() << "Running compare-transform-pass by laf.intel@gmail.com, "
                     "extended by heiko@hexco.de\n";
   transformCmps(M, true, true, true, true, true);
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index e16993d6..fe021071 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -1243,13 +1243,16 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
   simplifyIntSignedness(M);
 
-  if (getenv("AFL_QUIET") == NULL)
+  if (isatty(2) && getenv("AFL_QUIET") == NULL) {
+
     errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
               "heiko@hexco.de\n";
 
-  if (enableFPSplit)
-    errs() << "Split-floatingpoint-compare-pass: " << splitFPCompares(M)
-           << " FP comparisons splitted\n";
+    if (enableFPSplit)
+      errs() << "Split-floatingpoint-compare-pass: " << splitFPCompares(M)
+             << " FP comparisons splitted\n";
+
+  }
 
   switch (bitw) {
 
diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc
index 9101dc26..d2ba28cb 100644
--- a/llvm_mode/split-switches-pass.so.cc
+++ b/llvm_mode/split-switches-pass.so.cc
@@ -491,7 +491,8 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
      * less, don't bother with the code below. */
     if (!SI->getNumCases() || bitw <= 8) {
 
-      if (getenv("AFL_QUIET") == NULL) errs() << "skip trivial switch..\n";
+      if (isatty(2) && getenv("AFL_QUIET") == NULL)
+        errs() << "skip trivial switch..\n";
       continue;
 
     }
@@ -556,7 +557,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
 
 bool SplitSwitchesTransform::runOnModule(Module &M) {
 
-  if (getenv("AFL_QUIET") == NULL)
+  if (isatty(2) && getenv("AFL_QUIET") == NULL)
     llvm::errs() << "Running split-switches-pass by laf.intel@gmail.com\n";
   splitSwitches(M);
   verifyModule(M);
diff --git a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
index 6339d41c..2bb0ac9e 100644
--- a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
+++ b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
@@ -35,9 +35,9 @@
 #include "tcg.h"
 
 void HELPER(afl_entry_routine)(CPUArchState *env) {
-  
+
   afl_forkserver(ENV_GET_CPU(env));
-  
+
 }
 
 void HELPER(afl_compcov_16)(target_ulong cur_loc, target_ulong arg1,
diff --git a/src/afl-as.c b/src/afl-as.c
index c116ac10..72a27cd2 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -510,7 +510,7 @@ int main(int argc, char** argv) {
 
   clang_mode = !!getenv(CLANG_ENV_VAR);
 
-  if (!getenv("AFL_QUIET")) {
+  if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
 
     SAYF(cCYA "afl-as" VERSION cRST " by Michal Zalewski\n");
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index bafb1d63..2176c5cf 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -603,9 +603,11 @@ void perform_dry_run(char** argv) {
                "binary. Also,\n"
                "      if you are using ASAN, see %s/notes_for_asan.md.\n\n"
 
-               "    - In QEMU persistent mode the selected address(es) for the loop are not\n"
+               "    - In QEMU persistent mode the selected address(es) for the "
+               "loop are not\n"
                "      properly cleaning up variables and memory. Try adding\n"
-               "      AFL_QEMU_PERSISTENT_GPR=1 or select better addresses in the binary.\n\n"
+               "      AFL_QEMU_PERSISTENT_GPR=1 or select better addresses in "
+               "the binary.\n\n"
 
                MSG_FORK_ON_APPLE
 
@@ -628,9 +630,11 @@ void perform_dry_run(char** argv) {
                "interesting\n"
                "      inputs - but not ones that cause an outright crash.\n\n"
 
-               "    - In QEMU persistent mode the selected address(es) for the loop are not\n"
+               "    - In QEMU persistent mode the selected address(es) for the "
+               "loop are not\n"
                "      properly cleaning up variables and memory. Try adding\n"
-               "      AFL_QEMU_PERSISTENT_GPR=1 or select better addresses in the binary.\n\n"
+               "      AFL_QEMU_PERSISTENT_GPR=1 or select better addresses in "
+               "the binary.\n\n"
 
                MSG_FORK_ON_APPLE
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index eeb660f7..a9a6db97 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -113,7 +113,8 @@ static void usage(u8* argv0) {
       "                  pacemaker mode (minutes of no new paths, 0 = "
       "immediately).\n"
       "                  a recommended value is 10-60. see docs/README.MOpt\n"
-      "  -c program    - enable CmpLog by specifying a binary compiled for it.\n"
+      "  -c program    - enable CmpLog by specifying a binary compiled for "
+      "it.\n"
       "                  if using QEMU, just use -c 0.\n\n"
 
       "Fuzzing behavior settings:\n"
@@ -654,25 +655,6 @@ int main(int argc, char** argv, char** envp) {
   if (!strcmp(in_dir, out_dir))
     FATAL("Input and output directories can't be the same");
 
-  if ((tmp_dir = getenv("AFL_TMPDIR")) != NULL) {
-
-    char tmpfile[file_extension 
-         ? strlen(tmp_dir) + 1 + 10 + 1 + strlen(file_extension) + 1
-         : strlen(tmp_dir) + 1 + 10 + 1];
-    if (file_extension) {
-      sprintf(tmpfile, "%s/.cur_input.%s", tmp_dir, file_extension);
-    } else {
-      sprintf(tmpfile, "%s/.cur_input", tmp_dir);
-    }
-    if (access(tmpfile, F_OK) !=
-        -1)  // there is still a race condition here, but well ...
-      FATAL("AFL_TMPDIR already has an existing temporary input file: %s",
-            tmpfile);
-
-  } else
-
-    tmp_dir = out_dir;
-
   if (dumb_mode) {
 
     if (crash_mode) FATAL("-C and -n are mutually exclusive");
@@ -846,6 +828,32 @@ int main(int argc, char** argv, char** envp) {
 
   if (!timeout_given) find_timeout();
 
+  if ((tmp_dir = getenv("AFL_TMPDIR")) != NULL && !in_place_resume) {
+
+    char tmpfile[file_extension
+                     ? strlen(tmp_dir) + 1 + 10 + 1 + strlen(file_extension) + 1
+                     : strlen(tmp_dir) + 1 + 10 + 1];
+    if (file_extension) {
+
+      sprintf(tmpfile, "%s/.cur_input.%s", tmp_dir, file_extension);
+
+    } else {
+
+      sprintf(tmpfile, "%s/.cur_input", tmp_dir);
+
+    }
+
+    if (access(tmpfile, F_OK) !=
+        -1)  // there is still a race condition here, but well ...
+      FATAL(
+          "AFL_TMPDIR already has an existing temporary input file: %s - if "
+          "this is not from another instance, then just remove the file.",
+          tmpfile);
+
+  } else
+
+    tmp_dir = out_dir;
+
   /* If we don't have a file name chosen yet, use a safe default. */
 
   if (!out_file) {
@@ -883,11 +891,13 @@ int main(int argc, char** argv, char** envp) {
   if (!out_file) setup_stdio_file();
 
   if (cmplog_binary) {
+
     if (unicorn_mode)
       FATAL("CmpLog and Unicorn mode are not compatible at the moment, sorry");
-    if (!qemu_mode)
-      check_binary(cmplog_binary);
+    if (!qemu_mode) check_binary(cmplog_binary);
+
   }
+
   check_binary(argv[optind]);
 
   start_time = get_cur_time();
diff --git a/src/afl-gcc.c b/src/afl-gcc.c
index ff53cc8d..5baec062 100644
--- a/src/afl-gcc.c
+++ b/src/afl-gcc.c
@@ -342,31 +342,30 @@ static void edit_params(u32 argc, char** argv) {
 
 int main(int argc, char** argv) {
 
-  char *env_info =
-        "Environment variables used by afl-gcc:\n"
-        "AFL_CC: path to the C compiler to use\n"
-        "AFL_CXX: path to the C++ compiler to use\n"
-        "AFL_GCJ: path to the java compiler to use\n"
-        "AFL_PATH: path to the instrumenting assembler\n"
-        "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n"
-        "AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
-        "AFL_QUIET: suppress verbose output\n"
-        "AFL_CAL_FAST: speed up the initial calibration\n"
-        "AFL_HARDEN: adds code hardening to catch memory bugs\n"
-        "AFL_USE_ASAN: activate address sanitizer\n"
-        "AFL_USE_MSAN: activate memory sanitizer\n"
-        "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"
-
-        "\nEnvironment variables used by afl-as (called by afl-gcc):\n"
-        "AFL_AS: path to the assembler to use\n"
-        "TMPDIR: set the directory for temporary files of afl-as\n"
-        "TEMP: fall back path to directory for temporary files\n"
-        "TMP: fall back path to directory for temporary files\n"
-        "AFL_INST_RATIO: percentage of branches to instrument\n"
-        "AFL_QUIET: suppress verbose output\n"
-        "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n"
-        "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n"
-	;
+  char* env_info =
+      "Environment variables used by afl-gcc:\n"
+      "AFL_CC: path to the C compiler to use\n"
+      "AFL_CXX: path to the C++ compiler to use\n"
+      "AFL_GCJ: path to the java compiler to use\n"
+      "AFL_PATH: path to the instrumenting assembler\n"
+      "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n"
+      "AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
+      "AFL_QUIET: suppress verbose output\n"
+      "AFL_CAL_FAST: speed up the initial calibration\n"
+      "AFL_HARDEN: adds code hardening to catch memory bugs\n"
+      "AFL_USE_ASAN: activate address sanitizer\n"
+      "AFL_USE_MSAN: activate memory sanitizer\n"
+      "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"
+
+      "\nEnvironment variables used by afl-as (called by afl-gcc):\n"
+      "AFL_AS: path to the assembler to use\n"
+      "TMPDIR: set the directory for temporary files of afl-as\n"
+      "TEMP: fall back path to directory for temporary files\n"
+      "TMP: fall back path to directory for temporary files\n"
+      "AFL_INST_RATIO: percentage of branches to instrument\n"
+      "AFL_QUIET: suppress verbose output\n"
+      "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n"
+      "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n";
 
   if (argc == 2 && strcmp(argv[1], "-h") == 0) {
 
@@ -380,7 +379,7 @@ int main(int argc, char** argv) {
 
   }
 
-  if (isatty(2) && !getenv("AFL_QUIET")) {
+  if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
 
     SAYF(cCYA "afl-cc" VERSION cRST " by Michal Zalewski\n");
     SAYF(cYEL "[!] " cBRI "NOTE: " cRST
@@ -410,7 +409,8 @@ int main(int argc, char** argv) {
         "Setting AFL_HARDEN enables hardening optimizations in the compiled "
         "code.\n\n%s"
 
-        , BIN_PATH, BIN_PATH, env_info);
+        ,
+        BIN_PATH, BIN_PATH, env_info);
 
     exit(1);
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index a46645ab..cd4f2b7b 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -80,7 +80,7 @@ u8 *out_file,                          /* Trace output file                 */
     *stdin_file,                       /* stdin file                        */
     *in_dir,                           /* input folder                      */
     *doc_path,                         /* Path to docs                      */
-    *at_file;                          /* Substitution string for @@        */
+    *at_file = NULL;                          /* Substitution string for @@        */
 
 static u8* in_data;                    /* Input data                        */
 
@@ -901,11 +901,13 @@ int main(int argc, char** argv, char** envp) {
   if (in_dir) {
 
     if (at_file) PFATAL("Options -A and -i are mutually exclusive");
-    at_file = "@@";
+    detect_file_args(argv + optind, "");
 
-  }
+  } else {
 
-  detect_file_args(argv + optind, "");
+    detect_file_args(argv + optind, at_file);
+
+  }
 
   for (i = optind; i < argc; i++)
     if (strcmp(argv[i], "@@") == 0) arg_offset = i;
@@ -1014,12 +1016,12 @@ int main(int argc, char** argv, char** envp) {
         tcnt, highest, total, out_file);
 
   }
-  
+
   if (stdin_file) {
-  
+
     unlink(stdin_file);
     stdin_file = NULL;
-    
+
   }
 
   exit(child_crashed * 2 + child_timed_out);
diff --git a/test/test.sh b/test/test.sh
index 5c4c7cb5..f3b5798f 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -65,6 +65,8 @@ unset AFL_PYTHON_MODULE
 unset AFL_PRELOAD
 unset LD_PRELOAD
 
+rm -rf in in2 out
+
 export ASAN_OPTIONS=detect_leaks=0:allocator_may_return_null=1:abort_on_error=1:symbolize=0
 
 # on OpenBSD we need to work with llvm from /usr/local/bin
@@ -87,7 +89,7 @@ RED="\\033[0;31m"
 YELLOW="\\033[1;93m"
 RESET="\\033[0m"
 
-MEM_LIMIT=150
+MEM_LIMIT=none
 
 export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
 
@@ -172,7 +174,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
     echo 000000000000000000000000 > in/in2
     echo 111 > in/in3
     mkdir -p in2
-    ../afl-cmin -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+    ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
     CNT=`ls in2/* 2>/dev/null | wc -l`
     case "$CNT" in
       *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
@@ -181,7 +183,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
           ;;
     esac
     rm -f in2/in*
-    AFL_PATH=`pwd`/.. ../afl-cmin.bash -i in -o in2 -- ./test-instr.plain >/dev/null
+    AFL_PATH=`pwd`/.. ../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
     CNT=`ls in2/* 2>/dev/null | wc -l`
     case "$CNT" in
       *2) $ECHO "$GREEN[+] afl-cmin.bash correctly minimized the number of testcases" ;;
@@ -189,7 +191,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
           CODE=1
           ;;
     esac
-    ../afl-tmin -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
+    ../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
     SIZE=`ls -l in2/in2 2> /dev/null | awk '{print$5}'`
     test "$SIZE" = 1 && $ECHO "$GREEN[+] afl-tmin correctly minimized the testcase"
     test "$SIZE" = 1 || {
@@ -230,7 +232,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
       } || {
         $ECHO "$GREEN[+] llvm_mode instrumentation present and working correctly"
         TUPLES=`echo 0|../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.plain 2>&1 | grep Captur | awk '{print$3}'`
-        test "$TUPLES" -gt 3 -a "$TUPLES" -lt 6 && {
+        test "$TUPLES" -gt 3 -a "$TUPLES" -lt 7 && {
           $ECHO "$GREEN[+] llvm_mode run reported $TUPLES instrumented locations which is fine"
         } || {
           $ECHO "$RED[!] llvm_mode instrumentation produces weird numbers: $TUPLES"
@@ -288,7 +290,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
       echo 000000000000000000000000 > in/in2
       echo 111 > in/in3
       mkdir -p in2
-      ../afl-cmin -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+      ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
       CNT=`ls in2/* 2>/dev/null | wc -l`
       case "$CNT" in
         *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
@@ -297,7 +299,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
             ;;
       esac
       rm -f in2/in*
-      AFL_PATH=`pwd`/.. ../afl-cmin.bash -i in -o in2 -- ./test-instr.plain >/dev/null
+      AFL_PATH=`pwd`/.. ../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
       CNT=`ls in2/* 2>/dev/null | wc -l`
       case "$CNT" in
         *2) $ECHO "$GREEN[+] afl-cmin.bash correctly minimized the number of testcases" ;;
@@ -305,7 +307,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
             CODE=1
             ;;
       esac
-      ../afl-tmin -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
+      ../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
       SIZE=`ls -l in2/in2 2> /dev/null | awk '{print$5}'`
       test "$SIZE" = 1 && $ECHO "$GREEN[+] afl-tmin correctly minimized the testcase"
       test "$SIZE" = 1 || {
@@ -332,7 +334,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
     CODE=1
   }
   rm -f test-compcov.instrim test.out
-  AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -o test-compcov.compcov test-compcov.c > /dev/null 2> test.out
+  AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -o test-compcov.compcov test-compcov.c > /dev/null 2> test.out
   test -e test-compcov.compcov && {
     grep -Eq " [3-9][0-9] location" test.out && {
       $ECHO "$GREEN[+] llvm_mode laf-intel/compcov feature works correctly"
@@ -346,7 +348,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
   }
   rm -f test-compcov.compcov test.out
   echo foobar.c > whitelist.txt
-  AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1
+  AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1
   test -e test-compcov && {
     grep -q "No instrumentation targets found" test.out && {
       $ECHO "$GREEN[+] llvm_mode whitelist feature works correctly"
@@ -361,7 +363,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
   rm -f test-compcov test.out whitelist.txt
   ../afl-clang-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1
   test -e test-persistent && {
-    echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && {
+    echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && {
       $ECHO "$GREEN[+] llvm_mode persistent mode feature works correctly"
     } || {
       $ECHO "$RED[!] llvm_mode persistent mode feature failed to work"
@@ -470,7 +472,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && {
   rm -f test-compcov test.out whitelist.txt
   ../afl-gcc-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1
   test -e test-persistent && {
-    echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && {
+    echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && {
       $ECHO "$GREEN[+] gcc_plugin persistent mode feature works correctly"
     } || {
       $ECHO "$RED[!] gcc_plugin persistent mode feature failed to work"
@@ -568,7 +570,7 @@ test -e ../afl-qemu-trace && {
       echo 0 > in/in
       $ECHO "$GREY[*] running afl-fuzz for qemu_mode, this will take approx 10 seconds"
       {
-        ../afl-fuzz -V10 -Q -i in -o out -- ./test-instr >>errors 2>&1
+        ../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-instr >>errors 2>&1
       } >>errors 2>&1
       test -n "$( ls out/queue/id:000002* 2> /dev/null )" && {
         $ECHO "$GREEN[+] afl-fuzz is working correctly with qemu_mode"
@@ -582,12 +584,35 @@ test -e ../afl-qemu-trace && {
       }
       rm -f errors
 
+      $ECHO "$GREY[*] running afl-fuzz for qemu_mode AFL_ENTRYPOINT, this will take approx 6 seconds"
+      {
+        {
+          export AFL_ENTRYPOINT=`expr 0x4$(nm test-instr | grep "T main" | awk '{print $1}' | sed 's/^.......//')`
+          $ECHO AFL_ENTRYPOINT=$AFL_ENTRYPOINT - $(m test-instr | grep "T main") - $(file ./test-instr)
+          ../afl-fuzz -m ${MEM_LIMIT} -V2 -Q -i in -o out -- ./test-instr
+          unset AFL_ENTRYPOINT
+        } >>errors 2>&1
+      } >>errors 2>&1
+      test -n "$( ls out/queue/id:000001* 2> /dev/null )" && {
+        $ECHO "$GREEN[+] afl-fuzz is working correctly with qemu_mode AFL_ENTRYPOINT"
+        RUNTIME=`grep execs_done out/fuzzer_stats | awk '{print$3}'`
+      } || {
+        echo CUT------------------------------------------------------------------CUT
+        cat errors
+        echo CUT------------------------------------------------------------------CUT
+        $ECHO "$RED[!] afl-fuzz is not working correctly with qemu_mode AFL_ENTRYPOINT"
+        CODE=1
+      }
+      rm -f errors
+
       test -e ../libcompcov.so && {
         $ECHO "$GREY[*] running afl-fuzz for qemu_mode libcompcov, this will take approx 10 seconds"
         {
           export AFL_PRELOAD=../libcompcov.so 
           export AFL_COMPCOV_LEVEL=2
-          ../afl-fuzz -V10 -Q -i in -o out -- ./test-compcov >>errors 2>&1
+          ../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-compcov >>errors 2>&1
+          unset AFL_PRELOAD
+          unset AFL_COMPCOV_LEVEL
         } >>errors 2>&1
         test -n "$( ls out/queue/id:000002* 2> /dev/null )" && {
           $ECHO "$GREEN[+] afl-fuzz is working correctly with qemu_mode libcompcov"
@@ -611,7 +636,8 @@ test -e ../afl-qemu-trace && {
           export AFL_QEMU_PERSISTENT_GPR=1
           $ECHO "Info: AFL_QEMU_PERSISTENT_ADDR=$AFL_QEMU_PERSISTENT_ADDR <= $(nm test-instr | grep "T main" | awk '{print $1}')"
           file test-instr
-          ../afl-fuzz -V10 -Q -i in -o out -- ./test-instr
+          ../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-instr
+          unset AFL_QEMU_PERSISTENT_ADDR
         } >>errors 2>&1
         test -n "$( ls out/queue/id:000002* 2> /dev/null )" && {
           $ECHO "$GREEN[+] afl-fuzz is working correctly with persistent qemu_mode"
@@ -684,6 +710,7 @@ test -e ../afl-qemu-trace && {
 	    }
             CODE=1
           }
+          unset LD_PRELOAD
         } || {
           echo CUT------------------------------------------------------------------CUT
           cat errors
@@ -725,7 +752,7 @@ test -d ../unicorn_mode/unicornafl && {
       {
         $ECHO "$GREY[*] running afl-fuzz for unicorn_mode, this will take approx 25 seconds"
         {
-          ../afl-fuzz -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1
+          ../afl-fuzz -m ${MEM_LIMIT} -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1
         } >>errors 2>&1
         test -n "$( ls out/queue/id:000002* 2> /dev/null )" && {
           $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode"
@@ -744,7 +771,8 @@ test -d ../unicorn_mode/unicornafl && {
         $ECHO "$GREY[*] running afl-fuzz for unicorn_mode compcov, this will take approx 35 seconds"
         {
           export AFL_COMPCOV_LEVEL=2
-          ../afl-fuzz -V35 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1
+          ../afl-fuzz -m ${MEM_LIMIT} -V35 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1
+          unset AFL_COMPCOV_LEVEL
         } >>errors 2>&1
         test -n "$( ls out/queue/id:000001* 2> /dev/null )" && {
           $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode compcov"
diff --git a/unicorn_mode/samples/c/harness.c b/unicorn_mode/samples/c/harness.c
index 2eddeb8e..eb226f9a 100644
--- a/unicorn_mode/samples/c/harness.c
+++ b/unicorn_mode/samples/c/harness.c
@@ -203,7 +203,7 @@ int main(int argc, char **argv, char **envp) {
     // Setup the Stack
     mem_map_checked(uc, STACK_ADDRESS - STACK_SIZE, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE);
     uint64_t stack_val = STACK_ADDRESS;
-    printf("%lu", stack_val);
+    //printf("Stack at %lu\n", stack_val);
     uc_reg_write(uc, UC_X86_REG_RSP, &stack_val);
 
     // reserve some space for our input data