mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-28 20:41:07 +00:00
[libFuzzer] reorganize the tracing code to make it easier to experiment with inlined coverage instrumentation. NFC
llvm-svn: 293928
This commit is contained in:
parent
28c30ce250
commit
68382d0900
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user