X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FFuzzer%2FFuzzerDriver.cpp;h=4b9b57f27ea76c6e4b7607f668e56bf282d0796b;hp=8506fb48d0fd6371046e5b60dd17100057f5f0ab;hb=cd0d243e72c28dbdb8046a283ff704b6044c9aa9;hpb=6cc3ed7cdddcd09a5905039054fbd306e414202d diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index 8506fb48d0f..4b9b57f27ea 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -55,12 +55,12 @@ static FlagDescription FlagDescriptions [] { static const size_t kNumFlags = sizeof(FlagDescriptions) / sizeof(FlagDescriptions[0]); -static std::vector inputs; -static const char *ProgName; +static std::vector *Inputs; +static std::string *ProgName; static void PrintHelp() { Printf("Usage: %s [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\n", - ProgName); + ProgName->c_str()); Printf("\nFlags: (strictly in form -flag=value)\n"); size_t MaxFlagLen = 0; for (size_t F = 0; F < kNumFlags; F++) @@ -119,16 +119,17 @@ static bool ParseOneFlag(const char *Param) { } // We don't use any library to minimize dependencies. -static void ParseFlags(int argc, char **argv) { +static void ParseFlags(const std::vector &Args) { for (size_t F = 0; F < kNumFlags; F++) { if (FlagDescriptions[F].IntFlag) *FlagDescriptions[F].IntFlag = FlagDescriptions[F].Default; if (FlagDescriptions[F].StrFlag) *FlagDescriptions[F].StrFlag = nullptr; } - for (int A = 1; A < argc; A++) { - if (ParseOneFlag(argv[A])) continue; - inputs.push_back(argv[A]); + Inputs = new std::vector; + for (size_t A = 1; A < Args.size(); A++) { + if (ParseOneFlag(Args[A].c_str())) continue; + Inputs->push_back(Args[A]); } } @@ -161,15 +162,15 @@ static void WorkerThread(const std::string &Cmd, std::atomic *Counter, } } -static int RunInMultipleProcesses(int argc, char **argv, int NumWorkers, - int NumJobs) { +static int RunInMultipleProcesses(const std::vector &Args, + int NumWorkers, int NumJobs) { std::atomic Counter(0); std::atomic HasErrors(false); std::string Cmd; - for (int i = 0; i < argc; i++) { - if (FlagValue(argv[i], "jobs") || FlagValue(argv[i], "workers")) continue; - Cmd += argv[i]; - Cmd += " "; + for (auto &S : Args) { + if (FlagValue(S.c_str(), "jobs") || FlagValue(S.c_str(), "workers")) + continue; + Cmd += S + " "; } std::vector V; std::thread Pulse(PulseThread); @@ -201,6 +202,12 @@ int ApplyTokens(const Fuzzer &F, const char *InputFilePath) { return 0; } +int RunOneTest(Fuzzer *F, const char *InputFilePath) { + Unit U = FileToVector(InputFilePath); + F->ExecuteCallback(U); + return 0; +} + int FuzzerDriver(int argc, char **argv, UserCallback Callback) { FuzzerRandomLibc Rand(0); SimpleUserSuppliedFuzzer SUSF(&Rand, Callback); @@ -208,10 +215,22 @@ int FuzzerDriver(int argc, char **argv, UserCallback Callback) { } int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) { - using namespace fuzzer; + std::vector Args(argv, argv + argc); + return FuzzerDriver(Args, USF); +} - ProgName = argv[0]; - ParseFlags(argc, argv); +int FuzzerDriver(const std::vector &Args, UserCallback Callback) { + FuzzerRandomLibc Rand(0); + SimpleUserSuppliedFuzzer SUSF(&Rand, Callback); + return FuzzerDriver(Args, SUSF); +} + +int FuzzerDriver(const std::vector &Args, + UserSuppliedFuzzer &USF) { + using namespace fuzzer; + assert(!Args.empty()); + ProgName = new std::string(Args[0]); + ParseFlags(Args); if (Flags.help) { PrintHelp(); return 0; @@ -224,12 +243,13 @@ int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) { } if (Flags.workers > 0 && Flags.jobs > 0) - return RunInMultipleProcesses(argc, argv, Flags.workers, Flags.jobs); + return RunInMultipleProcesses(Args, Flags.workers, Flags.jobs); Fuzzer::FuzzingOptions Options; Options.Verbosity = Flags.verbosity; Options.MaxLen = Flags.max_len; Options.UnitTimeoutSec = Flags.timeout; + Options.MaxTotalTimeSec = Flags.max_total_time; Options.DoCrossOver = Flags.cross_over; Options.MutateDepth = Flags.mutate_depth; Options.ExitOnFirst = Flags.exit_on_first; @@ -245,8 +265,8 @@ int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) { Options.TBMWidth = Flags.tbm_width; if (Flags.runs >= 0) Options.MaxNumberOfRuns = Flags.runs; - if (!inputs.empty()) - Options.OutputCorpus = inputs[0]; + if (!Inputs->empty()) + Options.OutputCorpus = (*Inputs)[0]; if (Flags.sync_command) Options.SyncCommand = Flags.sync_command; Options.SyncTimeout = Flags.sync_timeout; @@ -262,6 +282,9 @@ int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) { if (Flags.apply_tokens) return ApplyTokens(F, Flags.apply_tokens); + if (Flags.test_single_input) + return RunOneTest(&F, Flags.test_single_input); + unsigned Seed = Flags.seed; // Initialize Seed. if (Seed == 0) @@ -282,7 +305,7 @@ int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) { } F.RereadOutputCorpus(); - for (auto &inp : inputs) + for (auto &inp : *Inputs) if (inp != Options.OutputCorpus) F.ReadDir(inp, nullptr); @@ -291,7 +314,7 @@ int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) { F.ShuffleAndMinimize(); if (Flags.save_minimized_corpus) F.SaveCorpus(); - F.Loop(Flags.iterations < 0 ? INT_MAX : Flags.iterations); + F.Loop(); if (Flags.verbosity) Printf("Done %d runs in %zd second(s)\n", F.getTotalNumberOfRuns(), F.secondsSinceProcessStartUp());