[llvm] r282044 - [libFuzzer] refactoring: split the large header into many; NFC

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 20 18:50:51 PDT 2016


Author: kcc
Date: Tue Sep 20 20:50:50 2016
New Revision: 282044

URL: http://llvm.org/viewvc/llvm-project?rev=282044&view=rev
Log:
[libFuzzer] refactoring: split the large header into many; NFC

Added:
    llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
    llvm/trunk/lib/Fuzzer/FuzzerDefs.h
    llvm/trunk/lib/Fuzzer/FuzzerDictionary.h
    llvm/trunk/lib/Fuzzer/FuzzerMutate.h
    llvm/trunk/lib/Fuzzer/FuzzerRandom.h
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.h
Modified:
    llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
    llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
    llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
    llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp
    llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp
    llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp

Added: llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCorpus.h?rev=282044&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerCorpus.h (added)
+++ llvm/trunk/lib/Fuzzer/FuzzerCorpus.h Tue Sep 20 20:50:50 2016
@@ -0,0 +1,56 @@
+//===- FuzzerCorpus.h - Internal header for the Fuzzer ----------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// fuzzer::InputCorpus
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_CORPUS
+#define LLVM_FUZZER_CORPUS
+
+#include "FuzzerDefs.h"
+
+namespace fuzzer {
+
+struct InputInfo {
+  Unit U;  // The actual input data.
+};
+
+class InputCorpus {
+ public:
+  InputCorpus() {
+    Corpus.reserve(1 << 14);  // Avoid too many resizes.
+  }
+  size_t size() const { return Corpus.size(); }
+  bool empty() const { return Corpus.empty(); }
+  const Unit &operator[] (size_t Idx) const { return Corpus[Idx].U; }
+  void Append(const std::vector<Unit> &V) {
+    for (auto &U : V)
+      push_back(U);
+  }
+  void push_back(const Unit &U) {
+    auto H = Hash(U);
+    if (!Hashes.insert(H).second) return;
+    InputInfo II;
+    II.U = U;
+    Corpus.push_back(II);
+  }
+
+  typedef const std::vector<InputInfo>::const_iterator ConstIter;
+  ConstIter begin() const { return Corpus.begin(); }
+  ConstIter end() const { return Corpus.end(); }
+
+  bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
+
+ private:
+  std::unordered_set<std::string> Hashes;
+  std::vector<InputInfo> Corpus;
+};
+
+}  // namespace fuzzer
+
+#endif  // LLVM_FUZZER_CORPUS

Modified: llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp Tue Sep 20 20:50:50 2016
@@ -12,6 +12,8 @@
 #include <cstring>
 
 #include "FuzzerInternal.h"
+#include "FuzzerMutate.h"
+#include "FuzzerRandom.h"
 
 namespace fuzzer {
 

Added: llvm/trunk/lib/Fuzzer/FuzzerDefs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDefs.h?rev=282044&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDefs.h (added)
+++ llvm/trunk/lib/Fuzzer/FuzzerDefs.h Tue Sep 20 20:50:50 2016
@@ -0,0 +1,100 @@
+//===- FuzzerDefs.h - Internal header for the Fuzzer ------------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Basic definitions.
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_FUZZER_DEFS_H
+#define LLVM_FUZZER_DEFS_H
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+// Platform detection.
+#ifdef __linux__
+#define LIBFUZZER_LINUX 1
+#define LIBFUZZER_APPLE 0
+#elif __APPLE__
+#define LIBFUZZER_LINUX 0
+#define LIBFUZZER_APPLE 1
+#else
+#error "Support for your platform has not been implemented"
+#endif
+
+#ifdef __x86_64
+#define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt")))
+#else
+#define ATTRIBUTE_TARGET_POPCNT
+#endif
+
+namespace fuzzer {
+
+class Random;
+class Dictionary;
+class DictionaryEntry;
+class MutationDispatcher;
+
+typedef std::vector<uint8_t> Unit;
+typedef std::vector<Unit> UnitVector;
+typedef int (*UserCallback)(const uint8_t *Data, size_t Size);
+int FuzzerDriver(int *argc, char ***argv, UserCallback Callback);
+
+bool IsFile(const std::string &Path);
+long GetEpoch(const std::string &Path);
+std::string FileToString(const std::string &Path);
+Unit FileToVector(const std::string &Path, size_t MaxSize = 0);
+void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
+                            long *Epoch, size_t MaxSize);
+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);
+
+void DupAndCloseStderr();
+void CloseStdout();
+void Printf(const char *Fmt, ...);
+void PrintHexArray(const Unit &U, const char *PrintAfter = "");
+void PrintHexArray(const uint8_t *Data, size_t Size,
+                   const char *PrintAfter = "");
+void PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter = "");
+void PrintASCII(const Unit &U, const char *PrintAfter = "");
+
+void PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC);
+std::string Hash(const Unit &U);
+void SetTimer(int Seconds);
+void SetSigSegvHandler();
+void SetSigBusHandler();
+void SetSigAbrtHandler();
+void SetSigIllHandler();
+void SetSigFpeHandler();
+void SetSigIntHandler();
+void SetSigTermHandler();
+std::string Base64(const Unit &U);
+int ExecuteCommand(const std::string &Command);
+size_t GetPeakRSSMb();
+
+// Private copy of SHA1 implementation.
+static const int kSHA1NumBytes = 20;
+// Computes SHA1 hash of 'Len' bytes in 'Data', writes kSHA1NumBytes to 'Out'.
+void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out);
+std::string Sha1ToString(uint8_t Sha1[kSHA1NumBytes]);
+
+// Changes U to contain only ASCII (isprint+isspace) characters.
+// Returns true iff U has been changed.
+bool ToASCII(uint8_t *Data, size_t Size);
+bool IsASCII(const Unit &U);
+bool IsASCII(const uint8_t *Data, size_t Size);
+
+int NumberOfCpuCores();
+int GetPid();
+void SleepSeconds(int Seconds);
+
+}  // namespace fuzzer
+#endif  // LLVM_FUZZER_DEFS_H

Added: llvm/trunk/lib/Fuzzer/FuzzerDictionary.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDictionary.h?rev=282044&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDictionary.h (added)
+++ llvm/trunk/lib/Fuzzer/FuzzerDictionary.h Tue Sep 20 20:50:50 2016
@@ -0,0 +1,114 @@
+//===- FuzzerDictionary.h - Internal header for the Fuzzer ------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// fuzzer::Dictionary
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_DICTIONARY_H
+#define LLVM_FUZZER_DICTIONARY_H
+
+#include "FuzzerDefs.h"
+
+namespace fuzzer {
+// A simple POD sized array of bytes.
+template <size_t kMaxSize> class FixedWord {
+public:
+  FixedWord() {}
+  FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); }
+
+  void Set(const uint8_t *B, uint8_t S) {
+    assert(S <= kMaxSize);
+    memcpy(Data, B, S);
+    Size = S;
+  }
+
+  bool operator==(const FixedWord<kMaxSize> &w) const {
+    return Size == w.Size && 0 == memcmp(Data, w.Data, Size);
+  }
+
+  bool operator<(const FixedWord<kMaxSize> &w) const {
+    if (Size != w.Size)
+      return Size < w.Size;
+    return memcmp(Data, w.Data, Size) < 0;
+  }
+
+  static size_t GetMaxSize() { return kMaxSize; }
+  const uint8_t *data() const { return Data; }
+  uint8_t size() const { return Size; }
+
+private:
+  uint8_t Size = 0;
+  uint8_t Data[kMaxSize];
+};
+
+typedef FixedWord<27> Word; // 28 bytes.
+
+class DictionaryEntry {
+ public:
+  DictionaryEntry() {}
+  DictionaryEntry(Word W) : W(W) {}
+  DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
+  const Word &GetW() const { return W; }
+
+  bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); }
+  size_t GetPositionHint() const {
+    assert(HasPositionHint());
+    return PositionHint;
+  }
+  void IncUseCount() { UseCount++; }
+  void IncSuccessCount() { SuccessCount++; }
+  size_t GetUseCount() const { return UseCount; }
+  size_t GetSuccessCount() const {return SuccessCount; }
+
+private:
+  Word W;
+  size_t PositionHint = std::numeric_limits<size_t>::max();
+  size_t UseCount = 0;
+  size_t SuccessCount = 0;
+};
+
+class Dictionary {
+ public:
+  static const size_t kMaxDictSize = 1 << 14;
+
+  bool ContainsWord(const Word &W) const {
+    return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {
+      return DE.GetW() == W;
+    });
+  }
+  const DictionaryEntry *begin() const { return &DE[0]; }
+  const DictionaryEntry *end() const { return begin() + Size; }
+  DictionaryEntry & operator[] (size_t Idx) {
+    assert(Idx < Size);
+    return DE[Idx];
+  }
+  void push_back(DictionaryEntry DE) {
+    if (Size < kMaxDictSize)
+      this->DE[Size++] = DE;
+  }
+  void clear() { Size = 0; }
+  bool empty() const { return Size == 0; }
+  size_t size() const { return Size; }
+
+private:
+  DictionaryEntry DE[kMaxDictSize];
+  size_t Size = 0;
+};
+
+// Parses one dictionary entry.
+// If successfull, write the enty to Unit and returns true,
+// otherwise returns false.
+bool ParseOneDictionaryEntry(const std::string &Str, Unit *U);
+// Parses the dictionary file, fills Units, returns true iff all lines
+// were parsed succesfully.
+bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units);
+
+}  // namespace fuzzer
+
+#endif  // LLVM_FUZZER_DICTIONARY_H
+

Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Tue Sep 20 20:50:50 2016
@@ -11,6 +11,8 @@
 
 #include "FuzzerInterface.h"
 #include "FuzzerInternal.h"
+#include "FuzzerMutate.h"
+#include "FuzzerRandom.h"
 
 #include <algorithm>
 #include <atomic>

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Tue Sep 20 20:50:50 2016
@@ -17,205 +17,24 @@
 #include <cassert>
 #include <chrono>
 #include <climits>
-#include <cstddef>
 #include <cstdlib>
-#include <random>
 #include <string.h>
-#include <string>
 #include <unordered_set>
-#include <vector>
-
-// Platform detection.
-#ifdef __linux__
-#define LIBFUZZER_LINUX 1
-#define LIBFUZZER_APPLE 0
-#elif __APPLE__
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_APPLE 1
-#else
-#error "Support for your platform has not been implemented"
-#endif
-
-#ifdef __x86_64
-#define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt")))
-#else
-#define ATTRIBUTE_TARGET_POPCNT
-#endif
 
+#include "FuzzerDefs.h"
 #include "FuzzerExtFunctions.h"
 #include "FuzzerInterface.h"
 #include "FuzzerValueBitMap.h"
+#include "FuzzerCorpus.h"  // TODO(kcc): remove this from here.
 
 namespace fuzzer {
 
-typedef int (*UserCallback)(const uint8_t *Data, size_t Size);
-int FuzzerDriver(int *argc, char ***argv, UserCallback Callback);
-
 using namespace std::chrono;
-typedef std::vector<uint8_t> Unit;
-typedef std::vector<Unit> UnitVector;
-
-// A simple POD sized array of bytes.
-template <size_t kMaxSize> class FixedWord {
-public:
-  FixedWord() {}
-  FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); }
-
-  void Set(const uint8_t *B, uint8_t S) {
-    assert(S <= kMaxSize);
-    memcpy(Data, B, S);
-    Size = S;
-  }
-
-  bool operator==(const FixedWord<kMaxSize> &w) const {
-    return Size == w.Size && 0 == memcmp(Data, w.Data, Size);
-  }
-
-  bool operator<(const FixedWord<kMaxSize> &w) const {
-    if (Size != w.Size)
-      return Size < w.Size;
-    return memcmp(Data, w.Data, Size) < 0;
-  }
-
-  static size_t GetMaxSize() { return kMaxSize; }
-  const uint8_t *data() const { return Data; }
-  uint8_t size() const { return Size; }
-
-private:
-  uint8_t Size = 0;
-  uint8_t Data[kMaxSize];
-};
-
-typedef FixedWord<27> Word; // 28 bytes.
-
-bool IsFile(const std::string &Path);
-long GetEpoch(const std::string &Path);
-std::string FileToString(const std::string &Path);
-Unit FileToVector(const std::string &Path, size_t MaxSize = 0);
-void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
-                            long *Epoch, size_t MaxSize);
-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);
-
-void DupAndCloseStderr();
-void CloseStdout();
-void Printf(const char *Fmt, ...);
-void PrintHexArray(const Unit &U, const char *PrintAfter = "");
-void PrintHexArray(const uint8_t *Data, size_t Size,
-                   const char *PrintAfter = "");
-void PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter = "");
-void PrintASCII(const Unit &U, const char *PrintAfter = "");
-void PrintASCII(const Word &W, const char *PrintAfter = "");
-void PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC);
-std::string Hash(const Unit &U);
-void SetTimer(int Seconds);
-void SetSigSegvHandler();
-void SetSigBusHandler();
-void SetSigAbrtHandler();
-void SetSigIllHandler();
-void SetSigFpeHandler();
-void SetSigIntHandler();
-void SetSigTermHandler();
-std::string Base64(const Unit &U);
-int ExecuteCommand(const std::string &Command);
-size_t GetPeakRSSMb();
-
-// Private copy of SHA1 implementation.
-static const int kSHA1NumBytes = 20;
-// Computes SHA1 hash of 'Len' bytes in 'Data', writes kSHA1NumBytes to 'Out'.
-void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out);
-std::string Sha1ToString(uint8_t Sha1[kSHA1NumBytes]);
-
-// Changes U to contain only ASCII (isprint+isspace) characters.
-// Returns true iff U has been changed.
-bool ToASCII(uint8_t *Data, size_t Size);
-bool IsASCII(const Unit &U);
-bool IsASCII(const uint8_t *Data, size_t Size);
-
-int NumberOfCpuCores();
-int GetPid();
-void SleepSeconds(int Seconds);
 
 // See FuzzerTraceState.cpp
 void EnableValueProfile();
 size_t VPMapMergeFromCurrent(ValueBitMap &M);
 
-class Random {
- public:
-  Random(unsigned int seed) : R(seed) {}
-  size_t Rand() { return R(); }
-  size_t RandBool() { return Rand() % 2; }
-  size_t operator()(size_t n) { return n ? Rand() % n : 0; }
-  std::mt19937 &Get_mt19937() { return R; }
- private:
-  std::mt19937 R;
-};
-
-// Dictionary.
-
-// Parses one dictionary entry.
-// If successfull, write the enty to Unit and returns true,
-// otherwise returns false.
-bool ParseOneDictionaryEntry(const std::string &Str, Unit *U);
-// Parses the dictionary file, fills Units, returns true iff all lines
-// were parsed succesfully.
-bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units);
-
-class DictionaryEntry {
- public:
-  DictionaryEntry() {}
-  DictionaryEntry(Word W) : W(W) {}
-  DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
-  const Word &GetW() const { return W; }
-
-  bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); }
-  size_t GetPositionHint() const {
-    assert(HasPositionHint());
-    return PositionHint;
-  }
-  void IncUseCount() { UseCount++; }
-  void IncSuccessCount() { SuccessCount++; }
-  size_t GetUseCount() const { return UseCount; }
-  size_t GetSuccessCount() const {return SuccessCount; }
-
-private:
-  Word W;
-  size_t PositionHint = std::numeric_limits<size_t>::max();
-  size_t UseCount = 0;
-  size_t SuccessCount = 0;
-};
-
-class Dictionary {
- public:
-  static const size_t kMaxDictSize = 1 << 14;
-
-  bool ContainsWord(const Word &W) const {
-    return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {
-      return DE.GetW() == W;
-    });
-  }
-  const DictionaryEntry *begin() const { return &DE[0]; }
-  const DictionaryEntry *end() const { return begin() + Size; }
-  DictionaryEntry & operator[] (size_t Idx) {
-    assert(Idx < Size);
-    return DE[Idx];
-  }
-  void push_back(DictionaryEntry DE) {
-    if (Size < kMaxDictSize)
-      this->DE[Size++] = DE;
-  }
-  void clear() { Size = 0; }
-  bool empty() const { return Size == 0; }
-  size_t size() const { return Size; }
-
-private:
-  DictionaryEntry DE[kMaxDictSize];
-  size_t Size = 0;
-};
-
 struct FuzzingOptions {
   int Verbosity = 1;
   size_t MaxLen = 0;
@@ -250,212 +69,6 @@ struct FuzzingOptions {
   bool PruneCorpus = true;
 };
 
-struct InputInfo {
-  Unit U;  // The actual input data.
-};
-
-class InputCorpus {
- public:
-  InputCorpus() {
-    Corpus.reserve(1 << 14);  // Avoid too many resizes.
-  }
-  size_t size() const { return Corpus.size(); }
-  bool empty() const { return Corpus.empty(); }
-  const Unit &operator[] (size_t Idx) const { return Corpus[Idx].U; }
-  void Append(const std::vector<Unit> &V) {
-    for (auto &U : V)
-      push_back(U);
-  }
-  void push_back(const Unit &U) {
-    auto H = Hash(U);
-    if (!Hashes.insert(H).second) return;
-    InputInfo II;
-    II.U = U;
-    Corpus.push_back(II);
-  }
-
-  typedef const std::vector<InputInfo>::const_iterator ConstIter;
-  ConstIter begin() const { return Corpus.begin(); }
-  ConstIter end() const { return Corpus.end(); }
-
-  bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
-
- private:
-  std::unordered_set<std::string> Hashes;
-  std::vector<InputInfo> Corpus;
-};
-
-class MutationDispatcher {
-public:
-  MutationDispatcher(Random &Rand, const FuzzingOptions &Options);
-  ~MutationDispatcher() {}
-  /// Indicate that we are about to start a new sequence of mutations.
-  void StartMutationSequence();
-  /// Print the current sequence of mutations.
-  void PrintMutationSequence();
-  /// Indicate that the current sequence of mutations was successfull.
-  void RecordSuccessfulMutationSequence();
-  /// Mutates data by invoking user-provided mutator.
-  size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by invoking user-provided crossover.
-  size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by shuffling bytes.
-  size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by erasing bytes.
-  size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by inserting a byte.
-  size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by inserting several repeated bytes.
-  size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by chanding one byte.
-  size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by chanding one bit.
-  size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Mutates data by copying/inserting a part of data into a different place.
-  size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize);
-
-  /// Mutates data by adding a word from the manual dictionary.
-  size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,
-                                            size_t MaxSize);
-
-  /// Mutates data by adding a word from the temporary automatic dictionary.
-  size_t Mutate_AddWordFromTemporaryAutoDictionary(uint8_t *Data, size_t Size,
-                                                   size_t MaxSize);
-
-  /// Mutates data by adding a word from the persistent automatic dictionary.
-  size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,
-                                                    size_t MaxSize);
-
-  /// Tries to find an ASCII integer in Data, changes it to another ASCII int.
-  size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.
-  size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);
-
-  /// CrossOver Data with some other element of the corpus.
-  size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
-
-  /// Applies one of the configured mutations.
-  /// Returns the new size of data which could be up to MaxSize.
-  size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
-  /// Applies one of the default mutations. Provided as a service
-  /// to mutation authors.
-  size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
-
-  /// Creates a cross-over of two pieces of Data, returns its size.
-  size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
-                   size_t Size2, uint8_t *Out, size_t MaxOutSize);
-
-  void AddWordToManualDictionary(const Word &W);
-
-  void AddWordToAutoDictionary(DictionaryEntry DE);
-  void ClearAutoDictionary();
-  void PrintRecommendedDictionary();
-
-  void SetCorpus(const InputCorpus *Corpus) { this->Corpus = Corpus; }
-
-  Random &GetRand() { return Rand; }
-
-private:
-
-  struct Mutator {
-    size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
-    const char *Name;
-  };
-
-  size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
-                               size_t MaxSize);
-  size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
-                    const std::vector<Mutator> &Mutators);
-
-  size_t InsertPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
-                      size_t ToSize, size_t MaxToSize);
-  size_t CopyPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
-                    size_t ToSize);
-
-  Random &Rand;
-  const FuzzingOptions Options;
-
-  // Dictionary provided by the user via -dict=DICT_FILE.
-  Dictionary ManualDictionary;
-  // Temporary dictionary modified by the fuzzer itself,
-  // recreated periodically.
-  Dictionary TempAutoDictionary;
-  // Persistent dictionary modified by the fuzzer, consists of
-  // entries that led to successfull discoveries in the past mutations.
-  Dictionary PersistentAutoDictionary;
-  std::vector<Mutator> CurrentMutatorSequence;
-  std::vector<DictionaryEntry *> CurrentDictionaryEntrySequence;
-  const InputCorpus *Corpus = nullptr;
-  std::vector<uint8_t> MutateInPlaceHere;
-
-  std::vector<Mutator> Mutators;
-  std::vector<Mutator> DefaultMutators;
-};
-
-// See TracePC.cpp
-class TracePC {
- public:
-  void HandleTrace(uintptr_t *guard, uintptr_t PC);
-  void HandleInit(uintptr_t *start, uintptr_t *stop);
-  void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
-  size_t GetTotalCoverage() { return TotalCoverage; }
-  void SetUseCounters(bool UC) { UseCounters = UC; }
-  size_t UpdateCounterMap(ValueBitMap *Map);
-  void FinalizeTrace();
-
-  size_t GetNewPCsAndFlush(uintptr_t **NewPCsPtr = nullptr) {
-    if (NewPCsPtr)
-      *NewPCsPtr = NewPCs;
-    size_t Res = NumNewPCs;
-    NumNewPCs = 0;
-    return Res;
-  }
-
-  void Reset() {
-    TotalCoverage = 0;
-    TotalCounterBits = 0;
-    NumNewPCs = 0;
-    CounterMap.Reset();
-    TotalCoverageMap.Reset();
-    ResetGuards();
-  }
-
-  void PrintModuleInfo();
-
-  void PrintCoverage();
-
-private:
-  bool UseCounters = false;
-  size_t TotalCoverage = 0;
-  size_t TotalCounterBits = 0;
-
-  static const size_t kMaxNewPCs = 64;
-  uintptr_t NewPCs[kMaxNewPCs];
-  size_t NumNewPCs = 0;
-  void AddNewPC(uintptr_t PC) { NewPCs[(NumNewPCs++) % kMaxNewPCs] = PC; }
-
-  void ResetGuards();
-
-  struct Module {
-    uintptr_t *Start, *Stop;
-  };
-
-  Module Modules[4096];
-  size_t NumModules = 0;
-  size_t NumGuards = 0;
-
-  static const size_t kNumCounters = 1 << 14;
-  uint8_t Counters[kNumCounters];
-
-  static const size_t kNumPCs = 1 << 20;
-  uintptr_t PCs[kNumPCs];
-
-  ValueBitMap CounterMap;
-  ValueBitMap TotalCoverageMap;
-};
-
-extern TracePC TPC;
-
 class Fuzzer {
 public:
 

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Tue Sep 20 20:50:50 2016
@@ -10,6 +10,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "FuzzerInternal.h"
+#include "FuzzerMutate.h"
+#include "FuzzerTracePC.h"
+#include "FuzzerRandom.h"
+
 #include <algorithm>
 #include <cstring>
 #include <memory>

Modified: llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMain.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerMain.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerMain.cpp Tue Sep 20 20:50:50 2016
@@ -9,8 +9,7 @@
 // main() and flags.
 //===----------------------------------------------------------------------===//
 
-#include "FuzzerInterface.h"
-#include "FuzzerInternal.h"
+#include "FuzzerDefs.h"
 
 extern "C" {
 // This function should be defined by the user.

Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Tue Sep 20 20:50:50 2016
@@ -12,12 +12,16 @@
 #include <cstring>
 
 #include "FuzzerInternal.h"
-
+#include "FuzzerMutate.h"
 
 namespace fuzzer {
 
 const size_t Dictionary::kMaxDictSize;
 
+static void PrintASCII(const Word &W, const char *PrintAfter) {
+  PrintASCII(W.data(), W.size(), PrintAfter);
+}
+
 MutationDispatcher::MutationDispatcher(Random &Rand,
                                        const FuzzingOptions &Options)
     : Rand(Rand), Options(Options) {

Added: llvm/trunk/lib/Fuzzer/FuzzerMutate.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.h?rev=282044&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerMutate.h (added)
+++ llvm/trunk/lib/Fuzzer/FuzzerMutate.h Tue Sep 20 20:50:50 2016
@@ -0,0 +1,130 @@
+//===- FuzzerMutate.h - Internal header for the Fuzzer ----------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// fuzzer::MutationDispatcher
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_MUTATE_H
+#define LLVM_FUZZER_MUTATE_H
+
+#include "FuzzerDefs.h"
+#include "FuzzerDictionary.h"
+#include "FuzzerRandom.h"
+
+namespace fuzzer {
+
+class MutationDispatcher {
+public:
+  MutationDispatcher(Random &Rand, const FuzzingOptions &Options);
+  ~MutationDispatcher() {}
+  /// Indicate that we are about to start a new sequence of mutations.
+  void StartMutationSequence();
+  /// Print the current sequence of mutations.
+  void PrintMutationSequence();
+  /// Indicate that the current sequence of mutations was successfull.
+  void RecordSuccessfulMutationSequence();
+  /// Mutates data by invoking user-provided mutator.
+  size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by invoking user-provided crossover.
+  size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by shuffling bytes.
+  size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by erasing bytes.
+  size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by inserting a byte.
+  size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by inserting several repeated bytes.
+  size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by chanding one byte.
+  size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by chanding one bit.
+  size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Mutates data by copying/inserting a part of data into a different place.
+  size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize);
+
+  /// Mutates data by adding a word from the manual dictionary.
+  size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,
+                                            size_t MaxSize);
+
+  /// Mutates data by adding a word from the temporary automatic dictionary.
+  size_t Mutate_AddWordFromTemporaryAutoDictionary(uint8_t *Data, size_t Size,
+                                                   size_t MaxSize);
+
+  /// Mutates data by adding a word from the persistent automatic dictionary.
+  size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,
+                                                    size_t MaxSize);
+
+  /// Tries to find an ASCII integer in Data, changes it to another ASCII int.
+  size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.
+  size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);
+
+  /// CrossOver Data with some other element of the corpus.
+  size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
+
+  /// Applies one of the configured mutations.
+  /// Returns the new size of data which could be up to MaxSize.
+  size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
+  /// Applies one of the default mutations. Provided as a service
+  /// to mutation authors.
+  size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
+
+  /// Creates a cross-over of two pieces of Data, returns its size.
+  size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
+                   size_t Size2, uint8_t *Out, size_t MaxOutSize);
+
+  void AddWordToManualDictionary(const Word &W);
+
+  void AddWordToAutoDictionary(DictionaryEntry DE);
+  void ClearAutoDictionary();
+  void PrintRecommendedDictionary();
+
+  void SetCorpus(const InputCorpus *Corpus) { this->Corpus = Corpus; }
+
+  Random &GetRand() { return Rand; }
+
+private:
+
+  struct Mutator {
+    size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
+    const char *Name;
+  };
+
+  size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
+                               size_t MaxSize);
+  size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
+                    const std::vector<Mutator> &Mutators);
+
+  size_t InsertPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
+                      size_t ToSize, size_t MaxToSize);
+  size_t CopyPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
+                    size_t ToSize);
+
+  Random &Rand;
+  const FuzzingOptions Options;
+
+  // Dictionary provided by the user via -dict=DICT_FILE.
+  Dictionary ManualDictionary;
+  // Temporary dictionary modified by the fuzzer itself,
+  // recreated periodically.
+  Dictionary TempAutoDictionary;
+  // Persistent dictionary modified by the fuzzer, consists of
+  // entries that led to successfull discoveries in the past mutations.
+  Dictionary PersistentAutoDictionary;
+  std::vector<Mutator> CurrentMutatorSequence;
+  std::vector<DictionaryEntry *> CurrentDictionaryEntrySequence;
+  const InputCorpus *Corpus = nullptr;
+  std::vector<uint8_t> MutateInPlaceHere;
+
+  std::vector<Mutator> Mutators;
+  std::vector<Mutator> DefaultMutators;
+};
+
+}  // namespace fuzzer
+
+#endif  // LLVM_FUZZER_MUTATE_H

Added: llvm/trunk/lib/Fuzzer/FuzzerRandom.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerRandom.h?rev=282044&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerRandom.h (added)
+++ llvm/trunk/lib/Fuzzer/FuzzerRandom.h Tue Sep 20 20:50:50 2016
@@ -0,0 +1,31 @@
+//===- FuzzerRandom.h - Internal header for the Fuzzer ----------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// fuzzer::Random
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_RANDOM_H
+#define LLVM_FUZZER_RANDOM_H
+
+#include <random>
+
+namespace fuzzer {
+class Random {
+ public:
+  Random(unsigned int seed) : R(seed) {}
+  size_t Rand() { return R(); }
+  size_t RandBool() { return Rand() % 2; }
+  size_t operator()(size_t n) { return n ? Rand() % n : 0; }
+  std::mt19937 &Get_mt19937() { return R; }
+ private:
+  std::mt19937 R;
+};
+
+}  // namespace fuzzer
+
+#endif  // LLVM_FUZZER_RANDOM_H

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp Tue Sep 20 20:50:50 2016
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "FuzzerInternal.h"
+#include "FuzzerTracePC.h"
 
 namespace fuzzer {
 

Added: llvm/trunk/lib/Fuzzer/FuzzerTracePC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.h?rev=282044&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.h (added)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.h Tue Sep 20 20:50:50 2016
@@ -0,0 +1,84 @@
+//===- FuzzerTracePC.h - Internal header for the Fuzzer ---------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// fuzzer::TracePC
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_TRACE_PC
+#define LLVM_FUZZER_TRACE_PC
+
+#include "FuzzerDefs.h"
+
+namespace fuzzer {
+
+class TracePC {
+ public:
+  void HandleTrace(uintptr_t *guard, uintptr_t PC);
+  void HandleInit(uintptr_t *start, uintptr_t *stop);
+  void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
+  size_t GetTotalCoverage() { return TotalCoverage; }
+  void SetUseCounters(bool UC) { UseCounters = UC; }
+  size_t UpdateCounterMap(ValueBitMap *Map);
+  void FinalizeTrace();
+
+  size_t GetNewPCsAndFlush(uintptr_t **NewPCsPtr = nullptr) {
+    if (NewPCsPtr)
+      *NewPCsPtr = NewPCs;
+    size_t Res = NumNewPCs;
+    NumNewPCs = 0;
+    return Res;
+  }
+
+  void Reset() {
+    TotalCoverage = 0;
+    TotalCounterBits = 0;
+    NumNewPCs = 0;
+    CounterMap.Reset();
+    TotalCoverageMap.Reset();
+    ResetGuards();
+  }
+
+  void PrintModuleInfo();
+
+  void PrintCoverage();
+
+private:
+  bool UseCounters = false;
+  size_t TotalCoverage = 0;
+  size_t TotalCounterBits = 0;
+
+  static const size_t kMaxNewPCs = 64;
+  uintptr_t NewPCs[kMaxNewPCs];
+  size_t NumNewPCs = 0;
+  void AddNewPC(uintptr_t PC) { NewPCs[(NumNewPCs++) % kMaxNewPCs] = PC; }
+
+  void ResetGuards();
+
+  struct Module {
+    uintptr_t *Start, *Stop;
+  };
+
+  Module Modules[4096];
+  size_t NumModules = 0;
+  size_t NumGuards = 0;
+
+  static const size_t kNumCounters = 1 << 14;
+  uint8_t Counters[kNumCounters];
+
+  static const size_t kNumPCs = 1 << 20;
+  uintptr_t PCs[kNumPCs];
+
+  ValueBitMap CounterMap;
+  ValueBitMap TotalCoverageMap;
+};
+
+extern TracePC TPC;
+
+}  // namespace fuzzer
+
+#endif  // LLVM_FUZZER_TRACE_PC

Modified: llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp Tue Sep 20 20:50:50 2016
@@ -72,6 +72,9 @@
 
 #include "FuzzerDFSan.h"
 #include "FuzzerInternal.h"
+#include "FuzzerDictionary.h"
+#include "FuzzerMutate.h"
+#include "FuzzerRandom.h"
 
 #include <algorithm>
 #include <cstring>
@@ -236,7 +239,7 @@ public:
           Printf("AutoDict:\n");
           for (auto &I : CountedUnits) {
             Printf("   %zd ", I.first);
-            PrintASCII(I.second);
+            PrintASCII(I.second.data(), I.second.size());
             Printf("\n");
           }
         }

Modified: llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp Tue Sep 20 20:50:50 2016
@@ -55,10 +55,6 @@ void PrintASCII(const uint8_t *Data, siz
   Printf("%s", PrintAfter);
 }
 
-void PrintASCII(const Word &W, const char *PrintAfter) {
-  PrintASCII(W.data(), W.size(), PrintAfter);
-}
-
 void PrintASCII(const Unit &U, const char *PrintAfter) {
   PrintASCII(U.data(), U.size(), PrintAfter);
 }

Modified: llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=282044&r1=282043&r2=282044&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp Tue Sep 20 20:50:50 2016
@@ -6,6 +6,9 @@
 #define _LIBCPP_HAS_NO_ASAN
 
 #include "FuzzerInternal.h"
+#include "FuzzerDictionary.h"
+#include "FuzzerMutate.h"
+#include "FuzzerRandom.h"
 #include "gtest/gtest.h"
 #include <memory>
 #include <set>




More information about the llvm-commits mailing list