[sanitizer/coverage] Add AFL-style coverage counters (search heuristic for fuzzing).
[oota-llvm.git] / lib / Fuzzer / FuzzerInternal.h
index c361ffba83aa44ec1877959144923f99454a8a2e..e4e5eb7fd0516d0d35ac9dc2e61de5024af5bf2d 100644 (file)
@@ -9,11 +9,15 @@
 // Define the main class fuzzer::Fuzzer and most functions.
 //===----------------------------------------------------------------------===//
 #include <cassert>
+#include <climits>
 #include <chrono>
 #include <cstddef>
 #include <cstdlib>
 #include <string>
 #include <vector>
+#include <unordered_set>
+
+#include "FuzzerInterface.h"
 
 namespace fuzzer {
 typedef std::vector<uint8_t> Unit;
@@ -22,6 +26,7 @@ using namespace std::chrono;
 Unit ReadFile(const char *Path);
 void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V);
 void WriteToFile(const Unit &U, const std::string &Path);
+void CopyFileToErr(const std::string &Path);
 // Returns "Dir/FileName" or equivalent for the current OS.
 std::string DirPlusFile(const std::string &DirPath,
                         const std::string &FileName);
@@ -41,11 +46,17 @@ class Fuzzer {
     int Verbosity = 1;
     int MaxLen = 0;
     bool DoCrossOver = true;
-    bool MutateDepth = 10;
+    int  MutateDepth = 5;
     bool ExitOnFirst = false;
+    bool UseCounters = false;
+    bool UseFullCoverageSet  = false;
+    bool UseCoveragePairs = false;
+    int PreferSmallDuringInitialShuffle = -1;
+    size_t MaxNumberOfRuns = ULONG_MAX;
     std::string OutputCorpus;
   };
-  Fuzzer(FuzzingOptions Options) : Options(Options) {
+  Fuzzer(UserCallback Callback, FuzzingOptions Options)
+      : Callback(Callback), Options(Options) {
     SetDeathCallback();
   }
   void AddToCorpus(const Unit &U) { Corpus.push_back(U); }
@@ -58,11 +69,21 @@ class Fuzzer {
   // Save the current corpus to OutputCorpus.
   void SaveCorpus();
 
+  size_t secondsSinceProcessStartUp() {
+    return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
+        .count();
+  }
+
+  size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
+
   static void AlarmCallback();
 
  private:
   size_t MutateAndTestOne(Unit *U);
   size_t RunOne(const Unit &U);
+  size_t RunOneMaximizeTotalCoverage(const Unit &U);
+  size_t RunOneMaximizeFullCoverageSet(const Unit &U);
+  size_t RunOneMaximizeCoveragePairs(const Unit &U);
   void WriteToOutputCorpus(const Unit &U);
   static void WriteToCrash(const Unit &U, const char *Prefix);
 
@@ -73,6 +94,18 @@ class Fuzzer {
   size_t TotalNumberOfRuns = 0;
 
   std::vector<Unit> Corpus;
+  std::unordered_set<uintptr_t> FullCoverageSets;
+  std::unordered_set<uint64_t>  CoveragePairs;
+
+  // For UseCounters
+  std::vector<uint8_t> CounterBitmap;
+  size_t TotalBits() {  // Slow. Call it only for printing stats.
+    size_t Res = 0;
+    for (auto x : CounterBitmap) Res += __builtin_popcount(x);
+    return Res;
+  }
+
+  UserCallback Callback;
   FuzzingOptions Options;
   system_clock::time_point ProcessStartTime = system_clock::now();
   static system_clock::time_point UnitStartTime;