Index: third_party/afl/src/afl-tmin.c |
diff --git a/third_party/afl/src/afl-tmin.c b/third_party/afl/src/afl-tmin.c |
index 912acae54fd5e1fe8d577254cb37b2cffee49488..c1abbe7c7087f6ca938341250f105cfb0459f1e5 100644 |
--- a/third_party/afl/src/afl-tmin.c |
+++ b/third_party/afl/src/afl-tmin.c |
@@ -46,7 +46,8 @@ |
static s32 child_pid; /* PID of the tested program */ |
-static u8* trace_bits; /* SHM with instrumentation bitmap */ |
+static u8 *trace_bits, /* SHM with instrumentation bitmap */ |
+ *mask_bitmap; /* Mask for trace bits (-B) */ |
static u8 *in_file, /* Minimizer input test case */ |
*out_file, /* Minimizer output file */ |
@@ -118,6 +119,25 @@ static void classify_counts(u8* mem) { |
} |
+/* Apply mask to classified bitmap (if set). */ |
+ |
+static void apply_mask(u32* mem, u32* mask) { |
+ |
+ u32 i = (MAP_SIZE >> 2); |
+ |
+ if (!mask) return; |
+ |
+ while (i--) { |
+ |
+ *mem &= ~*mask; |
+ mem++; |
+ mask++; |
+ |
+ } |
+ |
+} |
+ |
+ |
/* See if any bytes are set in the bitmap. */ |
static inline u8 anything_set(void) { |
@@ -314,6 +334,7 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) { |
FATAL("Unable to execute '%s'", argv[0]); |
classify_counts(trace_bits); |
+ apply_mask((u32*)trace_bits, (u32*)mask_bitmap); |
total_execs++; |
if (stop_soon) { |
@@ -919,6 +940,22 @@ static char** get_qemu_argv(u8* own_loc, char** argv, int argc) { |
} |
+/* Read mask bitmap from file. This is for the -B option. */ |
+ |
+static void read_bitmap(u8* fname) { |
+ |
+ s32 fd = open(fname, O_RDONLY); |
+ |
+ if (fd < 0) PFATAL("Unable to open '%s'", fname); |
+ |
+ ck_read(fd, mask_bitmap, MAP_SIZE, fname); |
+ |
+ close(fd); |
+ |
+} |
+ |
+ |
+ |
/* Main entry point */ |
int main(int argc, char** argv) { |
@@ -931,7 +968,7 @@ int main(int argc, char** argv) { |
SAYF(cCYA "afl-tmin " cBRI VERSION cRST " by <lcamtuf@google.com>\n"); |
- while ((opt = getopt(argc,argv,"+i:o:f:m:t:xeQ")) > 0) |
+ while ((opt = getopt(argc,argv,"+i:o:f:m:t:B:xeQ")) > 0) |
switch (opt) { |
@@ -1023,6 +1060,26 @@ int main(int argc, char** argv) { |
qemu_mode = 1; |
break; |
+ case 'B': /* load bitmap */ |
+ |
+ /* This is a secret undocumented option! It is speculated to be useful |
+ if you have a baseline "boring" input file and another "interesting" |
+ file you want to minimize. |
+ |
+ You can dump a binary bitmap for the boring file using |
+ afl-showmap -b, and then load it into afl-tmin via -B. The minimizer |
+ will then minimize to preserve only the edges that are unique to |
+ the interesting input file, but ignoring everything from the |
+ original map. |
+ |
+ The option may be extended and made more official if it proves |
+ to be useful. */ |
+ |
+ if (mask_bitmap) FATAL("Multiple -B options not supported"); |
+ mask_bitmap = ck_alloc(MAP_SIZE); |
+ read_bitmap(optarg); |
+ break; |
+ |
default: |
usage(argv[0]); |