[llvm] r283409 - [libFuzzer] refactoring to make -shrink=1 work for value profile, added a test.

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 5 15:56:22 PDT 2016


Author: kcc
Date: Wed Oct  5 17:56:21 2016
New Revision: 283409

URL: http://llvm.org/viewvc/llvm-project?rev=283409&view=rev
Log:
[libFuzzer] refactoring to make -shrink=1 work for value profile, added a test.

Added:
    llvm/trunk/lib/Fuzzer/test/shrink.test
Modified:
    llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.h
    llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h
    llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
    llvm/trunk/lib/Fuzzer/test/ShrinkControlFlowTest.cpp
    llvm/trunk/lib/Fuzzer/test/ShrinkValueProfileTest.cpp
    llvm/trunk/lib/Fuzzer/test/fuzzer.test

Modified: llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCorpus.h?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerCorpus.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerCorpus.h Wed Oct  5 17:56:21 2016
@@ -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

Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Wed Oct  5 17:56:21 2016
@@ -342,7 +342,7 @@ int MinimizeCrashInputInternalStep(Fuzze
   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();

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Wed Oct  5 17:56:21 2016
@@ -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);

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Wed Oct  5 17:56:21 2016
@@ -299,18 +299,18 @@ void Fuzzer::PrintStats(const char *Wher
   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 M
     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(UnitVect
   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(UnitVect
   }
 }
 
-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
   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();
     }

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp Wed Oct  5 17:56:21 2016
@@ -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 *ca
 
 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);
 }
 

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.h?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.h Wed Oct  5 17:56:21 2016
@@ -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;

Modified: llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h Wed Oct  5 17:56:21 2016
@@ -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)));

Modified: llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp Wed Oct  5 17:56:21 2016
@@ -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++) {

Modified: llvm/trunk/lib/Fuzzer/test/ShrinkControlFlowTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/ShrinkControlFlowTest.cpp?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/ShrinkControlFlowTest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/ShrinkControlFlowTest.cpp Wed Oct  5 17:56:21 2016
@@ -21,7 +21,7 @@ extern "C" int LLVMFuzzerTestOneInput(co
   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;
 }

Modified: llvm/trunk/lib/Fuzzer/test/ShrinkValueProfileTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/ShrinkValueProfileTest.cpp?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/ShrinkValueProfileTest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/ShrinkValueProfileTest.cpp Wed Oct  5 17:56:21 2016
@@ -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;
 }
 

Modified: llvm/trunk/lib/Fuzzer/test/fuzzer.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer.test?rev=283409&r1=283408&r2=283409&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer.test Wed Oct  5 17:56:21 2016
@@ -27,13 +27,13 @@ NULL_DEREF_ON_EMPTY: stat::number_of_exe
 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
 

Added: llvm/trunk/lib/Fuzzer/test/shrink.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/shrink.test?rev=283409&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/shrink.test (added)
+++ llvm/trunk/lib/Fuzzer/test/shrink.test Wed Oct  5 17:56:21 2016
@@ -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




More information about the llvm-commits mailing list