about summary refs log tree commit diff
path: root/src/afl-fuzz-bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/afl-fuzz-bitmap.c')
-rw-r--r--src/afl-fuzz-bitmap.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 1b9df624..db57061d 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -177,6 +177,40 @@ u32 count_bits(afl_state_t *afl, u8 *mem) {
 
 }
 
+u32 count_bits_len(afl_state_t *afl, u8 *mem, u32 len) {
+
+  u32 *ptr = (u32 *)mem;
+  u32  i = (len >> 2);
+  u32  ret = 0;
+
+  (void)(afl);
+
+  if (len % 4) i++;
+
+  while (i--) {
+
+    u32 v = *(ptr++);
+
+    /* This gets called on the inverse, virgin bitmap; optimize for sparse
+       data. */
+
+    if (v == 0xffffffff) {
+
+      ret += 32;
+      continue;
+
+    }
+
+    v -= ((v >> 1) & 0x55555555);
+    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+    ret += (((v + (v >> 4)) & 0xF0F0F0F) * 0x01010101) >> 24;
+
+  }
+
+  return ret;
+
+}
+
 /* Count the number of bytes set in the bitmap. Called fairly sporadically,
    mostly to update the status screen or calibrate and examine confirmed
    new paths. */
@@ -203,6 +237,32 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) {
 
 }
 
+u32 count_bytes_len(afl_state_t *afl, u8 *mem, u32 len) {
+
+  u32 *ptr = (u32 *)mem;
+  u32  i = (len >> 2);
+  u32  ret = 0;
+
+  (void)(afl);
+
+  if (len % 4) i++;
+
+  while (i--) {
+
+    u32 v = *(ptr++);
+
+    if (!v) { continue; }
+    if (v & 0x000000ff) { ++ret; }
+    if (v & 0x0000ff00) { ++ret; }
+    if (v & 0x00ff0000) { ++ret; }
+    if (v & 0xff000000) { ++ret; }
+
+  }
+
+  return ret;
+
+}
+
 /* Count the number of non-255 bytes set in the bitmap. Used strictly for the
    status screen, several calls per second or so. */
 
@@ -595,7 +655,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
 #endif                                                    /* ^!SIMPLE_FILES */
 
-    add_to_queue(afl, queue_fn, len, 0);
+    add_to_queue(afl, queue_fn, mem, len, afl->queue_top, 0);
 
     if (hnb == 2) {