diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerCorpus.h | 110 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerDriver.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerInternal.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerLoop.cpp | 55 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerTracePC.cpp | 70 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerTracePC.h | 15 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerValueBitMap.h | 9 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/FuzzerUnittest.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/fuzzer.test | 10 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/shrink.test | 7 | 
12 files changed, 145 insertions, 150 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerCorpus.h b/llvm/lib/Fuzzer/FuzzerCorpus.h index ea4f0c706c7..a46f1dccb45 100644 --- a/llvm/lib/Fuzzer/FuzzerCorpus.h +++ b/llvm/lib/Fuzzer/FuzzerCorpus.h @@ -34,9 +34,11 @@ struct InputInfo {  class InputCorpus {   public: +  static const size_t kFeatureSetSize = 1 << 16;    InputCorpus() {      Inputs.reserve(1 << 14);  // Avoid too many resizes. -    memset(FeatureSet, 0, sizeof(FeatureSet)); +    memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature)); +    memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));    }    size_t size() const { return Inputs.size(); }    size_t SizeInBytes() const { @@ -53,17 +55,20 @@ class InputCorpus {    }    bool empty() const { return Inputs.empty(); }    const Unit &operator[] (size_t Idx) const { return Inputs[Idx].U; } -  void AddToCorpus(const Unit &U) { +  void AddToCorpus(const Unit &U, size_t NumFeatures) {      assert(!U.empty());      uint8_t Hash[kSHA1NumBytes]; +    if (FeatureDebug) +      Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures);      ComputeSHA1(U.data(), U.size(), Hash); -    if (!Hashes.insert(Sha1ToString(Hash)).second) return; +    Hashes.insert(Sha1ToString(Hash));      Inputs.push_back(InputInfo());      InputInfo &II = Inputs.back();      II.U = U; +    II.NumFeatures = NumFeatures;      memcpy(II.Sha1, Hash, kSHA1NumBytes); -    UpdateFeatureSet(Inputs.size() - 1);      UpdateCorpusDistribution(); +    ValidateFeatureSet();    }    typedef const std::vector<InputInfo>::const_iterator ConstIter; @@ -97,12 +102,9 @@ class InputCorpus {    }    void PrintFeatureSet() { -    Printf("Features [id: idx sz] ");      for (size_t i = 0; i < kFeatureSetSize; i++) { -      auto &Fe = FeatureSet[i]; -      if (!Fe.Count) continue; -      Printf("[%zd: %zd %zd] ", i, Fe.SmallestElementIdx, -             Fe.SmallestElementSize); +      if(size_t Sz = GetFeature(i)) +        Printf("[%zd: id %zd sz%zd] ", i, SmallestElementPerFeature[i], Sz);      }      Printf("\n\t");      for (size_t i = 0; i < Inputs.size(); i++) @@ -111,57 +113,59 @@ class InputCorpus {      Printf("\n");    } +  bool AddFeature(size_t Idx, uint32_t NewSize, bool Shrink) { +    assert(NewSize); +    Idx = Idx % kFeatureSetSize; +    uint32_t OldSize = GetFeature(Idx); +    if (OldSize == 0 || (Shrink && OldSize > NewSize)) { +      if (OldSize > 0) { +        InputInfo &II = Inputs[SmallestElementPerFeature[Idx]]; +        assert(II.NumFeatures > 0); +        II.NumFeatures--; +        if (II.NumFeatures == 0) { +          II.U.clear(); +          if (FeatureDebug) +            Printf("EVICTED %zd\n", SmallestElementPerFeature[Idx]); +        } +      } +      if (FeatureDebug) +        Printf("ADD FEATURE %zd sz %d\n", Idx, NewSize); +      SmallestElementPerFeature[Idx] = Inputs.size(); +      InputSizesPerFeature[Idx] = NewSize; +      CountingFeatures = true; +      return true; +    } +    return false; +  } + +  size_t NumFeatures() const { +    size_t Res = 0; +    for (size_t i = 0; i < kFeatureSetSize; i++) +      Res += GetFeature(i) != 0; +    return Res; +  } +  private:    static const bool FeatureDebug = false; -  static const size_t kFeatureSetSize = TracePC::kFeatureSetSize; + +  size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; }    void ValidateFeatureSet() { -    for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) { -      Feature &Fe = FeatureSet[Idx]; -      if(Fe.Count && Fe.SmallestElementSize) -        Inputs[Fe.SmallestElementIdx].Tmp++; -    } +    if (!CountingFeatures) return; +    if (FeatureDebug) +      PrintFeatureSet(); +    for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) +      if (GetFeature(Idx)) +        Inputs[SmallestElementPerFeature[Idx]].Tmp++;      for (auto &II: Inputs) { +      if (II.Tmp != II.NumFeatures) +        Printf("ZZZ %zd %zd\n", II.Tmp, II.NumFeatures);        assert(II.Tmp == II.NumFeatures);        II.Tmp = 0;      }    } -  void UpdateFeatureSet(size_t CurrentElementIdx) { -    auto &II = Inputs[CurrentElementIdx]; -    size_t Size = II.U.size(); -    if (!Size) -      return; -    bool Updated = false; -    for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) { -      if (!TPC.HasFeature(Idx)) -        continue; -      Feature &Fe = FeatureSet[Idx]; -      Fe.Count++; -      if (!Fe.SmallestElementSize || -          Fe.SmallestElementSize > Size) { -        II.NumFeatures++; -        CountingFeatures = true; -        if (Fe.SmallestElementSize > Size) { -          auto &OlderII = Inputs[Fe.SmallestElementIdx]; -          assert(OlderII.NumFeatures > 0); -          OlderII.NumFeatures--; -          if (!OlderII.NumFeatures) { -            OlderII.U.clear();  // Will be never used again. -            if (FeatureDebug) -              Printf("EVICTED %zd\n", Fe.SmallestElementIdx); -          } -        } -        Fe.SmallestElementIdx = CurrentElementIdx; -        Fe.SmallestElementSize = Size; -        Updated = true; -      } -    } -    if (Updated && FeatureDebug) PrintFeatureSet(); -    ValidateFeatureSet(); -  } -    // Updates the probability distribution for the units in the corpus.    // Must be called whenever the corpus or unit weights are changed.    void UpdateCorpusDistribution() { @@ -185,13 +189,9 @@ private:    std::unordered_set<std::string> Hashes;    std::vector<InputInfo> Inputs; -  struct Feature { -    size_t Count; -    size_t SmallestElementIdx; -    size_t SmallestElementSize; -  };    bool CountingFeatures = false; -  Feature FeatureSet[kFeatureSetSize]; +  uint32_t InputSizesPerFeature[kFeatureSetSize]; +  uint32_t SmallestElementPerFeature[kFeatureSetSize];  };  }  // namespace fuzzer diff --git a/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp index d0de517920d..fd88d50cfa8 100644 --- a/llvm/lib/Fuzzer/FuzzerDriver.cpp +++ b/llvm/lib/Fuzzer/FuzzerDriver.cpp @@ -342,7 +342,7 @@ int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {    Unit U = FileToVector(InputFilePath);    assert(U.size() > 2);    Printf("INFO: Starting MinimizeCrashInputInternalStep: %zd\n", U.size()); -  Corpus->AddToCorpus(U); +  Corpus->AddToCorpus(U, 0);    F->SetMaxInputLen(U.size());    F->SetMaxMutationLen(U.size() - 1);    F->Loop(); diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h index 29e810b0f6d..9ea5c96fe4b 100644 --- a/llvm/lib/Fuzzer/FuzzerInternal.h +++ b/llvm/lib/Fuzzer/FuzzerInternal.h @@ -42,17 +42,13 @@ public:        CounterBitmapBits = 0;        CounterBitmap.clear();        VPMap.Reset(); -      TPCMap.Reset();      } -    std::string DebugString() const; -      size_t BlockCoverage;      size_t CallerCalleeCoverage;      // Precalculated number of bits in CounterBitmap.      size_t CounterBitmapBits;      std::vector<uint8_t> CounterBitmap; -    ValueBitMap TPCMap;      ValueBitMap VPMap;    }; @@ -80,7 +76,7 @@ public:    static void StaticInterruptCallback();    void ExecuteCallback(const uint8_t *Data, size_t Size); -  bool RunOne(const uint8_t *Data, size_t Size); +  size_t RunOne(const uint8_t *Data, size_t Size);    // Merge Corpora[1:] into Corpora[0].    void Merge(const std::vector<std::string> &Corpora); @@ -106,7 +102,7 @@ private:    void ReportNewCoverage(InputInfo *II, const Unit &U);    void PrintNewPCs();    void PrintOneNewPC(uintptr_t PC); -  bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); } +  size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }    void WriteToOutputCorpus(const Unit &U);    void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);    void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0); diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 35d68bce694..6c1f376d8ef 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -299,18 +299,18 @@ void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {    Printf("#%zd\t%s", TotalNumberOfRuns, Where);    if (MaxCoverage.BlockCoverage)      Printf(" cov: %zd", MaxCoverage.BlockCoverage); +  if (size_t N = MaxCoverage.VPMap.GetNumBitsSinceLastMerge()) +    Printf(" vp: %zd", N);    if (size_t N = TPC.GetTotalPCCoverage())      Printf(" cov: %zd", N); -  if (MaxCoverage.VPMap.GetNumBitsSinceLastMerge()) -    Printf(" vp: %zd", MaxCoverage.VPMap.GetNumBitsSinceLastMerge());    if (auto TB = MaxCoverage.CounterBitmapBits)      Printf(" bits: %zd", TB); -  if (auto TB = MaxCoverage.TPCMap.GetNumBitsSinceLastMerge()) -    Printf(" bits: %zd", MaxCoverage.TPCMap.GetNumBitsSinceLastMerge()); +  if (size_t N = Corpus.NumFeatures()) +    Printf( " ft: %zd", N);    if (MaxCoverage.CallerCalleeCoverage)      Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);    if (size_t N = Corpus.size()) { -    Printf(" corpus: %zd", Corpus.NumActiveUnits()); +    Printf(" corp: %zd", Corpus.NumActiveUnits());      if (size_t N = Corpus.SizeInBytes()) {        if (N < (1<<14))          Printf("/%zdb", N); @@ -392,8 +392,8 @@ void Fuzzer::RereadOutputCorpus(size_t MaxSize) {      if (U.size() > MaxSize)        U.resize(MaxSize);      if (!Corpus.HasUnit(U)) { -      if (RunOne(U)) { -        Corpus.AddToCorpus(U); +      if (size_t NumFeatures = RunOne(U)) { +        Corpus.AddToCorpus(U, NumFeatures);          PrintStats("RELOAD");        }      } @@ -418,8 +418,8 @@ void Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) {    ExecuteCallback(&dummy, 0);    for (const auto &U : *InitialCorpus) { -    if (RunOne(U)) { -      Corpus.AddToCorpus(U); +    if (size_t NumFeatures = RunOne(U)) { +      Corpus.AddToCorpus(U, NumFeatures);        if (Options.Verbosity >= 2)          Printf("NEW0: %zd L %zd\n", MaxCoverage.BlockCoverage, U.size());      } @@ -434,27 +434,23 @@ void Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) {    }  } -bool Fuzzer::RunOne(const uint8_t *Data, size_t Size) { +size_t Fuzzer::RunOne(const uint8_t *Data, size_t Size) { +  if (!Size) return 0;    TotalNumberOfRuns++;    ExecuteCallback(Data, Size); -  bool Res = false; -  if (TPC.FinalizeTrace(Size)) -    if (Options.Shrink) -      Res = true; - -  if (!Res) { -    if (TPC.UpdateCounterMap(&MaxCoverage.TPCMap)) -      Res = true; +  size_t Res = 0; +  if (size_t NumFeatures = TPC.FinalizeTrace(&Corpus, Size, Options.Shrink)) +    Res = NumFeatures; +  if (!TPC.UsingTracePcGuard()) {      if (TPC.UpdateValueProfileMap(&MaxCoverage.VPMap)) -      Res = true; +      Res = 1; +    if (!Res && RecordMaxCoverage(&MaxCoverage)) +      Res = 1;    } -  if (RecordMaxCoverage(&MaxCoverage)) -    Res = true; -    CheckExitOnSrcPos();    auto TimeOfUnit =        duration_cast<seconds>(UnitStopTime - UnitStartTime).count(); @@ -500,16 +496,6 @@ void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {    delete[] DataCopy;  } -std::string Fuzzer::Coverage::DebugString() const { -  std::string Result = -      std::string("Coverage{") + "BlockCoverage=" + -      std::to_string(BlockCoverage) + " CallerCalleeCoverage=" + -      std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" + -      std::to_string(CounterBitmapBits) + " VPMapBits " + -      std::to_string(VPMap.GetNumBitsSinceLastMerge()) + "}"; -  return Result; -} -  void Fuzzer::WriteToOutputCorpus(const Unit &U) {    if (Options.OnlyASCII)      assert(IsASCII(U)); @@ -694,8 +680,9 @@ void Fuzzer::MutateAndTestOne() {      if (i == 0)        StartTraceRecording();      II.NumExecutedMutations++; -    if (RunOne(CurrentUnitData, Size)) { -      Corpus.AddToCorpus({CurrentUnitData, CurrentUnitData + Size}); +    if (size_t NumFeatures = RunOne(CurrentUnitData, Size)) { +      Corpus.AddToCorpus({CurrentUnitData, CurrentUnitData + Size}, +                         NumFeatures);        ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size});        CheckExitOnItem();      } diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp index c752002ab0f..aa5bd9b6087 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp +++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp @@ -12,6 +12,7 @@  //  //===----------------------------------------------------------------------===// +#include "FuzzerCorpus.h"  #include "FuzzerDefs.h"  #include "FuzzerTracePC.h"  #include "FuzzerValueBitMap.h" @@ -68,45 +69,46 @@ void TracePC::ResetGuards() {    assert(N == NumGuards);  } -bool TracePC::FinalizeTrace(size_t InputSize) { -  bool Res = false; -  if (TotalPCCoverage) { -    const size_t Step = 8; -    assert(reinterpret_cast<uintptr_t>(Counters) % Step == 0); -    size_t N = Min(kNumCounters, NumGuards + 1); -    N = (N + Step - 1) & ~(Step - 1);  // Round up. -    for (size_t Idx = 0; Idx < N; Idx += Step) { -      uint64_t Bundle = *reinterpret_cast<uint64_t*>(&Counters[Idx]); -      if (!Bundle) continue; -      for (size_t i = Idx; i < Idx + Step; i++) { -        uint8_t Counter = (Bundle >> (i * 8)) & 0xff; -        if (!Counter) continue; -        Counters[i] = 0; -        unsigned Bit = 0; -        /**/ if (Counter >= 128) Bit = 7; -        else if (Counter >= 32) Bit = 6; -        else if (Counter >= 16) Bit = 5; -        else if (Counter >= 8) Bit = 4; -        else if (Counter >= 4) Bit = 3; -        else if (Counter >= 3) Bit = 2; -        else if (Counter >= 2) Bit = 1; -        size_t Feature = i * 8 + Bit; -        CounterMap.AddValue(Feature); -        uint32_t *SizePtr = &InputSizesPerFeature[Feature % kFeatureSetSize]; -        if (!*SizePtr || *SizePtr > InputSize) { -          *SizePtr = InputSize; -          Res = true; -        } -      } +size_t TracePC::FinalizeTrace(InputCorpus *C, size_t InputSize, bool Shrink) { +  if (!UsingTracePcGuard()) return 0; +  size_t Res = 0; +  const size_t Step = 8; +  assert(reinterpret_cast<uintptr_t>(Counters) % Step == 0); +  size_t N = Min(kNumCounters, NumGuards + 1); +  N = (N + Step - 1) & ~(Step - 1);  // Round up. +  for (size_t Idx = 0; Idx < N; Idx += Step) { +    uint64_t Bundle = *reinterpret_cast<uint64_t*>(&Counters[Idx]); +    if (!Bundle) continue; +    for (size_t i = Idx; i < Idx + Step; i++) { +      uint8_t Counter = (Bundle >> (i * 8)) & 0xff; +      if (!Counter) continue; +      Counters[i] = 0; +      unsigned Bit = 0; +      /**/ if (Counter >= 128) Bit = 7; +      else if (Counter >= 32) Bit = 6; +      else if (Counter >= 16) Bit = 5; +      else if (Counter >= 8) Bit = 4; +      else if (Counter >= 4) Bit = 3; +      else if (Counter >= 3) Bit = 2; +      else if (Counter >= 2) Bit = 1; +      size_t Feature = (i * 8 + Bit); +      if (C->AddFeature(Feature, InputSize, Shrink)) +        Res++;      }    } +  if (UseValueProfile) +    ValueProfileMap.ForEach([&](size_t Idx) { +      if (C->AddFeature(NumGuards + Idx, InputSize, Shrink)) +        Res++; +    });    return Res;  }  void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {    const uintptr_t kBits = 12;    const uintptr_t kMask = (1 << kBits) - 1; -  CounterMap.AddValue((Caller & kMask) | ((Callee & kMask) << kBits)); +  uintptr_t Idx = (Caller & kMask) | ((Callee & kMask) << kBits); +  HandleValueProfile(Idx);  }  void TracePC::PrintCoverage() { @@ -163,11 +165,9 @@ void TracePC::AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,  ATTRIBUTE_TARGET_POPCNT  static void AddValueForCmp(void *PCptr, uint64_t Arg1, uint64_t Arg2) { -  if (Arg1 == Arg2) -    return;    uintptr_t PC = reinterpret_cast<uintptr_t>(PCptr); -  uint64_t ArgDistance = __builtin_popcountl(Arg1 ^ Arg2) - 1; // [0,63] -  uintptr_t Idx = (PC & 4095) | (ArgDistance << 12); +  uint64_t ArgDistance = __builtin_popcountl(Arg1 ^ Arg2) + 1; // [1,65] +  uintptr_t Idx = ((PC & 4095) + 1) * ArgDistance;    TPC.HandleValueProfile(Idx);  } diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.h b/llvm/lib/Fuzzer/FuzzerTracePC.h index a96a2c087e2..49f7faa6a1a 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.h +++ b/llvm/lib/Fuzzer/FuzzerTracePC.h @@ -29,13 +29,11 @@ class TracePC {    void ResetTotalPCCoverage() { TotalPCCoverage = 0; }    void SetUseCounters(bool UC) { UseCounters = UC; }    void SetUseValueProfile(bool VP) { UseValueProfile = VP; } -  bool UpdateCounterMap(ValueBitMap *MaxCounterMap) { -    return MaxCounterMap->MergeFrom(CounterMap); -  } +  size_t FinalizeTrace(InputCorpus *C, size_t InputSize, bool Shrink);    bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {      return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap); -  } -  bool FinalizeTrace(size_t InputSize); +    } +    size_t GetNewPCIDs(uintptr_t **NewPCIDsPtr) {      *NewPCIDsPtr = NewPCIDs; @@ -46,7 +44,6 @@ class TracePC {    void ResetMaps() {      NumNewPCIDs = 0; -    CounterMap.Reset();      ValueProfileMap.Reset();      memset(Counters, 0, sizeof(Counters));    } @@ -60,13 +57,13 @@ class TracePC {    void PrintCoverage(); -  bool HasFeature(size_t Idx) { return CounterMap.Get(Idx); } -    void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,                           size_t n);    void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,                           size_t n); +  bool UsingTracePcGuard() const {return NumModules; } +  private:    bool UseCounters = false;    bool UseValueProfile = false; @@ -93,9 +90,7 @@ private:    static const size_t kNumPCs = 1 << 20;    uintptr_t PCs[kNumPCs]; -  ValueBitMap CounterMap;    ValueBitMap ValueProfileMap; -  uint32_t InputSizesPerFeature[kFeatureSetSize];  };  extern TracePC TPC; diff --git a/llvm/lib/Fuzzer/FuzzerValueBitMap.h b/llvm/lib/Fuzzer/FuzzerValueBitMap.h index 97f4c5e51b9..0692acd13ee 100644 --- a/llvm/lib/Fuzzer/FuzzerValueBitMap.h +++ b/llvm/lib/Fuzzer/FuzzerValueBitMap.h @@ -68,6 +68,15 @@ struct ValueBitMap {      return OldNumBits < NumBits;    } +  template <class Callback> +  void ForEach(Callback CB) { +    for (size_t i = 0; i < kMapSizeInWords; i++) +      if (uintptr_t M = Map[i]) +        for (size_t j = 0; j < sizeof(M) * 8; j++) +          if (M & ((uintptr_t)1 << j)) +            CB(i * sizeof(M) * 8 + j); +  } +   private:    size_t NumBits = 0;    uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512))); diff --git a/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp b/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp index fdde1d3fbb9..ed37055fe45 100644 --- a/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp +++ b/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp @@ -583,7 +583,7 @@ TEST(Corpus, Distribution) {    size_t N = 10;    size_t TriesPerUnit = 1<<20;    for (size_t i = 0; i < N; i++) -    C.AddToCorpus(Unit{ static_cast<uint8_t>(i) }); +    C.AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 0);    std::vector<size_t> Hist(N);    for (size_t i = 0; i < N * TriesPerUnit; i++) { diff --git a/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp b/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp index 2fa17f156e2..0fd7c5e9a1f 100644 --- a/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp +++ b/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp @@ -21,7 +21,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {    int Z = Ids[(unsigned char)'Z'];    if (F >= 0 && U > F && Z > U) {      Sink++; -    // fprintf(stderr, "IDS: %d %d %d\n", F, U, Z); +    //fprintf(stderr, "IDS: %d %d %d\n", F, U, Z);    }    return 0;  } diff --git a/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp b/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp index 9ff5b19c7b6..026b8ce2659 100644 --- a/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp +++ b/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp @@ -12,10 +12,11 @@ static volatile uint32_t Sink;  extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {    if (Size < sizeof(uint32_t)) return 0; -  uint32_t X; +  uint32_t X, Y;    size_t Offset = Size < 8 ? 0 : Size / 2;    memcpy(&X, Data + Offset, sizeof(uint32_t)); -  Sink = X == 0xAABBCCDD; +  memcpy(&Y, "FUZZ", sizeof(uint32_t)); +  Sink = X == Y;    return 0;  } diff --git a/llvm/lib/Fuzzer/test/fuzzer.test b/llvm/lib/Fuzzer/test/fuzzer.test index 98139c09d6f..fe408596f5f 100644 --- a/llvm/lib/Fuzzer/test/fuzzer.test +++ b/llvm/lib/Fuzzer/test/fuzzer.test @@ -27,13 +27,13 @@ NULL_DEREF_ON_EMPTY: stat::number_of_executed_units:  RUN: not LLVMFuzzer-CounterTest         -use_counters=1 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS  RUN: not LLVMFuzzer-CounterTest-TracePC -use_counters=1 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS -COUNTERS: INITED {{.*}} bits: -COUNTERS: NEW {{.*}} bits: {{[1-9]*}} -COUNTERS: NEW {{.*}} bits: {{[1-9]*}} +COUNTERS: INITED {{.*}} {{bits:|ft:}} +COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}} +COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}  COUNTERS: BINGO -RUN: not LLVMFuzzer-CallerCalleeTest                     -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s -RUN: not LLVMFuzzer-CallerCalleeTest-TracePC             -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-CallerCalleeTest          -use_value_profile=1 -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-CallerCalleeTest-TracePC  -use_value_profile=1 -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s  # This one is flaky, may actually find the goal even w/o use_indir_calls.  # LLVMFuzzer-CallerCalleeTest  -use_indir_calls=0 -cross_over=0 -max_len=6 -seed=1 -runs=1000000 2>&1 | FileCheck %s  --check-prefix=Done1000000 diff --git a/llvm/lib/Fuzzer/test/shrink.test b/llvm/lib/Fuzzer/test/shrink.test new file mode 100644 index 00000000000..68206f0901b --- /dev/null +++ b/llvm/lib/Fuzzer/test/shrink.test @@ -0,0 +1,7 @@ +RUN: LLVMFuzzer-ShrinkControlFlowTest-TracePC -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000  -shrink=1 2>&1 | FileCheck %s --check-prefix=SHRINK1 +RUN: LLVMFuzzer-ShrinkControlFlowTest-TracePC -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=0 2>&1 | FileCheck %s --check-prefix=SHRINK0 +RUN: LLVMFuzzer-ShrinkValueProfileTest-TracePC -seed=1 -exit_on_item=aea2e3923af219a8956f626558ef32f30a914ebc -runs=100000 -shrink=1 -use_value_profile=1 2>&1 | FileCheck %s --check-prefix=SHRINK1_VP + +SHRINK0: Done 1000000 runs in +SHRINK1: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60', exiting. +SHRINK1_VP: INFO: found item with checksum 'aea2e3923af219a8956f626558ef32f30a914ebc', exiting  | 

