| Index: third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
|
| diff --git a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
|
| index e2ef1516fe78c17bd28e0f0704943bf595215037..905c76ffb5e18174f73dcf99f66e916a11a5a432 100644
|
| --- a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
|
| +++ b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
|
| @@ -34,6 +34,16 @@
|
| #include <sys/wait.h>
|
| #include <sys/types.h>
|
|
|
| +/* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode.
|
| + Basically, we need to make sure that the forkserver is initialized after
|
| + the LLVM-generated runtime initialization pass, not before. */
|
| +
|
| +#ifdef USE_TRACE_PC
|
| +# define CONST_PRIO 5
|
| +#else
|
| +# define CONST_PRIO 0
|
| +#endif /* ^USE_TRACE_PC */
|
| +
|
|
|
| /* Globals needed by the injected instrumentation. The __afl_area_initial region
|
| is used for instrumentation output before __afl_map_shm() has a chance to run.
|
| @@ -234,17 +244,12 @@ void __afl_manual_init(void) {
|
| }
|
|
|
|
|
| -static void __afl_trace_pc_init(void);
|
| -
|
| -
|
| /* Proper initialization routine. */
|
|
|
| -__attribute__((constructor(0))) void __afl_auto_init(void) {
|
| +__attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
|
|
|
| is_persistent = !!getenv(PERSIST_ENV_VAR);
|
|
|
| - __afl_trace_pc_init();
|
| -
|
| if (getenv(DEFER_ENV_VAR)) return;
|
|
|
| __afl_manual_init();
|
| @@ -252,63 +257,42 @@ __attribute__((constructor(0))) void __afl_auto_init(void) {
|
| }
|
|
|
|
|
| -/* The following stuff deals with support for -fsanitize-coverage=bb,trace-pc.
|
| +/* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard.
|
| It remains non-operational in the traditional, plugin-backed LLVM mode.
|
| - For more info about 'trace-pc', see README.llvm.
|
| -
|
| - The first function (__sanitizer_cov_trace_pc) is called back on every
|
| - basic block. Since LLVM is not giving us any stable IDs for the blocks,
|
| - we use 12 least significant bits of the return address (which should be
|
| - stable even with ASLR; more significant bits may vary across runs).
|
| -
|
| - Since MAP_SIZE is usually larger than 12 bits, we "pad" it by combining
|
| - left-shifted __afl_prev_loc. This gives us a theoretical maximum of 24
|
| - bits, although instruction alignment likely reduces this somewhat. */
|
| -
|
| -
|
| -static u32 inst_ratio_scaled = MIN(4096, MAP_SIZE);
|
| + For more info about 'trace-pc-guard', see README.llvm.
|
|
|
| -void __sanitizer_cov_trace_pc(void) {
|
| -
|
| - u32 cur = ((u32)__builtin_return_address(0)) & MIN(4095, MAP_SIZE - 1);
|
| -
|
| - if (cur > inst_ratio_scaled) return;
|
| -
|
| - __afl_area_ptr[cur ^ __afl_prev_loc]++;
|
| -
|
| -#if MAP_SIZE_POW2 > 12
|
| - __afl_prev_loc = cur << (MAP_SIZE_POW2 - 12);
|
| -#else
|
| - __afl_prev_loc = cur >> 1;
|
| -#endif /* ^MAP_SIZE_POW2 > 12 */
|
| + The first function (__sanitizer_cov_trace_pc_guard) is called back on every
|
| + edge (as opposed to every basic block). */
|
|
|
| +void __sanitizer_cov_trace_pc_guard(uint32_t* guard) {
|
| + __afl_area_ptr[*guard]++;
|
| }
|
|
|
|
|
| -/* Init callback. Unfortunately, LLVM does not support compile-time
|
| - instrumentation density scaling, at least not just yet. This means
|
| - taking some performance hit by checking inst_ratio_scaled at runtime. */
|
| +/* Init callback. Populates instrumentation IDs. Note that we're using
|
| + ID of 0 as a special value to indicate non-instrumented bits. That may
|
| + still touch the bitmap, but in a fairly harmless way. */
|
|
|
| -static void __afl_trace_pc_init(void) {
|
| +void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) {
|
|
|
| - u8* x = getenv("AFL_INST_RATIO");
|
| + u32 inst_ratio = 100;
|
| + u8* x;
|
|
|
| - if (!x) return;
|
| + x = getenv("AFL_INST_RATIO");
|
| + if (x) inst_ratio = atoi(x);
|
|
|
| - inst_ratio_scaled = atoi(x);
|
| -
|
| - if (!inst_ratio_scaled || inst_ratio_scaled > 100) {
|
| + if (!inst_ratio || inst_ratio > 100) {
|
| fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
|
| abort();
|
| }
|
|
|
| - inst_ratio_scaled = inst_ratio_scaled * MIN(4096, MAP_SIZE) / 100;
|
| -
|
| -}
|
| + while (start < stop) {
|
|
|
| + if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1;
|
| + else *start = 0;
|
|
|
| -/* Work around a short-lived bug in LLVM with -fsanitize-coverage=trace-pc. */
|
| + start++;
|
|
|
| -void __sanitizer_cov_module_init(void) __attribute__((weak));
|
| -void __sanitizer_cov_module_init(void) { }
|
| + }
|
|
|
| +}
|
|
|