about summary refs log tree commit diff
path: root/instrumentation
diff options
context:
space:
mode:
Diffstat (limited to 'instrumentation')
-rw-r--r--instrumentation/LLVMInsTrim.so.cc14
-rw-r--r--instrumentation/MarkNodes.cc2
-rw-r--r--instrumentation/README.instrument_list.md53
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc11
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc10
-rw-r--r--instrumentation/afl-compiler-rt.o.c189
-rw-r--r--instrumentation/afl-gcc-pass.so.cc11
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc6
-rw-r--r--instrumentation/afl-llvm-lto-instrumentation.so.cc35
-rw-r--r--instrumentation/afl-llvm-pass.so.cc12
-rw-r--r--instrumentation/cmplog-instructions-pass.cc89
-rw-r--r--instrumentation/compare-transform-pass.so.cc29
-rw-r--r--instrumentation/split-compares-pass.so.cc10
13 files changed, 348 insertions, 123 deletions
diff --git a/instrumentation/LLVMInsTrim.so.cc b/instrumentation/LLVMInsTrim.so.cc
index 6b3231e6..235ee30f 100644
--- a/instrumentation/LLVMInsTrim.so.cc
+++ b/instrumentation/LLVMInsTrim.so.cc
@@ -200,7 +200,7 @@ struct InsTrim : public ModulePass {
     LoadInst *      PrevCtx = NULL;  // for CTX sensitive coverage
 
     if (ctx_str)
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__HAIKU__)
       AFLContext = new GlobalVariable(
           M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
 #else
@@ -211,7 +211,7 @@ struct InsTrim : public ModulePass {
 
 #ifdef AFL_HAVE_VECTOR_INTRINSICS
     if (ngram_size)
-  #ifdef __ANDROID__
+  #if defined(__ANDROID__) || defined(__HAIKU__)
       AFLPrevLoc = new GlobalVariable(
           M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
           /* Initializer */ nullptr, "__afl_prev_loc");
@@ -224,7 +224,7 @@ struct InsTrim : public ModulePass {
   #endif
     else
 #endif
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__HAIKU__)
       AFLPrevLoc = new GlobalVariable(
           M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
 #else
@@ -407,10 +407,10 @@ struct InsTrim : public ModulePass {
           // does the function have calls? and is any of the calls larger than
           // one basic block?
           has_calls = 0;
-          for (auto &BB : F) {
+          for (auto &BB2 : F) {
 
             if (has_calls) break;
-            for (auto &IN : BB) {
+            for (auto &IN : BB2) {
 
               CallInst *callInst = nullptr;
               if ((callInst = dyn_cast<CallInst>(&IN))) {
@@ -454,7 +454,7 @@ struct InsTrim : public ModulePass {
 
           auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin());
           DenseMap<BasicBlock *, unsigned> PredMap;
-          for (auto PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) {
+          for (PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) {
 
             BasicBlock *PBB = *PI;
             auto        It = PredMap.insert({PBB, genLabel()});
@@ -568,7 +568,7 @@ struct InsTrim : public ModulePass {
                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
 
-      OKF("Instrumented %u locations (%llu, %llu) (%s mode)\n", total_instr,
+      OKF("Instrumented %d locations (%llu, %llu) (%s mode)\n", total_instr,
           total_rs, total_hs, modeline);
 
     }
diff --git a/instrumentation/MarkNodes.cc b/instrumentation/MarkNodes.cc
index 20a7df35..b77466d9 100644
--- a/instrumentation/MarkNodes.cc
+++ b/instrumentation/MarkNodes.cc
@@ -332,11 +332,11 @@ bool                             Indistinguish(uint32_t node1, uint32_t node2) {
 
 void MakeUniq(uint32_t now) {
 
-  bool StopFlag = false;
   if (Marked.find(now) == Marked.end()) {
 
     for (uint32_t pred1 : t_Pred[now]) {
 
+      bool StopFlag = false;
       for (uint32_t pred2 : t_Pred[now]) {
 
         if (pred1 == pred2) continue;
diff --git a/instrumentation/README.instrument_list.md b/instrumentation/README.instrument_list.md
index 122be2b6..b47b50f6 100644
--- a/instrumentation/README.instrument_list.md
+++ b/instrumentation/README.instrument_list.md
@@ -1,8 +1,9 @@
 # Using afl++ with partial instrumentation
 
-  This file describes how to selectively instrument only source files
-  or functions that are of interest to you using the LLVM and GCC_PLUGIN
-  instrumentation provided by afl++.
+  This file describes two different mechanisms to selectively instrument
+  only specific parts in the target.
+
+  Both mechanisms work for LLVM and GCC_PLUGIN, but not for afl-clang/afl-gcc.
 
 ## 1) Description and purpose
 
@@ -12,28 +13,42 @@ the program, leaving the rest uninstrumented. This helps to focus the fuzzer
 on the important parts of the program, avoiding undesired noise and
 disturbance by uninteresting code being exercised.
 
-For this purpose, a "partial instrumentation" support en par with llvm sancov
-is provided by afl++ that allows to specify on a source file and function
-level which function should be compiled with or without instrumentation.
+For this purpose, "partial instrumentation" support is provided by afl++ that
+allows to specify what should be instrumented and what not.
+
+Both mechanisms can be used together.
+
+## 2) Selective instrumentation with __AFL_COVERAGE_... directives
+
+In this mechanism the selective instrumentation is done in the source code.
 
-Note: When using PCGUARD mode - and llvm 12+ - you can use this instead:
-https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation
+After the includes a special define has to be made, eg.:
+
+```
+#include <stdio.h>
+#include <stdint.h>
+// ...
+ 
+__AFL_COVERAGE();  // <- required for this feature to work
+```
 
-The llvm sancov list format is fully supported by afl++, however afl++ has
-more flexibility.
+If you want to disable the coverage at startup until you specify coverage
+should be started, then add `__AFL_COVERAGE_START_OFF();` at that position.
 
-## 2a) Building the LLVM module
+From here on out you have the following macros available that you can use
+in any function where you want:
 
-The new code is part of the existing afl++ LLVM module in the instrumentation/
-subdirectory. There is nothing specifically to do for the build :)
+  * `__AFL_COVERAGE_ON();` - enable coverage from this point onwards
+  * `__AFL_COVERAGE_OFF();` - disable coverage from this point onwards
+  * `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point
+  * `__AFL_COVERAGE_SKIP();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
 
-## 2b) Building the GCC module
+## 3) Selective instrumenation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
 
-The new code is part of the existing afl++ GCC_PLUGIN module in the
-instrumentation/ subdirectory. There is nothing specifically to do for
-the build :)
+This feature is equivalent to llvm 12 sancov feature and allows to specify
+on a filename and/or function name level to instrument these or skip them.
 
-## 3) How to use the partial instrumentation mode
+### 3a) How to use the partial instrumentation mode
 
 In order to build with partial instrumentation, you need to build with
 afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++.
@@ -90,7 +105,7 @@ fun: MallocFoo
 ```
 Note that whitespace is ignored and comments (`# foo`) are supported.
 
-## 4) UNIX-style pattern matching
+### 3b) UNIX-style pattern matching
 
 You can add UNIX-style pattern matching in the "instrument file list" entries.
 See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags.
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 82e55218..016ac71f 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1111,7 +1111,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
       OKF("Instrumented %u locations with no collisions (on average %llu "
-          "collisions would be in afl-gcc/afl-clang-fast) (%s mode).",
+          "collisions would be in afl-gcc/vanilla AFL) (%s mode).",
           inst, calculateCollisions(inst), modeline);
 
     }
@@ -1403,24 +1403,17 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
 
   BasicBlock::iterator IP = BB.getFirstInsertionPt();
   bool                 IsEntryBB = &BB == &F.getEntryBlock();
-  DebugLoc             EntryLoc;
+
   if (IsEntryBB) {
 
-    if (auto SP = F.getSubprogram())
-      EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
     // Keep static allocas and llvm.localescape calls in the entry block.  Even
     // if we aren't splitting the block, it's nice for allocas to be before
     // calls.
     IP = PrepareToSplitEntryBlock(BB, IP);
 
-  } else {
-
-    EntryLoc = IP->getDebugLoc();
-
   }
 
   IRBuilder<> IRB(&*IP);
-  IRB.SetCurrentDebugLocation(EntryLoc);
   if (Options.TracePC) {
 
     IRB.CreateCall(SanCovTracePC)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 102b44a4..ecd6bc9b 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -1163,24 +1163,18 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
 
   BasicBlock::iterator IP = BB.getFirstInsertionPt();
   bool                 IsEntryBB = &BB == &F.getEntryBlock();
-  DebugLoc             EntryLoc;
+
   if (IsEntryBB) {
 
-    if (auto SP = F.getSubprogram())
-      EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
     // Keep static allocas and llvm.localescape calls in the entry block.  Even
     // if we aren't splitting the block, it's nice for allocas to be before
     // calls.
     IP = PrepareToSplitEntryBlock(BB, IP);
 
-  } else {
-
-    EntryLoc = IP->getDebugLoc();
-
   }
 
   IRBuilder<> IRB(&*IP);
-  IRB.SetCurrentDebugLocation(EntryLoc);
+
   if (Options.TracePC) {
 
     IRB.CreateCall(SanCovTracePC);
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index cddde87c..e31bff16 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -76,7 +76,9 @@
 #endif
 
 u8   __afl_area_initial[MAP_INITIAL_SIZE];
+u8 * __afl_area_ptr_dummy = __afl_area_initial;
 u8 * __afl_area_ptr = __afl_area_initial;
+u8 * __afl_area_ptr_backup = __afl_area_initial;
 u8 * __afl_dictionary;
 u8 * __afl_fuzz_ptr;
 u32  __afl_fuzz_len_dummy;
@@ -87,7 +89,12 @@ u32 __afl_map_size = MAP_SIZE;
 u32 __afl_dictionary_len;
 u64 __afl_map_addr;
 
-#ifdef __ANDROID__
+// for the __AFL_COVERAGE_ON/__AFL_COVERAGE_OFF features to work:
+int __afl_selective_coverage __attribute__((weak));
+int __afl_selective_coverage_start_off __attribute__((weak));
+int __afl_selective_coverage_temp = 1;
+
+#if defined(__ANDROID__) || defined(__HAIKU__)
 PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX];
 u32        __afl_prev_ctx;
 u32        __afl_cmp_counter;
@@ -100,6 +107,7 @@ __thread u32        __afl_cmp_counter;
 int __afl_sharedmem_fuzzing __attribute__((weak));
 
 struct cmp_map *__afl_cmp_map;
+struct cmp_map *__afl_cmp_map_backup;
 
 /* Child pid? */
 
@@ -230,7 +238,7 @@ static void __afl_map_shm_fuzz() {
 static void __afl_map_shm(void) {
 
   // if we are not running in afl ensure the map exists
-  if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_initial; }
+  if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_ptr_dummy; }
 
   char *id_str = getenv(SHM_ENV_VAR);
 
@@ -295,11 +303,17 @@ static void __afl_map_shm(void) {
 
     if (__afl_area_ptr && __afl_area_ptr != __afl_area_initial) {
 
-      if (__afl_map_addr)
+      if (__afl_map_addr) {
+
         munmap((void *)__afl_map_addr, __afl_final_loc);
-      else
+
+      } else {
+
         free(__afl_area_ptr);
-      __afl_area_ptr = __afl_area_initial;
+
+      }
+
+      __afl_area_ptr = __afl_area_ptr_dummy;
 
     }
 
@@ -352,6 +366,18 @@ static void __afl_map_shm(void) {
 #else
     u32 shm_id = atoi(id_str);
 
+    if (__afl_map_size && __afl_map_size > MAP_SIZE) {
+
+      u8 *map_env = getenv("AFL_MAP_SIZE");
+      if (!map_env || atoi(map_env) < MAP_SIZE) {
+
+        send_forkserver_error(FS_ERROR_MAP_SIZE);
+        _exit(1);
+
+      }
+
+    }
+
     __afl_area_ptr = shmat(shm_id, (void *)__afl_map_addr, 0);
 
     /* Whooooops. */
@@ -396,9 +422,42 @@ static void __afl_map_shm(void) {
 
     free(__afl_area_ptr);
     __afl_area_ptr = NULL;
-    if (__afl_final_loc > MAP_INITIAL_SIZE)
+
+    if (__afl_final_loc > MAP_INITIAL_SIZE) {
+
       __afl_area_ptr = malloc(__afl_final_loc);
-    if (!__afl_area_ptr) __afl_area_ptr = __afl_area_initial;
+
+    }
+
+    if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_ptr_dummy; }
+
+  }
+
+  __afl_area_ptr_backup = __afl_area_ptr;
+
+  if (__afl_selective_coverage) {
+
+    if (__afl_map_size > MAP_INITIAL_SIZE) {
+
+      __afl_area_ptr_dummy = malloc(__afl_map_size);
+
+      if (__afl_area_ptr_dummy) {
+
+        if (__afl_selective_coverage_start_off) {
+
+          __afl_area_ptr = __afl_area_ptr_dummy;
+
+        }
+
+      } else {
+
+        fprintf(stderr, "Error: __afl_selective_coverage failed!\n");
+        __afl_selective_coverage = 0;
+        // continue;
+
+      }
+
+    }
 
   }
 
@@ -449,6 +508,8 @@ static void __afl_map_shm(void) {
     __afl_cmp_map = shmat(shm_id, NULL, 0);
 #endif
 
+    __afl_cmp_map_backup = __afl_cmp_map;
+
     if (!__afl_cmp_map || __afl_cmp_map == (void *)-1) {
 
       perror("shmat for cmplog");
@@ -683,7 +744,7 @@ static void __afl_start_forkserver(void) {
 #endif
 
   u8  tmp[4] = {0, 0, 0, 0};
-  u32 status = 0;
+  u32 status_for_fsrv = 0;
   u32 already_read_first = 0;
   u32 was_killed;
 
@@ -691,17 +752,26 @@ static void __afl_start_forkserver(void) {
 
   void (*old_sigchld_handler)(int) = 0;  // = signal(SIGCHLD, SIG_DFL);
 
-  if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
-    status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
-  if (__afl_dictionary_len && __afl_dictionary) status |= FS_OPT_AUTODICT;
-  if (__afl_sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
-  if (status) status |= (FS_OPT_ENABLED);
-  memcpy(tmp, &status, 4);
+  if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) {
+
+    status_for_fsrv |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
+
+  }
+
+  if (__afl_dictionary_len && __afl_dictionary) {
+
+    status_for_fsrv |= FS_OPT_AUTODICT;
+
+  }
+
+  if (__afl_sharedmem_fuzzing != 0) { status_for_fsrv |= FS_OPT_SHDMEM_FUZZ; }
+  if (status_for_fsrv) { status_for_fsrv |= (FS_OPT_ENABLED); }
+  memcpy(tmp, &status_for_fsrv, 4);
 
   /* Phone home and tell the parent that we're OK. If parent isn't there,
      assume we're not running in forkserver mode and just execute program. */
 
-  if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
+  if (write(FORKSRV_FD + 1, tmp, 4) != 4) { return; }
 
   if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
 
@@ -726,7 +796,6 @@ static void __afl_start_forkserver(void) {
 
       // great lets pass the dictionary through the forkserver FD
       u32 len = __afl_dictionary_len, offset = 0;
-      s32 ret;
 
       if (write(FORKSRV_FD + 1, &len, 4) != 4) {
 
@@ -738,6 +807,7 @@ static void __afl_start_forkserver(void) {
 
       while (len != 0) {
 
+        s32 ret;
         ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len);
 
         if (ret < 1) {
@@ -894,6 +964,8 @@ int __afl_persistent_loop(unsigned int max_cnt) {
 
     cycle_cnt = max_cnt;
     first_pass = 0;
+    __afl_selective_coverage_temp = 1;
+
     return 1;
 
   }
@@ -906,6 +978,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
 
       __afl_area_ptr[0] = 1;
       memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
+      __afl_selective_coverage_temp = 1;
 
       return 1;
 
@@ -915,7 +988,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
          follows the loop is not traced. We do that by pivoting back to the
          dummy output region. */
 
-      __afl_area_ptr = __afl_area_initial;
+      __afl_area_ptr = __afl_area_ptr_dummy;
 
     }
 
@@ -937,7 +1010,7 @@ void __afl_manual_init(void) {
     init_done = 1;
     is_persistent = 0;
     __afl_sharedmem_fuzzing = 0;
-    if (__afl_area_ptr == NULL) __afl_area_ptr = __afl_area_initial;
+    if (__afl_area_ptr == NULL) __afl_area_ptr = __afl_area_ptr_dummy;
 
     if (getenv("AFL_DEBUG"))
       fprintf(stderr,
@@ -998,7 +1071,12 @@ __attribute__((constructor(1))) void __afl_auto_second(void) {
     else
       ptr = (u8 *)malloc(__afl_final_loc);
 
-    if (ptr && (ssize_t)ptr != -1) __afl_area_ptr = ptr;
+    if (ptr && (ssize_t)ptr != -1) {
+
+      __afl_area_ptr = ptr;
+      __afl_area_ptr_backup = __afl_area_ptr;
+
+    }
 
   }
 
@@ -1014,7 +1092,12 @@ __attribute__((constructor(0))) void __afl_auto_first(void) {
 
   ptr = (u8 *)malloc(1024000);
 
-  if (ptr && (ssize_t)ptr != -1) __afl_area_ptr = ptr;
+  if (ptr && (ssize_t)ptr != -1) {
+
+    __afl_area_ptr = ptr;
+    __afl_area_ptr_backup = __afl_area_ptr;
+
+  }
 
 }
 
@@ -1304,3 +1387,69 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
 
 }
 
+/* COVERAGE manipulation features */
+
+// this variable is then used in the shm setup to create an additional map
+// if __afl_map_size > MAP_SIZE or cmplog is used.
+// Especially with cmplog this would result in a ~260MB mem increase per
+// target run.
+
+// disable coverage from this point onwards until turned on again
+void __afl_coverage_off() {
+
+  if (likely(__afl_selective_coverage)) {
+
+    __afl_area_ptr = __afl_area_ptr_dummy;
+    __afl_cmp_map = NULL;
+
+  }
+
+}
+
+// enable coverage
+void __afl_coverage_on() {
+
+  if (likely(__afl_selective_coverage && __afl_selective_coverage_temp)) {
+
+    __afl_area_ptr = __afl_area_ptr_backup;
+    __afl_cmp_map = __afl_cmp_map_backup;
+
+  }
+
+}
+
+// discard all coverage up to this point
+void __afl_coverage_discard() {
+
+  memset(__afl_area_ptr_backup, 0, __afl_map_size);
+  __afl_area_ptr_backup[0] = 1;
+
+  if (__afl_cmp_map) { memset(__afl_cmp_map, 0, sizeof(struct cmp_map)); }
+
+}
+
+// discard the testcase
+void __afl_coverage_skip() {
+
+  __afl_coverage_discard();
+
+  if (likely(is_persistent && __afl_selective_coverage)) {
+
+    __afl_coverage_off();
+    __afl_selective_coverage_temp = 0;
+
+  } else {
+
+    exit(0);
+
+  }
+
+}
+
+// mark this area as especially interesting
+void __afl_coverage_interesting(u8 val, u32 id) {
+
+  __afl_area_ptr[id] = val;
+
+}
+
diff --git a/instrumentation/afl-gcc-pass.so.cc b/instrumentation/afl-gcc-pass.so.cc
index 25437609..41bb5152 100644
--- a/instrumentation/afl-gcc-pass.so.cc
+++ b/instrumentation/afl-gcc-pass.so.cc
@@ -228,7 +228,7 @@ struct afl_pass : gimple_opt_pass {
   const bool neverZero;
 
   /* Count instrumented blocks. */
-  int inst_blocks;
+  unsigned int inst_blocks;
 
   virtual unsigned int execute(function *fn) {
 
@@ -444,8 +444,10 @@ struct afl_pass : gimple_opt_pass {
     DECL_EXTERNAL(decl) = 1;
     DECL_ARTIFICIAL(decl) = 1;
     TREE_STATIC(decl) = 1;
+#if !defined(__ANDROID__) && !defined(__HAIKU__)
     set_decl_tls_model(
         decl, (flag_pic ? TLS_MODEL_INITIAL_EXEC : TLS_MODEL_LOCAL_EXEC));
+#endif
     return decl;
 
   }
@@ -920,8 +922,9 @@ int plugin_init(struct plugin_name_args *  info,
                 struct plugin_gcc_version *version) {
 
   if (!plugin_default_version_check(version, &gcc_version))
-    FATAL(G_("GCC and plugin have incompatible versions, expected GCC %d.%d"),
-          GCCPLUGIN_VERSION_MAJOR, GCCPLUGIN_VERSION_MINOR);
+    FATAL(G_("GCC and plugin have incompatible versions, expected GCC %s, "
+             "is %s"),
+          gcc_version.basever, version->basever);
 
   /* Show a banner.  */
   bool quiet = false;
@@ -931,7 +934,7 @@ int plugin_init(struct plugin_name_args *  info,
     quiet = true;
 
   /* Decide instrumentation ratio.  */
-  int inst_ratio = 100;
+  unsigned int inst_ratio = 100U;
   if (char *inst_ratio_str = getenv("AFL_INST_RATIO"))
     if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || !inst_ratio ||
         inst_ratio > 100)
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index bd8eb27a..a4b33732 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -355,7 +355,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
                 *Str2P = callInst->getArgOperand(1);
           std::string Str1, Str2;
           StringRef   TmpStr;
-          bool        HasStr1 = getConstantStringInfo(Str1P, TmpStr);
+          bool        HasStr1;
+          getConstantStringInfo(Str1P, TmpStr);
           if (TmpStr.empty()) {
 
             HasStr1 = false;
@@ -367,7 +368,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
           }
 
-          bool HasStr2 = getConstantStringInfo(Str2P, TmpStr);
+          bool HasStr2;
+          getConstantStringInfo(Str2P, TmpStr);
           if (TmpStr.empty()) {
 
             HasStr2 = false;
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index 9e026e57..13dca8c4 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -70,7 +70,7 @@ class AFLLTOPass : public ModulePass {
     if (getenv("AFL_DEBUG")) debug = 1;
     if ((ptr = getenv("AFL_LLVM_LTO_STARTID")) != NULL)
       if ((afl_global_id = atoi(ptr)) < 0 || afl_global_id >= MAP_SIZE)
-        FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is not between 0 and %d\n",
+        FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is not between 0 and %u\n",
               ptr, MAP_SIZE - 1);
 
     skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
@@ -100,9 +100,9 @@ class AFLLTOPass : public ModulePass {
 
 bool AFLLTOPass::runOnModule(Module &M) {
 
-  LLVMContext &                    C = M.getContext();
-  std::vector<std::string>         dictionary;
-  std::vector<CallInst *>          calls;
+  LLVMContext &            C = M.getContext();
+  std::vector<std::string> dictionary;
+  //  std::vector<CallInst *>          calls;
   DenseMap<Value *, std::string *> valueMap;
   std::vector<BasicBlock *>        BlockList;
   char *                           ptr;
@@ -471,7 +471,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
                   *Str2P = callInst->getArgOperand(1);
             std::string Str1, Str2;
             StringRef   TmpStr;
-            bool        HasStr1 = getConstantStringInfo(Str1P, TmpStr);
+            bool        HasStr1;
+            getConstantStringInfo(Str1P, TmpStr);
             if (TmpStr.empty()) {
 
               HasStr1 = false;
@@ -483,7 +484,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
             }
 
-            bool HasStr2 = getConstantStringInfo(Str2P, TmpStr);
+            bool HasStr2;
+            getConstantStringInfo(Str2P, TmpStr);
             if (TmpStr.empty()) {
 
               HasStr2 = false;
@@ -671,7 +673,6 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
             if (!be_quiet) {
 
-              std::string outstring;
               fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen,
                       thestring.length());
               for (uint8_t i = 0; i < thestring.length(); i++) {
@@ -799,7 +800,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
           if (documentFile) {
 
-            fprintf(documentFile, "ModuleID=%llu Function=%s edgeID=%u\n",
+            fprintf(documentFile, "ModuleID=%llu Function=%s edgeID=%d\n",
                     moduleID, F.getName().str().c_str(), afl_global_id);
 
           }
@@ -871,10 +872,10 @@ bool AFLLTOPass::runOnModule(Module &M) {
     while ((map = map >> 1))
       pow2map++;
     WARNF(
-        "We have %u blocks to instrument but the map size is only %u. Either "
-        "edit config.h and set MAP_SIZE_POW2 from %u to %u, then recompile "
+        "We have %d blocks to instrument but the map size is only %u. Either "
+        "edit config.h and set MAP_SIZE_POW2 from %d to %u, then recompile "
         "afl-fuzz and llvm_mode and then make this target - or set "
-        "AFL_MAP_SIZE with at least size %u when running afl-fuzz with this "
+        "AFL_MAP_SIZE with at least size %d when running afl-fuzz with this "
         "target.",
         afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map, afl_global_id);
 
@@ -937,8 +938,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
     if (dictionary.size()) {
 
-      size_t memlen = 0, count = 0, offset = 0;
-      char * ptr;
+      size_t memlen = 0, count = 0;
 
       // sort and unique the dictionary
       std::sort(dictionary.begin(), dictionary.end());
@@ -953,14 +953,14 @@ bool AFLLTOPass::runOnModule(Module &M) {
       }
 
       if (!be_quiet)
-        printf("AUTODICTIONARY: %lu string%s found\n", count,
+        printf("AUTODICTIONARY: %zu string%s found\n", count,
                count == 1 ? "" : "s");
 
       if (count) {
 
         if ((ptr = (char *)malloc(memlen + count)) == NULL) {
 
-          fprintf(stderr, "Error: malloc for %lu bytes failed!\n",
+          fprintf(stderr, "Error: malloc for %zu bytes failed!\n",
                   memlen + count);
           exit(-1);
 
@@ -968,6 +968,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
         count = 0;
 
+        size_t offset = 0;
         for (auto token : dictionary) {
 
           if (offset + token.length() < 0xfffff0 && count < MAX_AUTO_EXTRAS) {
@@ -1031,8 +1032,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
                getenv("AFL_USE_MSAN") ? ", MSAN" : "",
                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
-      OKF("Instrumented %u locations with no collisions (on average %llu "
-          "collisions would be in afl-gcc/afl-clang-fast) (%s mode).",
+      OKF("Instrumented %d locations with no collisions (on average %llu "
+          "collisions would be in afl-gcc/vanilla AFL) (%s mode).",
           inst_blocks, calculateCollisions(inst_blocks), modeline);
 
     }
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index 8c8c987a..57ff3b47 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -241,7 +241,7 @@ bool AFLCoverage::runOnModule(Module &M) {
   GlobalVariable *AFLContext = NULL;
 
   if (ctx_str)
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__HAIKU__)
     AFLContext = new GlobalVariable(
         M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
 #else
@@ -252,7 +252,7 @@ bool AFLCoverage::runOnModule(Module &M) {
 
 #ifdef AFL_HAVE_VECTOR_INTRINSICS
   if (ngram_size)
-  #ifdef __ANDROID__
+  #if defined(__ANDROID__) || defined(__HAIKU__)
     AFLPrevLoc = new GlobalVariable(
         M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
         /* Initializer */ nullptr, "__afl_prev_loc");
@@ -265,7 +265,7 @@ bool AFLCoverage::runOnModule(Module &M) {
   #endif
   else
 #endif
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__HAIKU__)
     AFLPrevLoc = new GlobalVariable(
         M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
 #else
@@ -327,10 +327,10 @@ bool AFLCoverage::runOnModule(Module &M) {
 
         // does the function have calls? and is any of the calls larger than one
         // basic block?
-        for (auto &BB : F) {
+        for (auto &BB_2 : F) {
 
           if (has_calls) break;
-          for (auto &IN : BB) {
+          for (auto &IN : BB_2) {
 
             CallInst *callInst = nullptr;
             if ((callInst = dyn_cast<CallInst>(&IN))) {
@@ -628,7 +628,7 @@ bool AFLCoverage::runOnModule(Module &M) {
                getenv("AFL_USE_MSAN") ? ", MSAN" : "",
                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
-      OKF("Instrumented %u locations (%s mode, ratio %u%%).", inst_blocks,
+      OKF("Instrumented %d locations (%s mode, ratio %u%%).", inst_blocks,
           modeline, inst_ratio);
 
     }
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 9921de0c..3499ccf0 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -186,16 +186,19 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
               selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
               selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
               selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
-              selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) {
-
-            auto op0 = selectcmpInst->getOperand(0);
-            auto op1 = selectcmpInst->getOperand(1);
-
-            IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
-            IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
-
-            /* this is probably not needed but we do it anyway */
-            if (!intTyOp0 || !intTyOp1) { continue; }
+              selectcmpInst->getPredicate() == CmpInst::ICMP_SLE ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_OGE ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_UGE ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_OLE ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_ULE ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_UGT ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_OLT ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_ULT ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_UEQ ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_OEQ ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_UNE ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_ONE) {
 
             icomps.push_back(selectcmpInst);
 
@@ -221,16 +224,66 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
     auto op0 = selectcmpInst->getOperand(0);
     auto op1 = selectcmpInst->getOperand(1);
 
-    IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
-    IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
+    IntegerType *        intTyOp0 = NULL;
+    IntegerType *        intTyOp1 = NULL;
+    unsigned             max_size = 0;
+    std::vector<Value *> args;
 
-    unsigned max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
-                            ? intTyOp0->getBitWidth()
-                            : intTyOp1->getBitWidth();
+    if (selectcmpInst->getOpcode() == Instruction::FCmp) {
 
-    std::vector<Value *> args;
-    args.push_back(op0);
-    args.push_back(op1);
+      auto ty0 = op0->getType();
+      if (ty0->isHalfTy()
+#if LLVM_VERSION_MAJOR >= 11
+          || ty0->isBFloatTy()
+#endif
+      )
+        max_size = 16;
+      else if (ty0->isFloatTy())
+        max_size = 32;
+      else if (ty0->isDoubleTy())
+        max_size = 64;
+
+      if (max_size) {
+
+        Value *V0 = IRB.CreateBitCast(op0, IntegerType::get(C, max_size));
+        intTyOp0 = dyn_cast<IntegerType>(V0->getType());
+        Value *V1 = IRB.CreateBitCast(op1, IntegerType::get(C, max_size));
+        intTyOp1 = dyn_cast<IntegerType>(V1->getType());
+
+        if (intTyOp0 && intTyOp1) {
+
+          max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
+                         ? intTyOp0->getBitWidth()
+                         : intTyOp1->getBitWidth();
+          args.push_back(V0);
+          args.push_back(V1);
+
+        } else {
+
+          max_size = 0;
+
+        }
+
+      }
+
+    } else {
+
+      intTyOp0 = dyn_cast<IntegerType>(op0->getType());
+      intTyOp1 = dyn_cast<IntegerType>(op1->getType());
+
+      if (intTyOp0 && intTyOp1) {
+
+        max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
+                       ? intTyOp0->getBitWidth()
+                       : intTyOp1->getBitWidth();
+        args.push_back(op0);
+        args.push_back(op1);
+
+      }
+
+    }
+
+    if (max_size < 8 || max_size > 64 || !intTyOp0 || !intTyOp1) continue;
 
     switch (max_size) {
 
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index de8b97f0..da5cf7e9 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -68,7 +68,7 @@ class CompareTransform : public ModulePass {
   const char *getPassName() const override {
 
 #else
-  StringRef getPassName() const override {
+  StringRef      getPassName() const override {
 
 #endif
     return "transforms compare functions";
@@ -101,22 +101,31 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
   IntegerType *                    Int64Ty = IntegerType::getInt64Ty(C);
 
 #if LLVM_VERSION_MAJOR < 9
-  Constant *
+  Function *tolowerFn;
 #else
-  FunctionCallee
+  FunctionCallee tolowerFn;
 #endif
-      c = M.getOrInsertFunction("tolower", Int32Ty, Int32Ty
+  {
+
+#if LLVM_VERSION_MAJOR < 9
+    Constant *
+#else
+    FunctionCallee
+#endif
+        c = M.getOrInsertFunction("tolower", Int32Ty, Int32Ty
 #if LLVM_VERSION_MAJOR < 5
-                                ,
-                                NULL
+                                  ,
+                                  NULL
 #endif
-      );
+        );
 #if LLVM_VERSION_MAJOR < 9
-  Function *tolowerFn = cast<Function>(c);
+    tolowerFn = cast<Function>(c);
 #else
-  FunctionCallee tolowerFn = c;
+    tolowerFn = c;
 #endif
 
+  }
+
   /* iterate over all functions, bbs and instruction and add suitable calls to
    * strcmp/memcmp/strncmp/strcasecmp/strncasecmp */
   for (auto &F : M) {
@@ -234,7 +243,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 
             if (!HasStr2) {
 
-              auto *Ptr = dyn_cast<ConstantExpr>(Str1P);
+              Ptr = dyn_cast<ConstantExpr>(Str1P);
               if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) {
 
                 if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 33a87719..b6d8c466 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -53,7 +53,7 @@ class SplitComparesTransform : public ModulePass {
 
  public:
   static char ID;
-  SplitComparesTransform() : ModulePass(ID) {
+  SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) {
 
     initInstrumentList();
 
@@ -555,6 +555,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
         if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
 
           if (selectcmpInst->getPredicate() == CmpInst::FCMP_OEQ ||
+              selectcmpInst->getPredicate() == CmpInst::FCMP_UEQ ||
               selectcmpInst->getPredicate() == CmpInst::FCMP_ONE ||
               selectcmpInst->getPredicate() == CmpInst::FCMP_UNE ||
               selectcmpInst->getPredicate() == CmpInst::FCMP_UGT ||
@@ -735,6 +736,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
     BasicBlock * signequal2_bb = signequal_bb;
     switch (FcmpInst->getPredicate()) {
 
+      case CmpInst::FCMP_UEQ:
       case CmpInst::FCMP_OEQ:
         icmp_exponent_result =
             CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
@@ -816,6 +818,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
       switch (FcmpInst->getPredicate()) {
 
+        case CmpInst::FCMP_UEQ:
         case CmpInst::FCMP_OEQ:
           /* if the exponents are satifying the compare do a fraction cmp in
            * middle_bb */
@@ -900,11 +903,11 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
     /* compare the fractions of the operands */
     Instruction *icmp_fraction_result;
-    Instruction *icmp_fraction_result2;
     BasicBlock * middle2_bb = middle_bb;
     PHINode *    PN2 = nullptr;
     switch (FcmpInst->getPredicate()) {
 
+      case CmpInst::FCMP_UEQ:
       case CmpInst::FCMP_OEQ:
         icmp_fraction_result =
             CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
@@ -927,6 +930,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
       case CmpInst::FCMP_OLT:
       case CmpInst::FCMP_ULT: {
 
+        Instruction *icmp_fraction_result2;
+
         middle2_bb = middle_bb->splitBasicBlock(
             BasicBlock::iterator(middle_bb->getTerminator()));
 
@@ -980,6 +985,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
     switch (FcmpInst->getPredicate()) {
 
+      case CmpInst::FCMP_UEQ:
       case CmpInst::FCMP_OEQ:
         /* unequal signs cannot be equal values */
         /* goto false branch */