xref: /aosp_15_r20/external/AFLplusplus/src/afl-ld-lto.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker   american fuzzy lop++ - wrapper for llvm 11+ lld
3*08b48e0bSAndroid Build Coastguard Worker   -----------------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker 
5*08b48e0bSAndroid Build Coastguard Worker   Written by Marc Heuse <[email protected]> for AFL++
6*08b48e0bSAndroid Build Coastguard Worker 
7*08b48e0bSAndroid Build Coastguard Worker   Maintained by Marc Heuse <[email protected]>,
8*08b48e0bSAndroid Build Coastguard Worker                 Heiko Eißfeldt <[email protected]>
9*08b48e0bSAndroid Build Coastguard Worker                 Andrea Fioraldi <[email protected]>
10*08b48e0bSAndroid Build Coastguard Worker                 Dominik Maier <[email protected]>
11*08b48e0bSAndroid Build Coastguard Worker 
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 clang LTO files when
21*08b48e0bSAndroid Build Coastguard Worker   linking with lld and performing the instrumentation on the whole program.
22*08b48e0bSAndroid Build Coastguard Worker 
23*08b48e0bSAndroid Build Coastguard Worker */
24*08b48e0bSAndroid Build Coastguard Worker 
25*08b48e0bSAndroid Build Coastguard Worker #define AFL_MAIN
26*08b48e0bSAndroid Build Coastguard Worker #ifndef _GNU_SOURCE
27*08b48e0bSAndroid Build Coastguard Worker   #define _GNU_SOURCE
28*08b48e0bSAndroid Build Coastguard Worker #endif
29*08b48e0bSAndroid Build Coastguard Worker 
30*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
31*08b48e0bSAndroid Build Coastguard Worker #include "types.h"
32*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
33*08b48e0bSAndroid Build Coastguard Worker #include "alloc-inl.h"
34*08b48e0bSAndroid Build Coastguard Worker 
35*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
36*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
37*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
38*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
39*08b48e0bSAndroid Build Coastguard Worker #include <time.h>
40*08b48e0bSAndroid Build Coastguard Worker #include <ctype.h>
41*08b48e0bSAndroid Build Coastguard Worker #include <fcntl.h>
42*08b48e0bSAndroid Build Coastguard Worker #include <limits.h>
43*08b48e0bSAndroid Build Coastguard Worker 
44*08b48e0bSAndroid Build Coastguard Worker #include <sys/stat.h>
45*08b48e0bSAndroid Build Coastguard Worker #include <sys/types.h>
46*08b48e0bSAndroid Build Coastguard Worker #include <sys/wait.h>
47*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
48*08b48e0bSAndroid Build Coastguard Worker 
49*08b48e0bSAndroid Build Coastguard Worker #include <dirent.h>
50*08b48e0bSAndroid Build Coastguard Worker 
51*08b48e0bSAndroid Build Coastguard Worker #ifdef __APPLE__
52*08b48e0bSAndroid Build Coastguard Worker   #include <sys/syslimits.h>
53*08b48e0bSAndroid Build Coastguard Worker #endif
54*08b48e0bSAndroid Build Coastguard Worker 
55*08b48e0bSAndroid Build Coastguard Worker #define MAX_PARAM_COUNT 4096
56*08b48e0bSAndroid Build Coastguard Worker 
57*08b48e0bSAndroid Build Coastguard Worker static u8 **ld_params;              /* Parameters passed to the real 'ld'   */
58*08b48e0bSAndroid Build Coastguard Worker 
59*08b48e0bSAndroid Build Coastguard Worker static u8 *afl_path = AFL_PATH;
60*08b48e0bSAndroid Build Coastguard Worker static u8 *real_ld = AFL_REAL_LD;
61*08b48e0bSAndroid Build Coastguard Worker 
62*08b48e0bSAndroid Build Coastguard Worker static u8 be_quiet,                 /* Quiet mode (no stderr output)        */
63*08b48e0bSAndroid Build Coastguard Worker     debug,                          /* AFL_DEBUG                            */
64*08b48e0bSAndroid Build Coastguard Worker     passthrough,                    /* AFL_LD_PASSTHROUGH - no link+optimize*/
65*08b48e0bSAndroid Build Coastguard Worker     just_version;                   /* Just show version?                   */
66*08b48e0bSAndroid Build Coastguard Worker 
67*08b48e0bSAndroid Build Coastguard Worker static u32 ld_param_cnt = 1;        /* Number of params to 'ld'             */
68*08b48e0bSAndroid Build Coastguard Worker 
69*08b48e0bSAndroid Build Coastguard Worker /* Examine and modify parameters to pass to 'ld', 'llvm-link' and 'llmv-ar'.
70*08b48e0bSAndroid Build Coastguard Worker    Note that the file name is always the last parameter passed by GCC,
71*08b48e0bSAndroid Build Coastguard Worker    so we exploit this property to keep the code "simple". */
edit_params(int argc,char ** argv)72*08b48e0bSAndroid Build Coastguard Worker static void edit_params(int argc, char **argv) {
73*08b48e0bSAndroid Build Coastguard Worker 
74*08b48e0bSAndroid Build Coastguard Worker   u32 i, gold_pos = 0, gold_present = 0, rt_present = 0, rt_lto_present = 0,
75*08b48e0bSAndroid Build Coastguard Worker          inst_present = 0;
76*08b48e0bSAndroid Build Coastguard Worker   char *ptr;
77*08b48e0bSAndroid Build Coastguard Worker 
78*08b48e0bSAndroid Build Coastguard Worker   ld_params = ck_alloc(4096 * sizeof(u8 *));
79*08b48e0bSAndroid Build Coastguard Worker 
80*08b48e0bSAndroid Build Coastguard Worker   ld_params[0] = (u8 *)real_ld;
81*08b48e0bSAndroid Build Coastguard Worker 
82*08b48e0bSAndroid Build Coastguard Worker   if (!passthrough) {
83*08b48e0bSAndroid Build Coastguard Worker 
84*08b48e0bSAndroid Build Coastguard Worker     for (i = 1; i < (u32)argc; i++) {
85*08b48e0bSAndroid Build Coastguard Worker 
86*08b48e0bSAndroid Build Coastguard Worker       if (strstr(argv[i], "/afl-llvm-rt-lto.o") != NULL) rt_lto_present = 1;
87*08b48e0bSAndroid Build Coastguard Worker       if (strstr(argv[i], "/afl-compiler-rt.o") != NULL) rt_present = 1;
88*08b48e0bSAndroid Build Coastguard Worker       if (strstr(argv[i], "/afl-llvm-lto-instr") != NULL) inst_present = 1;
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker     }
91*08b48e0bSAndroid Build Coastguard Worker 
92*08b48e0bSAndroid Build Coastguard Worker     for (i = 1; i < (u32)argc && !gold_pos; i++) {
93*08b48e0bSAndroid Build Coastguard Worker 
94*08b48e0bSAndroid Build Coastguard Worker       if (strcmp(argv[i], "-plugin") == 0) {
95*08b48e0bSAndroid Build Coastguard Worker 
96*08b48e0bSAndroid Build Coastguard Worker         if (strncmp(argv[i], "-plugin=", strlen("-plugin=")) == 0) {
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker           if (strcasestr(argv[i], "LLVMgold.so") != NULL)
99*08b48e0bSAndroid Build Coastguard Worker             gold_present = gold_pos = i + 1;
100*08b48e0bSAndroid Build Coastguard Worker 
101*08b48e0bSAndroid Build Coastguard Worker         } else if (i < (u32)argc &&
102*08b48e0bSAndroid Build Coastguard Worker 
103*08b48e0bSAndroid Build Coastguard Worker                    strcasestr(argv[i + 1], "LLVMgold.so") != NULL) {
104*08b48e0bSAndroid Build Coastguard Worker 
105*08b48e0bSAndroid Build Coastguard Worker           gold_present = gold_pos = i + 2;
106*08b48e0bSAndroid Build Coastguard Worker 
107*08b48e0bSAndroid Build Coastguard Worker         }
108*08b48e0bSAndroid Build Coastguard Worker 
109*08b48e0bSAndroid Build Coastguard Worker       }
110*08b48e0bSAndroid Build Coastguard Worker 
111*08b48e0bSAndroid Build Coastguard Worker     }
112*08b48e0bSAndroid Build Coastguard Worker 
113*08b48e0bSAndroid Build Coastguard Worker     if (!gold_pos) {
114*08b48e0bSAndroid Build Coastguard Worker 
115*08b48e0bSAndroid Build Coastguard Worker       for (i = 1; i + 1 < (u32)argc && !gold_pos; i++) {
116*08b48e0bSAndroid Build Coastguard Worker 
117*08b48e0bSAndroid Build Coastguard Worker         if (argv[i][0] != '-') {
118*08b48e0bSAndroid Build Coastguard Worker 
119*08b48e0bSAndroid Build Coastguard Worker           if (argv[i - 1][0] == '-') {
120*08b48e0bSAndroid Build Coastguard Worker 
121*08b48e0bSAndroid Build Coastguard Worker             switch (argv[i - 1][1]) {
122*08b48e0bSAndroid Build Coastguard Worker 
123*08b48e0bSAndroid Build Coastguard Worker               case 'b':
124*08b48e0bSAndroid Build Coastguard Worker                 break;
125*08b48e0bSAndroid Build Coastguard Worker               case 'd':
126*08b48e0bSAndroid Build Coastguard Worker                 break;
127*08b48e0bSAndroid Build Coastguard Worker               case 'e':
128*08b48e0bSAndroid Build Coastguard Worker                 break;
129*08b48e0bSAndroid Build Coastguard Worker               case 'F':
130*08b48e0bSAndroid Build Coastguard Worker                 break;
131*08b48e0bSAndroid Build Coastguard Worker               case 'f':
132*08b48e0bSAndroid Build Coastguard Worker                 break;
133*08b48e0bSAndroid Build Coastguard Worker               case 'I':
134*08b48e0bSAndroid Build Coastguard Worker                 break;
135*08b48e0bSAndroid Build Coastguard Worker               case 'l':
136*08b48e0bSAndroid Build Coastguard Worker                 break;
137*08b48e0bSAndroid Build Coastguard Worker               case 'L':
138*08b48e0bSAndroid Build Coastguard Worker                 break;
139*08b48e0bSAndroid Build Coastguard Worker               case 'm':
140*08b48e0bSAndroid Build Coastguard Worker                 break;
141*08b48e0bSAndroid Build Coastguard Worker               case 'o':
142*08b48e0bSAndroid Build Coastguard Worker                 break;
143*08b48e0bSAndroid Build Coastguard Worker               case 'O':
144*08b48e0bSAndroid Build Coastguard Worker                 break;
145*08b48e0bSAndroid Build Coastguard Worker               case 'p':
146*08b48e0bSAndroid Build Coastguard Worker                 if (index(argv[i - 1], '=') == NULL) gold_pos = i;
147*08b48e0bSAndroid Build Coastguard Worker                 break;
148*08b48e0bSAndroid Build Coastguard Worker               case 'R':
149*08b48e0bSAndroid Build Coastguard Worker                 break;
150*08b48e0bSAndroid Build Coastguard Worker               case 'T':
151*08b48e0bSAndroid Build Coastguard Worker                 break;
152*08b48e0bSAndroid Build Coastguard Worker               case 'u':
153*08b48e0bSAndroid Build Coastguard Worker                 break;
154*08b48e0bSAndroid Build Coastguard Worker               case 'y':
155*08b48e0bSAndroid Build Coastguard Worker                 break;
156*08b48e0bSAndroid Build Coastguard Worker               case 'z':
157*08b48e0bSAndroid Build Coastguard Worker                 break;
158*08b48e0bSAndroid Build Coastguard Worker               case '-': {
159*08b48e0bSAndroid Build Coastguard Worker 
160*08b48e0bSAndroid Build Coastguard Worker                 if (strcmp(argv[i - 1], "--oformat") == 0) break;
161*08b48e0bSAndroid Build Coastguard Worker                 if (strcmp(argv[i - 1], "--output") == 0) break;
162*08b48e0bSAndroid Build Coastguard Worker                 if (strncmp(argv[i - 1], "--opt-remarks-", 14) == 0) break;
163*08b48e0bSAndroid Build Coastguard Worker                 gold_pos = i;
164*08b48e0bSAndroid Build Coastguard Worker                 break;
165*08b48e0bSAndroid Build Coastguard Worker 
166*08b48e0bSAndroid Build Coastguard Worker               }
167*08b48e0bSAndroid Build Coastguard Worker 
168*08b48e0bSAndroid Build Coastguard Worker               default:
169*08b48e0bSAndroid Build Coastguard Worker                 gold_pos = i;
170*08b48e0bSAndroid Build Coastguard Worker 
171*08b48e0bSAndroid Build Coastguard Worker             }
172*08b48e0bSAndroid Build Coastguard Worker 
173*08b48e0bSAndroid Build Coastguard Worker           } else
174*08b48e0bSAndroid Build Coastguard Worker 
175*08b48e0bSAndroid Build Coastguard Worker             gold_pos = i;
176*08b48e0bSAndroid Build Coastguard Worker 
177*08b48e0bSAndroid Build Coastguard Worker         }
178*08b48e0bSAndroid Build Coastguard Worker 
179*08b48e0bSAndroid Build Coastguard Worker       }
180*08b48e0bSAndroid Build Coastguard Worker 
181*08b48e0bSAndroid Build Coastguard Worker     }
182*08b48e0bSAndroid Build Coastguard Worker 
183*08b48e0bSAndroid Build Coastguard Worker     if (!gold_pos) gold_pos = 1;
184*08b48e0bSAndroid Build Coastguard Worker 
185*08b48e0bSAndroid Build Coastguard Worker   }
186*08b48e0bSAndroid Build Coastguard Worker 
187*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_LLVM_INSTRIM") ||
188*08b48e0bSAndroid Build Coastguard Worker       ((ptr = getenv("AFL_LLVM_INSTRUMENT")) &&
189*08b48e0bSAndroid Build Coastguard Worker        (strcasestr(ptr, "CFG") == 0 || strcasestr(ptr, "INSTRIM") == 0)))
190*08b48e0bSAndroid Build Coastguard Worker     FATAL(
191*08b48e0bSAndroid Build Coastguard Worker         "InsTrim was removed because it is not effective. Use a modern LLVM "
192*08b48e0bSAndroid Build Coastguard Worker         "and PCGUARD (which is the default in afl-cc).\n");
193*08b48e0bSAndroid Build Coastguard Worker 
194*08b48e0bSAndroid Build Coastguard Worker   if (debug)
195*08b48e0bSAndroid Build Coastguard Worker     DEBUGF(
196*08b48e0bSAndroid Build Coastguard Worker         "passthrough=%s, gold_pos=%u, gold_present=%s "
197*08b48e0bSAndroid Build Coastguard Worker         "inst_present=%s rt_present=%s rt_lto_present=%s\n",
198*08b48e0bSAndroid Build Coastguard Worker         passthrough ? "true" : "false", gold_pos,
199*08b48e0bSAndroid Build Coastguard Worker         gold_present ? "true" : "false", inst_present ? "true" : "false",
200*08b48e0bSAndroid Build Coastguard Worker         rt_present ? "true" : "false", rt_lto_present ? "true" : "false");
201*08b48e0bSAndroid Build Coastguard Worker 
202*08b48e0bSAndroid Build Coastguard Worker   for (i = 1; i < (u32)argc; i++) {
203*08b48e0bSAndroid Build Coastguard Worker 
204*08b48e0bSAndroid Build Coastguard Worker     if (ld_param_cnt >= MAX_PARAM_COUNT)
205*08b48e0bSAndroid Build Coastguard Worker       FATAL(
206*08b48e0bSAndroid Build Coastguard Worker           "Too many command line parameters because of unpacking .a archives, "
207*08b48e0bSAndroid Build Coastguard Worker           "this would need to be done by hand ... sorry! :-(");
208*08b48e0bSAndroid Build Coastguard Worker 
209*08b48e0bSAndroid Build Coastguard Worker     if (strcmp(argv[i], "--afl") == 0) {
210*08b48e0bSAndroid Build Coastguard Worker 
211*08b48e0bSAndroid Build Coastguard Worker       if (!be_quiet) OKF("AFL++ test command line flag detected, exiting.");
212*08b48e0bSAndroid Build Coastguard Worker       exit(0);
213*08b48e0bSAndroid Build Coastguard Worker 
214*08b48e0bSAndroid Build Coastguard Worker     }
215*08b48e0bSAndroid Build Coastguard Worker 
216*08b48e0bSAndroid Build Coastguard Worker     if (i == gold_pos && !passthrough) {
217*08b48e0bSAndroid Build Coastguard Worker 
218*08b48e0bSAndroid Build Coastguard Worker       ld_params[ld_param_cnt++] = alloc_printf("-L%s/../lib", LLVM_BINDIR);
219*08b48e0bSAndroid Build Coastguard Worker 
220*08b48e0bSAndroid Build Coastguard Worker       if (!gold_present) {
221*08b48e0bSAndroid Build Coastguard Worker 
222*08b48e0bSAndroid Build Coastguard Worker         ld_params[ld_param_cnt++] = "-plugin";
223*08b48e0bSAndroid Build Coastguard Worker         ld_params[ld_param_cnt++] =
224*08b48e0bSAndroid Build Coastguard Worker             alloc_printf("%s/../lib/LLVMgold.so", LLVM_BINDIR);
225*08b48e0bSAndroid Build Coastguard Worker 
226*08b48e0bSAndroid Build Coastguard Worker       }
227*08b48e0bSAndroid Build Coastguard Worker 
228*08b48e0bSAndroid Build Coastguard Worker       ld_params[ld_param_cnt++] = "--allow-multiple-definition";
229*08b48e0bSAndroid Build Coastguard Worker 
230*08b48e0bSAndroid Build Coastguard Worker       if (!inst_present) {
231*08b48e0bSAndroid Build Coastguard Worker 
232*08b48e0bSAndroid Build Coastguard Worker         ld_params[ld_param_cnt++] = alloc_printf(
233*08b48e0bSAndroid Build Coastguard Worker             "-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", afl_path);
234*08b48e0bSAndroid Build Coastguard Worker 
235*08b48e0bSAndroid Build Coastguard Worker       }
236*08b48e0bSAndroid Build Coastguard Worker 
237*08b48e0bSAndroid Build Coastguard Worker       if (!rt_present)
238*08b48e0bSAndroid Build Coastguard Worker         ld_params[ld_param_cnt++] =
239*08b48e0bSAndroid Build Coastguard Worker             alloc_printf("%s/afl-compiler-rt.o", afl_path);
240*08b48e0bSAndroid Build Coastguard Worker       if (!rt_lto_present)
241*08b48e0bSAndroid Build Coastguard Worker         ld_params[ld_param_cnt++] =
242*08b48e0bSAndroid Build Coastguard Worker             alloc_printf("%s/afl-llvm-rt-lto.o", afl_path);
243*08b48e0bSAndroid Build Coastguard Worker 
244*08b48e0bSAndroid Build Coastguard Worker     }
245*08b48e0bSAndroid Build Coastguard Worker 
246*08b48e0bSAndroid Build Coastguard Worker     ld_params[ld_param_cnt++] = argv[i];
247*08b48e0bSAndroid Build Coastguard Worker 
248*08b48e0bSAndroid Build Coastguard Worker   }
249*08b48e0bSAndroid Build Coastguard Worker 
250*08b48e0bSAndroid Build Coastguard Worker   ld_params[ld_param_cnt] = NULL;
251*08b48e0bSAndroid Build Coastguard Worker 
252*08b48e0bSAndroid Build Coastguard Worker }
253*08b48e0bSAndroid Build Coastguard Worker 
254*08b48e0bSAndroid Build Coastguard Worker /* Main entry point */
255*08b48e0bSAndroid Build Coastguard Worker 
main(int argc,char ** argv)256*08b48e0bSAndroid Build Coastguard Worker int main(int argc, char **argv) {
257*08b48e0bSAndroid Build Coastguard Worker 
258*08b48e0bSAndroid Build Coastguard Worker   s32  pid, i, status;
259*08b48e0bSAndroid Build Coastguard Worker   char thecwd[PATH_MAX];
260*08b48e0bSAndroid Build Coastguard Worker 
261*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_LD_CALLER") != NULL) {
262*08b48e0bSAndroid Build Coastguard Worker 
263*08b48e0bSAndroid Build Coastguard Worker     FATAL("ld loop detected! Set AFL_REAL_LD!\n");
264*08b48e0bSAndroid Build Coastguard Worker 
265*08b48e0bSAndroid Build Coastguard Worker   }
266*08b48e0bSAndroid Build Coastguard Worker 
267*08b48e0bSAndroid Build Coastguard Worker   if (isatty(2) && !getenv("AFL_QUIET") && !getenv("AFL_DEBUG")) {
268*08b48e0bSAndroid Build Coastguard Worker 
269*08b48e0bSAndroid Build Coastguard Worker     SAYF(cCYA "afl-ld-to" VERSION cRST
270*08b48e0bSAndroid Build Coastguard Worker               " by Marc \"vanHauser\" Heuse <[email protected]>\n");
271*08b48e0bSAndroid Build Coastguard Worker 
272*08b48e0bSAndroid Build Coastguard Worker   } else
273*08b48e0bSAndroid Build Coastguard Worker 
274*08b48e0bSAndroid Build Coastguard Worker     be_quiet = 1;
275*08b48e0bSAndroid Build Coastguard Worker 
276*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_DEBUG") != NULL) debug = 1;
277*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_PATH") != NULL) afl_path = getenv("AFL_PATH");
278*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_LD_PASSTHROUGH") != NULL) passthrough = 1;
279*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_REAL_LD") != NULL) real_ld = getenv("AFL_REAL_LD");
280*08b48e0bSAndroid Build Coastguard Worker 
281*08b48e0bSAndroid Build Coastguard Worker   if (!afl_path || !*afl_path) afl_path = AFL_PATH;
282*08b48e0bSAndroid Build Coastguard Worker 
283*08b48e0bSAndroid Build Coastguard Worker   setenv("AFL_LD_CALLER", "1", 1);
284*08b48e0bSAndroid Build Coastguard Worker 
285*08b48e0bSAndroid Build Coastguard Worker   if (debug) {
286*08b48e0bSAndroid Build Coastguard Worker 
287*08b48e0bSAndroid Build Coastguard Worker     if (getcwd(thecwd, sizeof(thecwd)) != 0) strcpy(thecwd, ".");
288*08b48e0bSAndroid Build Coastguard Worker 
289*08b48e0bSAndroid Build Coastguard Worker     DEBUGF("cd \"%s\";", thecwd);
290*08b48e0bSAndroid Build Coastguard Worker     for (i = 0; i < argc; i++)
291*08b48e0bSAndroid Build Coastguard Worker       SAYF(" \"%s\"", argv[i]);
292*08b48e0bSAndroid Build Coastguard Worker     SAYF("\n");
293*08b48e0bSAndroid Build Coastguard Worker 
294*08b48e0bSAndroid Build Coastguard Worker   }
295*08b48e0bSAndroid Build Coastguard Worker 
296*08b48e0bSAndroid Build Coastguard Worker   if (argc < 2) {
297*08b48e0bSAndroid Build Coastguard Worker 
298*08b48e0bSAndroid Build Coastguard Worker     SAYF(
299*08b48e0bSAndroid Build Coastguard Worker         "\n"
300*08b48e0bSAndroid Build Coastguard Worker         "This is a helper application for afl-clang-lto.\n"
301*08b48e0bSAndroid Build Coastguard Worker         "It is a wrapper around llvm's 'lld' in case afl-clang-lto cannot be "
302*08b48e0bSAndroid Build Coastguard Worker         "used.\n"
303*08b48e0bSAndroid Build Coastguard Worker         "Note that the target still has to be compiled with -flto=full!\n"
304*08b48e0bSAndroid Build Coastguard Worker         "You probably don't want to run this program directly but rather pass "
305*08b48e0bSAndroid Build Coastguard Worker         "it as LD\nparameter to e.g. configure scripts.\n\n"
306*08b48e0bSAndroid Build Coastguard Worker 
307*08b48e0bSAndroid Build Coastguard Worker         "Environment variables:\n"
308*08b48e0bSAndroid Build Coastguard Worker         "  AFL_LD_PASSTHROUGH   do not link+optimize == no instrumentation\n"
309*08b48e0bSAndroid Build Coastguard Worker         "  AFL_REAL_LD          point to the real llvm 11 lld if necessary\n"
310*08b48e0bSAndroid Build Coastguard Worker 
311*08b48e0bSAndroid Build Coastguard Worker         "\nafl-ld-to was compiled with the fixed real 'ld' of %s and the "
312*08b48e0bSAndroid Build Coastguard Worker         "binary path of %s\n\n",
313*08b48e0bSAndroid Build Coastguard Worker         real_ld, LLVM_BINDIR);
314*08b48e0bSAndroid Build Coastguard Worker 
315*08b48e0bSAndroid Build Coastguard Worker     exit(1);
316*08b48e0bSAndroid Build Coastguard Worker 
317*08b48e0bSAndroid Build Coastguard Worker   }
318*08b48e0bSAndroid Build Coastguard Worker 
319*08b48e0bSAndroid Build Coastguard Worker   edit_params(argc, argv);  // here most of the magic happens :-)
320*08b48e0bSAndroid Build Coastguard Worker 
321*08b48e0bSAndroid Build Coastguard Worker   if (debug) {
322*08b48e0bSAndroid Build Coastguard Worker 
323*08b48e0bSAndroid Build Coastguard Worker     DEBUGF("cd \"%s\";", thecwd);
324*08b48e0bSAndroid Build Coastguard Worker     for (i = 0; i < (s32)ld_param_cnt; i++)
325*08b48e0bSAndroid Build Coastguard Worker       SAYF(" \"%s\"", ld_params[i]);
326*08b48e0bSAndroid Build Coastguard Worker     SAYF("\n");
327*08b48e0bSAndroid Build Coastguard Worker 
328*08b48e0bSAndroid Build Coastguard Worker   }
329*08b48e0bSAndroid Build Coastguard Worker 
330*08b48e0bSAndroid Build Coastguard Worker   if (!(pid = fork())) {
331*08b48e0bSAndroid Build Coastguard Worker 
332*08b48e0bSAndroid Build Coastguard Worker     if (strlen(real_ld) > 1) execvp(real_ld, (char **)ld_params);
333*08b48e0bSAndroid Build Coastguard Worker     execvp("ld", (char **)ld_params);  // fallback
334*08b48e0bSAndroid Build Coastguard Worker     FATAL("Oops, failed to execute 'ld' - check your PATH");
335*08b48e0bSAndroid Build Coastguard Worker 
336*08b48e0bSAndroid Build Coastguard Worker   }
337*08b48e0bSAndroid Build Coastguard Worker 
338*08b48e0bSAndroid Build Coastguard Worker   if (pid < 0) PFATAL("fork() failed");
339*08b48e0bSAndroid Build Coastguard Worker 
340*08b48e0bSAndroid Build Coastguard Worker   if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed");
341*08b48e0bSAndroid Build Coastguard Worker   if (debug) DEBUGF("linker result: %d\n", status);
342*08b48e0bSAndroid Build Coastguard Worker 
343*08b48e0bSAndroid Build Coastguard Worker   if (!just_version) {
344*08b48e0bSAndroid Build Coastguard Worker 
345*08b48e0bSAndroid Build Coastguard Worker     if (status == 0) {
346*08b48e0bSAndroid Build Coastguard Worker 
347*08b48e0bSAndroid Build Coastguard Worker       if (!be_quiet) OKF("Linker was successful");
348*08b48e0bSAndroid Build Coastguard Worker 
349*08b48e0bSAndroid Build Coastguard Worker     } else {
350*08b48e0bSAndroid Build Coastguard Worker 
351*08b48e0bSAndroid Build Coastguard Worker       SAYF(cLRD "[-] " cRST
352*08b48e0bSAndroid Build Coastguard Worker                 "Linker failed, please investigate and send a bug report. Most "
353*08b48e0bSAndroid Build Coastguard Worker                 "likely an 'ld' option is incompatible with %s.\n",
354*08b48e0bSAndroid Build Coastguard Worker            AFL_CLANG_FLTO);
355*08b48e0bSAndroid Build Coastguard Worker 
356*08b48e0bSAndroid Build Coastguard Worker     }
357*08b48e0bSAndroid Build Coastguard Worker 
358*08b48e0bSAndroid Build Coastguard Worker   }
359*08b48e0bSAndroid Build Coastguard Worker 
360*08b48e0bSAndroid Build Coastguard Worker   exit(WEXITSTATUS(status));
361*08b48e0bSAndroid Build Coastguard Worker 
362*08b48e0bSAndroid Build Coastguard Worker }
363*08b48e0bSAndroid Build Coastguard Worker 
364