|
34 | 34 | #include <sys/wait.h>
|
35 | 35 | #include <sys/types.h>
|
36 | 36 |
|
| 37 | +#ifdef USE_TRACE_PC |
| 38 | +# define CONST_PRIO 5 |
| 39 | +#else |
| 40 | +# define CONST_PRIO 0 |
| 41 | +#endif /* ^USE_TRACE_PC */ |
| 42 | + |
37 | 43 |
|
38 | 44 | /* Globals needed by the injected instrumentation. The __afl_area_initial region
|
39 | 45 | is used for instrumentation output before __afl_map_shm() has a chance to run.
|
@@ -234,81 +240,55 @@ void __afl_manual_init(void) {
|
234 | 240 | }
|
235 | 241 |
|
236 | 242 |
|
237 |
| -static void __afl_trace_pc_init(void); |
238 |
| - |
239 |
| - |
240 | 243 | /* Proper initialization routine. */
|
241 | 244 |
|
242 |
| -__attribute__((constructor(0))) void __afl_auto_init(void) { |
| 245 | +__attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) { |
243 | 246 |
|
244 | 247 | is_persistent = !!getenv(PERSIST_ENV_VAR);
|
245 | 248 |
|
246 |
| - __afl_trace_pc_init(); |
247 |
| - |
248 | 249 | if (getenv(DEFER_ENV_VAR)) return;
|
249 | 250 |
|
250 | 251 | __afl_manual_init();
|
251 | 252 |
|
252 | 253 | }
|
253 | 254 |
|
254 | 255 |
|
255 |
| -/* The following stuff deals with support for -fsanitize-coverage=bb,trace-pc. |
| 256 | +/* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard. |
256 | 257 | It remains non-operational in the traditional, plugin-backed LLVM mode.
|
257 |
| - For more info about 'trace-pc', see README.llvm. |
258 |
| -
|
259 |
| - The first function (__sanitizer_cov_trace_pc) is called back on every |
260 |
| - basic block. Since LLVM is not giving us any stable IDs for the blocks, |
261 |
| - we use 12 least significant bits of the return address (which should be |
262 |
| - stable even with ASLR; more significant bits may vary across runs). |
263 |
| -
|
264 |
| - Since MAP_SIZE is usually larger than 12 bits, we "pad" it by combining |
265 |
| - left-shifted __afl_prev_loc. This gives us a theoretical maximum of 24 |
266 |
| - bits, although instruction alignment likely reduces this somewhat. */ |
267 |
| - |
268 |
| - |
269 |
| -static u32 inst_ratio_scaled = MIN(4096, MAP_SIZE); |
| 258 | + For more info about 'trace-pc-guard', see README.llvm. |
270 | 259 |
|
271 |
| -void __sanitizer_cov_trace_pc(void) { |
| 260 | + The first function (__sanitizer_cov_trace_pc_guard) is called back on every |
| 261 | + edge (as opposed to every basic block). */ |
272 | 262 |
|
273 |
| - u32 cur = ((u32)__builtin_return_address(0)) & MIN(4095, MAP_SIZE - 1); |
274 |
| - |
275 |
| - if (cur > inst_ratio_scaled) return; |
276 |
| - |
277 |
| - __afl_area_ptr[cur ^ __afl_prev_loc]++; |
278 |
| - |
279 |
| -#if MAP_SIZE_POW2 > 12 |
280 |
| - __afl_prev_loc = cur << (MAP_SIZE_POW2 - 12); |
281 |
| -#else |
282 |
| - __afl_prev_loc = cur >> 1; |
283 |
| -#endif /* ^MAP_SIZE_POW2 > 12 */ |
284 | 263 |
|
| 264 | +void __sanitizer_cov_trace_pc_guard(uint32_t* guard) { |
| 265 | + __afl_area_ptr[*guard]++; |
285 | 266 | }
|
286 | 267 |
|
287 | 268 |
|
288 |
| -/* Init callback. Unfortunately, LLVM does not support compile-time |
289 |
| - instrumentation density scaling, at least not just yet. This means |
290 |
| - taking some performance hit by checking inst_ratio_scaled at runtime. */ |
291 |
| - |
292 |
| -static void __afl_trace_pc_init(void) { |
| 269 | +/* Init callback. Populates instrumentation IDs. Note that we're using |
| 270 | + ID of 0 as a special value to indicate non-instrumented bits. */ |
293 | 271 |
|
294 |
| - u8* x = getenv("AFL_INST_RATIO"); |
| 272 | +void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) { |
295 | 273 |
|
296 |
| - if (!x) return; |
| 274 | + u32 inst_ratio = 100; |
| 275 | + u8* x; |
297 | 276 |
|
298 |
| - inst_ratio_scaled = atoi(x); |
| 277 | + x = getenv("AFL_INST_RATIO"); |
| 278 | + if (x) inst_ratio = atoi(x); |
299 | 279 |
|
300 |
| - if (!inst_ratio_scaled || inst_ratio_scaled > 100) { |
| 280 | + if (!inst_ratio || inst_ratio > 100) { |
301 | 281 | fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
|
302 | 282 | abort();
|
303 | 283 | }
|
304 | 284 |
|
305 |
| - inst_ratio_scaled = inst_ratio_scaled * MIN(4096, MAP_SIZE) / 100; |
306 |
| - |
307 |
| -} |
| 285 | + while (start < stop) { |
308 | 286 |
|
| 287 | + if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1; |
| 288 | + else *start = 0; |
309 | 289 |
|
310 |
| -/* Work around a short-lived bug in LLVM with -fsanitize-coverage=trace-pc. */ |
| 290 | + start++; |
311 | 291 |
|
312 |
| -void __sanitizer_cov_module_init(void) __attribute__((weak)); |
313 |
| -void __sanitizer_cov_module_init(void) { } |
| 292 | + } |
314 | 293 |
|
| 294 | +} |
0 commit comments