mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-22 04:22:57 +02:00
[libFuzzer] implement print_pcs with trace-pc-guard. Change the trace-pc-guard heuristic for 8-bit counters to look more like in AFL (not that it's provable better, but the existin test preferes this heuristic)
llvm-svn: 281577
This commit is contained in:
parent
a0a4cc32ae
commit
a166497232
@ -365,13 +365,27 @@ class TracePC {
|
|||||||
size_t UpdateCounterMap(ValueBitMap *Map);
|
size_t UpdateCounterMap(ValueBitMap *Map);
|
||||||
void FinalizeTrace();
|
void FinalizeTrace();
|
||||||
|
|
||||||
|
size_t GetNewPCsAndFlush(uintptr_t **NewPCsPtr = nullptr) {
|
||||||
|
if (NewPCsPtr)
|
||||||
|
*NewPCsPtr = NewPCs;
|
||||||
|
size_t Res = NumNewPCs;
|
||||||
|
NumNewPCs = 0;
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool UseCounters = false;
|
bool UseCounters = false;
|
||||||
size_t TotalCoverage = 0;
|
size_t TotalCoverage = 0;
|
||||||
size_t TotalCounterBits = 0;
|
size_t TotalCounterBits = 0;
|
||||||
|
|
||||||
|
static const size_t kMaxNewPCs = 64;
|
||||||
|
uintptr_t NewPCs[kMaxNewPCs];
|
||||||
|
size_t NumNewPCs = 0;
|
||||||
|
void AddNewPC(uintptr_t PC) { NewPCs[(NumNewPCs++) % kMaxNewPCs] = PC; }
|
||||||
|
|
||||||
uint8_t *Start, *Stop;
|
uint8_t *Start, *Stop;
|
||||||
ValueBitMap CounterMap;
|
ValueBitMap CounterMap;
|
||||||
|
ValueBitMap TotalCoverageMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TracePC TPC;
|
extern TracePC TPC;
|
||||||
@ -469,6 +483,7 @@ private:
|
|||||||
void MutateAndTestOne();
|
void MutateAndTestOne();
|
||||||
void ReportNewCoverage(const Unit &U);
|
void ReportNewCoverage(const Unit &U);
|
||||||
void PrintNewPCs();
|
void PrintNewPCs();
|
||||||
|
void PrintOneNewPC(uintptr_t PC);
|
||||||
bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
|
bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
|
||||||
void RunOneAndUpdateCorpus(const uint8_t *Data, size_t Size);
|
void RunOneAndUpdateCorpus(const uint8_t *Data, size_t Size);
|
||||||
void WriteToOutputCorpus(const Unit &U);
|
void WriteToOutputCorpus(const Unit &U);
|
||||||
|
@ -63,6 +63,7 @@ void Fuzzer::ResetCounters() {
|
|||||||
}
|
}
|
||||||
if (EF->__sanitizer_get_coverage_pc_buffer_pos)
|
if (EF->__sanitizer_get_coverage_pc_buffer_pos)
|
||||||
PcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos();
|
PcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos();
|
||||||
|
TPC.GetNewPCsAndFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fuzzer::PrepareCounters(Fuzzer::Coverage *C) {
|
void Fuzzer::PrepareCounters(Fuzzer::Coverage *C) {
|
||||||
@ -556,22 +557,31 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fuzzer::PrintNewPCs() {
|
void Fuzzer::PrintOneNewPC(uintptr_t PC) {
|
||||||
if (Options.PrintNewCovPcs && PrevPcBufferPos != PcBufferPos) {
|
|
||||||
int NumPrinted = 0;
|
|
||||||
for (size_t I = PrevPcBufferPos; I < PcBufferPos; ++I) {
|
|
||||||
if (NumPrinted++ > 30) break; // Don't print too many new PCs.
|
|
||||||
if (EF->__sanitizer_symbolize_pc) {
|
if (EF->__sanitizer_symbolize_pc) {
|
||||||
char PcDescr[1024];
|
char PcDescr[1024];
|
||||||
EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PcBuffer[I]),
|
EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PC),
|
||||||
"%p %F %L", PcDescr, sizeof(PcDescr));
|
"%p %F %L", PcDescr, sizeof(PcDescr));
|
||||||
PcDescr[sizeof(PcDescr) - 1] = 0; // Just in case.
|
PcDescr[sizeof(PcDescr) - 1] = 0; // Just in case.
|
||||||
Printf("\tNEW_PC: %s\n", PcDescr);
|
Printf("\tNEW_PC: %s\n", PcDescr);
|
||||||
} else {
|
} else {
|
||||||
Printf("\tNEW_PC: %p\n", PcBuffer[I]);
|
Printf("\tNEW_PC: %p\n", PC);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fuzzer::PrintNewPCs() {
|
||||||
|
if (!Options.PrintNewCovPcs) return;
|
||||||
|
if (PrevPcBufferPos != PcBufferPos) {
|
||||||
|
int NumPrinted = 0;
|
||||||
|
for (size_t I = PrevPcBufferPos; I < PcBufferPos; ++I) {
|
||||||
|
if (NumPrinted++ > 30) break; // Don't print too many new PCs.
|
||||||
|
PrintOneNewPC(PcBuffer[I]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uintptr_t *PCs;
|
||||||
|
if (size_t NumNewPCs = TPC.GetNewPCsAndFlush(&PCs))
|
||||||
|
for (size_t i = 0; i < NumNewPCs; i++)
|
||||||
|
PrintOneNewPC(PCs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fuzzer::ReportNewCoverage(const Unit &U) {
|
void Fuzzer::ReportNewCoverage(const Unit &U) {
|
||||||
|
@ -21,14 +21,20 @@ TracePC TPC;
|
|||||||
void TracePC::HandleTrace(uint8_t *Guard, uintptr_t PC) {
|
void TracePC::HandleTrace(uint8_t *Guard, uintptr_t PC) {
|
||||||
if (UseCounters) {
|
if (UseCounters) {
|
||||||
uintptr_t GV = *Guard;
|
uintptr_t GV = *Guard;
|
||||||
if (GV == 0)
|
if (GV == 0) {
|
||||||
|
size_t Idx = Guard - Start;
|
||||||
|
if (TotalCoverageMap.AddValue(Idx)) {
|
||||||
TotalCoverage++;
|
TotalCoverage++;
|
||||||
|
AddNewPC(PC);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (GV < 255)
|
if (GV < 255)
|
||||||
GV++;
|
GV++;
|
||||||
*Guard = GV;
|
*Guard = GV;
|
||||||
} else {
|
} else {
|
||||||
*Guard = 0xff;
|
*Guard = 0xff;
|
||||||
TotalCoverage++;
|
TotalCoverage++;
|
||||||
|
AddNewPC(PC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,12 +49,18 @@ void TracePC::FinalizeTrace() {
|
|||||||
for (uint8_t *X = Start; X < Stop; X++) {
|
for (uint8_t *X = Start; X < Stop; X++) {
|
||||||
uint8_t Value = *X;
|
uint8_t Value = *X;
|
||||||
size_t Idx = X - Start;
|
size_t Idx = X - Start;
|
||||||
if (Value >= 2) {
|
if (Value >= 1) {
|
||||||
unsigned Bit = 31 - __builtin_clz(Value);
|
unsigned Bit = 0;
|
||||||
assert(Bit < 8);
|
/**/ if (Value >= 128) Bit = 7;
|
||||||
|
else if (Value >= 32) Bit = 6;
|
||||||
|
else if (Value >= 16) Bit = 5;
|
||||||
|
else if (Value >= 8) Bit = 4;
|
||||||
|
else if (Value >= 4) Bit = 3;
|
||||||
|
else if (Value >= 3) Bit = 2;
|
||||||
|
else if (Value >= 2) Bit = 1;
|
||||||
CounterMap.AddValue(Idx * 8 + Bit);
|
CounterMap.AddValue(Idx * 8 + Bit);
|
||||||
}
|
}
|
||||||
*X = 1;
|
*X = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,16 @@ struct ValueBitMap {
|
|||||||
// Clears all bits.
|
// Clears all bits.
|
||||||
void Reset() { memset(Map, 0, sizeof(Map)); }
|
void Reset() { memset(Map, 0, sizeof(Map)); }
|
||||||
|
|
||||||
// Computed a hash function of Value and sets the corresponding bit.
|
// Computes a hash function of Value and sets the corresponding bit.
|
||||||
inline void AddValue(uintptr_t Value) {
|
// Returns true if the bit was changed from 0 to 1.
|
||||||
|
inline bool AddValue(uintptr_t Value) {
|
||||||
uintptr_t Idx = Value < kMapSizeInBits ? Value : Value % kMapSizeInBits;
|
uintptr_t Idx = Value < kMapSizeInBits ? Value : Value % kMapSizeInBits;
|
||||||
uintptr_t WordIdx = Idx / kBitsInWord;
|
uintptr_t WordIdx = Idx / kBitsInWord;
|
||||||
uintptr_t BitIdx = Idx % kBitsInWord;
|
uintptr_t BitIdx = Idx % kBitsInWord;
|
||||||
Map[WordIdx] |= 1UL << BitIdx;
|
uintptr_t Old = Map[WordIdx];
|
||||||
|
uintptr_t New = Old | (1UL << BitIdx);
|
||||||
|
Map[WordIdx] = New;
|
||||||
|
return New != Old;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merges 'Other' into 'this', clears 'Other',
|
// Merges 'Other' into 'this', clears 'Other',
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
RUN: LLVMFuzzer-SimpleTest -print_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
|
RUN: LLVMFuzzer-SimpleTest -print_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
|
||||||
|
RUN: LLVMFuzzer-SimpleTest-TracePC -print_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
|
||||||
PCS-NOT: NEW_PC
|
PCS-NOT: NEW_PC
|
||||||
PCS:INITED
|
PCS:INITED
|
||||||
PCS:NEW_PC: {{0x[a-f0-9]+}}
|
PCS:NEW_PC: {{0x[a-f0-9]+}}
|
||||||
|
PCS:NEW_PC: {{0x[a-f0-9]+}}
|
||||||
PCS:NEW
|
PCS:NEW
|
||||||
PCS:BINGO
|
PCS:BINGO
|
||||||
|
|
||||||
|
RUN: LLVMFuzzer-CounterTest-TracePC -use_counters=0 -print_pcs=1 -runs=10000 2>&1 | FileCheck %s --check-prefix=C_PCS
|
||||||
|
RUN: LLVMFuzzer-CounterTest-TracePC -use_counters=1 -print_pcs=1 -runs=10000 2>&1 | FileCheck %s --check-prefix=C_PCS
|
||||||
|
|
||||||
|
C_PCS: NEW_PC: {{.*}} in LLVMFuzzerTestOneInput {{.*}}CounterTest.cpp:11
|
||||||
|
C_PCS: NEW_PC: {{.*}} in LLVMFuzzerTestOneInput {{.*}}CounterTest.cpp:12
|
||||||
|
Loading…
Reference in New Issue
Block a user