[fuzzer] make multi-process execution more verbose; fix mutation to actually respect...
[oota-llvm.git] / lib / Fuzzer / FuzzerInternal.h
1 //===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Define the main class fuzzer::Fuzzer and most functions.
10 //===----------------------------------------------------------------------===//
11 #include <cassert>
12 #include <chrono>
13 #include <cstddef>
14 #include <cstdlib>
15 #include <string>
16 #include <vector>
17 #include <unordered_set>
18
19 namespace fuzzer {
20 typedef std::vector<uint8_t> Unit;
21 using namespace std::chrono;
22
23 Unit ReadFile(const char *Path);
24 void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V);
25 void WriteToFile(const Unit &U, const std::string &Path);
26 void CopyFileToErr(const std::string &Path);
27 // Returns "Dir/FileName" or equivalent for the current OS.
28 std::string DirPlusFile(const std::string &DirPath,
29                         const std::string &FileName);
30
31 void Mutate(Unit *U, size_t MaxLen);
32
33 void CrossOver(const Unit &A, const Unit &B, Unit *U, size_t MaxLen);
34
35 void Print(const Unit &U, const char *PrintAfter = "");
36 void PrintASCII(const Unit &U, const char *PrintAfter = "");
37 std::string Hash(const Unit &U);
38 void SetTimer(int Seconds);
39
40 class Fuzzer {
41  public:
42   struct FuzzingOptions {
43     int Verbosity = 1;
44     int MaxLen = 0;
45     bool DoCrossOver = true;
46     int  MutateDepth = 5;
47     bool ExitOnFirst = false;
48     bool UseFullCoverageSet  = false;
49     std::string OutputCorpus;
50   };
51   Fuzzer(FuzzingOptions Options) : Options(Options) {
52     SetDeathCallback();
53   }
54   void AddToCorpus(const Unit &U) { Corpus.push_back(U); }
55   size_t Loop(size_t NumIterations);
56   void ShuffleAndMinimize();
57   size_t CorpusSize() const { return Corpus.size(); }
58   void ReadDir(const std::string &Path) {
59     ReadDirToVectorOfUnits(Path.c_str(), &Corpus);
60   }
61   // Save the current corpus to OutputCorpus.
62   void SaveCorpus();
63
64   static void AlarmCallback();
65
66  private:
67   size_t MutateAndTestOne(Unit *U);
68   size_t RunOne(const Unit &U);
69   size_t RunOneMaximizeTotalCoverage(const Unit &U);
70   size_t RunOneMaximizeFullCoverageSet(const Unit &U);
71   void WriteToOutputCorpus(const Unit &U);
72   static void WriteToCrash(const Unit &U, const char *Prefix);
73
74   void SetDeathCallback();
75   static void DeathCallback();
76   static Unit CurrentUnit;
77
78   size_t TotalNumberOfRuns = 0;
79
80   std::vector<Unit> Corpus;
81   std::unordered_set<uintptr_t> FullCoverageSets;
82   FuzzingOptions Options;
83   system_clock::time_point ProcessStartTime = system_clock::now();
84   static system_clock::time_point UnitStartTime;
85 };
86
87 };  // namespace fuzzer