LTO: apply laf-intel+redqueen/cmplog at link time

This commit is contained in:
van Hauser
2020-08-13 21:27:11 +02:00
parent 8e984c2aa0
commit 212bb990b7
11 changed files with 213 additions and 53 deletions

View File

@ -97,7 +97,13 @@ ifneq "$(shell uname -m)" "x86_64"
endif endif
endif endif
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) ifdef DEBUG
$(info Compiling DEBUG version of binaries)
CFLAGS += -ggdb3 -O0 -Wall -Wextra -Werror
else
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
endif
override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wpointer-arith \ override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wpointer-arith \
-I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \ -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
@ -305,6 +311,7 @@ help:
@echo "==========================================" @echo "=========================================="
@echo STATIC - compile AFL++ static @echo STATIC - compile AFL++ static
@echo ASAN_BUILD - compiles with memory sanitizer for debug purposes @echo ASAN_BUILD - compiles with memory sanitizer for debug purposes
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
@echo PROFILING - compile afl-fuzz with profiling information @echo PROFILING - compile afl-fuzz with profiling information
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms @echo AFL_NO_X86 - if compiling on non-intel/amd platforms
@echo "==========================================" @echo "=========================================="

View File

@ -178,6 +178,7 @@ These build options exist:
* STATIC - compile AFL++ static * STATIC - compile AFL++ static
* ASAN_BUILD - compiles with memory sanitizer for debug purposes * ASAN_BUILD - compiles with memory sanitizer for debug purposes
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
* PROFILING - compile with profiling information (gprof) * PROFILING - compile with profiling information (gprof)
* NO_PYTHON - disable python support * NO_PYTHON - disable python support
* AFL_NO_X86 - if compiling on non-intel/amd platforms * AFL_NO_X86 - if compiling on non-intel/amd platforms
@ -509,8 +510,8 @@ fuzz your target.
On the same machine - due to the design of how afl++ works - there is a maximum On the same machine - due to the design of how afl++ works - there is a maximum
number of CPU cores/threads that are useful, use more and the overall performance number of CPU cores/threads that are useful, use more and the overall performance
degrades instead. This value depends on the target and the limit is between 48 degrades instead. This value depends on the target, and the limit is between 32
and 96 cores/threads per machine. and 64 cores/threads per machine.
There should be one main fuzzer (`-M main` option) and as many secondary There should be one main fuzzer (`-M main` option) and as many secondary
fuzzers (eg `-S variant1`) as you have cores that you use. fuzzers (eg `-S variant1`) as you have cores that you use.
@ -562,11 +563,18 @@ To have only the summary use the `-s` switch e.g.: `afl-whatsup -s output/`
The `paths found` value is a bad indicator how good the coverage is. The `paths found` value is a bad indicator how good the coverage is.
A better indicator - if you use default llvm instrumentation with at least A better indicator - if you use default llvm instrumentation with at least
version 9 - to use `afl-showmap` on the target with all inputs of the version 9 - is to use `afl-showmap` with the collect coverage option `-C` on
queue/ directory one after another and collecting the found edge IDs (`-o N.out`), the output directory:
removing the counters of the edge IDs, making them unique - and there you have ```
the total number of found instrumented edges. $ afl-showmap -C -i out -o /dev/null -- ./target -params @@
...
[*] Using SHARED MEMORY FUZZING feature.
[*] Target map size: 9960
[+] Processed 7849 input files.
[+] Captured 4331 tuples (highest value 255, total values 67130596) in '/dev/nul
l'.
[+] A coverage of 4331 edges were achieved out of 9960 existing (43.48%) with 7849 input files.
```
It is even better to check out the exact lines of code that have been reached - It is even better to check out the exact lines of code that have been reached -
and which have not been found so far. and which have not been found so far.
@ -580,6 +588,11 @@ then terminate it. The main node will pick it up and make it available to the
other secondary nodes over time. Set `export AFL_NO_AFFINITY=1` if you have no other secondary nodes over time. Set `export AFL_NO_AFFINITY=1` if you have no
free core. free core.
Note that you in nearly all cases you can never reach full coverage. A lot of
functionality is usually behind options that were not activated or fuzz e.g.
if you fuzz a library to convert image formats and your target is the png to
tiff API then you will not touch any of the other library APIs and features.
#### e) How long to fuzz a target? #### e) How long to fuzz a target?
This is a difficult question. This is a difficult question.

View File

@ -4,7 +4,6 @@
- AFL_MAP_SIZE for qemu_mode and unicorn_mode - AFL_MAP_SIZE for qemu_mode and unicorn_mode
- CPU affinity for many cores? There seems to be an issue > 96 cores - CPU affinity for many cores? There seems to be an issue > 96 cores
- feature for afl-showmap to generate the coverage for all queue entries
- afl-plot to support multiple plot_data - afl-plot to support multiple plot_data
## Further down the road ## Further down the road

View File

@ -32,6 +32,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- skipping ctors and ifuncs for instrumentation - skipping ctors and ifuncs for instrumentation
- LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR - LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR
for a fixed map address (eg. 0x10000) for a fixed map address (eg. 0x10000)
- LTO: laf-intel and redqueen/cmplogare are now applied at link time
to prevent llvm optimizing away the splits
- LTO: autodictionary mode is a default - LTO: autodictionary mode is a default
- LTO: instrim instrumentation disabled, only classic support used - LTO: instrim instrumentation disabled, only classic support used
as it is always better as it is always better

View File

@ -246,6 +246,13 @@ static void edit_params(u32 argc, char **argv, char **envp) {
// laf // laf
if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) { if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) {
if (lto_mode) {
cc_params[cc_par_cnt++] =
alloc_printf("-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path);
} else {
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
@ -254,9 +261,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} }
}
if (getenv("LAF_TRANSFORM_COMPARES") || if (getenv("LAF_TRANSFORM_COMPARES") ||
getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) { getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
if (lto_mode) {
cc_params[cc_par_cnt++] = alloc_printf(
"-Wl,-mllvm=-load=%s/compare-transform-pass.so", obj_path);
} else {
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
@ -265,9 +281,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} }
}
if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") || if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) { getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) {
if (lto_mode) {
cc_params[cc_par_cnt++] =
alloc_printf("-Wl,-mllvm=-load=%s/split-compares-pass.so", obj_path);
} else {
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
@ -276,12 +301,25 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} }
}
// /laf // /laf
unsetenv("AFL_LD"); unsetenv("AFL_LD");
unsetenv("AFL_LD_CALLER"); unsetenv("AFL_LD_CALLER");
if (cmplog_mode) { if (cmplog_mode) {
if (lto_mode) {
cc_params[cc_par_cnt++] =
alloc_printf("-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path);
cc_params[cc_par_cnt++] =
alloc_printf("-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path);
cc_params[cc_par_cnt++] = alloc_printf(
"-Wl,-mllvm=-load=%s/cmplog-instructions-pass.so", obj_path);
} else {
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-Xclang";
@ -301,6 +339,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
cc_params[cc_par_cnt++] = cc_params[cc_par_cnt++] =
alloc_printf("%s/cmplog-instructions-pass.so", obj_path); alloc_printf("%s/cmplog-instructions-pass.so", obj_path);
}
cc_params[cc_par_cnt++] = "-fno-inline"; cc_params[cc_par_cnt++] = "-fno-inline";
} }
@ -314,6 +354,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", AFL_REAL_LD); cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", AFL_REAL_LD);
cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
/* /*
The current LTO instrim mode is not good, so we disable it The current LTO instrim mode is not good, so we disable it
if (instrument_mode == INSTRUMENT_CFG) if (instrument_mode == INSTRUMENT_CFG)
@ -321,6 +362,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so", alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so",
obj_path); else obj_path); else
*/ */
cc_params[cc_par_cnt++] = alloc_printf( cc_params[cc_par_cnt++] = alloc_printf(
"-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path); "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path);
cc_params[cc_par_cnt++] = lto_flag; cc_params[cc_par_cnt++] = lto_flag;

View File

@ -284,3 +284,7 @@ static RegisterStandardPasses RegisterCmpLogInstructionsPass(
static RegisterStandardPasses RegisterCmpLogInstructionsPass0( static RegisterStandardPasses RegisterCmpLogInstructionsPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogInstructionsPass); PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogInstructionsPass);
static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
registerCmpLogInstructionsPass);

View File

@ -204,3 +204,7 @@ static RegisterStandardPasses RegisterCmpLogRoutinesPass(
static RegisterStandardPasses RegisterCmpLogRoutinesPass0( static RegisterStandardPasses RegisterCmpLogRoutinesPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogRoutinesPass); PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogRoutinesPass);
static RegisterStandardPasses RegisterCmpLogRoutinesPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
registerCmpLogRoutinesPass);

View File

@ -585,3 +585,6 @@ static RegisterStandardPasses RegisterCompTransPass(
static RegisterStandardPasses RegisterCompTransPass0( static RegisterStandardPasses RegisterCompTransPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerCompTransPass); PassManagerBuilder::EP_EnabledOnOptLevel0, registerCompTransPass);
static RegisterStandardPasses RegisterCompTransPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCompTransPass);

View File

@ -1342,3 +1342,7 @@ static RegisterStandardPasses RegisterSplitComparesPass(
static RegisterStandardPasses RegisterSplitComparesTransPass0( static RegisterStandardPasses RegisterSplitComparesTransPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitComparesPass); PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitComparesPass);
static RegisterStandardPasses RegisterSplitComparesTransPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
registerSplitComparesPass);

View File

@ -439,3 +439,7 @@ static RegisterStandardPasses RegisterSplitSwitchesTransPass(
static RegisterStandardPasses RegisterSplitSwitchesTransPass0( static RegisterStandardPasses RegisterSplitSwitchesTransPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitSwitchesTransPass); PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitSwitchesTransPass);
static RegisterStandardPasses RegisterSplitSwitchesTransPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
registerSplitSwitchesTransPass);

View File

@ -68,9 +68,11 @@ static char *stdin_file; /* stdin file */
static u8 *in_dir = NULL, /* input folder */ static u8 *in_dir = NULL, /* input folder */
*out_file = NULL, *at_file = NULL; /* Substitution string for @@ */ *out_file = NULL, *at_file = NULL; /* Substitution string for @@ */
static u8 *in_data; /* Input data */ static u8 *in_data, /* Input data */
*coverage_map; /* Coverage map */
static u32 total, highest; /* tuple content information */ static u64 total; /* tuple content information */
static u32 tcnt, highest; /* tuple content information */
static u32 in_len, /* Input data length */ static u32 in_len, /* Input data length */
arg_offset; /* Total number of execs */ arg_offset; /* Total number of execs */
@ -83,7 +85,8 @@ static u8 quiet_mode, /* Hide non-essential messages? */
cmin_mode, /* Generate output in afl-cmin mode? */ cmin_mode, /* Generate output in afl-cmin mode? */
binary_mode, /* Write output as a binary map */ binary_mode, /* Write output as a binary map */
keep_cores, /* Allow coredumps? */ keep_cores, /* Allow coredumps? */
remove_shm = 1; /* remove shmem? */ remove_shm = 1, /* remove shmem? */
collect_coverage; /* collect coverage */
static volatile u8 stop_soon, /* Ctrl-C pressed? */ static volatile u8 stop_soon, /* Ctrl-C pressed? */
child_crashed; /* Child crashed? */ child_crashed; /* Child crashed? */
@ -175,6 +178,25 @@ static void at_exit_handler(void) {
} }
/* Analyze results. */
static void analyze_results(afl_forkserver_t *fsrv) {
u32 i;
for (i = 0; i < map_size; i++) {
if (fsrv->trace_bits[i]) {
total += fsrv->trace_bits[i];
if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i];
if (!coverage_map[i]) { coverage_map[i] = 1; }
}
}
}
/* Write results. */ /* Write results. */
static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
@ -588,9 +610,14 @@ static void usage(u8 *argv0) {
" (Not necessary, here for consistency with other afl-* " " (Not necessary, here for consistency with other afl-* "
"tools)\n\n" "tools)\n\n"
"Other settings:\n" "Other settings:\n"
" -i dir - process all files in this directory, -o must be a " " -i dir - process all files in this directory, must be combined "
"with -o.\n"
" With -C, -o is a file, without -C it must be a "
"directory\n" "directory\n"
" and each bitmap will be written there individually.\n" " and each bitmap will be written there individually.\n"
" -C - collect coverage, writes all edges to -o and gives a "
"summary\n"
" Must be combined with -i.\n"
" -q - sink program's output and don't show messages\n" " -q - sink program's output and don't show messages\n"
" -e - show edge coverage only, ignore hit counts\n" " -e - show edge coverage only, ignore hit counts\n"
" -r - show real tuple values instead of AFL filter values\n" " -r - show real tuple values instead of AFL filter values\n"
@ -624,7 +651,6 @@ int main(int argc, char **argv_orig, char **envp) {
s32 opt, i; s32 opt, i;
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
u32 tcnt = 0;
char **use_argv; char **use_argv;
char **argv = argv_cpy_dup(argc, argv_orig); char **argv = argv_cpy_dup(argc, argv_orig);
@ -639,10 +665,14 @@ int main(int argc, char **argv_orig, char **envp) {
if (getenv("AFL_QUIET") != NULL) { be_quiet = 1; } if (getenv("AFL_QUIET") != NULL) { be_quiet = 1; }
while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqZQUWbcrh")) > 0) { while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqCZQUWbcrh")) > 0) {
switch (opt) { switch (opt) {
case 'C':
collect_coverage = 1;
break;
case 'i': case 'i':
if (in_dir) { FATAL("Multiple -i options not supported"); } if (in_dir) { FATAL("Multiple -i options not supported"); }
in_dir = optarg; in_dir = optarg;
@ -820,6 +850,13 @@ int main(int argc, char **argv_orig, char **envp) {
if (optind == argc || !out_file) { usage(argv[0]); } if (optind == argc || !out_file) { usage(argv[0]); }
if (in_dir) {
if (!out_file && !collect_coverage)
FATAL("for -i you need to specify either -C and/or -o");
}
if (fsrv->qemu_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; } if (fsrv->qemu_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; }
if (unicorn_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; } if (unicorn_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; }
@ -910,7 +947,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (in_dir) { if (in_dir) {
DIR * dir_in, *dir_out; DIR * dir_in, *dir_out = NULL;
struct dirent *dir_ent; struct dirent *dir_ent;
int done = 0; int done = 0;
u8 infile[PATH_MAX], outfile[PATH_MAX]; u8 infile[PATH_MAX], outfile[PATH_MAX];
@ -924,12 +961,26 @@ int main(int argc, char **argv_orig, char **envp) {
fsrv->dev_null_fd = open("/dev/null", O_RDWR); fsrv->dev_null_fd = open("/dev/null", O_RDWR);
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
// if a queue subdirectory exists switch to that
u8 *dn = alloc_printf("%s/queue", in_dir);
if ((dir_in = opendir(in_dir))) {
closedir(dir_in);
in_dir = dn;
} else
ck_free(dn);
if (!be_quiet) ACTF("Reading from directory '%s'...", in_dir);
if (!(dir_in = opendir(in_dir))) { if (!(dir_in = opendir(in_dir))) {
PFATAL("cannot open directory %s", in_dir); PFATAL("cannot open directory %s", in_dir);
} }
if (!collect_coverage) {
if (!(dir_out = opendir(out_file))) { if (!(dir_out = opendir(out_file))) {
if (mkdir(out_file, 0700)) { if (mkdir(out_file, 0700)) {
@ -940,6 +991,15 @@ int main(int argc, char **argv_orig, char **envp) {
} }
} else {
if ((coverage_map = (u8 *)malloc(map_size)) == NULL)
FATAL("coult not grab memory");
edges_only = 0;
raw_instr_output = 1;
}
u8 *use_dir = "."; u8 *use_dir = ".";
if (access(use_dir, R_OK | W_OK | X_OK)) { if (access(use_dir, R_OK | W_OK | X_OK)) {
@ -978,6 +1038,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl_fsrv_start(fsrv, use_argv, &stop_soon, afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
map_size = fsrv->map_size;
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz); shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
@ -1005,6 +1066,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue; if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
#endif #endif
if (!collect_coverage)
snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name); snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name);
if (read_file(infile)) { if (read_file(infile)) {
@ -1019,6 +1081,9 @@ int main(int argc, char **argv_orig, char **envp) {
showmap_run_target_forkserver(fsrv, in_data, in_len); showmap_run_target_forkserver(fsrv, in_data, in_len);
ck_free(in_data); ck_free(in_data);
if (collect_coverage)
analyze_results(fsrv);
else
tcnt = write_results_to_file(fsrv, outfile); tcnt = write_results_to_file(fsrv, outfile);
} }
@ -1030,6 +1095,13 @@ int main(int argc, char **argv_orig, char **envp) {
closedir(dir_in); closedir(dir_in);
if (dir_out) { closedir(dir_out); } if (dir_out) { closedir(dir_out); }
if (collect_coverage) {
memcpy(fsrv->trace_bits, coverage_map, map_size);
tcnt = write_results_to_file(fsrv, out_file);
}
} else { } else {
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
@ -1043,8 +1115,14 @@ int main(int argc, char **argv_orig, char **envp) {
if (!quiet_mode) { if (!quiet_mode) {
if (!tcnt) { FATAL("No instrumentation detected" cRST); } if (!tcnt) { FATAL("No instrumentation detected" cRST); }
OKF("Captured %u tuples (highest value %u, total values %u) in '%s'." cRST, OKF("Captured %u tuples (highest value %u, total values %llu) in "
"'%s'." cRST,
tcnt, highest, total, out_file); tcnt, highest, total, out_file);
if (collect_coverage)
OKF("A coverage of %u edges were achieved out of %u existing (%.02f%%) "
"with %llu input files.",
tcnt, map_size, ((float)tcnt * 100) / (float)map_size,
fsrv->total_execs);
} }