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