[llvm] r271740 - [libfuzzer] hiding custom mutator handling in MutationDispatcher.

Mike Aizatsky via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 3 14:34:29 PDT 2016


Author: aizatsky
Date: Fri Jun  3 16:34:29 2016
New Revision: 271740

URL: http://llvm.org/viewvc/llvm-project?rev=271740&view=rev
Log:
[libfuzzer] hiding custom mutator handling in MutationDispatcher.

Summary: Refactoring, no functional changes.

Differential Revision: http://reviews.llvm.org/D20975

Modified:
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
    llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=271740&r1=271739&r2=271740&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Fri Jun  3 16:34:29 2016
@@ -205,7 +205,7 @@ private:
 
 class MutationDispatcher {
 public:
-  MutationDispatcher(Random &Rand) : Rand(Rand) {}
+  MutationDispatcher(Random &Rand);
   ~MutationDispatcher() {}
   /// Indicate that we are about to start a new sequence of mutations.
   void StartMutationSequence();
@@ -213,6 +213,8 @@ public:
   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 shuffling bytes.
   size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
   /// Mutates data by erasing a byte.
@@ -242,9 +244,12 @@ public:
   /// 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 above mutations.
+  /// 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,
@@ -269,6 +274,11 @@ private:
 
   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);
+
+  // Interface to functions that may or may not be available.
+  const ExternalFunctions EF;
 
   Random &Rand;
   // Dictionary provided by the user via -dict=DICT_FILE.
@@ -284,7 +294,8 @@ private:
   const std::vector<Unit> *Corpus = nullptr;
   std::vector<uint8_t> MutateInPlaceHere;
 
-  static Mutator Mutators[];
+  std::vector<Mutator> Mutators;
+  std::vector<Mutator> DefaultMutators;
 };
 
 class Fuzzer {
@@ -471,7 +482,8 @@ private:
   static thread_local bool IsMyThread;
 
   // Interface to functions that may or may not be available.
-  ExternalFunctions EF;
+  // For future use, currently not used.
+  const ExternalFunctions EF;
 };
 
 }; // namespace fuzzer

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=271740&r1=271739&r2=271740&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Fri Jun  3 16:34:29 2016
@@ -692,11 +692,7 @@ void Fuzzer::MutateAndTestOne() {
 
   for (int i = 0; i < Options.MutateDepth; i++) {
     size_t NewSize = 0;
-    if (EF.LLVMFuzzerCustomMutator)
-      NewSize = EF.LLVMFuzzerCustomMutator(CurrentUnitData, Size,
-                                           Options.MaxLen, MD.GetRand().Rand());
-    else
-      NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
+    NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
     assert(NewSize > 0 && "Mutator returned empty unit");
     assert(NewSize <= Options.MaxLen &&
            "Mutator return overisized unit");
@@ -816,6 +812,6 @@ extern "C" {
 
 size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
   assert(fuzzer::F);
-  return fuzzer::F->GetMD().Mutate(Data, Size, MaxSize);
+  return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
 }
 }  // extern "C"

Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=271740&r1=271739&r2=271740&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Fri Jun  3 16:34:29 2016
@@ -18,21 +18,30 @@ namespace fuzzer {
 
 const size_t Dictionary::kMaxDictSize;
 
-MutationDispatcher::Mutator MutationDispatcher::Mutators[] = {
-  {&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
-  {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
-  {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
-  {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
-  {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
-  {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
-  {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
-  {&MutationDispatcher::Mutate_AddWordFromManualDictionary,
-    "AddFromManualDict"},
-  {&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
-    "AddFromTempAutoDict"},
-  {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
-    "AddFromPersAutoDict"},
-};
+MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) {
+  DefaultMutators.insert(
+      DefaultMutators.begin(),
+      {
+          {&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
+          {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
+          {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
+          {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
+          {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
+          {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
+          {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
+          {&MutationDispatcher::Mutate_AddWordFromManualDictionary,
+           "AddFromManualDict"},
+          {&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
+           "AddFromTempAutoDict"},
+          {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
+           "AddFromPersAutoDict"},
+      });
+
+  if (EF.LLVMFuzzerCustomMutator)
+    Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
+  else
+    Mutators = DefaultMutators;
+}
 
 static char FlipRandomBit(char X, Random &Rand) {
   int Bit = Rand(8);
@@ -52,6 +61,11 @@ static char RandCh(Random &Rand) {
   return Special[Rand(sizeof(Special) - 1)];
 }
 
+size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
+                                         size_t MaxSize) {
+  return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
+}
+
 size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
                                                size_t MaxSize) {
   assert(Size);
@@ -230,8 +244,19 @@ void MutationDispatcher::PrintMutationSe
   }
 }
 
-// Mutates Data in place, returns new size.
 size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
+  return MutateImpl(Data, Size, MaxSize, Mutators);
+}
+
+size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
+                                         size_t MaxSize) {
+  return MutateImpl(Data, Size, MaxSize, DefaultMutators);
+}
+
+// Mutates Data in place, returns new size.
+size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
+                                      size_t MaxSize,
+                                      const std::vector<Mutator> &Mutators) {
   assert(MaxSize > 0);
   assert(Size <= MaxSize);
   if (Size == 0) {
@@ -244,9 +269,7 @@ size_t MutationDispatcher::Mutate(uint8_
   // in which case they will return 0.
   // Try several times before returning un-mutated data.
   for (int Iter = 0; Iter < 10; Iter++) {
-    size_t NumMutators = sizeof(Mutators) / sizeof(Mutators[0]);
-    size_t MutatorIdx = Rand(NumMutators);
-    auto M = Mutators[MutatorIdx];
+    auto M = Mutators[Rand(Mutators.size())];
     size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
     if (NewSize) {
       CurrentMutatorSequence.push_back(M);




More information about the llvm-commits mailing list