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) { } |
+ } |
+} |