blob: ad42d7f6b734f62b4024388d6893163625cc8fba [file] [log] [blame]
Aaron Ballmanef116982015-01-29 16:58:29 +00001//===- 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//===----------------------------------------------------------------------===//
Yaron Keren347663b2015-08-10 16:37:40 +000011
12#ifndef LLVM_FUZZER_INTERNAL_H
13#define LLVM_FUZZER_INTERNAL_H
14
Kostya Serebryany292cf032016-02-13 03:37:24 +000015#include <algorithm>
Kostya Serebryany0edb5632016-05-27 00:54:15 +000016#include <atomic>
Aaron Ballmanef116982015-01-29 16:58:29 +000017#include <chrono>
Ivan Krasindf919102016-01-22 22:28:27 +000018#include <climits>
Aaron Ballmanef116982015-01-29 16:58:29 +000019#include <cstdlib>
Kostya Serebryany476f0ce2016-01-16 03:53:32 +000020#include <string.h>
Aaron Ballmanef116982015-01-29 16:58:29 +000021
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000022#include "FuzzerDefs.h"
Kostya Serebryanybceadcf2016-08-24 01:38:42 +000023#include "FuzzerExtFunctions.h"
24#include "FuzzerInterface.h"
Kostya Serebryany556894f2016-09-21 02:05:39 +000025#include "FuzzerOptions.h"
Zachary Turner24a148b2016-11-30 19:06:14 +000026#include "FuzzerSHA1.h"
Kostya Serebryanybceadcf2016-08-24 01:38:42 +000027#include "FuzzerValueBitMap.h"
28
Aaron Ballmanef116982015-01-29 16:58:29 +000029namespace fuzzer {
Kostya Serebryany8b0d90a2016-05-13 18:04:35 +000030
Aaron Ballmanef116982015-01-29 16:58:29 +000031using namespace std::chrono;
Kostya Serebryany9690fcf2015-05-12 18:51:57 +000032
Aaron Ballmanef116982015-01-29 16:58:29 +000033class Fuzzer {
Ivan Krasindf919102016-01-22 22:28:27 +000034public:
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000035
36 // Aggregates all available coverage measurements.
37 struct Coverage {
38 Coverage() { Reset(); }
39
40 void Reset() {
41 BlockCoverage = 0;
42 CallerCalleeCoverage = 0;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000043 CounterBitmapBits = 0;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000044 CounterBitmap.clear();
Kostya Serebryanyd46a59f2016-08-16 19:33:51 +000045 VPMap.Reset();
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000046 }
47
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000048 size_t BlockCoverage;
49 size_t CallerCalleeCoverage;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000050 // Precalculated number of bits in CounterBitmap.
51 size_t CounterBitmapBits;
52 std::vector<uint8_t> CounterBitmap;
Kostya Serebryanyd46a59f2016-08-16 19:33:51 +000053 ValueBitMap VPMap;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000054 };
55
Kostya Serebryany29bb6642016-09-21 22:42:17 +000056 Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
57 FuzzingOptions Options);
Mike Aizatskyb4bbc3b2016-08-05 20:09:53 +000058 ~Fuzzer();
Kostya Serebryany468ed782015-09-08 17:30:35 +000059 void Loop();
Kostya Serebryanyf9b8e8b2016-10-15 01:00:24 +000060 void MinimizeCrashLoop(const Unit &U);
Kostya Serebryany09aa01a2016-09-21 01:04:43 +000061 void ShuffleAndMinimize(UnitVector *V);
Kostya Serebryany22526252015-05-11 21:16:27 +000062 void InitializeTraceState();
Kostya Serebryany64d24572016-03-12 01:57:04 +000063 void RereadOutputCorpus(size_t MaxSize);
Aaron Ballmanef116982015-01-29 16:58:29 +000064
Kostya Serebryany92e04762015-02-04 23:42:42 +000065 size_t secondsSinceProcessStartUp() {
66 return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
67 .count();
68 }
Kostya Serebryanyf9b8e8b2016-10-15 01:00:24 +000069
70 bool TimedOut() {
71 return Options.MaxTotalTimeSec > 0 &&
72 secondsSinceProcessStartUp() >
73 static_cast<size_t>(Options.MaxTotalTimeSec);
74 }
75
Kostya Serebryany66ff0752016-02-26 22:42:23 +000076 size_t execPerSec() {
77 size_t Seconds = secondsSinceProcessStartUp();
78 return Seconds ? TotalNumberOfRuns / Seconds : 0;
79 }
Kostya Serebryany92e04762015-02-04 23:42:42 +000080
81 size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
82
Kostya Serebryany52a788e2015-03-31 20:13:20 +000083 static void StaticAlarmCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +000084 static void StaticCrashSignalCallback();
85 static void StaticInterruptCallback();
Kostya Serebryany52a788e2015-03-31 20:13:20 +000086
Kostya Serebryany8a5bef02016-02-13 17:56:51 +000087 void ExecuteCallback(const uint8_t *Data, size_t Size);
Kostya Serebryany1c73f1b2016-10-05 22:56:21 +000088 size_t RunOne(const uint8_t *Data, size_t Size);
Aaron Ballmanef116982015-01-29 16:58:29 +000089
Kostya Serebryany9cc3b0d2015-10-24 01:16:40 +000090 // Merge Corpora[1:] into Corpora[0].
91 void Merge(const std::vector<std::string> &Corpora);
Kostya Serebryany945761b2016-03-18 00:23:29 +000092 // Returns a subset of 'Extra' that adds coverage to 'Initial'.
93 UnitVector FindExtraUnits(const UnitVector &Initial, const UnitVector &Extra);
Kostya Serebryany1deb0492016-02-13 06:24:18 +000094 MutationDispatcher &GetMD() { return MD; }
Kostya Serebryany66ff0752016-02-26 22:42:23 +000095 void PrintFinalStats();
Kostya Serebryanybe0ed592016-09-22 23:16:36 +000096 void SetMaxInputLen(size_t MaxInputLen);
97 void SetMaxMutationLen(size_t MaxMutationLen);
Kostya Serebryany8b8f7a32016-05-06 23:38:07 +000098 void RssLimitCallback();
Kostya Serebryany9cc3b0d2015-10-24 01:16:40 +000099
Mike Aizatskyaf432a42016-05-24 23:14:29 +0000100 // Public for tests.
101 void ResetCoverage();
102
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000103 bool InFuzzingThread() const { return IsMyThread; }
Kostya Serebryanyd8384122016-05-26 22:17:32 +0000104 size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
Kostya Serebryanybb59ef72016-10-18 18:38:08 +0000105 void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
106 bool DuringInitialCorpusExecution);
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000107
Kostya Serebryany05f77912016-11-30 22:39:35 +0000108 void HandleMalloc(size_t Size);
109
Ivan Krasindf919102016-01-22 22:28:27 +0000110private:
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000111 void AlarmCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +0000112 void CrashCallback();
113 void InterruptCallback();
Kostya Serebryany27ab2d72015-12-19 02:49:09 +0000114 void MutateAndTestOne();
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000115 void ReportNewCoverage(InputInfo *II, const Unit &U);
Kostya Serebryany1c73f1b2016-10-05 22:56:21 +0000116 size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
Aaron Ballmanef116982015-01-29 16:58:29 +0000117 void WriteToOutputCorpus(const Unit &U);
Kostya Serebryany2b7d2e92015-07-23 18:37:22 +0000118 void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
Kostya Serebryany16a145f2016-09-23 01:58:51 +0000119 void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
Kostya Serebryanydc3135d2015-11-12 01:02:01 +0000120 void PrintStatusForNewUnit(const Unit &U);
Kostya Serebryany945761b2016-03-18 00:23:29 +0000121 void ShuffleCorpus(UnitVector *V);
Kostya Serebryany90f8f362016-09-30 23:29:27 +0000122 void AddToCorpus(const Unit &U);
Kostya Serebryany8dfed452016-10-18 18:06:05 +0000123 void CheckExitOnSrcPosOrItem();
Kostya Serebryany945761b2016-03-18 00:23:29 +0000124
Kostya Serebryanybeb24c32015-05-07 21:02:11 +0000125 // Trace-based fuzzing: we run a unit with some kind of tracing
126 // enabled and record potentially useful mutations. Then
127 // We apply these mutations one by one to the unit and run it again.
128
129 // Start tracing; forget all previously proposed mutations.
130 void StartTraceRecording();
Kostya Serebryanyb65805a2016-01-09 03:08:58 +0000131 // Stop tracing.
132 void StopTraceRecording();
Kostya Serebryanybeb24c32015-05-07 21:02:11 +0000133
Aaron Ballmanef116982015-01-29 16:58:29 +0000134 void SetDeathCallback();
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000135 static void StaticDeathCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +0000136 void DumpCurrentUnit(const char *Prefix);
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000137 void DeathCallback();
Kostya Serebryany98abb2c2016-01-13 23:46:01 +0000138
Kostya Serebryanyf67357c2016-08-25 01:25:03 +0000139 void ResetEdgeCoverage();
Kostya Serebryanyb76a2a52016-09-09 02:38:28 +0000140 void ResetCounters();
Kostya Serebryanyf67357c2016-08-25 01:25:03 +0000141 void PrepareCounters(Fuzzer::Coverage *C);
142 bool RecordMaxCoverage(Fuzzer::Coverage *C);
143
Kostya Serebryanybe0ed592016-09-22 23:16:36 +0000144 void AllocateCurrentUnitData();
Kostya Serebryany8fc3a272016-05-27 00:21:33 +0000145 uint8_t *CurrentUnitData = nullptr;
Kostya Serebryany0edb5632016-05-27 00:54:15 +0000146 std::atomic<size_t> CurrentUnitSize;
Kostya Serebryanya9a54802016-08-17 20:45:23 +0000147 uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
Aaron Ballmanef116982015-01-29 16:58:29 +0000148
149 size_t TotalNumberOfRuns = 0;
Kostya Serebryany66ff0752016-02-26 22:42:23 +0000150 size_t NumberOfNewUnitsAdded = 0;
Aaron Ballmanef116982015-01-29 16:58:29 +0000151
Kostya Serebryany1bfd5832016-04-20 00:24:21 +0000152 bool HasMoreMallocsThanFrees = false;
Kostya Serebryany7018a1a2016-04-27 19:52:34 +0000153 size_t NumberOfLeakDetectionAttempts = 0;
Kostya Serebryany1bfd5832016-04-20 00:24:21 +0000154
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000155 UserCallback CB;
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000156 InputCorpus &Corpus;
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000157 MutationDispatcher &MD;
Aaron Ballmanef116982015-01-29 16:58:29 +0000158 FuzzingOptions Options;
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000159
Aaron Ballmanef116982015-01-29 16:58:29 +0000160 system_clock::time_point ProcessStartTime = system_clock::now();
Kostya Serebryany624f59f2016-09-22 01:34:58 +0000161 system_clock::time_point UnitStartTime, UnitStopTime;
Kostya Serebryany16901a92015-03-30 23:04:35 +0000162 long TimeOfLongestUnitInSeconds = 0;
Kostya Serebryany1ac80552015-05-08 21:30:55 +0000163 long EpochOfLastReadOfOutputCorpus = 0;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +0000164
165 // Maximum recorded coverage.
166 Coverage MaxCoverage;
Kostya Serebryanyf67357c2016-08-25 01:25:03 +0000167
Kostya Serebryanybe0ed592016-09-22 23:16:36 +0000168 size_t MaxInputLen = 0;
169 size_t MaxMutationLen = 0;
170
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000171 // Need to know our own thread.
172 static thread_local bool IsMyThread;
Kostya Serebryanyb991cc12016-09-10 00:15:41 +0000173
174 bool InMergeMode = false;
Aaron Ballmanef116982015-01-29 16:58:29 +0000175};
176
Ivan Krasindf919102016-01-22 22:28:27 +0000177}; // namespace fuzzer
Yaron Keren347663b2015-08-10 16:37:40 +0000178
179#endif // LLVM_FUZZER_INTERNAL_H