xref: /aosp_15_r20/external/AFLplusplus/src/afl-as.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker    american fuzzy lop++ - wrapper for GNU as
3*08b48e0bSAndroid Build Coastguard Worker    -----------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker 
5*08b48e0bSAndroid Build Coastguard Worker    Originally written by Michal Zalewski
6*08b48e0bSAndroid Build Coastguard Worker 
7*08b48e0bSAndroid Build Coastguard Worker    Now maintained by Marc Heuse <[email protected]>,
8*08b48e0bSAndroid Build Coastguard Worker                         Heiko Eißfeldt <[email protected]> and
9*08b48e0bSAndroid Build Coastguard Worker                         Andrea Fioraldi <[email protected]>
10*08b48e0bSAndroid Build Coastguard Worker 
11*08b48e0bSAndroid Build Coastguard Worker    Copyright 2016, 2017 Google Inc. All rights reserved.
12*08b48e0bSAndroid Build Coastguard Worker    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
13*08b48e0bSAndroid Build Coastguard Worker 
14*08b48e0bSAndroid Build Coastguard Worker    Licensed under the Apache License, Version 2.0 (the "License");
15*08b48e0bSAndroid Build Coastguard Worker    you may not use this file except in compliance with the License.
16*08b48e0bSAndroid Build Coastguard Worker    You may obtain a copy of the License at:
17*08b48e0bSAndroid Build Coastguard Worker 
18*08b48e0bSAndroid Build Coastguard Worker      https://www.apache.org/licenses/LICENSE-2.0
19*08b48e0bSAndroid Build Coastguard Worker 
20*08b48e0bSAndroid Build Coastguard Worker    The sole purpose of this wrapper is to preprocess assembly files generated
21*08b48e0bSAndroid Build Coastguard Worker    by GCC / clang and inject the instrumentation bits included from afl-as.h. It
22*08b48e0bSAndroid Build Coastguard Worker    is automatically invoked by the toolchain when compiling programs using
23*08b48e0bSAndroid Build Coastguard Worker    afl-gcc / afl-clang.
24*08b48e0bSAndroid Build Coastguard Worker 
25*08b48e0bSAndroid Build Coastguard Worker    Note that it's an explicit non-goal to instrument hand-written assembly,
26*08b48e0bSAndroid Build Coastguard Worker    be it in separate .s files or in __asm__ blocks. The only aspiration this
27*08b48e0bSAndroid Build Coastguard Worker    utility has right now is to be able to skip them gracefully and allow the
28*08b48e0bSAndroid Build Coastguard Worker    compilation process to continue.
29*08b48e0bSAndroid Build Coastguard Worker 
30*08b48e0bSAndroid Build Coastguard Worker    That said, see utils/clang_asm_normalize/ for a solution that may
31*08b48e0bSAndroid Build Coastguard Worker    allow clang users to make things work even with hand-crafted assembly. Just
32*08b48e0bSAndroid Build Coastguard Worker    note that there is no equivalent for GCC.
33*08b48e0bSAndroid Build Coastguard Worker 
34*08b48e0bSAndroid Build Coastguard Worker  */
35*08b48e0bSAndroid Build Coastguard Worker 
36*08b48e0bSAndroid Build Coastguard Worker #define AFL_MAIN
37*08b48e0bSAndroid Build Coastguard Worker 
38*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
39*08b48e0bSAndroid Build Coastguard Worker #include "types.h"
40*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
41*08b48e0bSAndroid Build Coastguard Worker #include "alloc-inl.h"
42*08b48e0bSAndroid Build Coastguard Worker 
43*08b48e0bSAndroid Build Coastguard Worker #include "afl-as.h"
44*08b48e0bSAndroid Build Coastguard Worker 
45*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
46*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
47*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
48*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
49*08b48e0bSAndroid Build Coastguard Worker #include <time.h>
50*08b48e0bSAndroid Build Coastguard Worker #include <limits.h>
51*08b48e0bSAndroid Build Coastguard Worker #include <ctype.h>
52*08b48e0bSAndroid Build Coastguard Worker #include <fcntl.h>
53*08b48e0bSAndroid Build Coastguard Worker 
54*08b48e0bSAndroid Build Coastguard Worker #include <sys/wait.h>
55*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
56*08b48e0bSAndroid Build Coastguard Worker 
57*08b48e0bSAndroid Build Coastguard Worker static u8 **as_params;              /* Parameters passed to the real 'as'   */
58*08b48e0bSAndroid Build Coastguard Worker 
59*08b48e0bSAndroid Build Coastguard Worker static u8 *input_file;              /* Originally specified input file      */
60*08b48e0bSAndroid Build Coastguard Worker static u8 *modified_file;           /* Instrumented file for the real 'as'  */
61*08b48e0bSAndroid Build Coastguard Worker 
62*08b48e0bSAndroid Build Coastguard Worker static u8 be_quiet,                 /* Quiet mode (no stderr output)        */
63*08b48e0bSAndroid Build Coastguard Worker     clang_mode,                     /* Running in clang mode?               */
64*08b48e0bSAndroid Build Coastguard Worker     pass_thru,                      /* Just pass data through?              */
65*08b48e0bSAndroid Build Coastguard Worker     just_version,                   /* Just show version?                   */
66*08b48e0bSAndroid Build Coastguard Worker     sanitizer;                      /* Using ASAN / MSAN                    */
67*08b48e0bSAndroid Build Coastguard Worker 
68*08b48e0bSAndroid Build Coastguard Worker static u32 inst_ratio = 100,        /* Instrumentation probability (%)      */
69*08b48e0bSAndroid Build Coastguard Worker     as_par_cnt = 1;                 /* Number of params to 'as'             */
70*08b48e0bSAndroid Build Coastguard Worker 
71*08b48e0bSAndroid Build Coastguard Worker /* If we don't find --32 or --64 in the command line, default to
72*08b48e0bSAndroid Build Coastguard Worker    instrumentation for whichever mode we were compiled with. This is not
73*08b48e0bSAndroid Build Coastguard Worker    perfect, but should do the trick for almost all use cases. */
74*08b48e0bSAndroid Build Coastguard Worker 
75*08b48e0bSAndroid Build Coastguard Worker #ifdef WORD_SIZE_64
76*08b48e0bSAndroid Build Coastguard Worker 
77*08b48e0bSAndroid Build Coastguard Worker static u8 use_64bit = 1;
78*08b48e0bSAndroid Build Coastguard Worker 
79*08b48e0bSAndroid Build Coastguard Worker #else
80*08b48e0bSAndroid Build Coastguard Worker 
81*08b48e0bSAndroid Build Coastguard Worker static u8 use_64bit = 0;
82*08b48e0bSAndroid Build Coastguard Worker 
83*08b48e0bSAndroid Build Coastguard Worker   #ifdef __APPLE__
84*08b48e0bSAndroid Build Coastguard Worker     #error "Sorry, 32-bit Apple platforms are not supported."
85*08b48e0bSAndroid Build Coastguard Worker   #endif                                                       /* __APPLE__ */
86*08b48e0bSAndroid Build Coastguard Worker 
87*08b48e0bSAndroid Build Coastguard Worker #endif                                                     /* ^WORD_SIZE_64 */
88*08b48e0bSAndroid Build Coastguard Worker 
89*08b48e0bSAndroid Build Coastguard Worker /* Examine and modify parameters to pass to 'as'. Note that the file name
90*08b48e0bSAndroid Build Coastguard Worker    is always the last parameter passed by GCC, so we exploit this property
91*08b48e0bSAndroid Build Coastguard Worker    to keep the code simple. */
92*08b48e0bSAndroid Build Coastguard Worker 
edit_params(int argc,char ** argv)93*08b48e0bSAndroid Build Coastguard Worker static void edit_params(int argc, char **argv) {
94*08b48e0bSAndroid Build Coastguard Worker 
95*08b48e0bSAndroid Build Coastguard Worker   u8 *tmp_dir = getenv("TMPDIR"), *afl_as = getenv("AFL_AS");
96*08b48e0bSAndroid Build Coastguard Worker   u32 i, input_index;
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker #ifdef __APPLE__
99*08b48e0bSAndroid Build Coastguard Worker 
100*08b48e0bSAndroid Build Coastguard Worker   u8 use_clang_as = 0;
101*08b48e0bSAndroid Build Coastguard Worker 
102*08b48e0bSAndroid Build Coastguard Worker   /* On MacOS X, the Xcode cctool 'as' driver is a bit stale and does not work
103*08b48e0bSAndroid Build Coastguard Worker      with the code generated by newer versions of clang that are hand-built
104*08b48e0bSAndroid Build Coastguard Worker      by the user. See the thread here: https://goo.gl/HBWDtn.
105*08b48e0bSAndroid Build Coastguard Worker 
106*08b48e0bSAndroid Build Coastguard Worker      To work around this, when using clang and running without AFL_AS
107*08b48e0bSAndroid Build Coastguard Worker      specified, we will actually call 'clang -c' instead of 'as -q' to
108*08b48e0bSAndroid Build Coastguard Worker      compile the assembly file.
109*08b48e0bSAndroid Build Coastguard Worker 
110*08b48e0bSAndroid Build Coastguard Worker      The tools aren't cmdline-compatible, but at least for now, we can
111*08b48e0bSAndroid Build Coastguard Worker      seemingly get away with this by making only very minor tweaks. Thanks
112*08b48e0bSAndroid Build Coastguard Worker      to Nico Weber for the idea. */
113*08b48e0bSAndroid Build Coastguard Worker 
114*08b48e0bSAndroid Build Coastguard Worker   if (clang_mode && !afl_as) {
115*08b48e0bSAndroid Build Coastguard Worker 
116*08b48e0bSAndroid Build Coastguard Worker     use_clang_as = 1;
117*08b48e0bSAndroid Build Coastguard Worker 
118*08b48e0bSAndroid Build Coastguard Worker     afl_as = getenv("AFL_CC");
119*08b48e0bSAndroid Build Coastguard Worker     if (!afl_as) afl_as = getenv("AFL_CXX");
120*08b48e0bSAndroid Build Coastguard Worker     if (!afl_as) afl_as = "clang";
121*08b48e0bSAndroid Build Coastguard Worker 
122*08b48e0bSAndroid Build Coastguard Worker   }
123*08b48e0bSAndroid Build Coastguard Worker 
124*08b48e0bSAndroid Build Coastguard Worker #endif                                                         /* __APPLE__ */
125*08b48e0bSAndroid Build Coastguard Worker 
126*08b48e0bSAndroid Build Coastguard Worker   /* Although this is not documented, GCC also uses TEMP and TMP when TMPDIR
127*08b48e0bSAndroid Build Coastguard Worker      is not set. We need to check these non-standard variables to properly
128*08b48e0bSAndroid Build Coastguard Worker      handle the pass_thru logic later on. */
129*08b48e0bSAndroid Build Coastguard Worker 
130*08b48e0bSAndroid Build Coastguard Worker   if (!tmp_dir) { tmp_dir = getenv("TEMP"); }
131*08b48e0bSAndroid Build Coastguard Worker   if (!tmp_dir) { tmp_dir = getenv("TMP"); }
132*08b48e0bSAndroid Build Coastguard Worker   if (!tmp_dir) { tmp_dir = "/tmp"; }
133*08b48e0bSAndroid Build Coastguard Worker 
134*08b48e0bSAndroid Build Coastguard Worker   as_params = ck_alloc((argc + 32) * sizeof(u8 *));
135*08b48e0bSAndroid Build Coastguard Worker   if (unlikely((INT_MAX - 32) < argc || !as_params)) {
136*08b48e0bSAndroid Build Coastguard Worker 
137*08b48e0bSAndroid Build Coastguard Worker     FATAL("Too many parameters passed to as");
138*08b48e0bSAndroid Build Coastguard Worker 
139*08b48e0bSAndroid Build Coastguard Worker   }
140*08b48e0bSAndroid Build Coastguard Worker 
141*08b48e0bSAndroid Build Coastguard Worker   as_params[0] = afl_as ? afl_as : (u8 *)"as";
142*08b48e0bSAndroid Build Coastguard Worker 
143*08b48e0bSAndroid Build Coastguard Worker   as_params[argc] = 0;
144*08b48e0bSAndroid Build Coastguard Worker 
145*08b48e0bSAndroid Build Coastguard Worker   /* Find the input file.  It's usually located near the end.
146*08b48e0bSAndroid Build Coastguard Worker      Assume there won't be any arguments referring to files after the input
147*08b48e0bSAndroid Build Coastguard Worker      file, e.g. as input.s -o output.o */
148*08b48e0bSAndroid Build Coastguard Worker   for (input_index = argc - 1; input_index > 0; input_index--) {
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker     input_file = argv[input_index];
151*08b48e0bSAndroid Build Coastguard Worker     /* Clang may add debug arguments after the input file. */
152*08b48e0bSAndroid Build Coastguard Worker     if (strncmp(input_file, "-g", 2)) break;
153*08b48e0bSAndroid Build Coastguard Worker 
154*08b48e0bSAndroid Build Coastguard Worker   }
155*08b48e0bSAndroid Build Coastguard Worker 
156*08b48e0bSAndroid Build Coastguard Worker   if (input_index == 0)
157*08b48e0bSAndroid Build Coastguard Worker     FATAL("Could not find input file (not called through afl-gcc?)");
158*08b48e0bSAndroid Build Coastguard Worker 
159*08b48e0bSAndroid Build Coastguard Worker   for (i = 1; (s32)i < argc; i++) {
160*08b48e0bSAndroid Build Coastguard Worker 
161*08b48e0bSAndroid Build Coastguard Worker     if (i == input_index) continue;
162*08b48e0bSAndroid Build Coastguard Worker 
163*08b48e0bSAndroid Build Coastguard Worker     if (!strcmp(argv[i], "--64")) {
164*08b48e0bSAndroid Build Coastguard Worker 
165*08b48e0bSAndroid Build Coastguard Worker       use_64bit = 1;
166*08b48e0bSAndroid Build Coastguard Worker 
167*08b48e0bSAndroid Build Coastguard Worker     } else if (!strcmp(argv[i], "--32")) {
168*08b48e0bSAndroid Build Coastguard Worker 
169*08b48e0bSAndroid Build Coastguard Worker       use_64bit = 0;
170*08b48e0bSAndroid Build Coastguard Worker 
171*08b48e0bSAndroid Build Coastguard Worker     }
172*08b48e0bSAndroid Build Coastguard Worker 
173*08b48e0bSAndroid Build Coastguard Worker #ifdef __APPLE__
174*08b48e0bSAndroid Build Coastguard Worker 
175*08b48e0bSAndroid Build Coastguard Worker     /* The Apple case is a bit different... */
176*08b48e0bSAndroid Build Coastguard Worker 
177*08b48e0bSAndroid Build Coastguard Worker     if (!strcmp(argv[i], "-arch") && i + 1 < (u32)argc) {
178*08b48e0bSAndroid Build Coastguard Worker 
179*08b48e0bSAndroid Build Coastguard Worker       if (!strcmp(argv[i + 1], "x86_64"))
180*08b48e0bSAndroid Build Coastguard Worker         use_64bit = 1;
181*08b48e0bSAndroid Build Coastguard Worker       else if (!strcmp(argv[i + 1], "i386"))
182*08b48e0bSAndroid Build Coastguard Worker         FATAL("Sorry, 32-bit Apple platforms are not supported.");
183*08b48e0bSAndroid Build Coastguard Worker 
184*08b48e0bSAndroid Build Coastguard Worker     }
185*08b48e0bSAndroid Build Coastguard Worker 
186*08b48e0bSAndroid Build Coastguard Worker     /* Strip options that set the preference for a particular upstream
187*08b48e0bSAndroid Build Coastguard Worker        assembler in Xcode. */
188*08b48e0bSAndroid Build Coastguard Worker 
189*08b48e0bSAndroid Build Coastguard Worker     if (clang_mode && (!strcmp(argv[i], "-q") || !strcmp(argv[i], "-Q")))
190*08b48e0bSAndroid Build Coastguard Worker       continue;
191*08b48e0bSAndroid Build Coastguard Worker 
192*08b48e0bSAndroid Build Coastguard Worker #endif                                                         /* __APPLE__ */
193*08b48e0bSAndroid Build Coastguard Worker 
194*08b48e0bSAndroid Build Coastguard Worker     as_params[as_par_cnt++] = argv[i];
195*08b48e0bSAndroid Build Coastguard Worker 
196*08b48e0bSAndroid Build Coastguard Worker   }
197*08b48e0bSAndroid Build Coastguard Worker 
198*08b48e0bSAndroid Build Coastguard Worker #ifdef __APPLE__
199*08b48e0bSAndroid Build Coastguard Worker 
200*08b48e0bSAndroid Build Coastguard Worker   /* When calling clang as the upstream assembler, append -c -x assembler
201*08b48e0bSAndroid Build Coastguard Worker      and hope for the best. */
202*08b48e0bSAndroid Build Coastguard Worker 
203*08b48e0bSAndroid Build Coastguard Worker   if (use_clang_as) {
204*08b48e0bSAndroid Build Coastguard Worker 
205*08b48e0bSAndroid Build Coastguard Worker     as_params[as_par_cnt++] = "-c";
206*08b48e0bSAndroid Build Coastguard Worker     as_params[as_par_cnt++] = "-x";
207*08b48e0bSAndroid Build Coastguard Worker     as_params[as_par_cnt++] = "assembler";
208*08b48e0bSAndroid Build Coastguard Worker 
209*08b48e0bSAndroid Build Coastguard Worker   }
210*08b48e0bSAndroid Build Coastguard Worker 
211*08b48e0bSAndroid Build Coastguard Worker #endif                                                         /* __APPLE__ */
212*08b48e0bSAndroid Build Coastguard Worker 
213*08b48e0bSAndroid Build Coastguard Worker   if (input_file[0] == '-') {
214*08b48e0bSAndroid Build Coastguard Worker 
215*08b48e0bSAndroid Build Coastguard Worker     if (!strcmp(input_file + 1, "-version")) {
216*08b48e0bSAndroid Build Coastguard Worker 
217*08b48e0bSAndroid Build Coastguard Worker       just_version = 1;
218*08b48e0bSAndroid Build Coastguard Worker       modified_file = input_file;
219*08b48e0bSAndroid Build Coastguard Worker       goto wrap_things_up;
220*08b48e0bSAndroid Build Coastguard Worker 
221*08b48e0bSAndroid Build Coastguard Worker     }
222*08b48e0bSAndroid Build Coastguard Worker 
223*08b48e0bSAndroid Build Coastguard Worker     if (input_file[1]) {
224*08b48e0bSAndroid Build Coastguard Worker 
225*08b48e0bSAndroid Build Coastguard Worker       FATAL("Incorrect use (not called through afl-gcc?)");
226*08b48e0bSAndroid Build Coastguard Worker 
227*08b48e0bSAndroid Build Coastguard Worker     } else {
228*08b48e0bSAndroid Build Coastguard Worker 
229*08b48e0bSAndroid Build Coastguard Worker       input_file = NULL;
230*08b48e0bSAndroid Build Coastguard Worker 
231*08b48e0bSAndroid Build Coastguard Worker     }
232*08b48e0bSAndroid Build Coastguard Worker 
233*08b48e0bSAndroid Build Coastguard Worker   } else {
234*08b48e0bSAndroid Build Coastguard Worker 
235*08b48e0bSAndroid Build Coastguard Worker     /* Check if this looks like a standard invocation as a part of an attempt
236*08b48e0bSAndroid Build Coastguard Worker        to compile a program, rather than using gcc on an ad-hoc .s file in
237*08b48e0bSAndroid Build Coastguard Worker        a format we may not understand. This works around an issue compiling
238*08b48e0bSAndroid Build Coastguard Worker        NSS. */
239*08b48e0bSAndroid Build Coastguard Worker 
240*08b48e0bSAndroid Build Coastguard Worker     if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) &&
241*08b48e0bSAndroid Build Coastguard Worker         strncmp(input_file, "/var/tmp/", 9) &&
242*08b48e0bSAndroid Build Coastguard Worker         strncmp(input_file, "/tmp/", 5) &&
243*08b48e0bSAndroid Build Coastguard Worker         getenv("AFL_AS_FORCE_INSTRUMENT") == NULL) {
244*08b48e0bSAndroid Build Coastguard Worker 
245*08b48e0bSAndroid Build Coastguard Worker       pass_thru = 1;
246*08b48e0bSAndroid Build Coastguard Worker 
247*08b48e0bSAndroid Build Coastguard Worker     } else if (getenv("AFL_AS_FORCE_INSTRUMENT")) {
248*08b48e0bSAndroid Build Coastguard Worker 
249*08b48e0bSAndroid Build Coastguard Worker       unsetenv("AFL_AS_FORCE_INSTRUMENT");
250*08b48e0bSAndroid Build Coastguard Worker 
251*08b48e0bSAndroid Build Coastguard Worker     }
252*08b48e0bSAndroid Build Coastguard Worker 
253*08b48e0bSAndroid Build Coastguard Worker   }
254*08b48e0bSAndroid Build Coastguard Worker 
255*08b48e0bSAndroid Build Coastguard Worker   modified_file = alloc_printf("%s/.afl-%u-%u-%u.s", tmp_dir, (u32)getpid(),
256*08b48e0bSAndroid Build Coastguard Worker                                (u32)time(NULL), (u32)random());
257*08b48e0bSAndroid Build Coastguard Worker 
258*08b48e0bSAndroid Build Coastguard Worker wrap_things_up:
259*08b48e0bSAndroid Build Coastguard Worker 
260*08b48e0bSAndroid Build Coastguard Worker   as_params[as_par_cnt++] = modified_file;
261*08b48e0bSAndroid Build Coastguard Worker   as_params[as_par_cnt] = NULL;
262*08b48e0bSAndroid Build Coastguard Worker 
263*08b48e0bSAndroid Build Coastguard Worker }
264*08b48e0bSAndroid Build Coastguard Worker 
265*08b48e0bSAndroid Build Coastguard Worker /* Process input file, generate modified_file. Insert instrumentation in all
266*08b48e0bSAndroid Build Coastguard Worker    the appropriate places. */
267*08b48e0bSAndroid Build Coastguard Worker 
add_instrumentation(void)268*08b48e0bSAndroid Build Coastguard Worker static void add_instrumentation(void) {
269*08b48e0bSAndroid Build Coastguard Worker 
270*08b48e0bSAndroid Build Coastguard Worker   static u8 line[MAX_LINE];
271*08b48e0bSAndroid Build Coastguard Worker 
272*08b48e0bSAndroid Build Coastguard Worker   FILE *inf;
273*08b48e0bSAndroid Build Coastguard Worker   FILE *outf;
274*08b48e0bSAndroid Build Coastguard Worker   s32   outfd;
275*08b48e0bSAndroid Build Coastguard Worker   u32   ins_lines = 0;
276*08b48e0bSAndroid Build Coastguard Worker 
277*08b48e0bSAndroid Build Coastguard Worker   u8 instr_ok = 0, skip_csect = 0, skip_next_label = 0, skip_intel = 0,
278*08b48e0bSAndroid Build Coastguard Worker      skip_app = 0, instrument_next = 0;
279*08b48e0bSAndroid Build Coastguard Worker 
280*08b48e0bSAndroid Build Coastguard Worker #ifdef __APPLE__
281*08b48e0bSAndroid Build Coastguard Worker 
282*08b48e0bSAndroid Build Coastguard Worker   u8 *colon_pos;
283*08b48e0bSAndroid Build Coastguard Worker 
284*08b48e0bSAndroid Build Coastguard Worker #endif                                                         /* __APPLE__ */
285*08b48e0bSAndroid Build Coastguard Worker 
286*08b48e0bSAndroid Build Coastguard Worker   if (input_file) {
287*08b48e0bSAndroid Build Coastguard Worker 
288*08b48e0bSAndroid Build Coastguard Worker     inf = fopen(input_file, "r");
289*08b48e0bSAndroid Build Coastguard Worker     if (!inf) { PFATAL("Unable to read '%s'", input_file); }
290*08b48e0bSAndroid Build Coastguard Worker 
291*08b48e0bSAndroid Build Coastguard Worker   } else {
292*08b48e0bSAndroid Build Coastguard Worker 
293*08b48e0bSAndroid Build Coastguard Worker     inf = stdin;
294*08b48e0bSAndroid Build Coastguard Worker 
295*08b48e0bSAndroid Build Coastguard Worker   }
296*08b48e0bSAndroid Build Coastguard Worker 
297*08b48e0bSAndroid Build Coastguard Worker   outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, DEFAULT_PERMISSION);
298*08b48e0bSAndroid Build Coastguard Worker 
299*08b48e0bSAndroid Build Coastguard Worker   if (outfd < 0) { PFATAL("Unable to write to '%s'", modified_file); }
300*08b48e0bSAndroid Build Coastguard Worker 
301*08b48e0bSAndroid Build Coastguard Worker   outf = fdopen(outfd, "w");
302*08b48e0bSAndroid Build Coastguard Worker 
303*08b48e0bSAndroid Build Coastguard Worker   if (!outf) { PFATAL("fdopen() failed"); }
304*08b48e0bSAndroid Build Coastguard Worker 
305*08b48e0bSAndroid Build Coastguard Worker   while (fgets(line, MAX_LINE, inf)) {
306*08b48e0bSAndroid Build Coastguard Worker 
307*08b48e0bSAndroid Build Coastguard Worker     /* In some cases, we want to defer writing the instrumentation trampoline
308*08b48e0bSAndroid Build Coastguard Worker        until after all the labels, macros, comments, etc. If we're in this
309*08b48e0bSAndroid Build Coastguard Worker        mode, and if the line starts with a tab followed by a character, dump
310*08b48e0bSAndroid Build Coastguard Worker        the trampoline now. */
311*08b48e0bSAndroid Build Coastguard Worker 
312*08b48e0bSAndroid Build Coastguard Worker     if (!pass_thru && !skip_intel && !skip_app && !skip_csect && instr_ok &&
313*08b48e0bSAndroid Build Coastguard Worker         instrument_next && line[0] == '\t' && isalpha(line[1])) {
314*08b48e0bSAndroid Build Coastguard Worker 
315*08b48e0bSAndroid Build Coastguard Worker       fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32,
316*08b48e0bSAndroid Build Coastguard Worker               R(MAP_SIZE));
317*08b48e0bSAndroid Build Coastguard Worker 
318*08b48e0bSAndroid Build Coastguard Worker       instrument_next = 0;
319*08b48e0bSAndroid Build Coastguard Worker       ins_lines++;
320*08b48e0bSAndroid Build Coastguard Worker 
321*08b48e0bSAndroid Build Coastguard Worker     }
322*08b48e0bSAndroid Build Coastguard Worker 
323*08b48e0bSAndroid Build Coastguard Worker     /* Output the actual line, call it a day in pass-thru mode. */
324*08b48e0bSAndroid Build Coastguard Worker 
325*08b48e0bSAndroid Build Coastguard Worker     fputs(line, outf);
326*08b48e0bSAndroid Build Coastguard Worker 
327*08b48e0bSAndroid Build Coastguard Worker     if (pass_thru) { continue; }
328*08b48e0bSAndroid Build Coastguard Worker 
329*08b48e0bSAndroid Build Coastguard Worker     /* All right, this is where the actual fun begins. For one, we only want to
330*08b48e0bSAndroid Build Coastguard Worker        instrument the .text section. So, let's keep track of that in processed
331*08b48e0bSAndroid Build Coastguard Worker        files - and let's set instr_ok accordingly. */
332*08b48e0bSAndroid Build Coastguard Worker 
333*08b48e0bSAndroid Build Coastguard Worker     if (line[0] == '\t' && line[1] == '.') {
334*08b48e0bSAndroid Build Coastguard Worker 
335*08b48e0bSAndroid Build Coastguard Worker       /* OpenBSD puts jump tables directly inline with the code, which is
336*08b48e0bSAndroid Build Coastguard Worker          a bit annoying. They use a specific format of p2align directives
337*08b48e0bSAndroid Build Coastguard Worker          around them, so we use that as a signal. */
338*08b48e0bSAndroid Build Coastguard Worker 
339*08b48e0bSAndroid Build Coastguard Worker       if (!clang_mode && instr_ok && !strncmp(line + 2, "p2align ", 8) &&
340*08b48e0bSAndroid Build Coastguard Worker           isdigit(line[10]) && line[11] == '\n') {
341*08b48e0bSAndroid Build Coastguard Worker 
342*08b48e0bSAndroid Build Coastguard Worker         skip_next_label = 1;
343*08b48e0bSAndroid Build Coastguard Worker 
344*08b48e0bSAndroid Build Coastguard Worker       }
345*08b48e0bSAndroid Build Coastguard Worker 
346*08b48e0bSAndroid Build Coastguard Worker       if (!strncmp(line + 2, "text\n", 5) ||
347*08b48e0bSAndroid Build Coastguard Worker           !strncmp(line + 2, "section\t.text", 13) ||
348*08b48e0bSAndroid Build Coastguard Worker           !strncmp(line + 2, "section\t__TEXT,__text", 21) ||
349*08b48e0bSAndroid Build Coastguard Worker           !strncmp(line + 2, "section __TEXT,__text", 21)) {
350*08b48e0bSAndroid Build Coastguard Worker 
351*08b48e0bSAndroid Build Coastguard Worker         instr_ok = 1;
352*08b48e0bSAndroid Build Coastguard Worker         continue;
353*08b48e0bSAndroid Build Coastguard Worker 
354*08b48e0bSAndroid Build Coastguard Worker       }
355*08b48e0bSAndroid Build Coastguard Worker 
356*08b48e0bSAndroid Build Coastguard Worker       if (!strncmp(line + 2, "section\t", 8) ||
357*08b48e0bSAndroid Build Coastguard Worker           !strncmp(line + 2, "section ", 8) || !strncmp(line + 2, "bss\n", 4) ||
358*08b48e0bSAndroid Build Coastguard Worker           !strncmp(line + 2, "data\n", 5)) {
359*08b48e0bSAndroid Build Coastguard Worker 
360*08b48e0bSAndroid Build Coastguard Worker         instr_ok = 0;
361*08b48e0bSAndroid Build Coastguard Worker         continue;
362*08b48e0bSAndroid Build Coastguard Worker 
363*08b48e0bSAndroid Build Coastguard Worker       }
364*08b48e0bSAndroid Build Coastguard Worker 
365*08b48e0bSAndroid Build Coastguard Worker     }
366*08b48e0bSAndroid Build Coastguard Worker 
367*08b48e0bSAndroid Build Coastguard Worker     /* Detect off-flavor assembly (rare, happens in gdb). When this is
368*08b48e0bSAndroid Build Coastguard Worker        encountered, we set skip_csect until the opposite directive is
369*08b48e0bSAndroid Build Coastguard Worker        seen, and we do not instrument. */
370*08b48e0bSAndroid Build Coastguard Worker 
371*08b48e0bSAndroid Build Coastguard Worker     if (strstr(line, ".code")) {
372*08b48e0bSAndroid Build Coastguard Worker 
373*08b48e0bSAndroid Build Coastguard Worker       if (strstr(line, ".code32")) { skip_csect = use_64bit; }
374*08b48e0bSAndroid Build Coastguard Worker       if (strstr(line, ".code64")) { skip_csect = !use_64bit; }
375*08b48e0bSAndroid Build Coastguard Worker 
376*08b48e0bSAndroid Build Coastguard Worker     }
377*08b48e0bSAndroid Build Coastguard Worker 
378*08b48e0bSAndroid Build Coastguard Worker     /* Detect syntax changes, as could happen with hand-written assembly.
379*08b48e0bSAndroid Build Coastguard Worker        Skip Intel blocks, resume instrumentation when back to AT&T. */
380*08b48e0bSAndroid Build Coastguard Worker 
381*08b48e0bSAndroid Build Coastguard Worker     if (strstr(line, ".intel_syntax")) { skip_intel = 1; }
382*08b48e0bSAndroid Build Coastguard Worker     if (strstr(line, ".att_syntax")) { skip_intel = 0; }
383*08b48e0bSAndroid Build Coastguard Worker 
384*08b48e0bSAndroid Build Coastguard Worker     /* Detect and skip ad-hoc __asm__ blocks, likewise skipping them. */
385*08b48e0bSAndroid Build Coastguard Worker 
386*08b48e0bSAndroid Build Coastguard Worker     if (line[0] == '#' || line[1] == '#') {
387*08b48e0bSAndroid Build Coastguard Worker 
388*08b48e0bSAndroid Build Coastguard Worker       if (strstr(line, "#APP")) { skip_app = 1; }
389*08b48e0bSAndroid Build Coastguard Worker       if (strstr(line, "#NO_APP")) { skip_app = 0; }
390*08b48e0bSAndroid Build Coastguard Worker 
391*08b48e0bSAndroid Build Coastguard Worker     }
392*08b48e0bSAndroid Build Coastguard Worker 
393*08b48e0bSAndroid Build Coastguard Worker     /* If we're in the right mood for instrumenting, check for function
394*08b48e0bSAndroid Build Coastguard Worker        names or conditional labels. This is a bit messy, but in essence,
395*08b48e0bSAndroid Build Coastguard Worker        we want to catch:
396*08b48e0bSAndroid Build Coastguard Worker 
397*08b48e0bSAndroid Build Coastguard Worker          ^main:      - function entry point (always instrumented)
398*08b48e0bSAndroid Build Coastguard Worker          ^.L0:       - GCC branch label
399*08b48e0bSAndroid Build Coastguard Worker          ^.LBB0_0:   - clang branch label (but only in clang mode)
400*08b48e0bSAndroid Build Coastguard Worker          ^\tjnz foo  - conditional branches
401*08b48e0bSAndroid Build Coastguard Worker 
402*08b48e0bSAndroid Build Coastguard Worker        ...but not:
403*08b48e0bSAndroid Build Coastguard Worker 
404*08b48e0bSAndroid Build Coastguard Worker          ^# BB#0:    - clang comments
405*08b48e0bSAndroid Build Coastguard Worker          ^ # BB#0:   - ditto
406*08b48e0bSAndroid Build Coastguard Worker          ^.Ltmp0:    - clang non-branch labels
407*08b48e0bSAndroid Build Coastguard Worker          ^.LC0       - GCC non-branch labels
408*08b48e0bSAndroid Build Coastguard Worker          ^.LBB0_0:   - ditto (when in GCC mode)
409*08b48e0bSAndroid Build Coastguard Worker          ^\tjmp foo  - non-conditional jumps
410*08b48e0bSAndroid Build Coastguard Worker 
411*08b48e0bSAndroid Build Coastguard Worker        Additionally, clang and GCC on MacOS X follow a different convention
412*08b48e0bSAndroid Build Coastguard Worker        with no leading dots on labels, hence the weird maze of #ifdefs
413*08b48e0bSAndroid Build Coastguard Worker        later on.
414*08b48e0bSAndroid Build Coastguard Worker 
415*08b48e0bSAndroid Build Coastguard Worker      */
416*08b48e0bSAndroid Build Coastguard Worker 
417*08b48e0bSAndroid Build Coastguard Worker     if (skip_intel || skip_app || skip_csect || !instr_ok || line[0] == '#' ||
418*08b48e0bSAndroid Build Coastguard Worker         line[0] == ' ') {
419*08b48e0bSAndroid Build Coastguard Worker 
420*08b48e0bSAndroid Build Coastguard Worker       continue;
421*08b48e0bSAndroid Build Coastguard Worker 
422*08b48e0bSAndroid Build Coastguard Worker     }
423*08b48e0bSAndroid Build Coastguard Worker 
424*08b48e0bSAndroid Build Coastguard Worker     /* Conditional branch instruction (jnz, etc). We append the instrumentation
425*08b48e0bSAndroid Build Coastguard Worker        right after the branch (to instrument the not-taken path) and at the
426*08b48e0bSAndroid Build Coastguard Worker        branch destination label (handled later on). */
427*08b48e0bSAndroid Build Coastguard Worker 
428*08b48e0bSAndroid Build Coastguard Worker     if (line[0] == '\t') {
429*08b48e0bSAndroid Build Coastguard Worker 
430*08b48e0bSAndroid Build Coastguard Worker       if (line[1] == 'j' && line[2] != 'm' && R(100) < (long)inst_ratio) {
431*08b48e0bSAndroid Build Coastguard Worker 
432*08b48e0bSAndroid Build Coastguard Worker         fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32,
433*08b48e0bSAndroid Build Coastguard Worker                 R(MAP_SIZE));
434*08b48e0bSAndroid Build Coastguard Worker 
435*08b48e0bSAndroid Build Coastguard Worker         ins_lines++;
436*08b48e0bSAndroid Build Coastguard Worker 
437*08b48e0bSAndroid Build Coastguard Worker       }
438*08b48e0bSAndroid Build Coastguard Worker 
439*08b48e0bSAndroid Build Coastguard Worker       continue;
440*08b48e0bSAndroid Build Coastguard Worker 
441*08b48e0bSAndroid Build Coastguard Worker     }
442*08b48e0bSAndroid Build Coastguard Worker 
443*08b48e0bSAndroid Build Coastguard Worker     /* Label of some sort. This may be a branch destination, but we need to
444*08b48e0bSAndroid Build Coastguard Worker        read carefully and account for several different formatting
445*08b48e0bSAndroid Build Coastguard Worker        conventions. */
446*08b48e0bSAndroid Build Coastguard Worker 
447*08b48e0bSAndroid Build Coastguard Worker #ifdef __APPLE__
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker     /* Apple: L<whatever><digit>: */
450*08b48e0bSAndroid Build Coastguard Worker 
451*08b48e0bSAndroid Build Coastguard Worker     if ((colon_pos = strstr(line, ":"))) {
452*08b48e0bSAndroid Build Coastguard Worker 
453*08b48e0bSAndroid Build Coastguard Worker       if (line[0] == 'L' && isdigit(*(colon_pos - 1))) {
454*08b48e0bSAndroid Build Coastguard Worker 
455*08b48e0bSAndroid Build Coastguard Worker #else
456*08b48e0bSAndroid Build Coastguard Worker 
457*08b48e0bSAndroid Build Coastguard Worker     /* Everybody else: .L<whatever>: */
458*08b48e0bSAndroid Build Coastguard Worker 
459*08b48e0bSAndroid Build Coastguard Worker     if (strstr(line, ":")) {
460*08b48e0bSAndroid Build Coastguard Worker 
461*08b48e0bSAndroid Build Coastguard Worker       if (line[0] == '.') {
462*08b48e0bSAndroid Build Coastguard Worker 
463*08b48e0bSAndroid Build Coastguard Worker #endif                                                         /* __APPLE__ */
464*08b48e0bSAndroid Build Coastguard Worker 
465*08b48e0bSAndroid Build Coastguard Worker         /* .L0: or LBB0_0: style jump destination */
466*08b48e0bSAndroid Build Coastguard Worker 
467*08b48e0bSAndroid Build Coastguard Worker #ifdef __APPLE__
468*08b48e0bSAndroid Build Coastguard Worker 
469*08b48e0bSAndroid Build Coastguard Worker         /* Apple: L<num> / LBB<num> */
470*08b48e0bSAndroid Build Coastguard Worker 
471*08b48e0bSAndroid Build Coastguard Worker         if ((isdigit(line[1]) || (clang_mode && !strncmp(line, "LBB", 3))) &&
472*08b48e0bSAndroid Build Coastguard Worker             R(100) < (long)inst_ratio) {
473*08b48e0bSAndroid Build Coastguard Worker 
474*08b48e0bSAndroid Build Coastguard Worker #else
475*08b48e0bSAndroid Build Coastguard Worker 
476*08b48e0bSAndroid Build Coastguard Worker         /* Apple: .L<num> / .LBB<num> */
477*08b48e0bSAndroid Build Coastguard Worker 
478*08b48e0bSAndroid Build Coastguard Worker         if ((isdigit(line[2]) ||
479*08b48e0bSAndroid Build Coastguard Worker              (clang_mode && !strncmp(line + 1, "LBB", 3))) &&
480*08b48e0bSAndroid Build Coastguard Worker             R(100) < (long)inst_ratio) {
481*08b48e0bSAndroid Build Coastguard Worker 
482*08b48e0bSAndroid Build Coastguard Worker #endif                                                         /* __APPLE__ */
483*08b48e0bSAndroid Build Coastguard Worker 
484*08b48e0bSAndroid Build Coastguard Worker           /* An optimization is possible here by adding the code only if the
485*08b48e0bSAndroid Build Coastguard Worker              label is mentioned in the code in contexts other than call / jmp.
486*08b48e0bSAndroid Build Coastguard Worker              That said, this complicates the code by requiring two-pass
487*08b48e0bSAndroid Build Coastguard Worker              processing (messy with stdin), and results in a speed gain
488*08b48e0bSAndroid Build Coastguard Worker              typically under 10%, because compilers are generally pretty good
489*08b48e0bSAndroid Build Coastguard Worker              about not generating spurious intra-function jumps.
490*08b48e0bSAndroid Build Coastguard Worker 
491*08b48e0bSAndroid Build Coastguard Worker              We use deferred output chiefly to avoid disrupting
492*08b48e0bSAndroid Build Coastguard Worker              .Lfunc_begin0-style exception handling calculations (a problem on
493*08b48e0bSAndroid Build Coastguard Worker              MacOS X). */
494*08b48e0bSAndroid Build Coastguard Worker 
495*08b48e0bSAndroid Build Coastguard Worker           if (!skip_next_label) {
496*08b48e0bSAndroid Build Coastguard Worker 
497*08b48e0bSAndroid Build Coastguard Worker             instrument_next = 1;
498*08b48e0bSAndroid Build Coastguard Worker 
499*08b48e0bSAndroid Build Coastguard Worker           } else {
500*08b48e0bSAndroid Build Coastguard Worker 
501*08b48e0bSAndroid Build Coastguard Worker             skip_next_label = 0;
502*08b48e0bSAndroid Build Coastguard Worker 
503*08b48e0bSAndroid Build Coastguard Worker           }
504*08b48e0bSAndroid Build Coastguard Worker 
505*08b48e0bSAndroid Build Coastguard Worker         }
506*08b48e0bSAndroid Build Coastguard Worker 
507*08b48e0bSAndroid Build Coastguard Worker       } else {
508*08b48e0bSAndroid Build Coastguard Worker 
509*08b48e0bSAndroid Build Coastguard Worker         /* Function label (always instrumented, deferred mode). */
510*08b48e0bSAndroid Build Coastguard Worker 
511*08b48e0bSAndroid Build Coastguard Worker         instrument_next = 1;
512*08b48e0bSAndroid Build Coastguard Worker 
513*08b48e0bSAndroid Build Coastguard Worker       }
514*08b48e0bSAndroid Build Coastguard Worker 
515*08b48e0bSAndroid Build Coastguard Worker     }
516*08b48e0bSAndroid Build Coastguard Worker 
517*08b48e0bSAndroid Build Coastguard Worker   }
518*08b48e0bSAndroid Build Coastguard Worker 
519*08b48e0bSAndroid Build Coastguard Worker   if (ins_lines) { fputs(use_64bit ? main_payload_64 : main_payload_32, outf); }
520*08b48e0bSAndroid Build Coastguard Worker 
521*08b48e0bSAndroid Build Coastguard Worker   if (input_file) { fclose(inf); }
522*08b48e0bSAndroid Build Coastguard Worker   fclose(outf);
523*08b48e0bSAndroid Build Coastguard Worker 
524*08b48e0bSAndroid Build Coastguard Worker   if (!be_quiet) {
525*08b48e0bSAndroid Build Coastguard Worker 
526*08b48e0bSAndroid Build Coastguard Worker     if (!ins_lines) {
527*08b48e0bSAndroid Build Coastguard Worker 
528*08b48e0bSAndroid Build Coastguard Worker       WARNF("No instrumentation targets found%s.",
529*08b48e0bSAndroid Build Coastguard Worker             pass_thru ? " (pass-thru mode)" : "");
530*08b48e0bSAndroid Build Coastguard Worker 
531*08b48e0bSAndroid Build Coastguard Worker     } else {
532*08b48e0bSAndroid Build Coastguard Worker 
533*08b48e0bSAndroid Build Coastguard Worker       char modeline[100];
534*08b48e0bSAndroid Build Coastguard Worker       snprintf(modeline, sizeof(modeline), "%s%s%s%s%s%s",
535*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
536*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_ASAN") ? ", ASAN" : "",
537*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_MSAN") ? ", MSAN" : "",
538*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_TSAN") ? ", TSAN" : "",
539*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "",
540*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_LSAN") ? ", LSAN" : "");
541*08b48e0bSAndroid Build Coastguard Worker 
542*08b48e0bSAndroid Build Coastguard Worker       OKF("Instrumented %u locations (%s-bit, %s mode, ratio %u%%).", ins_lines,
543*08b48e0bSAndroid Build Coastguard Worker           use_64bit ? "64" : "32", modeline, inst_ratio);
544*08b48e0bSAndroid Build Coastguard Worker 
545*08b48e0bSAndroid Build Coastguard Worker     }
546*08b48e0bSAndroid Build Coastguard Worker 
547*08b48e0bSAndroid Build Coastguard Worker   }
548*08b48e0bSAndroid Build Coastguard Worker 
549*08b48e0bSAndroid Build Coastguard Worker }
550*08b48e0bSAndroid Build Coastguard Worker 
551*08b48e0bSAndroid Build Coastguard Worker /* Main entry point */
552*08b48e0bSAndroid Build Coastguard Worker 
553*08b48e0bSAndroid Build Coastguard Worker int main(int argc, char **argv) {
554*08b48e0bSAndroid Build Coastguard Worker 
555*08b48e0bSAndroid Build Coastguard Worker   s32 pid;
556*08b48e0bSAndroid Build Coastguard Worker   u32 rand_seed, i, j;
557*08b48e0bSAndroid Build Coastguard Worker   int status;
558*08b48e0bSAndroid Build Coastguard Worker   u8 *inst_ratio_str = getenv("AFL_INST_RATIO");
559*08b48e0bSAndroid Build Coastguard Worker 
560*08b48e0bSAndroid Build Coastguard Worker   struct timeval  tv;
561*08b48e0bSAndroid Build Coastguard Worker   struct timezone tz;
562*08b48e0bSAndroid Build Coastguard Worker 
563*08b48e0bSAndroid Build Coastguard Worker   clang_mode = !!getenv(CLANG_ENV_VAR);
564*08b48e0bSAndroid Build Coastguard Worker 
565*08b48e0bSAndroid Build Coastguard Worker   if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
566*08b48e0bSAndroid Build Coastguard Worker 
567*08b48e0bSAndroid Build Coastguard Worker     SAYF(cCYA "afl-as" VERSION cRST " by Michal Zalewski\n");
568*08b48e0bSAndroid Build Coastguard Worker 
569*08b48e0bSAndroid Build Coastguard Worker   } else {
570*08b48e0bSAndroid Build Coastguard Worker 
571*08b48e0bSAndroid Build Coastguard Worker     be_quiet = 1;
572*08b48e0bSAndroid Build Coastguard Worker 
573*08b48e0bSAndroid Build Coastguard Worker   }
574*08b48e0bSAndroid Build Coastguard Worker 
575*08b48e0bSAndroid Build Coastguard Worker   if (argc < 2 || (argc == 2 && strcmp(argv[1], "-h") == 0)) {
576*08b48e0bSAndroid Build Coastguard Worker 
577*08b48e0bSAndroid Build Coastguard Worker     fprintf(
578*08b48e0bSAndroid Build Coastguard Worker         stdout,
579*08b48e0bSAndroid Build Coastguard Worker         "afl-as" VERSION
580*08b48e0bSAndroid Build Coastguard Worker         " by Michal Zalewski\n"
581*08b48e0bSAndroid Build Coastguard Worker         "\n%s [-h]\n\n"
582*08b48e0bSAndroid Build Coastguard Worker         "This is a helper application for afl-fuzz. It is a wrapper around GNU "
583*08b48e0bSAndroid Build Coastguard Worker         "'as',\n"
584*08b48e0bSAndroid Build Coastguard Worker         "executed by the toolchain whenever using afl-gcc or afl-clang. You "
585*08b48e0bSAndroid Build Coastguard Worker         "probably\n"
586*08b48e0bSAndroid Build Coastguard Worker         "don't want to run this program directly.\n\n"
587*08b48e0bSAndroid Build Coastguard Worker 
588*08b48e0bSAndroid Build Coastguard Worker         "Rarely, when dealing with extremely complex projects, it may be "
589*08b48e0bSAndroid Build Coastguard Worker         "advisable\n"
590*08b48e0bSAndroid Build Coastguard Worker         "to set AFL_INST_RATIO to a value less than 100 in order to reduce "
591*08b48e0bSAndroid Build Coastguard Worker         "the\n"
592*08b48e0bSAndroid Build Coastguard Worker         "odds of instrumenting every discovered branch.\n\n"
593*08b48e0bSAndroid Build Coastguard Worker         "Environment variables used:\n"
594*08b48e0bSAndroid Build Coastguard Worker         "AFL_AS: path to assembler to use for instrumented files\n"
595*08b48e0bSAndroid Build Coastguard Worker         "AFL_CC: fall back path to assembler\n"
596*08b48e0bSAndroid Build Coastguard Worker         "AFL_CXX: fall back path to assembler\n"
597*08b48e0bSAndroid Build Coastguard Worker         "TMPDIR: directory to use for temporary files\n"
598*08b48e0bSAndroid Build Coastguard Worker         "TEMP: fall back path to directory for temporary files\n"
599*08b48e0bSAndroid Build Coastguard Worker         "TMP: fall back path to directory for temporary files\n"
600*08b48e0bSAndroid Build Coastguard Worker         "AFL_INST_RATIO: user specified instrumentation ratio\n"
601*08b48e0bSAndroid Build Coastguard Worker         "AFL_QUIET: suppress verbose output\n"
602*08b48e0bSAndroid Build Coastguard Worker         "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n"
603*08b48e0bSAndroid Build Coastguard Worker         "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n"
604*08b48e0bSAndroid Build Coastguard Worker         "AFL_HARDEN, AFL_USE_ASAN, AFL_USE_MSAN, AFL_USE_UBSAN, AFL_USE_LSAN:\n"
605*08b48e0bSAndroid Build Coastguard Worker         "  used in the instrumentation summary message\n",
606*08b48e0bSAndroid Build Coastguard Worker         argv[0]);
607*08b48e0bSAndroid Build Coastguard Worker 
608*08b48e0bSAndroid Build Coastguard Worker     exit(1);
609*08b48e0bSAndroid Build Coastguard Worker 
610*08b48e0bSAndroid Build Coastguard Worker   }
611*08b48e0bSAndroid Build Coastguard Worker 
612*08b48e0bSAndroid Build Coastguard Worker   gettimeofday(&tv, &tz);
613*08b48e0bSAndroid Build Coastguard Worker 
614*08b48e0bSAndroid Build Coastguard Worker   rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
615*08b48e0bSAndroid Build Coastguard Worker   // in fast systems where pids can repeat in the same seconds we need this
616*08b48e0bSAndroid Build Coastguard Worker   for (i = 1; (s32)i < argc; i++)
617*08b48e0bSAndroid Build Coastguard Worker     for (j = 0; j < strlen(argv[i]); j++)
618*08b48e0bSAndroid Build Coastguard Worker       rand_seed += argv[i][j];
619*08b48e0bSAndroid Build Coastguard Worker 
620*08b48e0bSAndroid Build Coastguard Worker   srandom(rand_seed);
621*08b48e0bSAndroid Build Coastguard Worker 
622*08b48e0bSAndroid Build Coastguard Worker   edit_params(argc, argv);
623*08b48e0bSAndroid Build Coastguard Worker 
624*08b48e0bSAndroid Build Coastguard Worker   if (inst_ratio_str) {
625*08b48e0bSAndroid Build Coastguard Worker 
626*08b48e0bSAndroid Build Coastguard Worker     if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || inst_ratio > 100) {
627*08b48e0bSAndroid Build Coastguard Worker 
628*08b48e0bSAndroid Build Coastguard Worker       FATAL("Bad value of AFL_INST_RATIO (must be between 0 and 100)");
629*08b48e0bSAndroid Build Coastguard Worker 
630*08b48e0bSAndroid Build Coastguard Worker     }
631*08b48e0bSAndroid Build Coastguard Worker 
632*08b48e0bSAndroid Build Coastguard Worker   }
633*08b48e0bSAndroid Build Coastguard Worker 
634*08b48e0bSAndroid Build Coastguard Worker   if (getenv(AS_LOOP_ENV_VAR)) {
635*08b48e0bSAndroid Build Coastguard Worker 
636*08b48e0bSAndroid Build Coastguard Worker     FATAL("Endless loop when calling 'as' (remove '.' from your PATH)");
637*08b48e0bSAndroid Build Coastguard Worker 
638*08b48e0bSAndroid Build Coastguard Worker   }
639*08b48e0bSAndroid Build Coastguard Worker 
640*08b48e0bSAndroid Build Coastguard Worker   setenv(AS_LOOP_ENV_VAR, "1", 1);
641*08b48e0bSAndroid Build Coastguard Worker 
642*08b48e0bSAndroid Build Coastguard Worker   /* When compiling with ASAN, we don't have a particularly elegant way to skip
643*08b48e0bSAndroid Build Coastguard Worker      ASAN-specific branches. But we can probabilistically compensate for
644*08b48e0bSAndroid Build Coastguard Worker      that... */
645*08b48e0bSAndroid Build Coastguard Worker 
646*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) {
647*08b48e0bSAndroid Build Coastguard Worker 
648*08b48e0bSAndroid Build Coastguard Worker     sanitizer = 1;
649*08b48e0bSAndroid Build Coastguard Worker     if (!getenv("AFL_INST_RATIO")) { inst_ratio /= 3; }
650*08b48e0bSAndroid Build Coastguard Worker 
651*08b48e0bSAndroid Build Coastguard Worker   }
652*08b48e0bSAndroid Build Coastguard Worker 
653*08b48e0bSAndroid Build Coastguard Worker   if (!just_version) { add_instrumentation(); }
654*08b48e0bSAndroid Build Coastguard Worker 
655*08b48e0bSAndroid Build Coastguard Worker   if (!(pid = fork())) {
656*08b48e0bSAndroid Build Coastguard Worker 
657*08b48e0bSAndroid Build Coastguard Worker     execvp(as_params[0], (char **)as_params);
658*08b48e0bSAndroid Build Coastguard Worker     FATAL("Oops, failed to execute '%s' - check your PATH", as_params[0]);
659*08b48e0bSAndroid Build Coastguard Worker 
660*08b48e0bSAndroid Build Coastguard Worker   }
661*08b48e0bSAndroid Build Coastguard Worker 
662*08b48e0bSAndroid Build Coastguard Worker   if (pid < 0) { PFATAL("fork() failed"); }
663*08b48e0bSAndroid Build Coastguard Worker 
664*08b48e0bSAndroid Build Coastguard Worker   if (waitpid(pid, &status, 0) <= 0) { PFATAL("waitpid() failed"); }
665*08b48e0bSAndroid Build Coastguard Worker 
666*08b48e0bSAndroid Build Coastguard Worker   if (!getenv("AFL_KEEP_ASSEMBLY")) { unlink(modified_file); }
667*08b48e0bSAndroid Build Coastguard Worker 
668*08b48e0bSAndroid Build Coastguard Worker   exit(WEXITSTATUS(status));
669*08b48e0bSAndroid Build Coastguard Worker 
670*08b48e0bSAndroid Build Coastguard Worker }
671*08b48e0bSAndroid Build Coastguard Worker 
672