blob: cfb04ad3ad394d78ba4c443d25f1c02b29d82f4b [file] [log] [blame]
kcc86e43882018-06-06 01:23:29 +00001//===- FuzzerDataFlowTrace.h - Internal header for the Fuzzer ---*- C++ -* ===//
2//
chandlerc40284492019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
kcc86e43882018-06-06 01:23:29 +00006//
7//===----------------------------------------------------------------------===//
8// fuzzer::DataFlowTrace; reads and handles a data-flow trace.
9//
10// A data flow trace is generated by e.g. dataflow/DataFlow.cpp
11// and is stored on disk in a separate directory.
12//
13// The trace dir contains a file 'functions.txt' which lists function names,
14// oner per line, e.g.
15// ==> functions.txt <==
16// Func2
17// LLVMFuzzerTestOneInput
18// Func1
19//
20// All other files in the dir are the traces, see dataflow/DataFlow.cpp.
21// The name of the file is sha1 of the input used to generate the trace.
22//
23// Current status:
24// the data is parsed and the summary is printed, but the data is not yet
25// used in any other way.
26//===----------------------------------------------------------------------===//
27
28#ifndef LLVM_FUZZER_DATA_FLOW_TRACE
29#define LLVM_FUZZER_DATA_FLOW_TRACE
30
31#include "FuzzerDefs.h"
kcc11883b22019-05-10 01:34:26 +000032#include "FuzzerIO.h"
kcc86e43882018-06-06 01:23:29 +000033
kccadf188b2018-06-07 01:40:20 +000034#include <unordered_map>
35#include <vector>
36#include <string>
37
kcc86e43882018-06-06 01:23:29 +000038namespace fuzzer {
kccf7d6ba32019-05-09 21:29:45 +000039
kcc908220a2019-05-10 00:59:32 +000040int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
kcc11883b22019-05-10 01:34:26 +000041 const Vector<SizedFile> &CorporaFiles);
kcc908220a2019-05-10 00:59:32 +000042
kccf7d6ba32019-05-09 21:29:45 +000043class BlockCoverage {
44 public:
45 bool AppendCoverage(std::istream &IN);
46 bool AppendCoverage(const std::string &S);
47
48 size_t NumCoveredFunctions() const { return Functions.size(); }
49
50 uint32_t GetCounter(size_t FunctionId, size_t BasicBlockId) {
51 auto It = Functions.find(FunctionId);
52 if (It == Functions.end()) return 0;
53 const auto &Counters = It->second;
54 if (BasicBlockId < Counters.size())
55 return Counters[BasicBlockId];
56 return 0;
57 }
58
59 uint32_t GetNumberOfBlocks(size_t FunctionId) {
60 auto It = Functions.find(FunctionId);
61 if (It == Functions.end()) return 0;
62 const auto &Counters = It->second;
63 return Counters.size();
64 }
65
66 uint32_t GetNumberOfCoveredBlocks(size_t FunctionId) {
67 auto It = Functions.find(FunctionId);
68 if (It == Functions.end()) return 0;
69 const auto &Counters = It->second;
70 uint32_t Result = 0;
71 for (auto Cnt: Counters)
72 if (Cnt)
73 Result++;
74 return Result;
75 }
76
77 Vector<double> FunctionWeights(size_t NumFunctions) const;
78 void clear() { Functions.clear(); }
79
80 private:
81
82 typedef Vector<uint32_t> CoverageVector;
83
84 uint32_t NumberOfCoveredBlocks(const CoverageVector &Counters) const {
85 uint32_t Res = 0;
86 for (auto Cnt : Counters)
87 if (Cnt)
88 Res++;
89 return Res;
90 }
91
92 uint32_t NumberOfUncoveredBlocks(const CoverageVector &Counters) const {
93 return Counters.size() - NumberOfCoveredBlocks(Counters);
94 }
95
96 uint32_t SmallestNonZeroCounter(const CoverageVector &Counters) const {
97 assert(!Counters.empty());
98 uint32_t Res = Counters[0];
99 for (auto Cnt : Counters)
100 if (Cnt)
101 Res = Min(Res, Cnt);
102 assert(Res);
103 return Res;
104 }
105
106 // Function ID => vector of counters.
107 // Each counter represents how many input files trigger the given basic block.
108 std::unordered_map<size_t, CoverageVector> Functions;
109};
110
kccadf188b2018-06-07 01:40:20 +0000111class DataFlowTrace {
112 public:
kccf7d6ba32019-05-09 21:29:45 +0000113 void ReadCoverage(const std::string &DirPath);
kcc81236df2019-05-14 21:47:35 +0000114 bool Init(const std::string &DirPath, std::string *FocusFunction,
kccf7d6ba32019-05-09 21:29:45 +0000115 Random &Rand);
kccadf188b2018-06-07 01:40:20 +0000116 void Clear() { Traces.clear(); }
kcc0cab3f02018-07-19 01:23:32 +0000117 const Vector<uint8_t> *Get(const std::string &InputSha1) const {
kccadf188b2018-06-07 01:40:20 +0000118 auto It = Traces.find(InputSha1);
119 if (It != Traces.end())
120 return &It->second;
121 return nullptr;
122 }
123
124 private:
125 // Input's sha1 => DFT for the FocusFunction.
kcc0cab3f02018-07-19 01:23:32 +0000126 std::unordered_map<std::string, Vector<uint8_t> > Traces;
kccf7d6ba32019-05-09 21:29:45 +0000127 BlockCoverage Coverage;
kcc86e43882018-06-06 01:23:29 +0000128};
129} // namespace fuzzer
130
131#endif // LLVM_FUZZER_DATA_FLOW_TRACE