| 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]);
|
|
|