[libFuzzer] refactoring around PCMap, NFC

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

View File

@ -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<uint8_t> CounterBitmap;
// Precalculated number of bits in PCMap.
size_t PcMapBits;
PcCoverageMap PCMap;
ValueBitMap PCMap;
size_t PCMapBits;
};
Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options);

View File

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

View File

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

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