diff options
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerFork.cpp | 11 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerMerge.cpp | 10 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerTracePC.cpp | 20 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerTracePC.h | 3 |
4 files changed, 33 insertions, 11 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp index 41fb5c1c57f..eff90094dae 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp @@ -13,6 +13,7 @@ #include "FuzzerIO.h" #include "FuzzerMerge.h" #include "FuzzerSHA1.h" +#include "FuzzerTracePC.h" #include "FuzzerUtil.h" #include <atomic> @@ -86,11 +87,13 @@ struct GlobalEnv { Cmd.removeArgument(C); Cmd.addFlag("reload", "0"); // working in an isolated dir, no reload. Cmd.addFlag("print_final_stats", "1"); + Cmd.addFlag("print_funcs", "0"); // no need to spend time symbolizing. Cmd.addFlag("max_total_time", std::to_string(std::min((size_t)300, JobId))); auto Job = new FuzzJob; std::string Seeds; - if (size_t CorpusSubsetSize = std::min(Files.size(), (size_t)100)) + if (size_t CorpusSubsetSize = + std::min(Files.size(), (size_t)sqrt(Files.size() + 2))) for (size_t i = 0; i < CorpusSubsetSize; i++) Seeds += (Seeds.empty() ? "" : ",") + Files[Rand->SkewTowardsLast(Files.size())]; @@ -135,6 +138,12 @@ struct GlobalEnv { RmDirRecursive(Job->CorpusDir); Features.insert(NewFeatures.begin(), NewFeatures.end()); Cov.insert(NewCov.begin(), NewCov.end()); + for (auto Idx : NewCov) + if (auto *TE = TPC.PCTableEntryByIdx(Idx)) + if (TPC.PcIsFuncEntry(TE)) + PrintPC(" NEW_FUNC: %p %F %L\n", "", + TPC.GetNextInstructionPc(TE->PC)); + auto Stats = ParseFinalStatsFromLog(Job->LogPath); NumRuns += Stats.number_of_executed_units; if (!FilesToAdd.empty()) diff --git a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp index 870a8752209..d70aa3e901a 100644 --- a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp @@ -100,7 +100,7 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) { LastSeenStartMarker = kInvalidStartMarker; if (ParseCoverage) { TmpFeatures.clear(); // use a vector from outer scope to avoid resizes. - while (ISS1 >> std::hex >> N) + while (ISS1 >> N) TmpFeatures.push_back(N); std::sort(TmpFeatures.begin(), TmpFeatures.end()); Files[CurrentFileIdx].Features = TmpFeatures; @@ -108,7 +108,7 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) { } else if (Marker == "COV") { size_t CurrentFileIdx = N; if (ParseCoverage) - while (ISS1 >> std::hex >> N) + while (ISS1 >> N) if (PCs.insert(N).second) Files[CurrentFileIdx].Cov.push_back(N); } else { @@ -220,7 +220,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { } std::ostringstream StartedLine; // Write the pre-run marker. - OF << "STARTED " << std::dec << i << " " << U.size() << "\n"; + OF << "STARTED " << i << " " << U.size() << "\n"; OF.flush(); // Flush is important since Command::Execute may crash. // Run. TPC.ResetMaps(); @@ -242,9 +242,9 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { // Write the post-run marker and the coverage. OF << "FT " << i; for (size_t F : UniqFeatures) - OF << " " << std::hex << F; + OF << " " << F; OF << "\n"; - OF << "COV " << std::dec << i; + OF << "COV " << i; TPC.ForEachObservedPC([&](const TracePC::PCTableEntry *TE) { if (AllPCs.insert(TE).second) OF << " " << TPC.PCTableEntryIdx(TE); diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp index f5fdbf5bd0d..a2d3b7e7faf 100644 --- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp @@ -174,7 +174,7 @@ inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { /// \return the address of the next instruction. /// Note: the logic is copied from `sanitizer_common/sanitizer_stacktrace.cc` -inline ALWAYS_INLINE uintptr_t GetNextInstructionPc(uintptr_t PC) { +ALWAYS_INLINE uintptr_t TracePC::GetNextInstructionPc(uintptr_t PC) { #if defined(__mips__) return PC + 8; #elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ @@ -196,7 +196,7 @@ void TracePC::UpdateObservedPCs() { }; auto Observe = [&](const PCTableEntry *TE) { - if (TE->PCFlags & 1) + if (PcIsFuncEntry(TE)) if (++ObservedFuncs[TE->PC] == 1 && NumPrintNewFuncs) CoveredFuncs.push_back(TE->PC); ObservePC(TE); @@ -239,6 +239,16 @@ uintptr_t TracePC::PCTableEntryIdx(const PCTableEntry *TE) { return 0; } +const TracePC::PCTableEntry *TracePC::PCTableEntryByIdx(uintptr_t Idx) { + for (size_t i = 0; i < NumPCTables; i++) { + auto &M = ModulePCTable[i]; + size_t Size = M.Stop - M.Start; + if (Idx < Size) return &M.Start[Idx]; + Idx -= Size; + } + return nullptr; +} + static std::string GetModuleName(uintptr_t PC) { char ModulePathRaw[4096] = ""; // What's PATH_MAX in portable C++? void *OffsetRaw = nullptr; @@ -257,10 +267,10 @@ void TracePC::IterateCoveredFunctions(CallBack CB) { auto ModuleName = GetModuleName(M.Start->PC); for (auto NextFE = M.Start; NextFE < M.Stop; ) { auto FE = NextFE; - assert((FE->PCFlags & 1) && "Not a function entry point"); + assert(PcIsFuncEntry(FE) && "Not a function entry point"); do { NextFE++; - } while (NextFE < M.Stop && !(NextFE->PCFlags & 1)); + } while (NextFE < M.Stop && !(PcIsFuncEntry(NextFE))); CB(FE, NextFE, ObservedFuncs[FE->PC]); } } @@ -275,7 +285,7 @@ void TracePC::SetFocusFunction(const std::string &FuncName) { auto &PCTE = ModulePCTable[M]; size_t N = PCTE.Stop - PCTE.Start; for (size_t I = 0; I < N; I++) { - if (!(PCTE.Start[I].PCFlags & 1)) continue; // not a function entry. + if (!(PcIsFuncEntry(&PCTE.Start[I]))) continue; // not a function entry. auto Name = DescribePC("%F", GetNextInstructionPc(PCTE.Start[I].PC)); if (Name[0] == 'i' && Name[1] == 'n' && Name[2] == ' ') Name = Name.substr(3, std::string::npos); diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.h b/compiler-rt/lib/fuzzer/FuzzerTracePC.h index f1d523e3348..4f5ebeb047a 100644 --- a/compiler-rt/lib/fuzzer/FuzzerTracePC.h +++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.h @@ -127,6 +127,9 @@ class TracePC { }; uintptr_t PCTableEntryIdx(const PCTableEntry *TE); + const PCTableEntry *PCTableEntryByIdx(uintptr_t Idx); + static uintptr_t GetNextInstructionPc(uintptr_t PC); + bool PcIsFuncEntry(const PCTableEntry *TE) { return TE->PCFlags & 1; } private: bool UseCounters = false; |