• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    american fuzzy lop++ - injectable parts
3    ---------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Now maintained by Marc Heuse <mh@mh-sec.de>,
8                      Heiko Eißfeldt <heiko.eissfeldt@hexco.de>,
9                      Andrea Fioraldi <andreafioraldi@gmail.com>,
10                      Dominik Maier <mail@dmnk.co>
11 
12    Copyright 2016, 2017 Google Inc. All rights reserved.
13    Copyright 2019-2022 AFLplusplus Project. All rights reserved.
14 
15    Licensed under the Apache License, Version 2.0 (the "License");
16    you may not use this file except in compliance with the License.
17    You may obtain a copy of the License at:
18 
19      https://www.apache.org/licenses/LICENSE-2.0
20 
21    This file houses the assembly-level instrumentation injected into fuzzed
22    programs. The instrumentation stores XORed pairs of data: identifiers of the
23    currently executing branch and the one that executed immediately before.
24 
25    TL;DR: the instrumentation does shm_trace_map[cur_loc ^ prev_loc]++
26 
27    The code is designed for 32-bit and 64-bit x86 systems. Both modes should
28    work everywhere except for Apple systems. Apple does relocations differently
29    from everybody else, so since their OSes have been 64-bit for a longer while,
30    I didn't go through the mental effort of porting the 32-bit code.
31 
32    In principle, similar code should be easy to inject into any well-behaved
33    binary-only code (e.g., using DynamoRIO). Conditional jumps offer natural
34    targets for instrumentation, and should offer comparable probe density.
35 
36  */
37 
38 #ifndef _HAVE_AFL_AS_H
39 #define _HAVE_AFL_AS_H
40 
41 #include "config.h"
42 #include "types.h"
43 
44 /*
45    ------------------
46    Performances notes
47    ------------------
48 
49    Contributions to make this code faster are appreciated! Here are some
50    rough notes that may help with the task:
51 
52    - Only the trampoline_fmt and the non-setup __afl_maybe_log code paths are
53      really worth optimizing; the setup / fork server stuff matters a lot less
54      and should be mostly just kept readable.
55 
56    - We're aiming for modern CPUs with out-of-order execution and large
57      pipelines; the code is mostly follows intuitive, human-readable
58      instruction ordering, because "textbook" manual reorderings make no
59      substantial difference.
60 
61    - Interestingly, instrumented execution isn't a lot faster if we store a
62      variable pointer to the setup, log, or return routine and then do a reg
63      call from within trampoline_fmt. It does speed up non-instrumented
64      execution quite a bit, though, since that path just becomes
65      push-call-ret-pop.
66 
67    - There is also not a whole lot to be gained by doing SHM attach at a
68      fixed address instead of retrieving __afl_area_ptr. Although it allows us
69      to have a shorter log routine inserted for conditional jumps and jump
70      labels (for a ~10% perf gain), there is a risk of bumping into other
71      allocations created by the program or by tools such as ASAN.
72 
73    - popf is *awfully* slow, which is why we're doing the lahf / sahf +
74      overflow test trick. Unfortunately, this forces us to taint eax / rax, but
75      this dependency on a commonly-used register still beats the alternative of
76      using pushf / popf.
77 
78      One possible optimization is to avoid touching flags by using a circular
79      buffer that stores just a sequence of current locations, with the XOR stuff
80      happening offline. Alas, this doesn't seem to have a huge impact:
81 
82      https://groups.google.com/d/msg/afl-users/MsajVf4fRLo/2u6t88ntUBIJ
83 
84    - Preforking one child a bit sooner, and then waiting for the "go" command
85      from within the child, doesn't offer major performance gains; fork() seems
86      to be relatively inexpensive these days. Preforking multiple children does
87      help, but badly breaks the "~1 core per fuzzer" design, making it harder to
88      scale up. Maybe there is some middle ground.
89 
90    Perhaps of note: in the 64-bit version for all platforms except for Apple,
91    the instrumentation is done slightly differently than on 32-bit, with
92    __afl_prev_loc and __afl_area_ptr being local to the object file (.lcomm),
93    rather than global (.comm). This is to avoid GOTRELPC lookups in the critical
94    code path, which AFAICT, are otherwise unavoidable if we want gcc -shared to
95    work; simple relocations between .bss and .text won't work on most 64-bit
96    platforms in such a case.
97 
98    (Fun fact: on Apple systems, .lcomm can segfault the linker.)
99 
100    The side effect is that state transitions are measured in a somewhat
101    different way, with previous tuple being recorded separately within the scope
102    of every .c file. This should have no impact in any practical sense.
103 
104    Another side effect of this design is that getenv() will be called once per
105    every .o file when running in non-instrumented mode; and since getenv() tends
106    to be optimized in funny ways, we need to be very careful to save every
107    oddball register it may touch.
108 
109  */
110 
111 static const u8 *trampoline_fmt_32 =
112 
113     "\n"
114     "/* --- AFL TRAMPOLINE (32-BIT) --- */\n"
115     "\n"
116     ".align 4\n"
117     "\n"
118     "leal -16(%%esp), %%esp\n"
119     "movl %%edi,  0(%%esp)\n"
120     "movl %%edx,  4(%%esp)\n"
121     "movl %%ecx,  8(%%esp)\n"
122     "movl %%eax, 12(%%esp)\n"
123     "movl $0x%08x, %%ecx\n"
124     "call __afl_maybe_log\n"
125     "movl 12(%%esp), %%eax\n"
126     "movl  8(%%esp), %%ecx\n"
127     "movl  4(%%esp), %%edx\n"
128     "movl  0(%%esp), %%edi\n"
129     "leal 16(%%esp), %%esp\n"
130     "\n"
131     "/* --- END --- */\n"
132     "\n";
133 
134 static const u8 *trampoline_fmt_64 =
135 
136     "\n"
137     "/* --- AFL TRAMPOLINE (64-BIT) --- */\n"
138     "\n"
139     ".align 4\n"
140     "\n"
141     "leaq -(128+24)(%%rsp), %%rsp\n"
142     "movq %%rdx,  0(%%rsp)\n"
143     "movq %%rcx,  8(%%rsp)\n"
144     "movq %%rax, 16(%%rsp)\n"
145     "movq $0x%08x, %%rcx\n"
146     "call __afl_maybe_log\n"
147     "movq 16(%%rsp), %%rax\n"
148     "movq  8(%%rsp), %%rcx\n"
149     "movq  0(%%rsp), %%rdx\n"
150     "leaq (128+24)(%%rsp), %%rsp\n"
151     "\n"
152     "/* --- END --- */\n"
153     "\n";
154 
155 static const u8 *main_payload_32 =
156 
157   "\n"
158   "/* --- AFL MAIN PAYLOAD (32-BIT) --- */\n"
159   "\n"
160   ".text\n"
161   ".att_syntax\n"
162   ".code32\n"
163   ".align 8\n"
164   "\n"
165 
166   "__afl_maybe_log:\n"
167   "\n"
168   "  lahf\n"
169   "  seto %al\n"
170   "\n"
171   "  /* Check if SHM region is already mapped. */\n"
172   "\n"
173   "  movl  __afl_area_ptr, %edx\n"
174   "  testl %edx, %edx\n"
175   "  je    __afl_setup\n"
176   "\n"
177   "__afl_store:\n"
178   "\n"
179   "  /* Calculate and store hit for the code location specified in ecx. There\n"
180   "     is a double-XOR way of doing this without tainting another register,\n"
181   "     and we use it on 64-bit systems; but it's slower for 32-bit ones. */\n"
182   "\n"
183 #ifndef COVERAGE_ONLY
184   "  movl __afl_prev_loc, %edi\n"
185   "  xorl %ecx, %edi\n"
186   "  shrl $1, %ecx\n"
187   "  movl %ecx, __afl_prev_loc\n"
188 #else
189   "  movl %ecx, %edi\n"
190 #endif                                                   /* ^!COVERAGE_ONLY */
191   "\n"
192 #ifdef SKIP_COUNTS
193   "  orb  $1, (%edx, %edi, 1)\n"
194 #else
195   "  addb $1, (%edx, %edi, 1)\n"
196   "  adcb $0, (%edx, %edi, 1)\n" // never zero counter implementation. slightly better path discovery and little performance impact
197 #endif                                                      /* ^SKIP_COUNTS */
198   "\n"
199   "__afl_return:\n"
200   "\n"
201   "  addb $127, %al\n"
202   "  sahf\n"
203   "  ret\n"
204   "\n"
205   ".align 8\n"
206   "\n"
207   "__afl_setup:\n"
208   "\n"
209   "  /* Do not retry setup if we had previous failures. */\n"
210   "\n"
211   "  cmpb $0, __afl_setup_failure\n"
212   "  jne  __afl_return\n"
213   "\n"
214   "  /* Map SHM, jumping to __afl_setup_abort if something goes wrong.\n"
215   "     We do not save FPU/MMX/SSE registers here, but hopefully, nobody\n"
216   "     will notice this early in the game. */\n"
217   "\n"
218   "  pushl %eax\n"
219   "  pushl %ecx\n"
220   "\n"
221   "  pushl $.AFL_SHM_ENV\n"
222   "  call  getenv\n"
223   "  addl  $4, %esp\n"
224   "\n"
225   "  testl %eax, %eax\n"
226   "  je    __afl_setup_abort\n"
227   "\n"
228 #ifdef USEMMAP
229   "  pushl $384        /* shm_open mode 0600 */\n"
230   "  pushl $2          /* flags O_RDWR   */\n"
231   "  pushl %eax        /* SHM file path  */\n"
232   "  call  shm_open\n"
233   "  addl  $12, %esp\n"
234   "\n"
235   "  cmpl $-1, %eax\n"
236   "  je   __afl_setup_abort\n"
237   "\n"
238   "  pushl $0          /* mmap off       */\n"
239   "  pushl %eax        /* shm fd         */\n"
240   "  pushl $1          /* mmap flags     */\n"
241   "  pushl $3          /* mmap prot      */\n"
242   "  pushl $"STRINGIFY(MAP_SIZE)"          /* mmap len       */\n"
243   "  pushl $0          /* mmap addr      */\n"
244   "  call  mmap\n"
245   "  addl  $12, %esp\n"
246   "\n"
247   "  cmpl $-1, %eax\n"
248   "  je   __afl_setup_abort\n"
249   "\n"
250 #else
251   "  pushl %eax\n"
252   "  call  atoi\n"
253   "  addl  $4, %esp\n"
254   "\n"
255   "  pushl $0          /* shmat flags    */\n"
256   "  pushl $0          /* requested addr */\n"
257   "  pushl %eax        /* SHM ID         */\n"
258   "  call  shmat\n"
259   "  addl  $12, %esp\n"
260   "\n"
261   "  cmpl $-1, %eax\n"
262   "  je   __afl_setup_abort\n"
263   "\n"
264 #endif
265   "  movb $1, (%eax)\n"
266   "  /* Store the address of the SHM region. */\n"
267   "\n"
268   "  movl %eax, __afl_area_ptr\n"
269   "  movl %eax, %edx\n"
270   "\n"
271   "  popl %ecx\n"
272   "  popl %eax\n"
273   "\n"
274   "__afl_forkserver:\n"
275   "\n"
276   "  /* Enter the fork server mode to avoid the overhead of execve() calls. */\n"
277   "\n"
278   "  pushl %eax\n"
279   "  pushl %ecx\n"
280   "  pushl %edx\n"
281   "\n"
282   "  /* Phone home and tell the parent that we're OK. (Note that signals with\n"
283   "     no SA_RESTART will mess it up). If this fails, assume that the fd is\n"
284   "     closed because we were execve()d from an instrumented binary, or because\n"
285   "     the parent doesn't want to use the fork server. */\n"
286   "\n"
287   "  pushl $4          /* length    */\n"
288   "  pushl $__afl_temp /* data      */\n"
289   "  pushl $" STRINGIFY((FORKSRV_FD + 1)) "  /* file desc */\n"
290   "  call  write\n"
291   "  addl  $12, %esp\n"
292   "\n"
293   "  cmpl  $4, %eax\n"
294   "  jne   __afl_fork_resume\n"
295   "\n"
296   "__afl_fork_wait_loop:\n"
297   "\n"
298   "  /* Wait for parent by reading from the pipe. Abort if read fails. */\n"
299   "\n"
300   "  pushl $4          /* length    */\n"
301   "  pushl $__afl_temp /* data      */\n"
302   "  pushl $" STRINGIFY(FORKSRV_FD) "        /* file desc */\n"
303   "  call  read\n"
304   "  addl  $12, %esp\n"
305   "\n"
306   "  cmpl  $4, %eax\n"
307   "  jne   __afl_die\n"
308   "\n"
309   "  /* Once woken up, create a clone of our process. This is an excellent use\n"
310   "     case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\n"
311   "     caches getpid() results and offers no way to update the value, breaking\n"
312   "     abort(), raise(), and a bunch of other things :-( */\n"
313   "\n"
314   "  call fork\n"
315   "\n"
316   "  cmpl $0, %eax\n"
317   "  jl   __afl_die\n"
318   "  je   __afl_fork_resume\n"
319   "\n"
320   "  /* In parent process: write PID to pipe, then wait for child. */\n"
321   "\n"
322   "  movl  %eax, __afl_fork_pid\n"
323   "\n"
324   "  pushl $4              /* length    */\n"
325   "  pushl $__afl_fork_pid /* data      */\n"
326   "  pushl $" STRINGIFY((FORKSRV_FD + 1)) "      /* file desc */\n"
327   "  call  write\n"
328   "  addl  $12, %esp\n"
329   "\n"
330   "  pushl $0             /* no flags  */\n"
331   "  pushl $__afl_temp    /* status    */\n"
332   "  pushl __afl_fork_pid /* PID       */\n"
333   "  call  waitpid\n"
334   "  addl  $12, %esp\n"
335   "\n"
336   "  cmpl  $0, %eax\n"
337   "  jle   __afl_die\n"
338   "\n"
339   "  /* Relay wait status to pipe, then loop back. */\n"
340   "\n"
341   "  pushl $4          /* length    */\n"
342   "  pushl $__afl_temp /* data      */\n"
343   "  pushl $" STRINGIFY((FORKSRV_FD + 1)) "  /* file desc */\n"
344   "  call  write\n"
345   "  addl  $12, %esp\n"
346   "\n"
347   "  jmp __afl_fork_wait_loop\n"
348   "\n"
349   "__afl_fork_resume:\n"
350   "\n"
351   "  /* In child process: close fds, resume execution. */\n"
352   "\n"
353   "  pushl $" STRINGIFY(FORKSRV_FD) "\n"
354   "  call  close\n"
355   "\n"
356   "  pushl $" STRINGIFY((FORKSRV_FD + 1)) "\n"
357   "  call  close\n"
358   "\n"
359   "  addl  $8, %esp\n"
360   "\n"
361   "  popl %edx\n"
362   "  popl %ecx\n"
363   "  popl %eax\n"
364   "  jmp  __afl_store\n"
365   "\n"
366   "__afl_die:\n"
367   "\n"
368   "  xorl %eax, %eax\n"
369   "  call _exit\n"
370   "\n"
371   "__afl_setup_abort:\n"
372   "\n"
373   "  /* Record setup failure so that we don't keep calling\n"
374   "     shmget() / shmat() over and over again. */\n"
375   "\n"
376   "  incb __afl_setup_failure\n"
377   "  popl %ecx\n"
378   "  popl %eax\n"
379   "  jmp __afl_return\n"
380   "\n"
381   ".AFL_VARS:\n"
382   "\n"
383   "  .comm   __afl_area_ptr, 4, 32\n"
384   "  .comm   __afl_setup_failure, 1, 32\n"
385 #ifndef COVERAGE_ONLY
386   "  .comm   __afl_prev_loc, 4, 32\n"
387 #endif                                                    /* !COVERAGE_ONLY */
388   "  .comm   __afl_final_loc, 4, 32\n"
389   "  .comm   __afl_fork_pid, 4, 32\n"
390   "  .comm   __afl_temp, 4, 32\n"
391   "\n"
392   ".AFL_SHM_ENV:\n"
393   "  .asciz \"" SHM_ENV_VAR "\"\n"
394   "\n"
395   "/* --- END --- */\n"
396   "\n";
397 
398 /* The OpenBSD hack is due to lahf and sahf not being recognized by some
399    versions of binutils: https://marc.info/?l=openbsd-cvs&m=141636589924400
400 
401    The Apple code is a bit different when calling libc functions because
402    they are doing relocations differently from everybody else. We also need
403    to work around the crash issue with .lcomm and the fact that they don't
404    recognize .string. */
405 
406 #ifdef __APPLE__
407   #define CALL_L64(str) "call _" str "\n"
408 #else
409   #define CALL_L64(str) "call " str "@PLT\n"
410 #endif                                                        /* ^__APPLE__ */
411 
412 static const u8 *main_payload_64 =
413 
414   "\n"
415   "/* --- AFL MAIN PAYLOAD (64-BIT) --- */\n"
416   "\n"
417   ".text\n"
418   ".att_syntax\n"
419   ".code64\n"
420   ".align 8\n"
421   "\n"
422   "__afl_maybe_log:\n"
423   "\n"
424 #if defined(__OpenBSD__) || (defined(__FreeBSD__) && (__FreeBSD__ < 9))
425   "  .byte 0x9f /* lahf */\n"
426 #else
427   "  lahf\n"
428 #endif                                                 /* ^__OpenBSD__, etc */
429   "  seto  %al\n"
430   "\n"
431   "  /* Check if SHM region is already mapped. */\n"
432   "\n"
433   "  movq  __afl_area_ptr(%rip), %rdx\n"
434   "  testq %rdx, %rdx\n"
435   "  je    __afl_setup\n"
436   "\n"
437   "__afl_store:\n"
438   "\n"
439   "  /* Calculate and store hit for the code location specified in rcx. */\n"
440   "\n"
441 #ifndef COVERAGE_ONLY
442   "  xorq __afl_prev_loc(%rip), %rcx\n"
443   "  xorq %rcx, __afl_prev_loc(%rip)\n"
444   "  shrq $1, __afl_prev_loc(%rip)\n"
445 #endif                                                   /* ^!COVERAGE_ONLY */
446   "\n"
447 #ifdef SKIP_COUNTS
448   "  orb  $1, (%rdx, %rcx, 1)\n"
449 #else
450   "  addb $1, (%rdx, %rcx, 1)\n"
451   "  adcb $0, (%rdx, %rcx, 1)\n" // never zero counter implementation. slightly better path discovery and little performance impact
452 #endif                                                      /* ^SKIP_COUNTS */
453   "\n"
454   "__afl_return:\n"
455   "\n"
456   "  addb $127, %al\n"
457 #if defined(__OpenBSD__) || (defined(__FreeBSD__) && (__FreeBSD__ < 9))
458   "  .byte 0x9e /* sahf */\n"
459 #else
460   "  sahf\n"
461 #endif                                                 /* ^__OpenBSD__, etc */
462   "  ret\n"
463   "\n"
464   ".align 8\n"
465   "\n"
466   "__afl_setup:\n"
467   "\n"
468   "  /* Do not retry setup if we had previous failures. */\n"
469   "\n"
470   "  cmpb $0, __afl_setup_failure(%rip)\n"
471   "  jne __afl_return\n"
472   "\n"
473   "  /* Check out if we have a global pointer on file. */\n"
474   "\n"
475 #ifndef __APPLE__
476   "  movq  __afl_global_area_ptr@GOTPCREL(%rip), %rdx\n"
477   "  movq  (%rdx), %rdx\n"
478 #else
479   "  movq  __afl_global_area_ptr(%rip), %rdx\n"
480 #endif                                                       /* !^__APPLE__ */
481   "  testq %rdx, %rdx\n"
482   "  je    __afl_setup_first\n"
483   "\n"
484   "  movq %rdx, __afl_area_ptr(%rip)\n"
485   "  jmp  __afl_store\n"
486   "\n"
487   "__afl_setup_first:\n"
488   "\n"
489   "  /* Save everything that is not yet saved and that may be touched by\n"
490   "     getenv() and several other libcalls we'll be relying on. */\n"
491   "\n"
492   "  leaq -352(%rsp), %rsp\n"
493   "\n"
494   "  movq %rax,   0(%rsp)\n"
495   "  movq %rcx,   8(%rsp)\n"
496   "  movq %rdi,  16(%rsp)\n"
497   "  movq %rsi,  32(%rsp)\n"
498   "  movq %r8,   40(%rsp)\n"
499   "  movq %r9,   48(%rsp)\n"
500   "  movq %r10,  56(%rsp)\n"
501   "  movq %r11,  64(%rsp)\n"
502   "\n"
503   "  movq %xmm0,  96(%rsp)\n"
504   "  movq %xmm1,  112(%rsp)\n"
505   "  movq %xmm2,  128(%rsp)\n"
506   "  movq %xmm3,  144(%rsp)\n"
507   "  movq %xmm4,  160(%rsp)\n"
508   "  movq %xmm5,  176(%rsp)\n"
509   "  movq %xmm6,  192(%rsp)\n"
510   "  movq %xmm7,  208(%rsp)\n"
511   "  movq %xmm8,  224(%rsp)\n"
512   "  movq %xmm9,  240(%rsp)\n"
513   "  movq %xmm10, 256(%rsp)\n"
514   "  movq %xmm11, 272(%rsp)\n"
515   "  movq %xmm12, 288(%rsp)\n"
516   "  movq %xmm13, 304(%rsp)\n"
517   "  movq %xmm14, 320(%rsp)\n"
518   "  movq %xmm15, 336(%rsp)\n"
519   "\n"
520   "  /* Map SHM, jumping to __afl_setup_abort if something goes wrong. */\n"
521   "\n"
522   "  /* The 64-bit ABI requires 16-byte stack alignment. We'll keep the\n"
523   "     original stack ptr in the callee-saved r12. */\n"
524   "\n"
525   "  pushq %r12\n"
526   "  movq  %rsp, %r12\n"
527   "  subq  $16, %rsp\n"
528   "  andq  $0xfffffffffffffff0, %rsp\n"
529   "\n"
530   "  leaq .AFL_SHM_ENV(%rip), %rdi\n"
531   CALL_L64("getenv")
532   "\n"
533   "  testq %rax, %rax\n"
534   "  je    __afl_setup_abort\n"
535   "\n"
536 #ifdef USEMMAP
537   "  movl $384, %edx   /* shm_open mode 0600 */\n"
538   "  movl $2,   %esi   /* flags O_RDWR   */\n"
539   "  movq %rax, %rdi   /* SHM file path  */\n"
540   CALL_L64("shm_open")
541   "\n"
542   "  cmpq $-1, %rax\n"
543   "  je   __afl_setup_abort\n"
544   "\n"
545   "  movl    $0, %r9d\n"
546   "  movl    %eax, %r8d\n"
547   "  movl    $1, %ecx\n"
548   "  movl    $3, %edx\n"
549   "  movl    $"STRINGIFY(MAP_SIZE)", %esi\n"
550   "  movl    $0, %edi\n"
551   CALL_L64("mmap")
552   "\n"
553   "  cmpq $-1, %rax\n"
554   "  je   __afl_setup_abort\n"
555   "\n"
556 #else
557   "  movq  %rax, %rdi\n"
558   CALL_L64("atoi")
559   "\n"
560   "  xorq %rdx, %rdx   /* shmat flags    */\n"
561   "  xorq %rsi, %rsi   /* requested addr */\n"
562   "  movq %rax, %rdi   /* SHM ID         */\n"
563   CALL_L64("shmat")
564   "\n"
565   "  cmpq $-1, %rax\n"
566   "  je   __afl_setup_abort\n"
567   "\n"
568 #endif
569   "  movb $1, (%rax)\n"
570   "  /* Store the address of the SHM region. */\n"
571   "\n"
572   "  movq %rax, %rdx\n"
573   "  movq %rax, __afl_area_ptr(%rip)\n"
574   "\n"
575 #ifdef __APPLE__
576   "  movq %rax, __afl_global_area_ptr(%rip)\n"
577 #else
578   "  movq __afl_global_area_ptr@GOTPCREL(%rip), %rdx\n"
579   "  movq %rax, (%rdx)\n"
580 #endif                                                        /* ^__APPLE__ */
581   "  movq %rax, %rdx\n"
582   "\n"
583   "__afl_forkserver:\n"
584   "\n"
585   "  /* Enter the fork server mode to avoid the overhead of execve() calls. We\n"
586   "     push rdx (area ptr) twice to keep stack alignment neat. */\n"
587   "\n"
588   "  pushq %rdx\n"
589   "  pushq %rdx\n"
590   "\n"
591   "  /* Phone home and tell the parent that we're OK. (Note that signals with\n"
592   "     no SA_RESTART will mess it up). If this fails, assume that the fd is\n"
593   "     closed because we were execve()d from an instrumented binary, or because\n"
594   "     the parent doesn't want to use the fork server. */\n"
595   "\n"
596   "  movq $4, %rdx               /* length    */\n"
597   "  leaq __afl_temp(%rip), %rsi /* data      */\n"
598   "  movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi       /* file desc */\n"
599   CALL_L64("write")
600   "\n"
601   "  cmpq $4, %rax\n"
602   "  jne  __afl_fork_resume\n"
603   "\n"
604   "__afl_fork_wait_loop:\n"
605   "\n"
606   "  /* Wait for parent by reading from the pipe. Abort if read fails. */\n"
607   "\n"
608   "  movq $4, %rdx               /* length    */\n"
609   "  leaq __afl_temp(%rip), %rsi /* data      */\n"
610   "  movq $" STRINGIFY(FORKSRV_FD) ", %rdi             /* file desc */\n"
611   CALL_L64("read")
612   "  cmpq $4, %rax\n"
613   "  jne  __afl_die\n"
614   "\n"
615   "  /* Once woken up, create a clone of our process. This is an excellent use\n"
616   "     case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\n"
617   "     caches getpid() results and offers no way to update the value, breaking\n"
618   "     abort(), raise(), and a bunch of other things :-( */\n"
619   "\n"
620   CALL_L64("fork")
621   "  cmpq $0, %rax\n"
622   "  jl   __afl_die\n"
623   "  je   __afl_fork_resume\n"
624   "\n"
625   "  /* In parent process: write PID to pipe, then wait for child. */\n"
626   "\n"
627   "  movl %eax, __afl_fork_pid(%rip)\n"
628   "\n"
629   "  movq $4, %rdx                   /* length    */\n"
630   "  leaq __afl_fork_pid(%rip), %rsi /* data      */\n"
631   "  movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi             /* file desc */\n"
632   CALL_L64("write")
633   "\n"
634   "  movq $0, %rdx                   /* no flags  */\n"
635   "  leaq __afl_temp(%rip), %rsi     /* status    */\n"
636   "  movq __afl_fork_pid(%rip), %rdi /* PID       */\n"
637   CALL_L64("waitpid")
638   "  cmpq $0, %rax\n"
639   "  jle  __afl_die\n"
640   "\n"
641   "  /* Relay wait status to pipe, then loop back. */\n"
642   "\n"
643   "  movq $4, %rdx               /* length    */\n"
644   "  leaq __afl_temp(%rip), %rsi /* data      */\n"
645   "  movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi         /* file desc */\n"
646   CALL_L64("write")
647   "\n"
648   "  jmp  __afl_fork_wait_loop\n"
649   "\n"
650   "__afl_fork_resume:\n"
651   "\n"
652   "  /* In child process: close fds, resume execution. */\n"
653   "\n"
654   "  movq $" STRINGIFY(FORKSRV_FD) ", %rdi\n"
655   CALL_L64("close")
656   "\n"
657   "  movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi\n"
658   CALL_L64("close")
659   "\n"
660   "  popq %rdx\n"
661   "  popq %rdx\n"
662   "\n"
663   "  movq %r12, %rsp\n"
664   "  popq %r12\n"
665   "\n"
666   "  movq  0(%rsp), %rax\n"
667   "  movq  8(%rsp), %rcx\n"
668   "  movq 16(%rsp), %rdi\n"
669   "  movq 32(%rsp), %rsi\n"
670   "  movq 40(%rsp), %r8\n"
671   "  movq 48(%rsp), %r9\n"
672   "  movq 56(%rsp), %r10\n"
673   "  movq 64(%rsp), %r11\n"
674   "\n"
675   "  movq  96(%rsp), %xmm0\n"
676   "  movq 112(%rsp), %xmm1\n"
677   "  movq 128(%rsp), %xmm2\n"
678   "  movq 144(%rsp), %xmm3\n"
679   "  movq 160(%rsp), %xmm4\n"
680   "  movq 176(%rsp), %xmm5\n"
681   "  movq 192(%rsp), %xmm6\n"
682   "  movq 208(%rsp), %xmm7\n"
683   "  movq 224(%rsp), %xmm8\n"
684   "  movq 240(%rsp), %xmm9\n"
685   "  movq 256(%rsp), %xmm10\n"
686   "  movq 272(%rsp), %xmm11\n"
687   "  movq 288(%rsp), %xmm12\n"
688   "  movq 304(%rsp), %xmm13\n"
689   "  movq 320(%rsp), %xmm14\n"
690   "  movq 336(%rsp), %xmm15\n"
691   "\n"
692   "  leaq 352(%rsp), %rsp\n"
693   "\n"
694   "  jmp  __afl_store\n"
695   "\n"
696   "__afl_die:\n"
697   "\n"
698   "  xorq %rax, %rax\n"
699   CALL_L64("_exit")
700   "\n"
701   "__afl_setup_abort:\n"
702   "\n"
703   "  /* Record setup failure so that we don't keep calling\n"
704   "     shmget() / shmat() over and over again. */\n"
705   "\n"
706   "  incb __afl_setup_failure(%rip)\n"
707   "\n"
708   "  movq %r12, %rsp\n"
709   "  popq %r12\n"
710   "\n"
711   "  movq  0(%rsp), %rax\n"
712   "  movq  8(%rsp), %rcx\n"
713   "  movq 16(%rsp), %rdi\n"
714   "  movq 32(%rsp), %rsi\n"
715   "  movq 40(%rsp), %r8\n"
716   "  movq 48(%rsp), %r9\n"
717   "  movq 56(%rsp), %r10\n"
718   "  movq 64(%rsp), %r11\n"
719   "\n"
720   "  movq  96(%rsp), %xmm0\n"
721   "  movq 112(%rsp), %xmm1\n"
722   "  movq 128(%rsp), %xmm2\n"
723   "  movq 144(%rsp), %xmm3\n"
724   "  movq 160(%rsp), %xmm4\n"
725   "  movq 176(%rsp), %xmm5\n"
726   "  movq 192(%rsp), %xmm6\n"
727   "  movq 208(%rsp), %xmm7\n"
728   "  movq 224(%rsp), %xmm8\n"
729   "  movq 240(%rsp), %xmm9\n"
730   "  movq 256(%rsp), %xmm10\n"
731   "  movq 272(%rsp), %xmm11\n"
732   "  movq 288(%rsp), %xmm12\n"
733   "  movq 304(%rsp), %xmm13\n"
734   "  movq 320(%rsp), %xmm14\n"
735   "  movq 336(%rsp), %xmm15\n"
736   "\n"
737   "  leaq 352(%rsp), %rsp\n"
738   "\n"
739   "  jmp __afl_return\n"
740   "\n"
741   ".AFL_VARS:\n"
742   "\n"
743 
744 #ifdef __APPLE__
745 
746   "  .comm   __afl_area_ptr, 8\n"
747   #ifndef COVERAGE_ONLY
748   "  .comm   __afl_prev_loc, 8\n"
749   #endif                                                  /* !COVERAGE_ONLY */
750   "  .comm   __afl_fork_pid, 4\n"
751   "  .comm   __afl_temp, 4\n"
752   "  .comm   __afl_setup_failure, 1\n"
753 
754 #else
755 
756   "  .lcomm   __afl_area_ptr, 8\n"
757   #ifndef COVERAGE_ONLY
758   "  .lcomm   __afl_prev_loc, 8\n"
759   #endif                                                  /* !COVERAGE_ONLY */
760   "  .lcomm   __afl_fork_pid, 4\n"
761   "  .lcomm   __afl_temp, 4\n"
762   "  .lcomm   __afl_setup_failure, 1\n"
763 
764 #endif                                                        /* ^__APPLE__ */
765 
766   "  .comm    __afl_global_area_ptr, 8, 8\n"
767   "\n"
768   ".AFL_SHM_ENV:\n"
769   "  .asciz \"" SHM_ENV_VAR "\"\n"
770   "\n"
771   "/* --- END --- */\n"
772   "\n";
773 
774 #endif                                                   /* !_HAVE_AFL_AS_H */
775 
776