[libFuzzer] reorganize the tracing code to make it easier to experiment with inlined coverage instrumentation. NFC

llvm-svn: 293928
This commit is contained in:
Kostya Serebryany 2017-02-02 19:56:01 +00:00
parent 28c30ce250
commit 68382d0900
2 changed files with 36 additions and 19 deletions

View File

@ -24,21 +24,36 @@
#include <set>
#include <sstream>
// 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<uintptr_t>;
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<void *>(PCs[i]), ModulePathRaw,
reinterpret_cast<void *>(PC), ModulePathRaw,
sizeof(ModulePathRaw), &OffsetRaw))
continue;
std::string Module = ModulePathRaw;
@ -207,7 +223,7 @@ void TracePC::DumpCoverage() {
if (EF->__sanitizer_dump_coverage) {
std::vector<uintptr_t> 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());
}
}

View File

@ -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<uintptr_t> *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<uintptr_t>(Counters) % Step == 0);
size_t N = GetNumPCs();
N = (N + Step - 1) & ~(Step - 1); // Round up.