diff options
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerInterface.h | 6 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerLoop.cpp | 9 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerMutate.cpp | 43 | 
3 files changed, 39 insertions, 19 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerInterface.h b/llvm/lib/Fuzzer/FuzzerInterface.h index c409c06eca1..329e3a9b1e6 100644 --- a/llvm/lib/Fuzzer/FuzzerInterface.h +++ b/llvm/lib/Fuzzer/FuzzerInterface.h @@ -70,6 +70,10 @@ class MutationDispatcher {   public:    MutationDispatcher(FuzzerRandomBase &Rand);    ~MutationDispatcher(); +  /// Indicate that we are about to start a new sequence of mutations. +  void StartMutationSequence(); +  /// Print the current sequence of mutations. +  void PrintMutationSequence();    /// Mutates data by shuffling bytes.    size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);    /// Mutates data by erasing a byte. @@ -138,6 +142,8 @@ class UserSuppliedFuzzer {    UserSuppliedFuzzer(FuzzerRandomBase *Rand);    /// Executes the target function on 'Size' bytes of 'Data'.    virtual int TargetFunction(const uint8_t *Data, size_t Size) = 0; +  virtual void StartMutationSequence() { MD.StartMutationSequence(); } +  virtual void PrintMutationSequence() { MD.PrintMutationSequence(); }    /// Mutates 'Size' bytes of data in 'Data' inplace into up to 'MaxSize' bytes,    /// returns the new size of the data, which should be positive.    virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) { diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 889c30c8748..b1ce294b972 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -320,12 +320,8 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U) {      return;    PrintStats("NEW   ", "");    if (Options.Verbosity) { -    Printf(" L: %zd", U.size()); -    if (U.size() < 30) { -      Printf(" "); -      PrintUnitInASCII(U, "\t"); -      Print(U); -    } +    Printf(" L: %zd ", U.size()); +    USF.PrintMutationSequence();      Printf("\n");    }  } @@ -483,6 +479,7 @@ void Fuzzer::Loop() {          secondsSinceProcessStartUp() >          static_cast<size_t>(Options.MaxTotalTimeSec))        break; +    USF.StartMutationSequence();      CurrentUnit = Corpus[J1];      // Optionally, cross with another unit.      if (Options.DoCrossOver && USF.GetRand().RandBool()) { diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp index 74ae0cbb75a..471ae6ce197 100644 --- a/llvm/lib/Fuzzer/FuzzerMutate.cpp +++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp @@ -17,29 +17,33 @@  namespace fuzzer { -typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size, -                                              size_t Max); +struct Mutator { +  size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max); +  const char *Name; +};  struct MutationDispatcher::Impl {    std::vector<Unit> Dictionary;    std::vector<Mutator> Mutators; +  std::vector<Mutator> CurrentMutatorSequence; + +  void Add(Mutator M) { Mutators.push_back(M); }    Impl() { -    Mutators.push_back(&MutationDispatcher::Mutate_EraseByte); -    Mutators.push_back(&MutationDispatcher::Mutate_InsertByte); -    Mutators.push_back(&MutationDispatcher::Mutate_ChangeByte); -    Mutators.push_back(&MutationDispatcher::Mutate_ChangeBit); -    Mutators.push_back(&MutationDispatcher::Mutate_ShuffleBytes); -    Mutators.push_back(&MutationDispatcher::Mutate_ChangeASCIIInteger); +    Add({&MutationDispatcher::Mutate_EraseByte, "EraseByte"}); +    Add({&MutationDispatcher::Mutate_InsertByte, "InsertByte"}); +    Add({&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"}); +    Add({&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"}); +    Add({&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"}); +    Add({&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"});    }    void AddWordToDictionary(const uint8_t *Word, size_t Size) {      if (Dictionary.empty()) { -      Mutators.push_back(&MutationDispatcher::Mutate_AddWordFromDictionary); +      Add({&MutationDispatcher::Mutate_AddWordFromDictionary, "AddFromDict"});      }      Dictionary.push_back(Unit(Word, Word + Size));    }  }; -  static char FlipRandomBit(char X, FuzzerRandomBase &Rand) {    int Bit = Rand(8);    char Mask = 1 << Bit; @@ -150,6 +154,16 @@ size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,    return Size;  } +void MutationDispatcher::StartMutationSequence() { +  MDImpl->CurrentMutatorSequence.clear(); +} + +void MutationDispatcher::PrintMutationSequence() { +  Printf("MS: %zd ", MDImpl->CurrentMutatorSequence.size()); +  for (auto M : MDImpl->CurrentMutatorSequence) +    Printf("%s-", M.Name); +} +  // Mutates Data in place, returns new size.  size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {    assert(MaxSize > 0); @@ -165,9 +179,12 @@ size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {    // Try several times before returning un-mutated data.    for (int Iter = 0; Iter < 10; Iter++) {      size_t MutatorIdx = Rand(MDImpl->Mutators.size()); -    size_t NewSize = -        (this->*(MDImpl->Mutators[MutatorIdx]))(Data, Size, MaxSize); -    if (NewSize) return NewSize; +    auto M = MDImpl->Mutators[MutatorIdx]; +    size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize); +    if (NewSize) { +      MDImpl->CurrentMutatorSequence.push_back(M); +      return NewSize; +    }    }    return Size;  }  | 

