mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[libFuzzer] start using trace-pc-guard as an alternative source of coverage
llvm-svn: 281435
This commit is contained in:
parent
562a9d7d62
commit
41b41f51a8
@ -137,9 +137,6 @@ int NumberOfCpuCores();
|
|||||||
int GetPid();
|
int GetPid();
|
||||||
void SleepSeconds(int Seconds);
|
void SleepSeconds(int Seconds);
|
||||||
|
|
||||||
// See FuzzerTracePC.cpp
|
|
||||||
size_t PCMapMergeFromCurrent(ValueBitMap &M);
|
|
||||||
|
|
||||||
// See FuzzerTraceState.cpp
|
// See FuzzerTraceState.cpp
|
||||||
void EnableValueProfile();
|
void EnableValueProfile();
|
||||||
size_t VPMapMergeFromCurrent(ValueBitMap &M);
|
size_t VPMapMergeFromCurrent(ValueBitMap &M);
|
||||||
@ -358,6 +355,18 @@ private:
|
|||||||
std::vector<Mutator> DefaultMutators;
|
std::vector<Mutator> DefaultMutators;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// See TracePC.cpp
|
||||||
|
class TracePC {
|
||||||
|
public:
|
||||||
|
void HandleTrace(uint8_t *guard, uintptr_t PC);
|
||||||
|
void HandleInit(uint8_t *start, uint8_t *stop);
|
||||||
|
size_t GetTotalCoverage();
|
||||||
|
private:
|
||||||
|
size_t TotalCoverage = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TracePC TPC;
|
||||||
|
|
||||||
class Fuzzer {
|
class Fuzzer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -370,8 +379,6 @@ public:
|
|||||||
CallerCalleeCoverage = 0;
|
CallerCalleeCoverage = 0;
|
||||||
CounterBitmapBits = 0;
|
CounterBitmapBits = 0;
|
||||||
CounterBitmap.clear();
|
CounterBitmap.clear();
|
||||||
PCMap.Reset();
|
|
||||||
PCMapBits = 0;
|
|
||||||
VPMap.Reset();
|
VPMap.Reset();
|
||||||
VPMapBits = 0;
|
VPMapBits = 0;
|
||||||
}
|
}
|
||||||
@ -383,8 +390,6 @@ 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;
|
||||||
ValueBitMap PCMap;
|
|
||||||
size_t PCMapBits;
|
|
||||||
ValueBitMap VPMap;
|
ValueBitMap VPMap;
|
||||||
size_t VPMapBits;
|
size_t VPMapBits;
|
||||||
};
|
};
|
||||||
|
@ -77,7 +77,8 @@ void Fuzzer::PrepareCounters(Fuzzer::Coverage *C) {
|
|||||||
bool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) {
|
bool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) {
|
||||||
bool Res = false;
|
bool Res = false;
|
||||||
|
|
||||||
uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();
|
uint64_t NewBlockCoverage =
|
||||||
|
EF->__sanitizer_get_total_unique_coverage() + TPC.GetTotalCoverage();
|
||||||
if (NewBlockCoverage > C->BlockCoverage) {
|
if (NewBlockCoverage > C->BlockCoverage) {
|
||||||
Res = true;
|
Res = true;
|
||||||
C->BlockCoverage = NewBlockCoverage;
|
C->BlockCoverage = NewBlockCoverage;
|
||||||
@ -103,12 +104,6 @@ bool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t NewPCMapBits = PCMapMergeFromCurrent(C->PCMap);
|
|
||||||
if (NewPCMapBits > C->PCMapBits) {
|
|
||||||
Res = true;
|
|
||||||
C->PCMapBits = NewPCMapBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t NewVPMapBits = VPMapMergeFromCurrent(C->VPMap);
|
size_t NewVPMapBits = VPMapMergeFromCurrent(C->VPMap);
|
||||||
if (NewVPMapBits > C->VPMapBits) {
|
if (NewVPMapBits > C->VPMapBits) {
|
||||||
Res = true;
|
Res = true;
|
||||||
@ -315,8 +310,6 @@ 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)
|
|
||||||
Printf(" path: %zd", MaxCoverage.PCMapBits);
|
|
||||||
if (MaxCoverage.VPMapBits)
|
if (MaxCoverage.VPMapBits)
|
||||||
Printf(" vp: %zd", MaxCoverage.VPMapBits);
|
Printf(" vp: %zd", MaxCoverage.VPMapBits);
|
||||||
if (auto TB = MaxCoverage.CounterBitmapBits)
|
if (auto TB = MaxCoverage.CounterBitmapBits)
|
||||||
@ -508,9 +501,8 @@ std::string Fuzzer::Coverage::DebugString() const {
|
|||||||
std::string("Coverage{") + "BlockCoverage=" +
|
std::string("Coverage{") + "BlockCoverage=" +
|
||||||
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) +
|
||||||
std::to_string(PCMapBits) + " VPMapBits " +
|
" VPMapBits " + std::to_string(VPMapBits) + "}";
|
||||||
std::to_string(VPMapBits) + "}";
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Trace PCs.
|
// Trace PCs.
|
||||||
// This module implements __sanitizer_cov_trace_pc, a callback required
|
// This module implements __sanitizer_cov_trace_pc_guard[_init],
|
||||||
// for -fsanitize-coverage=trace-pc instrumentation.
|
// the callback required for -fsanitize-coverage=trace-pc-guard instrumentation.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@ -16,37 +16,27 @@
|
|||||||
|
|
||||||
namespace fuzzer {
|
namespace fuzzer {
|
||||||
|
|
||||||
static size_t PreviouslyComputedPCHash;
|
TracePC TPC;
|
||||||
static ValueBitMap CurrentPCMap;
|
|
||||||
|
|
||||||
// Merges CurrentPCMap into M, returns the number of new bits.
|
void TracePC::HandleTrace(uint8_t *guard, uintptr_t PC) {
|
||||||
size_t PCMapMergeFromCurrent(ValueBitMap &M) {
|
*guard = 0xff;
|
||||||
if (!PreviouslyComputedPCHash)
|
TotalCoverage++;
|
||||||
return 0;
|
|
||||||
PreviouslyComputedPCHash = 0;
|
|
||||||
return M.MergeFrom(CurrentPCMap);
|
|
||||||
}
|
}
|
||||||
|
void TracePC::HandleInit(uint8_t *start, uint8_t *stop) {
|
||||||
static void HandlePC(uint32_t PC) {
|
Printf("INFO: guards: [%p,%p)\n", start, stop);
|
||||||
// We take 12 bits of PC and mix it with the previous PCs.
|
|
||||||
uintptr_t Next = (PreviouslyComputedPCHash << 5) ^ (PC & 4095);
|
|
||||||
CurrentPCMap.AddValue(Next);
|
|
||||||
PreviouslyComputedPCHash = Next;
|
|
||||||
}
|
}
|
||||||
|
size_t TracePC::GetTotalCoverage() { return TotalCoverage; }
|
||||||
|
|
||||||
} // namespace fuzzer
|
} // namespace fuzzer
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
void __sanitizer_cov_trace_pc() {
|
void __sanitizer_cov_trace_pc_guard(uint8_t *guard) {
|
||||||
fuzzer::HandlePC(static_cast<uint32_t>(
|
uintptr_t PC = (uintptr_t)__builtin_return_address(0);
|
||||||
reinterpret_cast<uintptr_t>(__builtin_return_address(0))));
|
fuzzer::TPC.HandleTrace(guard, PC);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
void __sanitizer_cov_trace_pc_indir(int *) {
|
void __sanitizer_cov_trace_pc_guard_init(uint8_t *start, uint8_t *stop) {
|
||||||
// Stub to allow linking with code built with
|
|
||||||
// -fsanitize=indirect-calls,trace-pc.
|
|
||||||
// This isn't used currently.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
CHECK: BINGO
|
|
||||||
REQUIRES: linux
|
|
||||||
RUN: not LLVMFuzzer-FourIndependentBranchesTest-TracePC -seed=1 -runs=1000000 2>&1 | FileCheck %s
|
|
||||||
// FIXME: The test below uses a significant amount of memory on OSX and
|
|
||||||
// sometimes hits the 2GiB memory limit. This needs to be investigated. For now
|
|
||||||
// only run the test on Linux.
|
|
||||||
RUN: not LLVMFuzzer-FullCoverageSetTest-TracePC -seed=1 -runs=10000000 2>&1 | FileCheck %s
|
|
@ -2,6 +2,7 @@ CHECK: BINGO
|
|||||||
Done1000000: Done 1000000 runs in
|
Done1000000: Done 1000000 runs in
|
||||||
|
|
||||||
RUN: LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s
|
RUN: LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s
|
||||||
|
RUN: LLVMFuzzer-SimpleTest-TracePC 2>&1 | FileCheck %s
|
||||||
|
|
||||||
# only_ascii mode. Will perform some minimal self-validation.
|
# only_ascii mode. Will perform some minimal self-validation.
|
||||||
RUN: LLVMFuzzer-SimpleTest -only_ascii=1 2>&1
|
RUN: LLVMFuzzer-SimpleTest -only_ascii=1 2>&1
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
# These tests are not instrumented with coverage.
|
# These tests are not instrumented with coverage.
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
"${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=8bit-counters -fsanitize-coverage=trace-pc")
|
"${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=8bit-counters -fsanitize-coverage=trace-pc-guard")
|
||||||
|
|
||||||
set(TracePCTests
|
set(TracePCTests
|
||||||
FourIndependentBranchesTest
|
SimpleTest
|
||||||
FullCoverageSetTest
|
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(Test ${TracePCTests})
|
foreach(Test ${TracePCTests})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user