]> granicus.if.org Git - llvm/commitdiff
[libFuzzer] change ValueBitMap to remember the number of bits in it
authorKostya Serebryany <kcc@google.com>
Fri, 23 Sep 2016 00:22:46 +0000 (00:22 +0000)
committerKostya Serebryany <kcc@google.com>
Fri, 23 Sep 2016 00:22:46 +0000 (00:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282216 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerDefs.h
lib/Fuzzer/FuzzerInternal.h
lib/Fuzzer/FuzzerLoop.cpp
lib/Fuzzer/FuzzerTracePC.cpp
lib/Fuzzer/FuzzerTracePC.h
lib/Fuzzer/FuzzerTraceState.cpp
lib/Fuzzer/FuzzerValueBitMap.h

index 79a6f0111cbddc9be9524a5b15257266a0565dd9..4c60572ab4c06dcca482a960bbf1b71f5d157802 100644 (file)
@@ -37,6 +37,9 @@
 
 namespace fuzzer {
 
+template <class T> T Min(T a, T b) { return a < b ? a : b; }
+template <class T> T Max(T a, T b) { return a > b ? a : b; }
+
 class Random;
 class Dictionary;
 class DictionaryEntry;
index 7c92ac84fa00a7b042fb706280d11ded5ccbfcca..12a160d22960f97e6e21a32c5ea37345bf90c599 100644 (file)
@@ -31,7 +31,7 @@ using namespace std::chrono;
 
 // See FuzzerTraceState.cpp
 void EnableValueProfile();
-size_t VPMapMergeFromCurrent(ValueBitMap &M);
+bool VPMapMergeFromCurrent(ValueBitMap &M);
 
 class Fuzzer {
 public:
@@ -47,7 +47,6 @@ public:
       CounterBitmap.clear();
       VPMap.Reset();
       TPCMap.Reset();
-      VPMapBits = 0;
     }
 
     std::string DebugString() const;
@@ -59,7 +58,6 @@ public:
     std::vector<uint8_t> CounterBitmap;
     ValueBitMap TPCMap;
     ValueBitMap VPMap;
-    size_t VPMapBits;
   };
 
   Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
index 2e2d38cfb3b943849e83d426c452b18ff76baa9b..781266a4d98291788aa616917a7efaa17ad164f8 100644 (file)
@@ -105,19 +105,18 @@ bool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) {
   if (Options.UseCounters) {
     uint64_t CounterDelta =
         EF->__sanitizer_update_counter_bitset_and_clear_counters(
-            C->CounterBitmap.data()) +
-        TPC.UpdateCounterMap(&C->TPCMap);
+            C->CounterBitmap.data());
     if (CounterDelta > 0) {
       Res = true;
       C->CounterBitmapBits += CounterDelta;
     }
   }
 
-  size_t NewVPMapBits = VPMapMergeFromCurrent(C->VPMap);
-  if (NewVPMapBits > C->VPMapBits) {
+  if (TPC.UpdateCounterMap(&C->TPCMap))
+    Res = true;
+
+  if (VPMapMergeFromCurrent(C->VPMap))
     Res = true;
-    C->VPMapBits = NewVPMapBits;
-  }
 
   if (EF->__sanitizer_get_coverage_pc_buffer_pos) {
     uint64_t NewPcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos();
@@ -327,10 +326,12 @@ void Fuzzer::PrintStats(const char *Where, const char *End) {
   Printf("#%zd\t%s", TotalNumberOfRuns, Where);
   if (MaxCoverage.BlockCoverage)
     Printf(" cov: %zd", MaxCoverage.BlockCoverage);
-  if (MaxCoverage.VPMapBits)
-    Printf(" vp: %zd", MaxCoverage.VPMapBits);
+  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 (MaxCoverage.CallerCalleeCoverage)
     Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);
   Printf(" units: %zd exec/s: %zd", Corpus.size(), ExecPerSec);
@@ -479,8 +480,8 @@ std::string Fuzzer::Coverage::DebugString() const {
       std::string("Coverage{") + "BlockCoverage=" +
       std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
       std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
-      std::to_string(CounterBitmapBits) +
-      " VPMapBits " + std::to_string(VPMapBits) + "}";
+      std::to_string(CounterBitmapBits) + " VPMapBits " +
+      std::to_string(VPMap.GetNumBitsSinceLastMerge()) + "}";
   return Result;
 }
 
index 34fd5730dcc11940da677990336cf228fb4ba40b..5c038cde67fd8558c6ba98d8f7e0fa573cc5074c 100644 (file)
@@ -91,14 +91,6 @@ void TracePC::FinalizeTrace() {
   }
 }
 
-size_t TracePC::UpdateCounterMap(ValueBitMap *Map) {
-  if (!TotalCoverage) return 0;
-  size_t NewTotalCounterBits = Map->MergeFrom(CounterMap);
-  size_t Delta = NewTotalCounterBits - TotalCounterBits;
-  TotalCounterBits = NewTotalCounterBits;
-  return Delta;
-}
-
 void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {
   const uintptr_t kBits = 12;
   const uintptr_t kMask = (1 << kBits) - 1;
index e26a59f44271c7a744ba55ac23fc87777857f5dc..079f734c742f7c6dded8e9f88ab9720dafd4b1ea 100644 (file)
@@ -24,12 +24,14 @@ class TracePC {
   void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
   size_t GetTotalCoverage() { return TotalCoverage; }
   void SetUseCounters(bool UC) { UseCounters = UC; }
-  size_t UpdateCounterMap(ValueBitMap *Map);
+  bool UpdateCounterMap(ValueBitMap *MaxCounterMap) {
+    return UseCounters && MaxCounterMap->MergeFrom(CounterMap);
+  }
   void FinalizeTrace();
 
   size_t GetNewPCIDs(uintptr_t **NewPCIDsPtr) {
     *NewPCIDsPtr = NewPCIDs;
-    return NumNewPCIDs;
+    return Min(kMaxNewPCIDs, NumNewPCIDs);
   }
 
   void ResetNewPCIDs() { NumNewPCIDs = 0; }
@@ -37,7 +39,6 @@ class TracePC {
 
   void Reset() {
     TotalCoverage = 0;
-    TotalCounterBits = 0;
     NumNewPCIDs = 0;
     CounterMap.Reset();
     TotalCoverageMap.Reset();
@@ -51,7 +52,6 @@ class TracePC {
 private:
   bool UseCounters = false;
   size_t TotalCoverage = 0;
-  size_t TotalCounterBits = 0;
 
   static const size_t kMaxNewPCIDs = 64;
   uintptr_t NewPCIDs[kMaxNewPCIDs];
index 7280e3ffa53eaa9ee84e11ed6665fef97d0d8b56..902a1896d2c4b3251716c13d4ccf4ed3ec74bca6 100644 (file)
@@ -543,7 +543,7 @@ static ValueBitMap VP;
 
 void EnableValueProfile() { RecordingValueProfile = true; }
 
-size_t VPMapMergeFromCurrent(ValueBitMap &M) {
+bool VPMapMergeFromCurrent(ValueBitMap &M) {
   if (!RecordingValueProfile) return 0;
   return M.MergeFrom(VP);
 }
index 07e52fc5a542256848aeea61029219323881d2c2..fdc92189b4776da078536e30d3b76cd30af38b1c 100644 (file)
@@ -38,11 +38,14 @@ struct ValueBitMap {
     return New != Old;
   }
 
-  // Merges 'Other' into 'this', clears 'Other',
-  // returns the number of set bits in 'this'.
+  size_t GetNumBitsSinceLastMerge() const { return NumBits; }
+
+  // Merges 'Other' into 'this', clears 'Other', updates NumBits,
+  // returns true if new bits were added.
   ATTRIBUTE_TARGET_POPCNT
-  size_t MergeFrom(ValueBitMap &Other) {
+  bool MergeFrom(ValueBitMap &Other) {
     uintptr_t Res = 0;
+    size_t OldNumBits = NumBits;
     for (size_t i = 0; i < kMapSizeInWords; i++) {
       auto O = Other.Map[i];
       auto M = Map[i];
@@ -53,10 +56,12 @@ struct ValueBitMap {
       if (M)
         Res += __builtin_popcountl(M);
     }
-    return Res;
+    NumBits = Res;
+    return OldNumBits < NumBits;
   }
 
  private:
+  size_t NumBits;
   uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512)));
 };