aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2017-08-04 23:13:58 +0000
committerKostya Serebryany <kcc@google.com>2017-08-04 23:13:58 +0000
commit0b67c739d8828d1aaac7c7c18c0525a404628a7f (patch)
treee01c097bf3d076d6042b0321376155d96d6cf09d
parent2d30fac6e9ddaf3bef828d2ce76aab3651c5ad45 (diff)
[libFuzzer] print PCs using the in-binary PC-table instead of relying on PCs captured at run-time
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310148 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Fuzzer/FuzzerLoop.cpp5
-rw-r--r--lib/Fuzzer/FuzzerTracePC.cpp51
-rw-r--r--lib/Fuzzer/FuzzerTracePC.h5
3 files changed, 40 insertions, 21 deletions
diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp
index 682e4b7b05d..41fd213a653 100644
--- a/lib/Fuzzer/FuzzerLoop.cpp
+++ b/lib/Fuzzer/FuzzerLoop.cpp
@@ -122,7 +122,6 @@ Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
EF->__sanitizer_install_malloc_and_free_hooks(MallocHook, FreeHook);
TPC.SetUseCounters(Options.UseCounters);
TPC.SetUseValueProfile(Options.UseValueProfile);
- TPC.SetPrintNewPCs(Options.PrintNewCovPcs);
if (Options.Verbosity)
TPC.PrintModuleInfo();
@@ -438,6 +437,7 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
PrintPulseAndReportSlowInput(Data, Size);
size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore;
if (NumNewFeatures) {
+ TPC.UpdateObservedPCs();
Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile,
UniqFeatureSetTmp);
return true;
@@ -546,7 +546,6 @@ void Fuzzer::ReportNewCoverage(InputInfo *II, const Unit &U) {
"NEW ");
WriteToOutputCorpus(U);
NumberOfNewUnitsAdded++;
- TPC.PrintNewPCs();
CheckExitOnSrcPosOrItem(); // Check only after the unit is saved to corpus.
LastCorpusUpdateRun = TotalNumberOfRuns;
LastCorpusUpdateTime = system_clock::now();
@@ -626,7 +625,7 @@ void Fuzzer::MutateAndTestOne() {
}
void Fuzzer::Loop() {
- TPC.InitializePrintNewPCs();
+ TPC.SetPrintNewPCs(Options.PrintNewCovPcs);
system_clock::time_point LastCorpusReload = system_clock::now();
if (Options.DoCrossOver)
MD.SetCorpus(&Corpus);
diff --git a/lib/Fuzzer/FuzzerTracePC.cpp b/lib/Fuzzer/FuzzerTracePC.cpp
index 1cfd3f3ecff..45deaa21a4c 100644
--- a/lib/Fuzzer/FuzzerTracePC.cpp
+++ b/lib/Fuzzer/FuzzerTracePC.cpp
@@ -48,6 +48,8 @@ uintptr_t *TracePC::PCs() const {
}
size_t TracePC::GetTotalPCCoverage() {
+ if (ObservedPCs)
+ return ObservedPCs->size();
size_t Res = 0;
for (size_t i = 1, N = GetNumPCs(); i < N; i++)
if (PCs()[i])
@@ -136,21 +138,40 @@ void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {
ValueProfileMap.AddValueModPrime(Idx);
}
-void TracePC::InitializePrintNewPCs() {
- if (!DoPrintNewPCs) return;
- assert(!PrintedPCs);
- PrintedPCs = new std::set<uintptr_t>;
- for (size_t i = 1; i < GetNumPCs(); 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]);
+void TracePC::UpdateObservedPCs() {
+ if (NumPCsInPCTables) {
+ auto Observe = [&](uintptr_t PC) {
+ bool Inserted = ObservedPCs->insert(PC).second;
+ if (Inserted && DoPrintNewPCs)
+ PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PC + 1);
+ };
+
+ if (!ObservedPCs)
+ ObservedPCs = new std::set<uintptr_t>;
+
+ if (NumInline8bitCounters == NumPCsInPCTables) {
+ for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
+ uint8_t *Beg = ModuleCounters[i].Start;
+ size_t Size = ModuleCounters[i].Stop - Beg;
+ assert(Size ==
+ (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
+ for (size_t j = 0; j < Size; j++)
+ if (Beg[j])
+ Observe(ModulePCTable[i].Start[j]);
+ }
+ } else if (NumGuards == NumPCsInPCTables) {
+ size_t GuardIdx = 1;
+ for (size_t i = 0; i < NumModules; i++) {
+ uint32_t *Beg = Modules[i].Start;
+ size_t Size = Modules[i].Stop - Beg;
+ assert(Size ==
+ (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
+ for (size_t j = 0; j < Size; j++, GuardIdx++)
+ if (Counters()[GuardIdx])
+ Observe(ModulePCTable[i].Start[j]);
+ }
+ }
+ }
}
void TracePC::PrintCoverage() {
diff --git a/lib/Fuzzer/FuzzerTracePC.h b/lib/Fuzzer/FuzzerTracePC.h
index ba882b3af86..ad832d7b2d4 100644
--- a/lib/Fuzzer/FuzzerTracePC.h
+++ b/lib/Fuzzer/FuzzerTracePC.h
@@ -82,6 +82,7 @@ class TracePC {
void SetUseCounters(bool UC) { UseCounters = UC; }
void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }
+ void UpdateObservedPCs();
template <class Callback> void CollectFeatures(Callback CB) const;
void ResetMaps() {
@@ -110,8 +111,6 @@ class TracePC {
TableOfRecentCompares<Word, 32> TORCW;
MemMemTable<1024> MMT;
- void PrintNewPCs();
- void InitializePrintNewPCs();
size_t GetNumPCs() const {
return NumGuards == 0 ? (1 << kTracePcBits) : Min(kNumPCs, NumGuards + 1);
}
@@ -158,7 +157,7 @@ private:
uint8_t *Counters() const;
uintptr_t *PCs() const;
- std::set<uintptr_t> *PrintedPCs;
+ std::set<uintptr_t> *ObservedPCs;
ValueBitMap ValueProfileMap;
uintptr_t InitialStack, LowestStack; // Assume stack grows down.