]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Fuzzer/FuzzerInternal.h
Vendor import of llvm trunk r291274:
[FreeBSD/FreeBSD.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
12 #ifndef LLVM_FUZZER_INTERNAL_H
13 #define LLVM_FUZZER_INTERNAL_H
14
15 #include "FuzzerDefs.h"
16 #include "FuzzerExtFunctions.h"
17 #include "FuzzerInterface.h"
18 #include "FuzzerOptions.h"
19 #include "FuzzerSHA1.h"
20 #include "FuzzerValueBitMap.h"
21 #include <algorithm>
22 #include <atomic>
23 #include <chrono>
24 #include <climits>
25 #include <cstdlib>
26 #include <string.h>
27
28 namespace fuzzer {
29
30 using namespace std::chrono;
31
32 class Fuzzer {
33 public:
34
35   // Aggregates all available coverage measurements.
36   struct Coverage {
37     Coverage() { Reset(); }
38
39     void Reset() {
40       BlockCoverage = 0;
41       CallerCalleeCoverage = 0;
42       CounterBitmapBits = 0;
43       CounterBitmap.clear();
44       VPMap.Reset();
45     }
46
47     size_t BlockCoverage;
48     size_t CallerCalleeCoverage;
49     // Precalculated number of bits in CounterBitmap.
50     size_t CounterBitmapBits;
51     std::vector<uint8_t> CounterBitmap;
52     ValueBitMap VPMap;
53   };
54
55   Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
56          FuzzingOptions Options);
57   ~Fuzzer();
58   void Loop();
59   void MinimizeCrashLoop(const Unit &U);
60   void ShuffleAndMinimize(UnitVector *V);
61   void InitializeTraceState();
62   void RereadOutputCorpus(size_t MaxSize);
63
64   size_t secondsSinceProcessStartUp() {
65     return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
66         .count();
67   }
68
69   bool TimedOut() {
70     return Options.MaxTotalTimeSec > 0 &&
71            secondsSinceProcessStartUp() >
72                static_cast<size_t>(Options.MaxTotalTimeSec);
73   }
74
75   size_t execPerSec() {
76     size_t Seconds = secondsSinceProcessStartUp();
77     return Seconds ? TotalNumberOfRuns / Seconds : 0;
78   }
79
80   size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
81
82   static void StaticAlarmCallback();
83   static void StaticCrashSignalCallback();
84   static void StaticInterruptCallback();
85   static void StaticFileSizeExceedCallback();
86
87   void ExecuteCallback(const uint8_t *Data, size_t Size);
88   size_t RunOne(const uint8_t *Data, size_t Size);
89
90   // Merge Corpora[1:] into Corpora[0].
91   void Merge(const std::vector<std::string> &Corpora);
92   void CrashResistantMerge(const std::vector<std::string> &Args,
93                            const std::vector<std::string> &Corpora);
94   void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
95   // Returns a subset of 'Extra' that adds coverage to 'Initial'.
96   UnitVector FindExtraUnits(const UnitVector &Initial, const UnitVector &Extra);
97   MutationDispatcher &GetMD() { return MD; }
98   void PrintFinalStats();
99   void SetMaxInputLen(size_t MaxInputLen);
100   void SetMaxMutationLen(size_t MaxMutationLen);
101   void RssLimitCallback();
102
103   // Public for tests.
104   void ResetCoverage();
105
106   bool InFuzzingThread() const { return IsMyThread; }
107   size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
108   void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
109                                bool DuringInitialCorpusExecution);
110
111   void HandleMalloc(size_t Size);
112
113 private:
114   void AlarmCallback();
115   void CrashCallback();
116   void InterruptCallback();
117   void MutateAndTestOne();
118   void ReportNewCoverage(InputInfo *II, const Unit &U);
119   size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
120   void WriteToOutputCorpus(const Unit &U);
121   void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
122   void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
123   void PrintStatusForNewUnit(const Unit &U);
124   void ShuffleCorpus(UnitVector *V);
125   void AddToCorpus(const Unit &U);
126   void CheckExitOnSrcPosOrItem();
127
128   // Trace-based fuzzing: we run a unit with some kind of tracing
129   // enabled and record potentially useful mutations. Then
130   // We apply these mutations one by one to the unit and run it again.
131
132   // Start tracing; forget all previously proposed mutations.
133   void StartTraceRecording();
134   // Stop tracing.
135   void StopTraceRecording();
136
137   void SetDeathCallback();
138   static void StaticDeathCallback();
139   void DumpCurrentUnit(const char *Prefix);
140   void DeathCallback();
141
142   void ResetEdgeCoverage();
143   void ResetCounters();
144   void PrepareCounters(Fuzzer::Coverage *C);
145   bool RecordMaxCoverage(Fuzzer::Coverage *C);
146
147   void AllocateCurrentUnitData();
148   uint8_t *CurrentUnitData = nullptr;
149   std::atomic<size_t> CurrentUnitSize;
150   uint8_t BaseSha1[kSHA1NumBytes];  // Checksum of the base unit.
151   bool RunningCB = false;
152
153   size_t TotalNumberOfRuns = 0;
154   size_t NumberOfNewUnitsAdded = 0;
155
156   bool HasMoreMallocsThanFrees = false;
157   size_t NumberOfLeakDetectionAttempts = 0;
158
159   UserCallback CB;
160   InputCorpus &Corpus;
161   MutationDispatcher &MD;
162   FuzzingOptions Options;
163
164   system_clock::time_point ProcessStartTime = system_clock::now();
165   system_clock::time_point UnitStartTime, UnitStopTime;
166   long TimeOfLongestUnitInSeconds = 0;
167   long EpochOfLastReadOfOutputCorpus = 0;
168
169   // Maximum recorded coverage.
170   Coverage MaxCoverage;
171
172   size_t MaxInputLen = 0;
173   size_t MaxMutationLen = 0;
174
175   // Need to know our own thread.
176   static thread_local bool IsMyThread;
177
178   bool InMergeMode = false;
179 };
180
181 }; // namespace fuzzer
182
183 #endif // LLVM_FUZZER_INTERNAL_H