int GetPid();
void SleepSeconds(int Seconds);
-// See FuzzerTracePC.cpp
-size_t PCMapMergeFromCurrent(ValueBitMap &M);
-
// See FuzzerTraceState.cpp
void EnableValueProfile();
size_t VPMapMergeFromCurrent(ValueBitMap &M);
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 {
public:
CallerCalleeCoverage = 0;
CounterBitmapBits = 0;
CounterBitmap.clear();
- PCMap.Reset();
- PCMapBits = 0;
VPMap.Reset();
VPMapBits = 0;
}
// Precalculated number of bits in CounterBitmap.
size_t CounterBitmapBits;
std::vector<uint8_t> CounterBitmap;
- ValueBitMap PCMap;
- size_t PCMapBits;
ValueBitMap VPMap;
size_t VPMapBits;
};
bool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) {
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) {
Res = true;
C->BlockCoverage = NewBlockCoverage;
}
}
- size_t NewPCMapBits = PCMapMergeFromCurrent(C->PCMap);
- if (NewPCMapBits > C->PCMapBits) {
- Res = true;
- C->PCMapBits = NewPCMapBits;
- }
-
size_t NewVPMapBits = VPMapMergeFromCurrent(C->VPMap);
if (NewVPMapBits > C->VPMapBits) {
Res = true;
Printf("#%zd\t%s", TotalNumberOfRuns, Where);
if (MaxCoverage.BlockCoverage)
Printf(" cov: %zd", MaxCoverage.BlockCoverage);
- if (MaxCoverage.PCMapBits)
- Printf(" path: %zd", MaxCoverage.PCMapBits);
if (MaxCoverage.VPMapBits)
Printf(" vp: %zd", MaxCoverage.VPMapBits);
if (auto TB = MaxCoverage.CounterBitmapBits)
std::string("Coverage{") + "BlockCoverage=" +
std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
- std::to_string(CounterBitmapBits) + " PCMapBits=" +
- std::to_string(PCMapBits) + " VPMapBits " +
- std::to_string(VPMapBits) + "}";
+ std::to_string(CounterBitmapBits) +
+ " VPMapBits " + std::to_string(VPMapBits) + "}";
return Result;
}
//
//===----------------------------------------------------------------------===//
// Trace PCs.
-// This module implements __sanitizer_cov_trace_pc, a callback required
-// for -fsanitize-coverage=trace-pc instrumentation.
+// This module implements __sanitizer_cov_trace_pc_guard[_init],
+// the callback required for -fsanitize-coverage=trace-pc-guard instrumentation.
//
//===----------------------------------------------------------------------===//
namespace fuzzer {
-static size_t PreviouslyComputedPCHash;
-static ValueBitMap CurrentPCMap;
+TracePC TPC;
-// Merges CurrentPCMap into M, returns the number of new bits.
-size_t PCMapMergeFromCurrent(ValueBitMap &M) {
- if (!PreviouslyComputedPCHash)
- return 0;
- PreviouslyComputedPCHash = 0;
- return M.MergeFrom(CurrentPCMap);
+void TracePC::HandleTrace(uint8_t *guard, uintptr_t PC) {
+ *guard = 0xff;
+ TotalCoverage++;
}
-
-static void HandlePC(uint32_t PC) {
- // 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;
+void TracePC::HandleInit(uint8_t *start, uint8_t *stop) {
+ Printf("INFO: guards: [%p,%p)\n", start, stop);
}
+size_t TracePC::GetTotalCoverage() { return TotalCoverage; }
} // namespace fuzzer
extern "C" {
__attribute__((visibility("default")))
-void __sanitizer_cov_trace_pc() {
- fuzzer::HandlePC(static_cast<uint32_t>(
- reinterpret_cast<uintptr_t>(__builtin_return_address(0))));
+void __sanitizer_cov_trace_pc_guard(uint8_t *guard) {
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ fuzzer::TPC.HandleTrace(guard, PC);
}
__attribute__((visibility("default")))
-void __sanitizer_cov_trace_pc_indir(int *) {
- // Stub to allow linking with code built with
- // -fsanitize=indirect-calls,trace-pc.
- // This isn't used currently.
+void __sanitizer_cov_trace_pc_guard_init(uint8_t *start, uint8_t *stop) {
}
}
+++ /dev/null
-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
Done1000000: Done 1000000 runs in
RUN: LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-SimpleTest-TracePC 2>&1 | FileCheck %s
# only_ascii mode. Will perform some minimal self-validation.
RUN: LLVMFuzzer-SimpleTest -only_ascii=1 2>&1
# These tests are not instrumented with coverage.
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
- FourIndependentBranchesTest
- FullCoverageSetTest
+ SimpleTest
)
foreach(Test ${TracePCTests})