xref: /aosp_15_r20/external/llvm/lib/Fuzzer/FuzzerDriver.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- FuzzerDriver.cpp - FuzzerDriver function and flags -----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker // FuzzerDriver and flag parsing.
10*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
11*9880d681SAndroid Build Coastguard Worker 
12*9880d681SAndroid Build Coastguard Worker #include "FuzzerInterface.h"
13*9880d681SAndroid Build Coastguard Worker #include "FuzzerInternal.h"
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include <algorithm>
16*9880d681SAndroid Build Coastguard Worker #include <atomic>
17*9880d681SAndroid Build Coastguard Worker #include <chrono>
18*9880d681SAndroid Build Coastguard Worker #include <cstring>
19*9880d681SAndroid Build Coastguard Worker #include <mutex>
20*9880d681SAndroid Build Coastguard Worker #include <string>
21*9880d681SAndroid Build Coastguard Worker #include <thread>
22*9880d681SAndroid Build Coastguard Worker #include <unistd.h>
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker // This function should be present in the libFuzzer so that the client
25*9880d681SAndroid Build Coastguard Worker // binary can test for its existence.
__libfuzzer_is_present()26*9880d681SAndroid Build Coastguard Worker extern "C" __attribute__((used)) void __libfuzzer_is_present() {}
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker namespace fuzzer {
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker // Program arguments.
31*9880d681SAndroid Build Coastguard Worker struct FlagDescription {
32*9880d681SAndroid Build Coastguard Worker   const char *Name;
33*9880d681SAndroid Build Coastguard Worker   const char *Description;
34*9880d681SAndroid Build Coastguard Worker   int   Default;
35*9880d681SAndroid Build Coastguard Worker   int   *IntFlag;
36*9880d681SAndroid Build Coastguard Worker   const char **StrFlag;
37*9880d681SAndroid Build Coastguard Worker   unsigned int *UIntFlag;
38*9880d681SAndroid Build Coastguard Worker };
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker struct {
41*9880d681SAndroid Build Coastguard Worker #define FUZZER_DEPRECATED_FLAG(Name)
42*9880d681SAndroid Build Coastguard Worker #define FUZZER_FLAG_INT(Name, Default, Description) int Name;
43*9880d681SAndroid Build Coastguard Worker #define FUZZER_FLAG_UNSIGNED(Name, Default, Description) unsigned int Name;
44*9880d681SAndroid Build Coastguard Worker #define FUZZER_FLAG_STRING(Name, Description) const char *Name;
45*9880d681SAndroid Build Coastguard Worker #include "FuzzerFlags.def"
46*9880d681SAndroid Build Coastguard Worker #undef FUZZER_DEPRECATED_FLAG
47*9880d681SAndroid Build Coastguard Worker #undef FUZZER_FLAG_INT
48*9880d681SAndroid Build Coastguard Worker #undef FUZZER_FLAG_UNSIGNED
49*9880d681SAndroid Build Coastguard Worker #undef FUZZER_FLAG_STRING
50*9880d681SAndroid Build Coastguard Worker } Flags;
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker static const FlagDescription FlagDescriptions [] {
53*9880d681SAndroid Build Coastguard Worker #define FUZZER_DEPRECATED_FLAG(Name)                                           \
54*9880d681SAndroid Build Coastguard Worker   {#Name, "Deprecated; don't use", 0, nullptr, nullptr, nullptr},
55*9880d681SAndroid Build Coastguard Worker #define FUZZER_FLAG_INT(Name, Default, Description)                            \
56*9880d681SAndroid Build Coastguard Worker   {#Name, Description, Default, &Flags.Name, nullptr, nullptr},
57*9880d681SAndroid Build Coastguard Worker #define FUZZER_FLAG_UNSIGNED(Name, Default, Description)                       \
58*9880d681SAndroid Build Coastguard Worker   {#Name,   Description, static_cast<int>(Default),                            \
59*9880d681SAndroid Build Coastguard Worker    nullptr, nullptr, &Flags.Name},
60*9880d681SAndroid Build Coastguard Worker #define FUZZER_FLAG_STRING(Name, Description)                                  \
61*9880d681SAndroid Build Coastguard Worker   {#Name, Description, 0, nullptr, &Flags.Name, nullptr},
62*9880d681SAndroid Build Coastguard Worker #include "FuzzerFlags.def"
63*9880d681SAndroid Build Coastguard Worker #undef FUZZER_DEPRECATED_FLAG
64*9880d681SAndroid Build Coastguard Worker #undef FUZZER_FLAG_INT
65*9880d681SAndroid Build Coastguard Worker #undef FUZZER_FLAG_UNSIGNED
66*9880d681SAndroid Build Coastguard Worker #undef FUZZER_FLAG_STRING
67*9880d681SAndroid Build Coastguard Worker };
68*9880d681SAndroid Build Coastguard Worker 
69*9880d681SAndroid Build Coastguard Worker static const size_t kNumFlags =
70*9880d681SAndroid Build Coastguard Worker     sizeof(FlagDescriptions) / sizeof(FlagDescriptions[0]);
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker static std::vector<std::string> *Inputs;
73*9880d681SAndroid Build Coastguard Worker static std::string *ProgName;
74*9880d681SAndroid Build Coastguard Worker 
PrintHelp()75*9880d681SAndroid Build Coastguard Worker static void PrintHelp() {
76*9880d681SAndroid Build Coastguard Worker   Printf("Usage:\n");
77*9880d681SAndroid Build Coastguard Worker   auto Prog = ProgName->c_str();
78*9880d681SAndroid Build Coastguard Worker   Printf("\nTo run fuzzing pass 0 or more directories.\n");
79*9880d681SAndroid Build Coastguard Worker   Printf("%s [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\n", Prog);
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker   Printf("\nTo run individual tests without fuzzing pass 1 or more files:\n");
82*9880d681SAndroid Build Coastguard Worker   Printf("%s [-flag1=val1 [-flag2=val2 ...] ] file1 [file2 ...]\n", Prog);
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   Printf("\nFlags: (strictly in form -flag=value)\n");
85*9880d681SAndroid Build Coastguard Worker   size_t MaxFlagLen = 0;
86*9880d681SAndroid Build Coastguard Worker   for (size_t F = 0; F < kNumFlags; F++)
87*9880d681SAndroid Build Coastguard Worker     MaxFlagLen = std::max(strlen(FlagDescriptions[F].Name), MaxFlagLen);
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   for (size_t F = 0; F < kNumFlags; F++) {
90*9880d681SAndroid Build Coastguard Worker     const auto &D = FlagDescriptions[F];
91*9880d681SAndroid Build Coastguard Worker     Printf(" %s", D.Name);
92*9880d681SAndroid Build Coastguard Worker     for (size_t i = 0, n = MaxFlagLen - strlen(D.Name); i < n; i++)
93*9880d681SAndroid Build Coastguard Worker       Printf(" ");
94*9880d681SAndroid Build Coastguard Worker     Printf("\t");
95*9880d681SAndroid Build Coastguard Worker     Printf("%d\t%s\n", D.Default, D.Description);
96*9880d681SAndroid Build Coastguard Worker   }
97*9880d681SAndroid Build Coastguard Worker   Printf("\nFlags starting with '--' will be ignored and "
98*9880d681SAndroid Build Coastguard Worker             "will be passed verbatim to subprocesses.\n");
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker 
FlagValue(const char * Param,const char * Name)101*9880d681SAndroid Build Coastguard Worker static const char *FlagValue(const char *Param, const char *Name) {
102*9880d681SAndroid Build Coastguard Worker   size_t Len = strlen(Name);
103*9880d681SAndroid Build Coastguard Worker   if (Param[0] == '-' && strstr(Param + 1, Name) == Param + 1 &&
104*9880d681SAndroid Build Coastguard Worker       Param[Len + 1] == '=')
105*9880d681SAndroid Build Coastguard Worker       return &Param[Len + 2];
106*9880d681SAndroid Build Coastguard Worker   return nullptr;
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker 
109*9880d681SAndroid Build Coastguard Worker // Avoid calling stol as it triggers a bug in clang/glibc build.
MyStol(const char * Str)110*9880d681SAndroid Build Coastguard Worker static long MyStol(const char *Str) {
111*9880d681SAndroid Build Coastguard Worker   long Res = 0;
112*9880d681SAndroid Build Coastguard Worker   long Sign = 1;
113*9880d681SAndroid Build Coastguard Worker   if (*Str == '-') {
114*9880d681SAndroid Build Coastguard Worker     Str++;
115*9880d681SAndroid Build Coastguard Worker     Sign = -1;
116*9880d681SAndroid Build Coastguard Worker   }
117*9880d681SAndroid Build Coastguard Worker   for (size_t i = 0; Str[i]; i++) {
118*9880d681SAndroid Build Coastguard Worker     char Ch = Str[i];
119*9880d681SAndroid Build Coastguard Worker     if (Ch < '0' || Ch > '9')
120*9880d681SAndroid Build Coastguard Worker       return Res;
121*9880d681SAndroid Build Coastguard Worker     Res = Res * 10 + (Ch - '0');
122*9880d681SAndroid Build Coastguard Worker   }
123*9880d681SAndroid Build Coastguard Worker   return Res * Sign;
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker 
ParseOneFlag(const char * Param)126*9880d681SAndroid Build Coastguard Worker static bool ParseOneFlag(const char *Param) {
127*9880d681SAndroid Build Coastguard Worker   if (Param[0] != '-') return false;
128*9880d681SAndroid Build Coastguard Worker   if (Param[1] == '-') {
129*9880d681SAndroid Build Coastguard Worker     static bool PrintedWarning = false;
130*9880d681SAndroid Build Coastguard Worker     if (!PrintedWarning) {
131*9880d681SAndroid Build Coastguard Worker       PrintedWarning = true;
132*9880d681SAndroid Build Coastguard Worker       Printf("INFO: libFuzzer ignores flags that start with '--'\n");
133*9880d681SAndroid Build Coastguard Worker     }
134*9880d681SAndroid Build Coastguard Worker     for (size_t F = 0; F < kNumFlags; F++)
135*9880d681SAndroid Build Coastguard Worker       if (FlagValue(Param + 1, FlagDescriptions[F].Name))
136*9880d681SAndroid Build Coastguard Worker         Printf("WARNING: did you mean '%s' (single dash)?\n", Param + 1);
137*9880d681SAndroid Build Coastguard Worker     return true;
138*9880d681SAndroid Build Coastguard Worker   }
139*9880d681SAndroid Build Coastguard Worker   for (size_t F = 0; F < kNumFlags; F++) {
140*9880d681SAndroid Build Coastguard Worker     const char *Name = FlagDescriptions[F].Name;
141*9880d681SAndroid Build Coastguard Worker     const char *Str = FlagValue(Param, Name);
142*9880d681SAndroid Build Coastguard Worker     if (Str)  {
143*9880d681SAndroid Build Coastguard Worker       if (FlagDescriptions[F].IntFlag) {
144*9880d681SAndroid Build Coastguard Worker         int Val = MyStol(Str);
145*9880d681SAndroid Build Coastguard Worker         *FlagDescriptions[F].IntFlag = Val;
146*9880d681SAndroid Build Coastguard Worker         if (Flags.verbosity >= 2)
147*9880d681SAndroid Build Coastguard Worker           Printf("Flag: %s %d\n", Name, Val);;
148*9880d681SAndroid Build Coastguard Worker         return true;
149*9880d681SAndroid Build Coastguard Worker       } else if (FlagDescriptions[F].UIntFlag) {
150*9880d681SAndroid Build Coastguard Worker         unsigned int Val = std::stoul(Str);
151*9880d681SAndroid Build Coastguard Worker         *FlagDescriptions[F].UIntFlag = Val;
152*9880d681SAndroid Build Coastguard Worker         if (Flags.verbosity >= 2)
153*9880d681SAndroid Build Coastguard Worker           Printf("Flag: %s %u\n", Name, Val);
154*9880d681SAndroid Build Coastguard Worker         return true;
155*9880d681SAndroid Build Coastguard Worker       } else if (FlagDescriptions[F].StrFlag) {
156*9880d681SAndroid Build Coastguard Worker         *FlagDescriptions[F].StrFlag = Str;
157*9880d681SAndroid Build Coastguard Worker         if (Flags.verbosity >= 2)
158*9880d681SAndroid Build Coastguard Worker           Printf("Flag: %s %s\n", Name, Str);
159*9880d681SAndroid Build Coastguard Worker         return true;
160*9880d681SAndroid Build Coastguard Worker       } else {  // Deprecated flag.
161*9880d681SAndroid Build Coastguard Worker         Printf("Flag: %s: deprecated, don't use\n", Name);
162*9880d681SAndroid Build Coastguard Worker         return true;
163*9880d681SAndroid Build Coastguard Worker       }
164*9880d681SAndroid Build Coastguard Worker     }
165*9880d681SAndroid Build Coastguard Worker   }
166*9880d681SAndroid Build Coastguard Worker   Printf("\n\nWARNING: unrecognized flag '%s'; "
167*9880d681SAndroid Build Coastguard Worker          "use -help=1 to list all flags\n\n", Param);
168*9880d681SAndroid Build Coastguard Worker   return true;
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker 
171*9880d681SAndroid Build Coastguard Worker // We don't use any library to minimize dependencies.
ParseFlags(const std::vector<std::string> & Args)172*9880d681SAndroid Build Coastguard Worker static void ParseFlags(const std::vector<std::string> &Args) {
173*9880d681SAndroid Build Coastguard Worker   for (size_t F = 0; F < kNumFlags; F++) {
174*9880d681SAndroid Build Coastguard Worker     if (FlagDescriptions[F].IntFlag)
175*9880d681SAndroid Build Coastguard Worker       *FlagDescriptions[F].IntFlag = FlagDescriptions[F].Default;
176*9880d681SAndroid Build Coastguard Worker     if (FlagDescriptions[F].UIntFlag)
177*9880d681SAndroid Build Coastguard Worker       *FlagDescriptions[F].UIntFlag =
178*9880d681SAndroid Build Coastguard Worker           static_cast<unsigned int>(FlagDescriptions[F].Default);
179*9880d681SAndroid Build Coastguard Worker     if (FlagDescriptions[F].StrFlag)
180*9880d681SAndroid Build Coastguard Worker       *FlagDescriptions[F].StrFlag = nullptr;
181*9880d681SAndroid Build Coastguard Worker   }
182*9880d681SAndroid Build Coastguard Worker   Inputs = new std::vector<std::string>;
183*9880d681SAndroid Build Coastguard Worker   for (size_t A = 1; A < Args.size(); A++) {
184*9880d681SAndroid Build Coastguard Worker     if (ParseOneFlag(Args[A].c_str())) continue;
185*9880d681SAndroid Build Coastguard Worker     Inputs->push_back(Args[A]);
186*9880d681SAndroid Build Coastguard Worker   }
187*9880d681SAndroid Build Coastguard Worker }
188*9880d681SAndroid Build Coastguard Worker 
189*9880d681SAndroid Build Coastguard Worker static std::mutex Mu;
190*9880d681SAndroid Build Coastguard Worker 
PulseThread()191*9880d681SAndroid Build Coastguard Worker static void PulseThread() {
192*9880d681SAndroid Build Coastguard Worker   while (true) {
193*9880d681SAndroid Build Coastguard Worker     SleepSeconds(600);
194*9880d681SAndroid Build Coastguard Worker     std::lock_guard<std::mutex> Lock(Mu);
195*9880d681SAndroid Build Coastguard Worker     Printf("pulse...\n");
196*9880d681SAndroid Build Coastguard Worker   }
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker 
WorkerThread(const std::string & Cmd,std::atomic<int> * Counter,int NumJobs,std::atomic<bool> * HasErrors)199*9880d681SAndroid Build Coastguard Worker static void WorkerThread(const std::string &Cmd, std::atomic<int> *Counter,
200*9880d681SAndroid Build Coastguard Worker                         int NumJobs, std::atomic<bool> *HasErrors) {
201*9880d681SAndroid Build Coastguard Worker   while (true) {
202*9880d681SAndroid Build Coastguard Worker     int C = (*Counter)++;
203*9880d681SAndroid Build Coastguard Worker     if (C >= NumJobs) break;
204*9880d681SAndroid Build Coastguard Worker     std::string Log = "fuzz-" + std::to_string(C) + ".log";
205*9880d681SAndroid Build Coastguard Worker     std::string ToRun = Cmd + " > " + Log + " 2>&1\n";
206*9880d681SAndroid Build Coastguard Worker     if (Flags.verbosity)
207*9880d681SAndroid Build Coastguard Worker       Printf("%s", ToRun.c_str());
208*9880d681SAndroid Build Coastguard Worker     int ExitCode = ExecuteCommand(ToRun);
209*9880d681SAndroid Build Coastguard Worker     if (ExitCode != 0)
210*9880d681SAndroid Build Coastguard Worker       *HasErrors = true;
211*9880d681SAndroid Build Coastguard Worker     std::lock_guard<std::mutex> Lock(Mu);
212*9880d681SAndroid Build Coastguard Worker     Printf("================== Job %d exited with exit code %d ============\n",
213*9880d681SAndroid Build Coastguard Worker            C, ExitCode);
214*9880d681SAndroid Build Coastguard Worker     fuzzer::CopyFileToErr(Log);
215*9880d681SAndroid Build Coastguard Worker   }
216*9880d681SAndroid Build Coastguard Worker }
217*9880d681SAndroid Build Coastguard Worker 
RunInMultipleProcesses(const std::vector<std::string> & Args,int NumWorkers,int NumJobs)218*9880d681SAndroid Build Coastguard Worker static int RunInMultipleProcesses(const std::vector<std::string> &Args,
219*9880d681SAndroid Build Coastguard Worker                                   int NumWorkers, int NumJobs) {
220*9880d681SAndroid Build Coastguard Worker   std::atomic<int> Counter(0);
221*9880d681SAndroid Build Coastguard Worker   std::atomic<bool> HasErrors(false);
222*9880d681SAndroid Build Coastguard Worker   std::string Cmd;
223*9880d681SAndroid Build Coastguard Worker   for (auto &S : Args) {
224*9880d681SAndroid Build Coastguard Worker     if (FlagValue(S.c_str(), "jobs") || FlagValue(S.c_str(), "workers"))
225*9880d681SAndroid Build Coastguard Worker       continue;
226*9880d681SAndroid Build Coastguard Worker     Cmd += S + " ";
227*9880d681SAndroid Build Coastguard Worker   }
228*9880d681SAndroid Build Coastguard Worker   std::vector<std::thread> V;
229*9880d681SAndroid Build Coastguard Worker   std::thread Pulse(PulseThread);
230*9880d681SAndroid Build Coastguard Worker   Pulse.detach();
231*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < NumWorkers; i++)
232*9880d681SAndroid Build Coastguard Worker     V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs, &HasErrors));
233*9880d681SAndroid Build Coastguard Worker   for (auto &T : V)
234*9880d681SAndroid Build Coastguard Worker     T.join();
235*9880d681SAndroid Build Coastguard Worker   return HasErrors ? 1 : 0;
236*9880d681SAndroid Build Coastguard Worker }
237*9880d681SAndroid Build Coastguard Worker 
RssThread(Fuzzer * F,size_t RssLimitMb)238*9880d681SAndroid Build Coastguard Worker static void RssThread(Fuzzer *F, size_t RssLimitMb) {
239*9880d681SAndroid Build Coastguard Worker   while (true) {
240*9880d681SAndroid Build Coastguard Worker     SleepSeconds(1);
241*9880d681SAndroid Build Coastguard Worker     size_t Peak = GetPeakRSSMb();
242*9880d681SAndroid Build Coastguard Worker     if (Peak > RssLimitMb)
243*9880d681SAndroid Build Coastguard Worker       F->RssLimitCallback();
244*9880d681SAndroid Build Coastguard Worker   }
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker 
StartRssThread(Fuzzer * F,size_t RssLimitMb)247*9880d681SAndroid Build Coastguard Worker static void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
248*9880d681SAndroid Build Coastguard Worker   if (!RssLimitMb) return;
249*9880d681SAndroid Build Coastguard Worker   std::thread T(RssThread, F, RssLimitMb);
250*9880d681SAndroid Build Coastguard Worker   T.detach();
251*9880d681SAndroid Build Coastguard Worker }
252*9880d681SAndroid Build Coastguard Worker 
RunOneTest(Fuzzer * F,const char * InputFilePath)253*9880d681SAndroid Build Coastguard Worker int RunOneTest(Fuzzer *F, const char *InputFilePath) {
254*9880d681SAndroid Build Coastguard Worker   Unit U = FileToVector(InputFilePath);
255*9880d681SAndroid Build Coastguard Worker   Unit PreciseSizedU(U);
256*9880d681SAndroid Build Coastguard Worker   assert(PreciseSizedU.size() == PreciseSizedU.capacity());
257*9880d681SAndroid Build Coastguard Worker   F->RunOne(PreciseSizedU.data(), PreciseSizedU.size());
258*9880d681SAndroid Build Coastguard Worker   return 0;
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker 
AllInputsAreFiles()261*9880d681SAndroid Build Coastguard Worker static bool AllInputsAreFiles() {
262*9880d681SAndroid Build Coastguard Worker   if (Inputs->empty()) return false;
263*9880d681SAndroid Build Coastguard Worker   for (auto &Path : *Inputs)
264*9880d681SAndroid Build Coastguard Worker     if (!IsFile(Path))
265*9880d681SAndroid Build Coastguard Worker       return false;
266*9880d681SAndroid Build Coastguard Worker   return true;
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker 
FuzzerDriver(int * argc,char *** argv,UserCallback Callback)269*9880d681SAndroid Build Coastguard Worker int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
270*9880d681SAndroid Build Coastguard Worker   using namespace fuzzer;
271*9880d681SAndroid Build Coastguard Worker   assert(argc && argv && "Argument pointers cannot be nullptr");
272*9880d681SAndroid Build Coastguard Worker   EF = new ExternalFunctions();
273*9880d681SAndroid Build Coastguard Worker   if (EF->LLVMFuzzerInitialize)
274*9880d681SAndroid Build Coastguard Worker     EF->LLVMFuzzerInitialize(argc, argv);
275*9880d681SAndroid Build Coastguard Worker   const std::vector<std::string> Args(*argv, *argv + *argc);
276*9880d681SAndroid Build Coastguard Worker   assert(!Args.empty());
277*9880d681SAndroid Build Coastguard Worker   ProgName = new std::string(Args[0]);
278*9880d681SAndroid Build Coastguard Worker   ParseFlags(Args);
279*9880d681SAndroid Build Coastguard Worker   if (Flags.help) {
280*9880d681SAndroid Build Coastguard Worker     PrintHelp();
281*9880d681SAndroid Build Coastguard Worker     return 0;
282*9880d681SAndroid Build Coastguard Worker   }
283*9880d681SAndroid Build Coastguard Worker 
284*9880d681SAndroid Build Coastguard Worker   if (Flags.close_fd_mask & 2)
285*9880d681SAndroid Build Coastguard Worker     DupAndCloseStderr();
286*9880d681SAndroid Build Coastguard Worker   if (Flags.close_fd_mask & 1)
287*9880d681SAndroid Build Coastguard Worker     CloseStdout();
288*9880d681SAndroid Build Coastguard Worker 
289*9880d681SAndroid Build Coastguard Worker   if (Flags.jobs > 0 && Flags.workers == 0) {
290*9880d681SAndroid Build Coastguard Worker     Flags.workers = std::min(NumberOfCpuCores() / 2, Flags.jobs);
291*9880d681SAndroid Build Coastguard Worker     if (Flags.workers > 1)
292*9880d681SAndroid Build Coastguard Worker       Printf("Running %d workers\n", Flags.workers);
293*9880d681SAndroid Build Coastguard Worker   }
294*9880d681SAndroid Build Coastguard Worker 
295*9880d681SAndroid Build Coastguard Worker   if (Flags.workers > 0 && Flags.jobs > 0)
296*9880d681SAndroid Build Coastguard Worker     return RunInMultipleProcesses(Args, Flags.workers, Flags.jobs);
297*9880d681SAndroid Build Coastguard Worker 
298*9880d681SAndroid Build Coastguard Worker   const size_t kMaxSaneLen = 1 << 20;
299*9880d681SAndroid Build Coastguard Worker   const size_t kMinDefaultLen = 64;
300*9880d681SAndroid Build Coastguard Worker   FuzzingOptions Options;
301*9880d681SAndroid Build Coastguard Worker   Options.Verbosity = Flags.verbosity;
302*9880d681SAndroid Build Coastguard Worker   Options.MaxLen = Flags.max_len;
303*9880d681SAndroid Build Coastguard Worker   Options.UnitTimeoutSec = Flags.timeout;
304*9880d681SAndroid Build Coastguard Worker   Options.TimeoutExitCode = Flags.timeout_exitcode;
305*9880d681SAndroid Build Coastguard Worker   Options.MaxTotalTimeSec = Flags.max_total_time;
306*9880d681SAndroid Build Coastguard Worker   Options.DoCrossOver = Flags.cross_over;
307*9880d681SAndroid Build Coastguard Worker   Options.MutateDepth = Flags.mutate_depth;
308*9880d681SAndroid Build Coastguard Worker   Options.UseCounters = Flags.use_counters;
309*9880d681SAndroid Build Coastguard Worker   Options.UseIndirCalls = Flags.use_indir_calls;
310*9880d681SAndroid Build Coastguard Worker   Options.UseTraces = Flags.use_traces;
311*9880d681SAndroid Build Coastguard Worker   Options.UseMemcmp = Flags.use_memcmp;
312*9880d681SAndroid Build Coastguard Worker   Options.ShuffleAtStartUp = Flags.shuffle;
313*9880d681SAndroid Build Coastguard Worker   Options.PreferSmall = Flags.prefer_small;
314*9880d681SAndroid Build Coastguard Worker   Options.Reload = Flags.reload;
315*9880d681SAndroid Build Coastguard Worker   Options.OnlyASCII = Flags.only_ascii;
316*9880d681SAndroid Build Coastguard Worker   Options.OutputCSV = Flags.output_csv;
317*9880d681SAndroid Build Coastguard Worker   Options.DetectLeaks = Flags.detect_leaks;
318*9880d681SAndroid Build Coastguard Worker   Options.RssLimitMb = Flags.rss_limit_mb;
319*9880d681SAndroid Build Coastguard Worker   if (Flags.runs >= 0)
320*9880d681SAndroid Build Coastguard Worker     Options.MaxNumberOfRuns = Flags.runs;
321*9880d681SAndroid Build Coastguard Worker   if (!Inputs->empty())
322*9880d681SAndroid Build Coastguard Worker     Options.OutputCorpus = (*Inputs)[0];
323*9880d681SAndroid Build Coastguard Worker   Options.ReportSlowUnits = Flags.report_slow_units;
324*9880d681SAndroid Build Coastguard Worker   if (Flags.artifact_prefix)
325*9880d681SAndroid Build Coastguard Worker     Options.ArtifactPrefix = Flags.artifact_prefix;
326*9880d681SAndroid Build Coastguard Worker   if (Flags.exact_artifact_path)
327*9880d681SAndroid Build Coastguard Worker     Options.ExactArtifactPath = Flags.exact_artifact_path;
328*9880d681SAndroid Build Coastguard Worker   std::vector<Unit> Dictionary;
329*9880d681SAndroid Build Coastguard Worker   if (Flags.dict)
330*9880d681SAndroid Build Coastguard Worker     if (!ParseDictionaryFile(FileToString(Flags.dict), &Dictionary))
331*9880d681SAndroid Build Coastguard Worker       return 1;
332*9880d681SAndroid Build Coastguard Worker   if (Flags.verbosity > 0 && !Dictionary.empty())
333*9880d681SAndroid Build Coastguard Worker     Printf("Dictionary: %zd entries\n", Dictionary.size());
334*9880d681SAndroid Build Coastguard Worker   bool DoPlainRun = AllInputsAreFiles();
335*9880d681SAndroid Build Coastguard Worker   Options.SaveArtifacts = !DoPlainRun;
336*9880d681SAndroid Build Coastguard Worker   Options.PrintNewCovPcs = Flags.print_new_cov_pcs;
337*9880d681SAndroid Build Coastguard Worker   Options.PrintFinalStats = Flags.print_final_stats;
338*9880d681SAndroid Build Coastguard Worker   Options.TruncateUnits = Flags.truncate_units;
339*9880d681SAndroid Build Coastguard Worker   Options.PruneCorpus = Flags.prune_corpus;
340*9880d681SAndroid Build Coastguard Worker 
341*9880d681SAndroid Build Coastguard Worker   unsigned Seed = Flags.seed;
342*9880d681SAndroid Build Coastguard Worker   // Initialize Seed.
343*9880d681SAndroid Build Coastguard Worker   if (Seed == 0)
344*9880d681SAndroid Build Coastguard Worker     Seed = (std::chrono::system_clock::now().time_since_epoch().count() << 10) +
345*9880d681SAndroid Build Coastguard Worker            getpid();
346*9880d681SAndroid Build Coastguard Worker   if (Flags.verbosity)
347*9880d681SAndroid Build Coastguard Worker     Printf("INFO: Seed: %u\n", Seed);
348*9880d681SAndroid Build Coastguard Worker 
349*9880d681SAndroid Build Coastguard Worker   Random Rand(Seed);
350*9880d681SAndroid Build Coastguard Worker   MutationDispatcher MD(Rand, Options);
351*9880d681SAndroid Build Coastguard Worker   Fuzzer F(Callback, MD, Options);
352*9880d681SAndroid Build Coastguard Worker 
353*9880d681SAndroid Build Coastguard Worker   for (auto &U: Dictionary)
354*9880d681SAndroid Build Coastguard Worker     if (U.size() <= Word::GetMaxSize())
355*9880d681SAndroid Build Coastguard Worker       MD.AddWordToManualDictionary(Word(U.data(), U.size()));
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker   StartRssThread(&F, Flags.rss_limit_mb);
358*9880d681SAndroid Build Coastguard Worker 
359*9880d681SAndroid Build Coastguard Worker   // Timer
360*9880d681SAndroid Build Coastguard Worker   if (Flags.timeout > 0)
361*9880d681SAndroid Build Coastguard Worker     SetTimer(Flags.timeout / 2 + 1);
362*9880d681SAndroid Build Coastguard Worker   if (Flags.handle_segv) SetSigSegvHandler();
363*9880d681SAndroid Build Coastguard Worker   if (Flags.handle_bus) SetSigBusHandler();
364*9880d681SAndroid Build Coastguard Worker   if (Flags.handle_abrt) SetSigAbrtHandler();
365*9880d681SAndroid Build Coastguard Worker   if (Flags.handle_ill) SetSigIllHandler();
366*9880d681SAndroid Build Coastguard Worker   if (Flags.handle_fpe) SetSigFpeHandler();
367*9880d681SAndroid Build Coastguard Worker   if (Flags.handle_int) SetSigIntHandler();
368*9880d681SAndroid Build Coastguard Worker   if (Flags.handle_term) SetSigTermHandler();
369*9880d681SAndroid Build Coastguard Worker 
370*9880d681SAndroid Build Coastguard Worker   if (DoPlainRun) {
371*9880d681SAndroid Build Coastguard Worker     Options.SaveArtifacts = false;
372*9880d681SAndroid Build Coastguard Worker     int Runs = std::max(1, Flags.runs);
373*9880d681SAndroid Build Coastguard Worker     Printf("%s: Running %zd inputs %d time(s) each.\n", ProgName->c_str(),
374*9880d681SAndroid Build Coastguard Worker            Inputs->size(), Runs);
375*9880d681SAndroid Build Coastguard Worker     for (auto &Path : *Inputs) {
376*9880d681SAndroid Build Coastguard Worker       auto StartTime = system_clock::now();
377*9880d681SAndroid Build Coastguard Worker       Printf("Running: %s\n", Path.c_str());
378*9880d681SAndroid Build Coastguard Worker       for (int Iter = 0; Iter < Runs; Iter++)
379*9880d681SAndroid Build Coastguard Worker         RunOneTest(&F, Path.c_str());
380*9880d681SAndroid Build Coastguard Worker       auto StopTime = system_clock::now();
381*9880d681SAndroid Build Coastguard Worker       auto MS = duration_cast<milliseconds>(StopTime - StartTime).count();
382*9880d681SAndroid Build Coastguard Worker       Printf("Executed %s in %zd ms\n", Path.c_str(), (long)MS);
383*9880d681SAndroid Build Coastguard Worker     }
384*9880d681SAndroid Build Coastguard Worker     F.PrintFinalStats();
385*9880d681SAndroid Build Coastguard Worker     exit(0);
386*9880d681SAndroid Build Coastguard Worker   }
387*9880d681SAndroid Build Coastguard Worker 
388*9880d681SAndroid Build Coastguard Worker 
389*9880d681SAndroid Build Coastguard Worker   if (Flags.merge) {
390*9880d681SAndroid Build Coastguard Worker     if (Options.MaxLen == 0)
391*9880d681SAndroid Build Coastguard Worker       F.SetMaxLen(kMaxSaneLen);
392*9880d681SAndroid Build Coastguard Worker     F.Merge(*Inputs);
393*9880d681SAndroid Build Coastguard Worker     exit(0);
394*9880d681SAndroid Build Coastguard Worker   }
395*9880d681SAndroid Build Coastguard Worker 
396*9880d681SAndroid Build Coastguard Worker   size_t TemporaryMaxLen = Options.MaxLen ? Options.MaxLen : kMaxSaneLen;
397*9880d681SAndroid Build Coastguard Worker 
398*9880d681SAndroid Build Coastguard Worker   F.RereadOutputCorpus(TemporaryMaxLen);
399*9880d681SAndroid Build Coastguard Worker   for (auto &inp : *Inputs)
400*9880d681SAndroid Build Coastguard Worker     if (inp != Options.OutputCorpus)
401*9880d681SAndroid Build Coastguard Worker       F.ReadDir(inp, nullptr, TemporaryMaxLen);
402*9880d681SAndroid Build Coastguard Worker 
403*9880d681SAndroid Build Coastguard Worker   if (Options.MaxLen == 0)
404*9880d681SAndroid Build Coastguard Worker     F.SetMaxLen(
405*9880d681SAndroid Build Coastguard Worker         std::min(std::max(kMinDefaultLen, F.MaxUnitSizeInCorpus()), kMaxSaneLen));
406*9880d681SAndroid Build Coastguard Worker 
407*9880d681SAndroid Build Coastguard Worker   if (F.CorpusSize() == 0) {
408*9880d681SAndroid Build Coastguard Worker     F.AddToCorpus(Unit());  // Can't fuzz empty corpus, so add an empty input.
409*9880d681SAndroid Build Coastguard Worker     if (Options.Verbosity)
410*9880d681SAndroid Build Coastguard Worker       Printf("INFO: A corpus is not provided, starting from an empty corpus\n");
411*9880d681SAndroid Build Coastguard Worker   }
412*9880d681SAndroid Build Coastguard Worker   F.ShuffleAndMinimize();
413*9880d681SAndroid Build Coastguard Worker   if (Flags.drill)
414*9880d681SAndroid Build Coastguard Worker     F.Drill();
415*9880d681SAndroid Build Coastguard Worker   else
416*9880d681SAndroid Build Coastguard Worker     F.Loop();
417*9880d681SAndroid Build Coastguard Worker 
418*9880d681SAndroid Build Coastguard Worker   if (Flags.verbosity)
419*9880d681SAndroid Build Coastguard Worker     Printf("Done %d runs in %zd second(s)\n", F.getTotalNumberOfRuns(),
420*9880d681SAndroid Build Coastguard Worker            F.secondsSinceProcessStartUp());
421*9880d681SAndroid Build Coastguard Worker   F.PrintFinalStats();
422*9880d681SAndroid Build Coastguard Worker 
423*9880d681SAndroid Build Coastguard Worker   exit(0);  // Don't let F destroy itself.
424*9880d681SAndroid Build Coastguard Worker }
425*9880d681SAndroid Build Coastguard Worker 
426*9880d681SAndroid Build Coastguard Worker // Storage for global ExternalFunctions object.
427*9880d681SAndroid Build Coastguard Worker ExternalFunctions *EF = nullptr;
428*9880d681SAndroid Build Coastguard Worker 
429*9880d681SAndroid Build Coastguard Worker }  // namespace fuzzer
430