diff options
author | Kostya Serebryany <kcc@google.com> | 2019-05-09 21:29:45 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2019-05-09 21:29:45 +0000 |
commit | e61a1d3a91aa80f8a4d188f7ea94ecb860622032 (patch) | |
tree | bf2dc05aff19c52f8bd07bfe07e4cca677b4a124 /lib/fuzzer/FuzzerDataFlowTrace.h | |
parent | 2ccfefe8f06d7cb3050f0ee5e8c794a16aeb79bd (diff) | |
download | compiler-rt-e61a1d3a91aa80f8a4d188f7ea94ecb860622032.tar.gz |
[libFuzzer] implement -focus_function=auto, to be used with Data Flow Traces
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@360378 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/fuzzer/FuzzerDataFlowTrace.h')
-rw-r--r-- | lib/fuzzer/FuzzerDataFlowTrace.h | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/lib/fuzzer/FuzzerDataFlowTrace.h b/lib/fuzzer/FuzzerDataFlowTrace.h index 9523a01e1..405845126 100644 --- a/lib/fuzzer/FuzzerDataFlowTrace.h +++ b/lib/fuzzer/FuzzerDataFlowTrace.h @@ -35,9 +35,80 @@ #include <string> namespace fuzzer { + +class BlockCoverage { + public: + bool AppendCoverage(std::istream &IN); + bool AppendCoverage(const std::string &S); + + size_t NumCoveredFunctions() const { return Functions.size(); } + + uint32_t GetCounter(size_t FunctionId, size_t BasicBlockId) { + auto It = Functions.find(FunctionId); + if (It == Functions.end()) return 0; + const auto &Counters = It->second; + if (BasicBlockId < Counters.size()) + return Counters[BasicBlockId]; + return 0; + } + + uint32_t GetNumberOfBlocks(size_t FunctionId) { + auto It = Functions.find(FunctionId); + if (It == Functions.end()) return 0; + const auto &Counters = It->second; + return Counters.size(); + } + + uint32_t GetNumberOfCoveredBlocks(size_t FunctionId) { + auto It = Functions.find(FunctionId); + if (It == Functions.end()) return 0; + const auto &Counters = It->second; + uint32_t Result = 0; + for (auto Cnt: Counters) + if (Cnt) + Result++; + return Result; + } + + Vector<double> FunctionWeights(size_t NumFunctions) const; + void clear() { Functions.clear(); } + + private: + + typedef Vector<uint32_t> CoverageVector; + + uint32_t NumberOfCoveredBlocks(const CoverageVector &Counters) const { + uint32_t Res = 0; + for (auto Cnt : Counters) + if (Cnt) + Res++; + return Res; + } + + uint32_t NumberOfUncoveredBlocks(const CoverageVector &Counters) const { + return Counters.size() - NumberOfCoveredBlocks(Counters); + } + + uint32_t SmallestNonZeroCounter(const CoverageVector &Counters) const { + assert(!Counters.empty()); + uint32_t Res = Counters[0]; + for (auto Cnt : Counters) + if (Cnt) + Res = Min(Res, Cnt); + assert(Res); + return Res; + } + + // Function ID => vector of counters. + // Each counter represents how many input files trigger the given basic block. + std::unordered_map<size_t, CoverageVector> Functions; +}; + class DataFlowTrace { public: - void Init(const std::string &DirPath, const std::string &FocusFunction); + void ReadCoverage(const std::string &DirPath); + void Init(const std::string &DirPath, std::string *FocusFunction, + Random &Rand); void Clear() { Traces.clear(); } const Vector<uint8_t> *Get(const std::string &InputSha1) const { auto It = Traces.find(InputSha1); @@ -49,6 +120,7 @@ class DataFlowTrace { private: // Input's sha1 => DFT for the FocusFunction. std::unordered_map<std::string, Vector<uint8_t> > Traces; + BlockCoverage Coverage; }; } // namespace fuzzer |