From d28099de5db44eb3f9f115ab60a11d9d4f9f0ecf Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Fri, 23 Sep 2016 00:22:46 +0000 Subject: [PATCH] [libFuzzer] change ValueBitMap to remember the number of bits in it llvm-svn: 282216 --- llvm/lib/Fuzzer/FuzzerDefs.h | 3 +++ llvm/lib/Fuzzer/FuzzerInternal.h | 4 +--- llvm/lib/Fuzzer/FuzzerLoop.cpp | 21 +++++++++++---------- llvm/lib/Fuzzer/FuzzerTracePC.cpp | 8 -------- llvm/lib/Fuzzer/FuzzerTracePC.h | 8 ++++---- llvm/lib/Fuzzer/FuzzerTraceState.cpp | 2 +- llvm/lib/Fuzzer/FuzzerValueBitMap.h | 13 +++++++++---- 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/llvm/lib/Fuzzer/FuzzerDefs.h b/llvm/lib/Fuzzer/FuzzerDefs.h index 79a6f0111cbd..4c60572ab4c0 100644 --- a/llvm/lib/Fuzzer/FuzzerDefs.h +++ b/llvm/lib/Fuzzer/FuzzerDefs.h @@ -37,6 +37,9 @@ namespace fuzzer { +template T Min(T a, T b) { return a < b ? a : b; } +template T Max(T a, T b) { return a > b ? a : b; } + class Random; class Dictionary; class DictionaryEntry; diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h index 7c92ac84fa00..12a160d22960 100644 --- a/llvm/lib/Fuzzer/FuzzerInternal.h +++ b/llvm/lib/Fuzzer/FuzzerInternal.h @@ -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 CounterBitmap; ValueBitMap TPCMap; ValueBitMap VPMap; - size_t VPMapBits; }; Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD, diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 2e2d38cfb3b9..781266a4d982 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -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; } diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp index 34fd5730dcc1..5c038cde67fd 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp +++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp @@ -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; diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.h b/llvm/lib/Fuzzer/FuzzerTracePC.h index e26a59f44271..079f734c742f 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.h +++ b/llvm/lib/Fuzzer/FuzzerTracePC.h @@ -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]; diff --git a/llvm/lib/Fuzzer/FuzzerTraceState.cpp b/llvm/lib/Fuzzer/FuzzerTraceState.cpp index 7280e3ffa53e..902a1896d2c4 100644 --- a/llvm/lib/Fuzzer/FuzzerTraceState.cpp +++ b/llvm/lib/Fuzzer/FuzzerTraceState.cpp @@ -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); } diff --git a/llvm/lib/Fuzzer/FuzzerValueBitMap.h b/llvm/lib/Fuzzer/FuzzerValueBitMap.h index 07e52fc5a542..fdc92189b477 100644 --- a/llvm/lib/Fuzzer/FuzzerValueBitMap.h +++ b/llvm/lib/Fuzzer/FuzzerValueBitMap.h @@ -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))); };