From: Kostya Serebryany Date: Tue, 16 Aug 2016 17:37:13 +0000 (+0000) Subject: [libFuzzer] refactoring around PCMap, NFC X-Git-Tag: llvmorg-4.0.0-rc1~12309 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c98ef718eab85e44701a23f63c1e69eb6e43cc51;p=platform%2Fupstream%2Fllvm.git [libFuzzer] refactoring around PCMap, NFC llvm-svn: 278825 --- diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h index 61f4866..db1e505 100644 --- a/llvm/lib/Fuzzer/FuzzerInternal.h +++ b/llvm/lib/Fuzzer/FuzzerInternal.h @@ -28,7 +28,7 @@ #include "FuzzerExtFunctions.h" #include "FuzzerInterface.h" -#include "FuzzerTracePC.h" +#include "FuzzerValueBitMap.h" // Platform detection. #ifdef __linux__ @@ -131,6 +131,9 @@ int NumberOfCpuCores(); int GetPid(); void SleepSeconds(int Seconds); +// See FuzzerTracePC.cpp +size_t PCMapMergeFromCurrent(ValueBitMap &M); + class Random { public: Random(unsigned int seed) : R(seed) {} @@ -349,10 +352,10 @@ public: void Reset() { BlockCoverage = 0; CallerCalleeCoverage = 0; - PcMapBits = 0; CounterBitmapBits = 0; CounterBitmap.clear(); PCMap.Reset(); + PCMapBits = 0; PcBufferPos = 0; } @@ -364,9 +367,8 @@ public: // Precalculated number of bits in CounterBitmap. size_t CounterBitmapBits; std::vector CounterBitmap; - // Precalculated number of bits in PCMap. - size_t PcMapBits; - PcCoverageMap PCMap; + ValueBitMap PCMap; + size_t PCMapBits; }; Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options); diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index db8868c..f90b709 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -56,7 +56,7 @@ static Fuzzer *F; // Only one CoverageController per process should be created. class CoverageController { public: - explicit CoverageController(const FuzzingOptions &Options) + explicit CoverageController(const FuzzingOptions &Options) : Options(Options) { if (Options.PrintNewCovPcs) { PcBufferLen = 1 << 24; @@ -70,7 +70,6 @@ class CoverageController { void Reset() { CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage); EF->__sanitizer_reset_coverage(); - PcMapResetCurrent(); } void ResetCounters() { @@ -117,10 +116,10 @@ class CoverageController { } } - uint64_t NewPcMapBits = PcMapMergeInto(&C->PCMap); - if (NewPcMapBits > C->PcMapBits) { + size_t NewPCMapBits = PCMapMergeFromCurrent(C->PCMap); + if (NewPCMapBits > C->PCMapBits) { Res = true; - C->PcMapBits = NewPcMapBits; + C->PCMapBits = NewPCMapBits; } if (EF->__sanitizer_get_coverage_pc_buffer_pos) { @@ -306,8 +305,8 @@ 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.PcMapBits) - Printf(" path: %zd", MaxCoverage.PcMapBits); + if (MaxCoverage.PCMapBits) + Printf(" path: %zd", MaxCoverage.PCMapBits); if (auto TB = MaxCoverage.CounterBitmapBits) Printf(" bits: %zd", TB); if (MaxCoverage.CallerCalleeCoverage) @@ -522,7 +521,7 @@ std::string Fuzzer::Coverage::DebugString() const { std::to_string(BlockCoverage) + " CallerCalleeCoverage=" + std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" + std::to_string(CounterBitmapBits) + " PcMapBits=" + - std::to_string(PcMapBits) + "}"; + std::to_string(PCMapBits) + "}"; return Result; } diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp index 46c43d0..53341d3 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp +++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp @@ -16,43 +16,22 @@ namespace fuzzer { -void PcCoverageMap::Reset() { memset(Map, 0, sizeof(Map)); } +static size_t PreviouslyComputedPCHash; +static ValueBitMap CurrentPCMap; -void PcCoverageMap::Update(uintptr_t Addr) { - uintptr_t Idx = Addr % kMapSizeInBits; - uintptr_t WordIdx = Idx / kBitsInWord; - uintptr_t BitIdx = Idx % kBitsInWord; - Map[WordIdx] |= 1UL << BitIdx; -} - -size_t PcCoverageMap::MergeFrom(const PcCoverageMap &Other) { - uintptr_t Res = 0; - for (size_t i = 0; i < kMapSizeInWords; i++) - Res += __builtin_popcountl(Map[i] |= Other.Map[i]); - return Res; -} - -static PcCoverageMap CurrentMap; -static thread_local uintptr_t Prev; - -void PcMapResetCurrent() { - if (Prev) { - Prev = 0; - CurrentMap.Reset(); - } -} - -size_t PcMapMergeInto(PcCoverageMap *Map) { - if (!Prev) +// Merges CurrentPCMap into M, returns the number of new bits. +size_t PCMapMergeFromCurrent(ValueBitMap &M) { + if (!PreviouslyComputedPCHash) return 0; - return Map->MergeFrom(CurrentMap); + PreviouslyComputedPCHash = 0; + return M.MergeFrom(CurrentPCMap); } static void HandlePC(uint32_t PC) { // We take 12 bits of PC and mix it with the previous PCs. - uintptr_t Next = (Prev << 5) ^ (PC & 4095); - CurrentMap.Update(Next); - Prev = Next; + uintptr_t Next = (PreviouslyComputedPCHash << 5) ^ (PC & 4095); + CurrentPCMap.AddValue(Next); + PreviouslyComputedPCHash = Next; } } // namespace fuzzer diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.h b/llvm/lib/Fuzzer/FuzzerTracePC.h deleted file mode 100644 index 47280ba..0000000 --- a/llvm/lib/Fuzzer/FuzzerTracePC.h +++ /dev/null @@ -1,37 +0,0 @@ -//===- FuzzerTracePC.h - INTERNAL - Path tracer. --------*- C++ -* ===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Trace PCs. -// This module implements __sanitizer_cov_trace_pc, a callback required -// for -fsanitize-coverage=trace-pc instrumentation. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_FUZZER_TRACE_PC_H -#define LLVM_FUZZER_TRACE_PC_H - -namespace fuzzer { -struct PcCoverageMap { - static const size_t kMapSizeInBits = 65371; // Prime. - static const size_t kMapSizeInBitsAligned = 65536; // 2^16 - static const size_t kBitsInWord = (sizeof(uintptr_t) * 8); - static const size_t kMapSizeInWords = kMapSizeInBitsAligned / kBitsInWord; - - void Reset(); - inline void Update(uintptr_t Addr); - size_t MergeFrom(const PcCoverageMap &Other); - - uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512))); -}; - -// Clears the current PC Map. -void PcMapResetCurrent(); -// Merges the current PC Map into the combined one, and clears the former. -size_t PcMapMergeInto(PcCoverageMap *Map); -} - -#endif diff --git a/llvm/lib/Fuzzer/FuzzerValueBitMap.h b/llvm/lib/Fuzzer/FuzzerValueBitMap.h new file mode 100644 index 0000000..41169d6 --- /dev/null +++ b/llvm/lib/Fuzzer/FuzzerValueBitMap.h @@ -0,0 +1,57 @@ +//===- FuzzerValueBitMap.h - INTERNAL - Bit map -----------------*- C++ -* ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// ValueBitMap. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_FUZZER_VALUE_BIT_MAP_H +#define LLVM_FUZZER_VALUE_BIT_MAP_H + +namespace fuzzer { + +// A bit map containing kMapSizeInWords bits. +struct ValueBitMap { + static const size_t kMapSizeInBits = 65371; // Prime. + static const size_t kMapSizeInBitsAligned = 65536; // 2^16 + static const size_t kBitsInWord = (sizeof(uintptr_t) * 8); + static const size_t kMapSizeInWords = kMapSizeInBitsAligned / kBitsInWord; + public: + // Clears all bits. + void Reset() { memset(Map, 0, sizeof(Map)); } + + // Computed a hash function of Value and sets the corresponding bit. + void AddValue(uintptr_t Value) { + uintptr_t Idx = Value % kMapSizeInBits; + uintptr_t WordIdx = Idx / kBitsInWord; + uintptr_t BitIdx = Idx % kBitsInWord; + Map[WordIdx] |= 1UL << BitIdx; + } + + // Merges 'Other' into 'this', clear Other, + // returns the number of set bits in 'this'. + size_t MergeFrom(ValueBitMap &Other) { + uintptr_t Res = 0; + for (size_t i = 0; i < kMapSizeInWords; i++) { + auto O = Other.Map[i]; + auto M = Map[i]; + if (O) { + Map[i] = (M |= O); + Other.Map[i] = 0; + } + Res += __builtin_popcountl(M); + } + return Res; + } + + private: + uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512))); +}; + +} // namespace fuzzer + +#endif // LLVM_FUZZER_VALUE_BIT_MAP_H