about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--include/afl-fuzz.h9
-rw-r--r--libtokencap/Makefile3
-rw-r--r--libtokencap/libtokencap.so.c30
-rw-r--r--llvm_mode/README.laf-intel.md3
-rw-r--r--llvm_mode/split-compares-pass.so.cc14
-rw-r--r--qemu_mode/README.md6
-rwxr-xr-xqemu_mode/build_qemu_support.sh3
-rw-r--r--qemu_mode/patches/afl-qemu-common.h12
-rw-r--r--qemu_mode/patches/afl-qemu-floats.h217
-rw-r--r--qemu_mode/patches/i386-fpu_helper.diff54
-rw-r--r--qemu_mode/patches/i386-ops_sse.diff61
-rw-r--r--qemu_mode/patches/softfloat.diff10
-rw-r--r--src/afl-fuzz-init.c21
-rw-r--r--src/afl-fuzz.c2
-rw-r--r--src/afl-gotcpu.c10
15 files changed, 430 insertions, 25 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 1e6140dd..637c2795 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -72,18 +72,21 @@
 #include <sys/file.h>
 
 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
-    defined(__NetBSD__)
+    defined(__NetBSD__) || defined(__DragonFly__)
 #include <sys/sysctl.h>
 #endif                           /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
 
 /* For systems that have sched_setaffinity; right now just Linux, but one
    can hope... */
 
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
+    defined(__DragonFly__)
 #define HAVE_AFFINITY 1
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
 #include <sys/param.h>
+#if defined(__FreeBSD__)
 #include <sys/cpuset.h>
+#endif
 #include <sys/user.h>
 #include <pthread.h>
 #include <pthread_np.h>
diff --git a/libtokencap/Makefile b/libtokencap/Makefile
index 07c13144..441412c7 100644
--- a/libtokencap/Makefile
+++ b/libtokencap/Makefile
@@ -30,6 +30,9 @@ endif
 ifeq "$(shell uname)" "FreeBSD"
   TARGETS = libtokencap.so
 endif
+ifeq "$(shell uname)" "OpenBSD"
+  TARGETS = libtokencap.so
+endif
 all: $(TARGETS)
 
 libtokencap.so: libtokencap.so.c ../config.h
diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c
index ddeae8b8..d33de8a4 100644
--- a/libtokencap/libtokencap.so.c
+++ b/libtokencap/libtokencap.so.c
@@ -27,14 +27,14 @@
 #include "../types.h"
 #include "../config.h"
 
-#if !defined __linux__  && !defined __APPLE__  && !defined __FreeBSD__
+#if !defined __linux__  && !defined __APPLE__  && !defined __FreeBSD__ && !defined __OpenBSD__
 # error "Sorry, this library is unsupported in this platform for now!"
 #endif                         /* !__linux__ && !__APPLE__ && ! __FreeBSD__ */
 
 #if defined __APPLE__
 # include <mach/vm_map.h>
 # include <mach/mach_init.h>
-#elif defined __FreeBSD__
+#elif defined __FreeBSD__ || defined __OpenBSD__
 # include <sys/types.h>
 # include <sys/sysctl.h>
 # include <sys/user.h>
@@ -111,17 +111,29 @@ static void __tokencap_load_mappings(void) {
     }
   }
 
-#elif defined __FreeBSD__
+#elif defined __FreeBSD__ || defined __OpenBSD__
 
+#if defined __FreeBSD__
   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()};
+#elif defined __OpenBSD__
+  int mib[] = {CTL_KERN, KERN_PROC_VMMAP, getpid()};
+#endif
   char *buf, *low, *high;
   size_t miblen = sizeof(mib)/sizeof(mib[0]);
   size_t len;
 
   if (sysctl(mib, miblen, NULL, &len, NULL, 0) == -1) return;
 
+#if defined __FreeBSD__
   len = len * 4 / 3;
+#elif defined __OpenBSD__
+  len -= len % sizeof(struct kinfo_vmentry);
+#endif
+
   buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+  if (!buf) {
+     return;
+  }
 
   if (sysctl(mib, miblen, buf, &len, NULL, 0) == -1) {
 
@@ -137,6 +149,9 @@ static void __tokencap_load_mappings(void) {
 
   while (low < high) {
      struct kinfo_vmentry *region = (struct kinfo_vmentry *)low;
+
+#if defined __FreeBSD__
+
      size_t size = region->kve_structsize;
 
      if (size == 0) break;
@@ -144,6 +159,15 @@ static void __tokencap_load_mappings(void) {
      /* We go through the whole mapping of the process and track read-only addresses */
      if ((region->kve_protection & KVME_PROT_READ) &&
 	 !(region->kve_protection & KVME_PROT_WRITE)) {
+
+#elif defined __OpenBSD__
+
+     size_t size = sizeof (*region);
+
+     /* We go through the whole mapping of the process and track read-only addresses */
+     if ((region->kve_protection & KVE_PROT_READ) &&
+	 !(region->kve_protection & KVE_PROT_WRITE)) {
+#endif
           __tokencap_ro[__tokencap_ro_cnt].st = (void *)region->kve_start;
           __tokencap_ro[__tokencap_ro_cnt].en = (void *)region->kve_end;
 
diff --git a/llvm_mode/README.laf-intel.md b/llvm_mode/README.laf-intel.md
index c787744b..462c7bac 100644
--- a/llvm_mode/README.laf-intel.md
+++ b/llvm_mode/README.laf-intel.md
@@ -35,4 +35,5 @@ bit_width may be 64, 32 or 16.
 A new experimental feature is splitting floating point comparisons into a
 series of sign, exponent and mantissa comparisons followed by splitting each
 of them into 8 bit comparisons when necessary.
-It is activated with the `AFL_LLVM_LAF_SPLIT_COMPARES` setting.
+It is activated with the `AFL_LLVM_LAF_SPLIT_FLOATS` setting, available only
+when `AFL_LLVM_LAF_SPLIT_COMPARES` is set.
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index f1a0f94e..4248b238 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -50,6 +50,8 @@ class SplitComparesTransform : public ModulePass {
   }
 
  private:
+  int enableFPSplit;
+
   size_t splitIntCompares(Module &M, unsigned bitw);
   size_t splitFPCompares(Module &M);
   bool   simplifyCompares(Module &M);
@@ -101,10 +103,11 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
 
           }
 
-          if (selectcmpInst->getPredicate() == CmpInst::FCMP_OGE ||
+          if (enableFPSplit && (
+              selectcmpInst->getPredicate() == CmpInst::FCMP_OGE ||
               selectcmpInst->getPredicate() == CmpInst::FCMP_UGE ||
               selectcmpInst->getPredicate() == CmpInst::FCMP_OLE ||
-              selectcmpInst->getPredicate() == CmpInst::FCMP_ULE) {
+              selectcmpInst->getPredicate() == CmpInst::FCMP_ULE)) {
 
             auto op0 = selectcmpInst->getOperand(0);
             auto op1 = selectcmpInst->getOperand(1);
@@ -1039,6 +1042,8 @@ bool SplitComparesTransform::runOnModule(Module &M) {
   char *bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
   if (!bitw_env) bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
   if (bitw_env) { bitw = atoi(bitw_env); }
+  
+  enableFPSplit = getenv("AFL_LLVM_LAF_SPLIT_FLOATS") != NULL;
 
   simplifyCompares(M);
 
@@ -1048,8 +1053,9 @@ bool SplitComparesTransform::runOnModule(Module &M) {
     errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
               "heiko@hexco.de\n";
 
-  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/qemu_mode/README.md b/qemu_mode/README.md
index a85407e4..c88c1e41 100644
--- a/qemu_mode/README.md
+++ b/qemu_mode/README.md
@@ -100,7 +100,11 @@ afl-fuzz).
 AFL_COMPCOV_LEVEL=1 is to instrument comparisons with only immediate
 values / read-only memory. AFL_COMPCOV_LEVEL=2 instruments all
 comparison instructions and memory comparison functions when libcompcov
-is preloaded. Comparison instructions are currently instrumented only
+is preloaded.
+AFL_COMPCOV_LEVEL=3 has the same effects of AFL_COMPCOV_LEVEL=2 but enables also
+the instrumentation of the floating-point comparisons on x86 and x86_64 (experimental).
+
+Integer comparison instructions are currently instrumented only
 on the x86, x86_64 and ARM targets.
 
 Highly recommended.
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index f18cbdf3..6b9f91f9 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -150,6 +150,9 @@ patch -p1 <../patches/translate-all.diff || exit 1
 patch -p1 <../patches/tcg.diff || exit 1
 patch -p1 <../patches/i386-translate.diff || exit 1
 patch -p1 <../patches/arm-translate.diff || exit 1
+patch -p1 <../patches/i386-ops_sse.diff || exit 1
+patch -p1 <../patches/i386-fpu_helper.diff || exit 1
+patch -p1 <../patches/softfloat.diff || exit 1
 
 echo "[+] Patching done."
 
diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h
index 409a7eab..d4024353 100644
--- a/qemu_mode/patches/afl-qemu-common.h
+++ b/qemu_mode/patches/afl-qemu-common.h
@@ -31,6 +31,9 @@
 
  */
 
+#ifndef __AFL_QEMU_COMMON
+#define __AFL_QEMU_COMMON
+
 #include "../../config.h"
 
 #ifndef CPU_NB_REGS
@@ -81,6 +84,12 @@ void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc,
 
 void tcg_gen_afl_maybe_log_call(target_ulong cur_loc);
 
+void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2,
+                              void *status);
+void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2,
+                              void *status);
+void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1,
+                              floatx80 arg2);
 
 /* Check if an address is valid in the current mapping */
 
@@ -99,3 +108,6 @@ static inline int is_valid_addr(target_ulong addr) {
   return 1;
 
 }
+
+#endif
+
diff --git a/qemu_mode/patches/afl-qemu-floats.h b/qemu_mode/patches/afl-qemu-floats.h
new file mode 100644
index 00000000..0b2ac2ae
--- /dev/null
+++ b/qemu_mode/patches/afl-qemu-floats.h
@@ -0,0 +1,217 @@
+/*
+   american fuzzy lop++ - high-performance binary-only instrumentation
+   -------------------------------------------------------------------
+
+   Originally written by Andrew Griffiths <agriffiths@google.com> and
+                         Michal Zalewski
+
+   TCG instrumentation and block chaining support by Andrea Biondo
+                                      <andrea.biondo965@gmail.com>
+
+   QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero
+   counters by Andrea Fioraldi <andreafioraldi@gmail.com>
+
+   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
+   Copyright 2019 AFLplusplus Project. All rights reserved.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at:
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   This code is a shim patched into the separately-distributed source
+   code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality
+   to implement AFL-style instrumentation and to take care of the remaining
+   parts of the AFL fork server logic.
+
+   The resulting QEMU binary is essentially a standalone instrumentation
+   tool; for an example of how to leverage it for other purposes, you can
+   have a look at afl-showmap.c.
+
+ */
+
+#include "tcg.h"
+#include "afl-qemu-common.h"
+
+union afl_float32 {
+  float32 f;
+  struct {
+    u64 sign :  1;
+    u64 exp  :  7;
+    u64 frac : 24;
+  };
+};
+
+
+union afl_float64 {
+  float64 f;
+  struct {
+    u64 sign :  1;
+    u64 exp  : 11;
+    u64 frac : 52;
+  };
+};
+
+
+// TODO 16 and 128 bits floats
+// TODO figure out why float*_unpack_canonical does not work
+
+void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2,
+                              void* status) {
+
+  cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
+  cur_loc &= MAP_SIZE - 7;
+
+  if (cur_loc >= afl_inst_rms) return;
+
+  //float_status* s = (float_status*)status;
+  //FloatParts    a = float32_unpack_canonical(arg1, s);
+  //FloatParts    b = float32_unpack_canonical(arg2, s);
+  union afl_float32 a = { .f = arg1 };
+  union afl_float32 b = { .f = arg2 };
+
+  // if (is_nan(a.cls) || is_nan(b.cls)) return;
+
+  register uintptr_t idx = cur_loc;
+
+  if (a.sign != b.sign) return;
+  INC_AFL_AREA(idx);
+  if (a.exp != b.exp) return;
+  INC_AFL_AREA(idx + 1);
+
+  if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) {
+
+    INC_AFL_AREA(idx + 2);
+    if ((a.frac & 0xff00) == (b.frac & 0xff00)) { INC_AFL_AREA(idx + 3); }
+
+  }
+
+}
+
+void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2,
+                              void* status) {
+
+  cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
+  cur_loc &= MAP_SIZE - 7;
+
+  if (cur_loc >= afl_inst_rms) return;
+
+  //float_status* s = (float_status*)status;
+  //FloatParts    a = float64_unpack_canonical(arg1, s);
+  //FloatParts    b = float64_unpack_canonical(arg2, s);
+  union afl_float64 a = { .f = arg1 };
+  union afl_float64 b = { .f = arg2 };
+
+  // if (is_nan(a.cls) || is_nan(b.cls)) return;
+
+  register uintptr_t idx = cur_loc;
+
+  if (a.sign == b.sign) INC_AFL_AREA(idx);
+  if ((a.exp & 0xff00) == (b.exp & 0xff00)) {
+
+    INC_AFL_AREA(idx + 1);
+    if ((a.exp & 0xff) == (b.exp & 0xff)) INC_AFL_AREA(idx + 2);
+
+  }
+
+  if ((a.frac & 0xff000000000000) == (b.frac & 0xff000000000000)) {
+
+    INC_AFL_AREA(idx + 3);
+    if ((a.frac & 0xff0000000000) == (b.frac & 0xff0000000000)) {
+
+      INC_AFL_AREA(idx + 4);
+      if ((a.frac & 0xff00000000) == (b.frac & 0xff00000000)) {
+
+        INC_AFL_AREA(idx + 5);
+        if ((a.frac & 0xff000000) == (b.frac & 0xff000000)) {
+
+          INC_AFL_AREA(idx + 6);
+          if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) {
+
+            INC_AFL_AREA(idx + 7);
+            if ((a.frac & 0xff00) == (b.frac & 0xff00)) INC_AFL_AREA(idx + 8);
+
+          }
+
+        }
+
+      }
+
+    }
+
+  }
+
+}
+
+void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1,
+                              floatx80 arg2) {
+
+  cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
+  cur_loc &= MAP_SIZE - 7;
+
+  if (cur_loc >= afl_inst_rms) return;
+
+  if (floatx80_invalid_encoding(arg1) || floatx80_invalid_encoding(arg2))
+    return;
+
+  flag a_sign = extractFloatx80Sign(arg1);
+  flag b_sign = extractFloatx80Sign(arg2);
+
+  /*if (((extractFloatx80Exp(arg1) == 0x7fff) &&
+       (extractFloatx80Frac(arg1) << 1)) ||
+      ((extractFloatx80Exp(arg2) == 0x7fff) &&
+       (extractFloatx80Frac(arg2) << 1)))
+    return;*/
+
+  register uintptr_t idx = cur_loc;
+
+  if (a_sign == b_sign) INC_AFL_AREA(idx);
+
+  if ((arg1.high & 0x7f00) == (arg2.high & 0x7f00)) {
+
+    INC_AFL_AREA(idx + 1);
+    if ((arg1.high & 0xff) == (arg2.high & 0xff)) INC_AFL_AREA(idx + 2);
+
+  }
+
+  if ((arg1.low & 0xff00000000000000) == (arg2.low & 0xff00000000000000)) {
+
+    INC_AFL_AREA(idx + 3);
+    if ((arg1.low & 0xff000000000000) == (arg2.low & 0xff000000000000)) {
+
+      INC_AFL_AREA(idx + 4);
+      if ((arg1.low & 0xff0000000000) == (arg2.low & 0xff0000000000)) {
+
+        INC_AFL_AREA(idx + 5);
+        if ((arg1.low & 0xff00000000) == (arg2.low & 0xff00000000)) {
+
+          INC_AFL_AREA(idx + 6);
+          if ((arg1.low & 0xff000000) == (arg2.low & 0xff000000)) {
+
+            INC_AFL_AREA(idx + 7);
+            if ((arg1.low & 0xff0000) == (arg2.low & 0xff0000)) {
+
+              INC_AFL_AREA(idx + 8);
+              if ((arg1.low & 0xff00) == (arg2.low & 0xff00)) {
+
+                INC_AFL_AREA(idx + 9);
+                //if ((arg1.low & 0xff) == (arg2.low & 0xff))
+                //  INC_AFL_AREA(idx + 10);
+
+              }
+
+            }
+
+          }
+
+        }
+
+      }
+
+    }
+
+  }
+
+}
+
diff --git a/qemu_mode/patches/i386-fpu_helper.diff b/qemu_mode/patches/i386-fpu_helper.diff
new file mode 100644
index 00000000..3bd09d9c
--- /dev/null
+++ b/qemu_mode/patches/i386-fpu_helper.diff
@@ -0,0 +1,54 @@
+diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c
+index ea5a0c48..89901315 100644
+--- a/target/i386/fpu_helper.c
++++ b/target/i386/fpu_helper.c
+@@ -384,10 +384,16 @@ void helper_fxchg_ST0_STN(CPUX86State *env, int st_index)
+ 
+ static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500};
+ 
++#include "../patches/afl-qemu-common.h"
++
+ void helper_fcom_ST0_FT0(CPUX86State *env)
+ {
+     int ret;
+ 
++    if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_80(env->eip, ST0, FT0);
++
+     ret = floatx80_compare(ST0, FT0, &env->fp_status);
+     env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
+ }
+@@ -396,6 +402,10 @@ void helper_fucom_ST0_FT0(CPUX86State *env)
+ {
+     int ret;
+ 
++    if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_80(env->eip, ST0, FT0);
++
+     ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status);
+     env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
+ }
+@@ -407,6 +417,10 @@ void helper_fcomi_ST0_FT0(CPUX86State *env)
+     int eflags;
+     int ret;
+ 
++    if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_80(env->eip, ST0, FT0);
++
+     ret = floatx80_compare(ST0, FT0, &env->fp_status);
+     eflags = cpu_cc_compute_all(env, CC_OP);
+     eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
+@@ -418,6 +432,10 @@ void helper_fucomi_ST0_FT0(CPUX86State *env)
+     int eflags;
+     int ret;
+ 
++    if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_80(env->eip, ST0, FT0);
++
+     ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status);
+     eflags = cpu_cc_compute_all(env, CC_OP);
+     eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
diff --git a/qemu_mode/patches/i386-ops_sse.diff b/qemu_mode/patches/i386-ops_sse.diff
new file mode 100644
index 00000000..d2779ea8
--- /dev/null
+++ b/qemu_mode/patches/i386-ops_sse.diff
@@ -0,0 +1,61 @@
+diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h
+index ed059897..a5296caa 100644
+--- a/target/i386/ops_sse.h
++++ b/target/i386/ops_sse.h
+@@ -997,6 +997,8 @@ SSE_HELPER_CMP(cmpord, FPU_CMPORD)
+ 
+ static const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
+ 
++#include "../patches/afl-qemu-common.h"
++
+ void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s)
+ {
+     int ret;
+@@ -1004,6 +1006,11 @@ void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s)
+ 
+     s0 = d->ZMM_S(0);
+     s1 = s->ZMM_S(0);
++
++   if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status);
++
+     ret = float32_compare_quiet(s0, s1, &env->sse_status);
+     CC_SRC = comis_eflags[ret + 1];
+ }
+@@ -1015,6 +1022,11 @@ void helper_comiss(CPUX86State *env, Reg *d, Reg *s)
+ 
+     s0 = d->ZMM_S(0);
+     s1 = s->ZMM_S(0);
++
++   if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status);
++
+     ret = float32_compare(s0, s1, &env->sse_status);
+     CC_SRC = comis_eflags[ret + 1];
+ }
+@@ -1026,6 +1038,11 @@ void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s)
+ 
+     d0 = d->ZMM_D(0);
+     d1 = s->ZMM_D(0);
++
++   if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status);
++
+     ret = float64_compare_quiet(d0, d1, &env->sse_status);
+     CC_SRC = comis_eflags[ret + 1];
+ }
+@@ -1037,6 +1054,11 @@ void helper_comisd(CPUX86State *env, Reg *d, Reg *s)
+ 
+     d0 = d->ZMM_D(0);
+     d1 = s->ZMM_D(0);
++
++   if (afl_compcov_level > 2 && env->eip < afl_end_code &&
++        env->eip >= afl_start_code)
++      afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status);
++
+     ret = float64_compare(d0, d1, &env->sse_status);
+     CC_SRC = comis_eflags[ret + 1];
+ }
diff --git a/qemu_mode/patches/softfloat.diff b/qemu_mode/patches/softfloat.diff
new file mode 100644
index 00000000..86ffb97f
--- /dev/null
+++ b/qemu_mode/patches/softfloat.diff
@@ -0,0 +1,10 @@
+diff --git a/fpu/softfloat.c b/fpu/softfloat.c
+index e1eef954..2f8d0d62 100644
+--- a/fpu/softfloat.c
++++ b/fpu/softfloat.c
+@@ -7205,3 +7205,5 @@ float128 float128_scalbn(float128 a, int n, float_status *status)
+                                          , status);
+ 
+ }
++
++#include "../../patches/afl-qemu-floats.h"
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index a77904b5..64b24087 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -32,7 +32,7 @@
 
 void bind_to_free_cpu(void) {
 
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
   cpu_set_t c;
 #elif defined(__NetBSD__)
   cpuset_t*          c;
@@ -117,7 +117,7 @@ void bind_to_free_cpu(void) {
   }
 
   closedir(d);
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
   struct kinfo_proc* procs;
   size_t             nprocs;
   size_t             proccount;
@@ -138,8 +138,13 @@ void bind_to_free_cpu(void) {
 
   for (i = 0; i < proccount; i++) {
 
+#if defined(__FreeBSD__)
     if (procs[i].ki_oncpu < sizeof(cpu_used) && procs[i].ki_pctcpu > 2)
       cpu_used[procs[i].ki_oncpu] = 1;
+#elif defined(__DragonFly__)
+    if (procs[i].kp_lwp.kl_cpuid < sizeof(cpu_used) && procs[i].kp_lwp.kl_pctcpu > 2)
+      cpu_used[procs[i].kp_lwp.kl_cpuid] = 1;
+#endif
 
   }
 
@@ -200,7 +205,7 @@ void bind_to_free_cpu(void) {
 
   cpu_aff = i;
 
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
   CPU_ZERO(&c);
   CPU_SET(i, &c);
 #elif defined(__NetBSD__)
@@ -212,7 +217,7 @@ void bind_to_free_cpu(void) {
 
 #if defined(__linux__)
   if (sched_setaffinity(0, sizeof(c), &c)) PFATAL("sched_setaffinity failed");
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
   if (pthread_setaffinity_np(pthread_self(), sizeof(c), &c))
     PFATAL("pthread_setaffinity failed");
 #elif defined(__NetBSD__)
@@ -729,7 +734,7 @@ void pivot_inputs(void) {
         use_name += 6;
       else
         use_name = rsl;
-      nfn = alloc_printf("%s/queue/id:%06u,orig:%s", out_dir, id, use_name);
+      nfn = alloc_printf("%s/queue/id:%06u,time:0,orig:%s", out_dir, id, use_name);
 
 #else
 
@@ -871,7 +876,7 @@ double get_runnable_processes(void) {
   static double res;
 
 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
-    defined(__NetBSD__)
+    defined(__NetBSD__) || defined(__DragonFly__)
 
   /* I don't see any portable sysctl or so that would quickly give us the
      number of runnable processes; the 1-minute load average can be a
@@ -1605,7 +1610,7 @@ void check_cpu_governor(void) {
 
 void get_core_count(void) {
 
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
 
   size_t s = sizeof(cpu_core_count);
 
@@ -1651,7 +1656,7 @@ void get_core_count(void) {
 
     cur_runnable = (u32)get_runnable_processes();
 
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
 
     /* Add ourselves, since the 1-minute average doesn't include that yet. */
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 877df0d3..14d7802d 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -554,7 +554,7 @@ int main(int argc, char** argv) {
   if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI"))
     FATAL("AFL_NO_UI and AFL_FORCE_UI are mutually exclusive");
 
-  if (strchr(argv[optind], '/') == NULL)
+  if (strchr(argv[optind], '/') == NULL && !unicorn_mode)
     WARNF(cLRD
           "Target binary called without a prefixed path, make sure you are "
           "fuzzing the right binary: " cRST "%s",
diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c
index 850943dd..fe5d035f 100644
--- a/src/afl-gotcpu.c
+++ b/src/afl-gotcpu.c
@@ -52,12 +52,14 @@
 #include "types.h"
 #include "debug.h"
 
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__DragonFly__)
 #define HAVE_AFFINITY 1
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
 #include <pthread.h>
 #include <pthread_np.h>
+#if defined(__FreeBSD__)
 #include <sys/cpuset.h>
+#endif
 #define cpu_set_t cpuset_t
 #elif defined(__NetBSD__)
 #include <pthread.h>
@@ -168,7 +170,7 @@ int main(int argc, char** argv) {
     if (!fr) {
 
       u32 util_perc;
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
       cpu_set_t c;
 
       CPU_ZERO(&c);
@@ -188,7 +190,7 @@ int main(int argc, char** argv) {
 	PFATAL("thread_policy_set failed");
 #endif
 
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
       if (pthread_setaffinity_np(pthread_self(), sizeof(c), &c))
         PFATAL("pthread_setaffinity_np failed");
 #endif