From 68382d0900d9aa2f126d9e38463e6006607f55b8 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Thu, 2 Feb 2017 19:56:01 +0000 Subject: [PATCH] [libFuzzer] reorganize the tracing code to make it easier to experiment with inlined coverage instrumentation. NFC llvm-svn: 293928 --- llvm/lib/Fuzzer/FuzzerTracePC.cpp | 44 +++++++++++++++++++++---------- llvm/lib/Fuzzer/FuzzerTracePC.h | 11 ++++---- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp index 9981fc3459dc..e7cd8610fe4c 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp +++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp @@ -24,21 +24,36 @@ #include #include +// The coverage counters and PCs. +// These are declared as global variables named "__sancov_*" to simplify +// experiments with inlined instrumentation. +alignas(8) uint8_t + __sancov_trace_pc_guard_8bit_counters[fuzzer::TracePC::kNumPCs]; +uintptr_t __sancov_trace_pc_pcs[fuzzer::TracePC::kNumPCs]; + namespace fuzzer { TracePC TPC; +uint8_t *TracePC::Counters() const { + return __sancov_trace_pc_guard_8bit_counters; +} + +uintptr_t *TracePC::PCs() const { + return __sancov_trace_pc_pcs; +} + ATTRIBUTE_NO_SANITIZE_ALL void TracePC::HandleTrace(uint32_t *Guard, uintptr_t PC) { uint32_t Idx = *Guard; - PCs[Idx] = PC; - Counters[Idx]++; + __sancov_trace_pc_pcs[Idx] = PC; + __sancov_trace_pc_guard_8bit_counters[Idx]++; } size_t TracePC::GetTotalPCCoverage() { size_t Res = 0; for (size_t i = 1, N = GetNumPCs(); i < N; i++) - if (PCs[i]) + if (PCs()[i]) Res++; return Res; } @@ -81,16 +96,16 @@ void TracePC::InitializePrintNewPCs() { assert(!PrintedPCs); PrintedPCs = new std::set; for (size_t i = 1; i < GetNumPCs(); i++) - if (PCs[i]) - PrintedPCs->insert(PCs[i]); + if (PCs()[i]) + PrintedPCs->insert(PCs()[i]); } void TracePC::PrintNewPCs() { if (!DoPrintNewPCs) return; assert(PrintedPCs); for (size_t i = 1; i < GetNumPCs(); i++) - if (PCs[i] && PrintedPCs->insert(PCs[i]).second) - PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PCs[i]); + if (PCs()[i] && PrintedPCs->insert(PCs()[i]).second) + PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PCs()[i]); } void TracePC::PrintCoverage() { @@ -107,16 +122,17 @@ void TracePC::PrintCoverage() { CoveredLines; Printf("COVERAGE:\n"); for (size_t i = 1; i < GetNumPCs(); i++) { - if (!PCs[i]) continue; - std::string FileStr = DescribePC("%s", PCs[i]); + uintptr_t PC = PCs()[i]; + if (!PC) continue; + std::string FileStr = DescribePC("%s", PC); if (!IsInterestingCoverageFile(FileStr)) continue; - std::string FixedPCStr = DescribePC("%p", PCs[i]); - std::string FunctionStr = DescribePC("%F", PCs[i]); - std::string LineStr = DescribePC("%l", PCs[i]); + std::string FixedPCStr = DescribePC("%p", PC); + std::string FunctionStr = DescribePC("%F", PC); + std::string LineStr = DescribePC("%l", PC); char ModulePathRaw[4096] = ""; // What's PATH_MAX in portable C++? void *OffsetRaw = nullptr; if (!EF->__sanitizer_get_module_and_offset_for_pc( - reinterpret_cast(PCs[i]), ModulePathRaw, + reinterpret_cast(PC), ModulePathRaw, sizeof(ModulePathRaw), &OffsetRaw)) continue; std::string Module = ModulePathRaw; @@ -207,7 +223,7 @@ void TracePC::DumpCoverage() { if (EF->__sanitizer_dump_coverage) { std::vector PCsCopy(GetNumPCs()); for (size_t i = 0; i < GetNumPCs(); i++) - PCsCopy[i] = PCs[i] ? GetPreviousInstructionPc(PCs[i]) : 0; + PCsCopy[i] = PCs()[i] ? GetPreviousInstructionPc(PCs()[i]) : 0; EF->__sanitizer_dump_coverage(PCsCopy.data(), PCsCopy.size()); } } diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.h b/llvm/lib/Fuzzer/FuzzerTracePC.h index 0b666e1963d9..b33d38747a35 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.h +++ b/llvm/lib/Fuzzer/FuzzerTracePC.h @@ -47,6 +47,7 @@ struct TableOfRecentCompares { class TracePC { public: + static const size_t kNumPCs = 1 << 21; void HandleTrace(uint32_t *guard, uintptr_t PC); void HandleInit(uint32_t *start, uint32_t *stop); @@ -60,7 +61,7 @@ class TracePC { void ResetMaps() { ValueProfileMap.Reset(); - memset(Counters, 0, GetNumPCs()); + memset(Counters(), 0, GetNumPCs()); } void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize); @@ -85,7 +86,7 @@ class TracePC { size_t GetNumPCs() const { return Min(kNumPCs, NumGuards + 1); } uintptr_t GetPC(size_t Idx) { assert(Idx < GetNumPCs()); - return PCs[Idx]; + return PCs()[Idx]; } private: @@ -101,9 +102,8 @@ private: size_t NumModules; // linker-initialized. size_t NumGuards; // linker-initialized. - static const size_t kNumPCs = 1 << 21; - alignas(8) uint8_t Counters[kNumPCs]; - uintptr_t PCs[kNumPCs]; + uint8_t *Counters() const; + uintptr_t *PCs() const; std::set *PrintedPCs; @@ -115,6 +115,7 @@ size_t TracePC::CollectFeatures(Callback CB) { if (!UsingTracePcGuard()) return 0; size_t Res = 0; const size_t Step = 8; + uint8_t *Counters = this->Counters(); assert(reinterpret_cast(Counters) % Step == 0); size_t N = GetNumPCs(); N = (N + Step - 1) & ~(Step - 1); // Round up.