Index: FuzzerDriver.cpp =================================================================== --- FuzzerDriver.cpp +++ FuzzerDriver.cpp @@ -565,6 +565,10 @@ return RunInMultipleProcesses(Args, Flags.workers, Flags.jobs); FuzzingOptions Options; + Options.Ngram = Flags.ngram; + if (Options.Ngram > 1) + TPC.SetNgram(Options.Ngram); + Options.Verbosity = Flags.verbosity; Options.MaxLen = Flags.max_len; Options.LenControl = Flags.len_control; Index: FuzzerFlags.def =================================================================== --- FuzzerFlags.def +++ FuzzerFlags.def @@ -151,3 +151,5 @@ FUZZER_FLAG_INT(analyze_dict, 0, "Experimental") FUZZER_FLAG_INT(use_clang_coverage, 0, "Experimental") FUZZER_FLAG_INT(use_feature_frequency, 0, "Experimental/internal") +FUZZER_FLAG_INT(ngram, 1, "Experimental. Use ngram of PCs.") + Index: FuzzerOptions.h =================================================================== --- FuzzerOptions.h +++ FuzzerOptions.h @@ -40,6 +40,7 @@ size_t MaxNumberOfRuns = -1L; int ReportSlowUnits = 10; bool OnlyASCII = false; + int Ngram = 1; std::string OutputCorpus; std::string ArtifactPrefix = "./"; std::string ExactArtifactPath; Index: FuzzerTracePC.h =================================================================== --- FuzzerTracePC.h +++ FuzzerTracePC.h @@ -72,6 +72,8 @@ static const size_t kNumPCs = 1 << 21; // How many bits of PC are used from __sanitizer_cov_trace_pc. static const size_t kTracePcBits = 18; + static const uint8_t nGramMax = 1 << 7; + uint8_t Ngram = 1; void HandleInit(uint32_t *Start, uint32_t *Stop); void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop); @@ -83,6 +85,7 @@ void SetUseClangCoverage(bool UCC) { UseClangCoverage = UCC; } void SetUseValueProfile(bool VP) { UseValueProfile = VP; } void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; } + void SetNgram(uint8_t N) { if (N <= nGramMax) Ngram = N; else Ngram = nGramMax; } void SetPrintNewFuncs(size_t P) { NumPrintNewFuncs = P; } void UpdateObservedPCs(); template void CollectFeatures(Callback CB) const; Index: FuzzerTracePC.cpp =================================================================== --- FuzzerTracePC.cpp +++ FuzzerTracePC.cpp @@ -372,13 +372,23 @@ } // namespace fuzzer extern "C" { +static uint32_t GuardHist[fuzzer::TracePC::nGramMax] = {0}; +static uint32_t XorState = 0; +//static uint8_t Ngram = fuzzer::TPC.Ngram;//NGRAM_MAX; ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_ALL void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) { uintptr_t PC = reinterpret_cast(__builtin_return_address(0)); uint32_t Idx = *Guard; + uint32_t Idx8bit = Idx; + if (fuzzer::TPC.Ngram > 1) { + uint32_t Idx8bit = XorState ^ Idx; + XorState = XorState ^ *Guard ^ GuardHist[fuzzer::TPC.Ngram-1]; + for (uint8_t i=fuzzer::TPC.Ngram-1; i>0;i--) GuardHist[i] = GuardHist[i-1]; + GuardHist[0] = *Guard; + } __sancov_trace_pc_pcs[Idx] = PC; - __sancov_trace_pc_guard_8bit_counters[Idx]++; + __sancov_trace_pc_guard_8bit_counters[Idx8bit]++; } // Best-effort support for -fsanitize-coverage=trace-pc, which is available