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