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:
parent
f1fa2f71c5
commit
91340fc197
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
57
lib/Fuzzer/FuzzerValueBitMap.h
Normal file
57
lib/Fuzzer/FuzzerValueBitMap.h
Normal 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
|
Loading…
Reference in New Issue
Block a user