1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00

[libFuzzer] refactoring around PCMap, NFC

llvm-svn: 278825
This commit is contained in:
Kostya Serebryany 2016-08-16 17:37:13 +00:00
parent f1fa2f71c5
commit 91340fc197
5 changed files with 81 additions and 81 deletions

View File

@ -28,7 +28,7 @@
#include "FuzzerExtFunctions.h" #include "FuzzerExtFunctions.h"
#include "FuzzerInterface.h" #include "FuzzerInterface.h"
#include "FuzzerTracePC.h" #include "FuzzerValueBitMap.h"
// Platform detection. // Platform detection.
#ifdef __linux__ #ifdef __linux__
@ -131,6 +131,9 @@ int NumberOfCpuCores();
int GetPid(); int GetPid();
void SleepSeconds(int Seconds); void SleepSeconds(int Seconds);
// See FuzzerTracePC.cpp
size_t PCMapMergeFromCurrent(ValueBitMap &M);
class Random { class Random {
public: public:
Random(unsigned int seed) : R(seed) {} Random(unsigned int seed) : R(seed) {}
@ -349,10 +352,10 @@ public:
void Reset() { void Reset() {
BlockCoverage = 0; BlockCoverage = 0;
CallerCalleeCoverage = 0; CallerCalleeCoverage = 0;
PcMapBits = 0;
CounterBitmapBits = 0; CounterBitmapBits = 0;
CounterBitmap.clear(); CounterBitmap.clear();
PCMap.Reset(); PCMap.Reset();
PCMapBits = 0;
PcBufferPos = 0; PcBufferPos = 0;
} }
@ -364,9 +367,8 @@ public:
// Precalculated number of bits in CounterBitmap. // Precalculated number of bits in CounterBitmap.
size_t CounterBitmapBits; size_t CounterBitmapBits;
std::vector<uint8_t> CounterBitmap; std::vector<uint8_t> CounterBitmap;
// Precalculated number of bits in PCMap. ValueBitMap PCMap;
size_t PcMapBits; size_t PCMapBits;
PcCoverageMap PCMap;
}; };
Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options); Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options);

View File

@ -56,7 +56,7 @@ static Fuzzer *F;
// Only one CoverageController per process should be created. // Only one CoverageController per process should be created.
class CoverageController { class CoverageController {
public: public:
explicit CoverageController(const FuzzingOptions &Options) explicit CoverageController(const FuzzingOptions &Options)
: Options(Options) { : Options(Options) {
if (Options.PrintNewCovPcs) { if (Options.PrintNewCovPcs) {
PcBufferLen = 1 << 24; PcBufferLen = 1 << 24;
@ -70,7 +70,6 @@ class CoverageController {
void Reset() { void Reset() {
CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage); CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage);
EF->__sanitizer_reset_coverage(); EF->__sanitizer_reset_coverage();
PcMapResetCurrent();
} }
void ResetCounters() { void ResetCounters() {
@ -117,10 +116,10 @@ class CoverageController {
} }
} }
uint64_t NewPcMapBits = PcMapMergeInto(&C->PCMap); size_t NewPCMapBits = PCMapMergeFromCurrent(C->PCMap);
if (NewPcMapBits > C->PcMapBits) { if (NewPCMapBits > C->PCMapBits) {
Res = true; Res = true;
C->PcMapBits = NewPcMapBits; C->PCMapBits = NewPCMapBits;
} }
if (EF->__sanitizer_get_coverage_pc_buffer_pos) { 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); Printf("#%zd\t%s", TotalNumberOfRuns, Where);
if (MaxCoverage.BlockCoverage) if (MaxCoverage.BlockCoverage)
Printf(" cov: %zd", MaxCoverage.BlockCoverage); Printf(" cov: %zd", MaxCoverage.BlockCoverage);
if (MaxCoverage.PcMapBits) if (MaxCoverage.PCMapBits)
Printf(" path: %zd", MaxCoverage.PcMapBits); Printf(" path: %zd", MaxCoverage.PCMapBits);
if (auto TB = MaxCoverage.CounterBitmapBits) if (auto TB = MaxCoverage.CounterBitmapBits)
Printf(" bits: %zd", TB); Printf(" bits: %zd", TB);
if (MaxCoverage.CallerCalleeCoverage) if (MaxCoverage.CallerCalleeCoverage)
@ -522,7 +521,7 @@ std::string Fuzzer::Coverage::DebugString() const {
std::to_string(BlockCoverage) + " CallerCalleeCoverage=" + std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" + std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
std::to_string(CounterBitmapBits) + " PcMapBits=" + std::to_string(CounterBitmapBits) + " PcMapBits=" +
std::to_string(PcMapBits) + "}"; std::to_string(PCMapBits) + "}";
return Result; return Result;
} }

View File

@ -16,43 +16,22 @@
namespace fuzzer { namespace fuzzer {
void PcCoverageMap::Reset() { memset(Map, 0, sizeof(Map)); } static size_t PreviouslyComputedPCHash;
static ValueBitMap CurrentPCMap;
void PcCoverageMap::Update(uintptr_t Addr) { // Merges CurrentPCMap into M, returns the number of new bits.
uintptr_t Idx = Addr % kMapSizeInBits; size_t PCMapMergeFromCurrent(ValueBitMap &M) {
uintptr_t WordIdx = Idx / kBitsInWord; if (!PreviouslyComputedPCHash)
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)
return 0; return 0;
return Map->MergeFrom(CurrentMap); PreviouslyComputedPCHash = 0;
return M.MergeFrom(CurrentPCMap);
} }
static void HandlePC(uint32_t PC) { static void HandlePC(uint32_t PC) {
// We take 12 bits of PC and mix it with the previous PCs. // We take 12 bits of PC and mix it with the previous PCs.
uintptr_t Next = (Prev << 5) ^ (PC & 4095); uintptr_t Next = (PreviouslyComputedPCHash << 5) ^ (PC & 4095);
CurrentMap.Update(Next); CurrentPCMap.AddValue(Next);
Prev = Next; PreviouslyComputedPCHash = Next;
} }
} // namespace fuzzer } // namespace fuzzer

View File

@ -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

View File

@ -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