/src/mozilla-central/tools/fuzzing/libfuzzer/FuzzerTracePC.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- FuzzerTracePC.h - Internal header for the Fuzzer ---------*- C++ -* ===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // fuzzer::TracePC |
10 | | //===----------------------------------------------------------------------===// |
11 | | |
12 | | #ifndef LLVM_FUZZER_TRACE_PC |
13 | | #define LLVM_FUZZER_TRACE_PC |
14 | | |
15 | | #include "FuzzerDefs.h" |
16 | | #include "FuzzerDictionary.h" |
17 | | #include "FuzzerValueBitMap.h" |
18 | | |
19 | | #include <set> |
20 | | #include <unordered_map> |
21 | | |
22 | | namespace fuzzer { |
23 | | |
24 | | // TableOfRecentCompares (TORC) remembers the most recently performed |
25 | | // comparisons of type T. |
26 | | // We record the arguments of CMP instructions in this table unconditionally |
27 | | // because it seems cheaper this way than to compute some expensive |
28 | | // conditions inside __sanitizer_cov_trace_cmp*. |
29 | | // After the unit has been executed we may decide to use the contents of |
30 | | // this table to populate a Dictionary. |
31 | | template<class T, size_t kSizeT> |
32 | | struct TableOfRecentCompares { |
33 | | static const size_t kSize = kSizeT; |
34 | | struct Pair { |
35 | | T A, B; |
36 | | }; |
37 | | ATTRIBUTE_NO_SANITIZE_ALL |
38 | 6.08G | void Insert(size_t Idx, const T &Arg1, const T &Arg2) { |
39 | 6.08G | Idx = Idx % kSize; |
40 | 6.08G | Table[Idx].A = Arg1; |
41 | 6.08G | Table[Idx].B = Arg2; |
42 | 6.08G | } Unexecuted instantiation: fuzzer::TableOfRecentCompares<fuzzer::FixedWord<64ul>, 32ul>::Insert(unsigned long, fuzzer::FixedWord<64ul> const&, fuzzer::FixedWord<64ul> const&) fuzzer::TableOfRecentCompares<unsigned long, 32ul>::Insert(unsigned long, unsigned long const&, unsigned long const&) Line | Count | Source | 38 | 1.48G | void Insert(size_t Idx, const T &Arg1, const T &Arg2) { | 39 | 1.48G | Idx = Idx % kSize; | 40 | 1.48G | Table[Idx].A = Arg1; | 41 | 1.48G | Table[Idx].B = Arg2; | 42 | 1.48G | } |
fuzzer::TableOfRecentCompares<unsigned int, 32ul>::Insert(unsigned long, unsigned int const&, unsigned int const&) Line | Count | Source | 38 | 4.59G | void Insert(size_t Idx, const T &Arg1, const T &Arg2) { | 39 | 4.59G | Idx = Idx % kSize; | 40 | 4.59G | Table[Idx].A = Arg1; | 41 | 4.59G | Table[Idx].B = Arg2; | 42 | 4.59G | } |
|
43 | | |
44 | 0 | Pair Get(size_t I) { return Table[I % kSize]; } Unexecuted instantiation: fuzzer::TableOfRecentCompares<unsigned long, 32ul>::Get(unsigned long) Unexecuted instantiation: fuzzer::TableOfRecentCompares<unsigned int, 32ul>::Get(unsigned long) Unexecuted instantiation: fuzzer::TableOfRecentCompares<fuzzer::FixedWord<64ul>, 32ul>::Get(unsigned long) |
45 | | |
46 | | Pair Table[kSize]; |
47 | | }; |
48 | | |
49 | | template <size_t kSizeT> |
50 | | struct MemMemTable { |
51 | | static const size_t kSize = kSizeT; |
52 | | Word MemMemWords[kSize]; |
53 | | Word EmptyWord; |
54 | | |
55 | 0 | void Add(const uint8_t *Data, size_t Size) { |
56 | 0 | if (Size <= 2) return; |
57 | 0 | Size = std::min(Size, Word::GetMaxSize()); |
58 | 0 | size_t Idx = SimpleFastHash(Data, Size) % kSize; |
59 | 0 | MemMemWords[Idx].Set(Data, Size); |
60 | 0 | } |
61 | 0 | const Word &Get(size_t Idx) { |
62 | 0 | for (size_t i = 0; i < kSize; i++) { |
63 | 0 | const Word &W = MemMemWords[(Idx + i) % kSize]; |
64 | 0 | if (W.size()) return W; |
65 | 0 | } |
66 | 0 | EmptyWord.Set(nullptr, 0); |
67 | 0 | return EmptyWord; |
68 | 0 | } |
69 | | }; |
70 | | |
71 | | class TracePC { |
72 | | public: |
73 | | static const size_t kNumPCs = 1 << 21; |
74 | | // How many bits of PC are used from __sanitizer_cov_trace_pc. |
75 | | static const size_t kTracePcBits = 18; |
76 | | |
77 | | enum HandleUnstableOptions { |
78 | | MinUnstable = 1, |
79 | | ZeroUnstable = 2, |
80 | | }; |
81 | | |
82 | | void HandleInit(uint32_t *Start, uint32_t *Stop); |
83 | | void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop); |
84 | | void HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop); |
85 | | void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee); |
86 | | template <class T> void HandleCmp(uintptr_t PC, T Arg1, T Arg2); |
87 | | size_t GetTotalPCCoverage(); |
88 | 3 | void SetUseCounters(bool UC) { UseCounters = UC; } |
89 | 3 | void SetUseValueProfileMask(uint32_t VPMask) { UseValueProfileMask = VPMask; } |
90 | 3 | void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; } |
91 | 3 | void SetPrintNewFuncs(size_t P) { NumPrintNewFuncs = P; } |
92 | | void UpdateObservedPCs(); |
93 | | template <class Callback> void CollectFeatures(Callback CB) const; |
94 | | |
95 | 16.2k | void ResetMaps() { |
96 | 16.2k | ValueProfileMap.Reset(); |
97 | 16.2k | if (NumModules) |
98 | 0 | memset(Counters(), 0, GetNumPCs()); |
99 | 16.2k | ClearExtraCounters(); |
100 | 16.2k | ClearInlineCounters(); |
101 | 16.2k | } |
102 | | |
103 | | void ClearInlineCounters(); |
104 | | |
105 | | void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize); |
106 | | void PrintFeatureSet(); |
107 | | |
108 | | void PrintModuleInfo(); |
109 | | |
110 | | void PrintCoverage(); |
111 | | void DumpCoverage(); |
112 | | void PrintUnstableStats(); |
113 | | |
114 | | template<class CallBack> |
115 | | void IterateCoveredFunctions(CallBack CB); |
116 | | |
117 | | void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2, |
118 | | size_t n, bool StopAtZero); |
119 | | |
120 | | TableOfRecentCompares<uint32_t, 32> TORC4; |
121 | | TableOfRecentCompares<uint64_t, 32> TORC8; |
122 | | TableOfRecentCompares<Word, 32> TORCW; |
123 | | MemMemTable<1024> MMT; |
124 | | |
125 | 16.2k | size_t GetNumPCs() const { |
126 | 16.2k | return NumGuards == 0 ? (1 << kTracePcBits) : Min(kNumPCs, NumGuards + 1); |
127 | 16.2k | } |
128 | 0 | uintptr_t GetPC(size_t Idx) { |
129 | 0 | assert(Idx < GetNumPCs()); |
130 | 0 | return PCs()[Idx]; |
131 | 0 | } |
132 | | |
133 | | void RecordInitialStack(); |
134 | | uintptr_t GetMaxStackOffset() const; |
135 | | |
136 | | template<class CallBack> |
137 | 0 | void ForEachObservedPC(CallBack CB) { |
138 | 0 | for (auto PC : ObservedPCs) |
139 | 0 | CB(PC); |
140 | 0 | } |
141 | | |
142 | | void SetFocusFunction(const std::string &FuncName); |
143 | | bool ObservedFocusFunction(); |
144 | | |
145 | | void InitializeUnstableCounters(); |
146 | | bool UpdateUnstableCounters(int UnstableMode); |
147 | | void UpdateAndApplyUnstableCounters(int UnstableMode); |
148 | | |
149 | | private: |
150 | | struct UnstableEdge { |
151 | | uint8_t Counter; |
152 | | bool IsUnstable; |
153 | | }; |
154 | | |
155 | | UnstableEdge UnstableCounters[kNumPCs]; |
156 | | |
157 | | bool UseCounters = false; |
158 | | uint32_t UseValueProfileMask = false; |
159 | | bool DoPrintNewPCs = false; |
160 | | size_t NumPrintNewFuncs = 0; |
161 | | |
162 | | struct Module { |
163 | | uint32_t *Start, *Stop; |
164 | | }; |
165 | | |
166 | | Module Modules[4096]; |
167 | | size_t NumModules; // linker-initialized. |
168 | | size_t NumGuards; // linker-initialized. |
169 | | |
170 | | struct { uint8_t *Start, *Stop; } ModuleCounters[4096]; |
171 | | size_t NumModulesWithInline8bitCounters; // linker-initialized. |
172 | | size_t NumInline8bitCounters; |
173 | | |
174 | | struct PCTableEntry { |
175 | | uintptr_t PC, PCFlags; |
176 | | }; |
177 | | |
178 | | struct { const PCTableEntry *Start, *Stop; } ModulePCTable[4096]; |
179 | | size_t NumPCTables; |
180 | | size_t NumPCsInPCTables; |
181 | | |
182 | | uint8_t *Counters() const; |
183 | | uintptr_t *PCs() const; |
184 | | |
185 | | Set<uintptr_t> ObservedPCs; |
186 | | std::unordered_map<uintptr_t, uintptr_t> ObservedFuncs; // PC => Counter. |
187 | | |
188 | | template <class Callback> |
189 | | void IterateInline8bitCounters(Callback CB) const; |
190 | | |
191 | | std::pair<size_t, size_t> FocusFunction = {-1, -1}; // Module and PC IDs. |
192 | | |
193 | | ValueBitMap ValueProfileMap; |
194 | | uintptr_t InitialStack; |
195 | | }; |
196 | | |
197 | | template <class Callback> |
198 | | // void Callback(size_t FirstFeature, size_t Idx, uint8_t Value); |
199 | | ATTRIBUTE_NO_SANITIZE_ALL |
200 | | void ForEachNonZeroByte(const uint8_t *Begin, const uint8_t *End, |
201 | 32.4k | size_t FirstFeature, Callback Handle8bitCounter) { |
202 | 32.4k | typedef uintptr_t LargeType; |
203 | 32.4k | const size_t Step = sizeof(LargeType) / sizeof(uint8_t); |
204 | 32.4k | const size_t StepMask = Step - 1; |
205 | 32.4k | auto P = Begin; |
206 | 32.4k | // Iterate by 1 byte until either the alignment boundary or the end. |
207 | 32.4k | for (; reinterpret_cast<uintptr_t>(P) & StepMask && P < End; P++) |
208 | 0 | if (uint8_t V = *P) |
209 | 0 | Handle8bitCounter(FirstFeature, P - Begin, V); |
210 | 32.4k | |
211 | 32.4k | // Iterate by Step bytes at a time. |
212 | 2.80G | for (; P < End; P += Step) |
213 | 2.80G | if (LargeType Bundle = *reinterpret_cast<const LargeType *>(P)) |
214 | 37.7M | for (size_t I = 0; I < Step; I++, Bundle >>= 8) |
215 | 33.5M | if (uint8_t V = Bundle & 0xff) |
216 | 10.5M | Handle8bitCounter(FirstFeature, P - Begin + I, V); |
217 | 32.4k | |
218 | 32.4k | // Iterate by 1 byte until the end. |
219 | 32.4k | for (; P < End; P++) |
220 | 0 | if (uint8_t V = *P) |
221 | 0 | Handle8bitCounter(FirstFeature, P - Begin, V); |
222 | 32.4k | } Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::ForEachNonZeroByte<void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0) const::{lambda(unsigned long, unsigned long, unsigned char)#1}>(unsigned char const*, unsigned char const, unsigned long, void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0) const::{lambda(unsigned long, unsigned long, unsigned char)#1}) Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::ForEachNonZeroByte<void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1) const::{lambda(unsigned long, unsigned long, unsigned char)#1}>(unsigned char const*, unsigned char const, unsigned long, void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1) const::{lambda(unsigned long, unsigned long, unsigned char)#1}) Unexecuted instantiation: FuzzerLoop.cpp:void fuzzer::ForEachNonZeroByte<void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2) const::{lambda(unsigned long, unsigned long, unsigned char)#1}>(unsigned char const*, unsigned char const*, unsigned long, void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2) const::{lambda(unsigned long, unsigned long, unsigned char)#1}) FuzzerLoop.cpp:void fuzzer::ForEachNonZeroByte<void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3) const::{lambda(unsigned long, unsigned long, unsigned char)#1}>(unsigned char const*, unsigned char const*, unsigned long, void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3) const::{lambda(unsigned long, unsigned long, unsigned char)#1}) Line | Count | Source | 201 | 32.4k | size_t FirstFeature, Callback Handle8bitCounter) { | 202 | 32.4k | typedef uintptr_t LargeType; | 203 | 32.4k | const size_t Step = sizeof(LargeType) / sizeof(uint8_t); | 204 | 32.4k | const size_t StepMask = Step - 1; | 205 | 32.4k | auto P = Begin; | 206 | 32.4k | // Iterate by 1 byte until either the alignment boundary or the end. | 207 | 32.4k | for (; reinterpret_cast<uintptr_t>(P) & StepMask && P < End; P++) | 208 | 0 | if (uint8_t V = *P) | 209 | 0 | Handle8bitCounter(FirstFeature, P - Begin, V); | 210 | 32.4k | | 211 | 32.4k | // Iterate by Step bytes at a time. | 212 | 2.80G | for (; P < End; P += Step) | 213 | 2.80G | if (LargeType Bundle = *reinterpret_cast<const LargeType *>(P)) | 214 | 37.7M | for (size_t I = 0; I < Step; I++, Bundle >>= 8) | 215 | 33.5M | if (uint8_t V = Bundle & 0xff) | 216 | 10.5M | Handle8bitCounter(FirstFeature, P - Begin + I, V); | 217 | 32.4k | | 218 | 32.4k | // Iterate by 1 byte until the end. | 219 | 32.4k | for (; P < End; P++) | 220 | 0 | if (uint8_t V = *P) | 221 | 0 | Handle8bitCounter(FirstFeature, P - Begin, V); | 222 | 32.4k | } |
Unexecuted instantiation: FuzzerMerge.cpp:void fuzzer::ForEachNonZeroByte<void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1>(fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1) const::{lambda(unsigned long, unsigned long, unsigned char)#1}>(unsigned char const*, unsigned char const, unsigned long, void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1>(fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1) const::{lambda(unsigned long, unsigned long, unsigned char)#1}) |
223 | | |
224 | | // Given a non-zero Counter returns a number in the range [0,7]. |
225 | | template<class T> |
226 | 10.5M | unsigned CounterToFeature(T Counter) { |
227 | 10.5M | // Returns a feature number by placing Counters into buckets as illustrated |
228 | 10.5M | // below. |
229 | 10.5M | // |
230 | 10.5M | // Counter bucket: [1] [2] [3] [4-7] [8-15] [16-31] [32-127] [128+] |
231 | 10.5M | // Feature number: 0 1 2 3 4 5 6 7 |
232 | 10.5M | // |
233 | 10.5M | // This is a heuristic taken from AFL (see |
234 | 10.5M | // http://lcamtuf.coredump.cx/afl/technical_details.txt). |
235 | 10.5M | // |
236 | 10.5M | // This implementation may change in the future so clients should |
237 | 10.5M | // not rely on it. |
238 | 10.5M | assert(Counter); |
239 | 10.5M | unsigned Bit = 0; |
240 | 10.5M | /**/ if (Counter >= 128) Bit = 7; |
241 | 9.62M | else if (Counter >= 32) Bit = 6; |
242 | 8.29M | else if (Counter >= 16) Bit = 5; |
243 | 7.65M | else if (Counter >= 8) Bit = 4; |
244 | 6.85M | else if (Counter >= 4) Bit = 3; |
245 | 5.75M | else if (Counter >= 3) Bit = 2; |
246 | 5.17M | else if (Counter >= 2) Bit = 1; |
247 | 10.5M | return Bit; |
248 | 10.5M | } |
249 | | |
250 | | template <class Callback> // void Callback(size_t Feature) |
251 | | ATTRIBUTE_NO_SANITIZE_ADDRESS |
252 | | __attribute__((noinline)) |
253 | 16.2k | void TracePC::CollectFeatures(Callback HandleFeature) const { |
254 | 16.2k | uint8_t *Counters = this->Counters(); |
255 | 16.2k | size_t N = GetNumPCs(); |
256 | 16.2k | auto Handle8bitCounter = [&](size_t FirstFeature, |
257 | 10.5M | size_t Idx, uint8_t Counter) { |
258 | 10.5M | if (UseCounters) |
259 | 10.5M | HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Counter)); |
260 | 0 | else |
261 | 0 | HandleFeature(FirstFeature + Idx); |
262 | 10.5M | }; Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0) const::{lambda(unsigned long, unsigned long, unsigned char)#1}::operator()(unsigned long, unsigned long, unsigned char) const Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1) const::{lambda(unsigned long, unsigned long, unsigned char)#1}::operator()(unsigned long, unsigned long, unsigned char) const Unexecuted instantiation: FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2) const::{lambda(unsigned long, unsigned long, unsigned char)#1}::operator()(unsigned long, unsigned long, unsigned char) const FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3) const::{lambda(unsigned long, unsigned long, unsigned char)#1}::operator()(unsigned long, unsigned long, unsigned char) const Line | Count | Source | 257 | 10.5M | size_t Idx, uint8_t Counter) { | 258 | 10.5M | if (UseCounters) | 259 | 10.5M | HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Counter)); | 260 | 0 | else | 261 | 0 | HandleFeature(FirstFeature + Idx); | 262 | 10.5M | }; |
Unexecuted instantiation: FuzzerMerge.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1>(fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1) const::{lambda(unsigned long, unsigned long, unsigned char)#1}::operator()(unsigned long, unsigned long, unsigned char) const |
263 | 16.2k | |
264 | 16.2k | size_t FirstFeature = 0; |
265 | 16.2k | |
266 | 16.2k | if (!NumInline8bitCounters) { |
267 | 0 | ForEachNonZeroByte(Counters, Counters + N, FirstFeature, Handle8bitCounter); |
268 | 0 | FirstFeature += N * 8; |
269 | 0 | } |
270 | 16.2k | |
271 | 16.2k | if (NumInline8bitCounters) { |
272 | 32.4k | for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) { |
273 | 16.2k | ForEachNonZeroByte(ModuleCounters[i].Start, ModuleCounters[i].Stop, |
274 | 16.2k | FirstFeature, Handle8bitCounter); |
275 | 16.2k | FirstFeature += 8 * (ModuleCounters[i].Stop - ModuleCounters[i].Start); |
276 | 16.2k | } |
277 | 16.2k | } |
278 | 16.2k | |
279 | 16.2k | ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(), FirstFeature, |
280 | 16.2k | Handle8bitCounter); |
281 | 16.2k | FirstFeature += (ExtraCountersEnd() - ExtraCountersBegin()) * 8; |
282 | 16.2k | |
283 | 16.2k | if (UseValueProfileMask) { |
284 | 0 | ValueProfileMap.ForEach([&](size_t Idx) { |
285 | 0 | HandleFeature(FirstFeature + Idx); |
286 | 0 | }); Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0) const::{lambda(unsigned long)#1}::operator()(unsigned long) const Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1) const::{lambda(unsigned long)#1}::operator()(unsigned long) const Unexecuted instantiation: FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2) const::{lambda(unsigned long)#1}::operator()(unsigned long) const Unexecuted instantiation: FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3) const::{lambda(unsigned long)#1}::operator()(unsigned long) const Unexecuted instantiation: FuzzerMerge.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1>(fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1) const::{lambda(unsigned long)#1}::operator()(unsigned long) const |
287 | 0 | FirstFeature += ValueProfileMap.SizeInBits(); |
288 | 0 | } |
289 | 16.2k | |
290 | 16.2k | // Step function, grows similar to 8 * Log_2(A). |
291 | 16.2k | auto StackDepthStepFunction = [](uint32_t A) -> uint32_t { |
292 | 16.2k | if (!A) return A; |
293 | 16.2k | uint32_t Log2 = Log(A); |
294 | 16.2k | if (Log2 < 3) return A; |
295 | 16.2k | Log2 -= 3; |
296 | 16.2k | return (Log2 + 1) * 8 + ((A >> Log2) & 7); |
297 | 16.2k | }; Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0) const::{lambda(unsigned int)#1}::operator()(unsigned int) const Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1) const::{lambda(unsigned int)#1}::operator()(unsigned int) const Unexecuted instantiation: FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2) const::{lambda(unsigned int)#1}::operator()(unsigned int) const FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3) const::{lambda(unsigned int)#1}::operator()(unsigned int) const Line | Count | Source | 291 | 16.2k | auto StackDepthStepFunction = [](uint32_t A) -> uint32_t { | 292 | 16.2k | if (!A) return A; | 293 | 16.2k | uint32_t Log2 = Log(A); | 294 | 16.2k | if (Log2 < 3) return A; | 295 | 16.2k | Log2 -= 3; | 296 | 16.2k | return (Log2 + 1) * 8 + ((A >> Log2) & 7); | 297 | 16.2k | }; |
Unexecuted instantiation: FuzzerMerge.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1>(fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1) const::{lambda(unsigned int)#1}::operator()(unsigned int) const |
298 | 16.2k | assert(StackDepthStepFunction(1024) == 64); |
299 | 16.2k | assert(StackDepthStepFunction(1024 * 4) == 80); |
300 | 16.2k | assert(StackDepthStepFunction(1024 * 1024) == 144); |
301 | 16.2k | |
302 | 16.2k | if (auto MaxStackOffset = GetMaxStackOffset()) |
303 | 16.2k | HandleFeature(FirstFeature + StackDepthStepFunction(MaxStackOffset / 8)); |
304 | 16.2k | } Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_0) const Unexecuted instantiation: FuzzerDriver.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1>(fuzzer::AnalyzeDictionary(fuzzer::Fuzzer*, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > > const&, std::__1::vector<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> >, fuzzer::fuzzer_allocator<std::__1::vector<unsigned char, fuzzer::fuzzer_allocator<unsigned char> > > >&)::$_1) const Unexecuted instantiation: FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_2) const FuzzerLoop.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3>(fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*)::$_3) const Line | Count | Source | 253 | 16.2k | void TracePC::CollectFeatures(Callback HandleFeature) const { | 254 | 16.2k | uint8_t *Counters = this->Counters(); | 255 | 16.2k | size_t N = GetNumPCs(); | 256 | 16.2k | auto Handle8bitCounter = [&](size_t FirstFeature, | 257 | 16.2k | size_t Idx, uint8_t Counter) { | 258 | 16.2k | if (UseCounters) | 259 | 16.2k | HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Counter)); | 260 | 16.2k | else | 261 | 16.2k | HandleFeature(FirstFeature + Idx); | 262 | 16.2k | }; | 263 | 16.2k | | 264 | 16.2k | size_t FirstFeature = 0; | 265 | 16.2k | | 266 | 16.2k | if (!NumInline8bitCounters) { | 267 | 0 | ForEachNonZeroByte(Counters, Counters + N, FirstFeature, Handle8bitCounter); | 268 | 0 | FirstFeature += N * 8; | 269 | 0 | } | 270 | 16.2k | | 271 | 16.2k | if (NumInline8bitCounters) { | 272 | 32.4k | for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) { | 273 | 16.2k | ForEachNonZeroByte(ModuleCounters[i].Start, ModuleCounters[i].Stop, | 274 | 16.2k | FirstFeature, Handle8bitCounter); | 275 | 16.2k | FirstFeature += 8 * (ModuleCounters[i].Stop - ModuleCounters[i].Start); | 276 | 16.2k | } | 277 | 16.2k | } | 278 | 16.2k | | 279 | 16.2k | ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(), FirstFeature, | 280 | 16.2k | Handle8bitCounter); | 281 | 16.2k | FirstFeature += (ExtraCountersEnd() - ExtraCountersBegin()) * 8; | 282 | 16.2k | | 283 | 16.2k | if (UseValueProfileMask) { | 284 | 0 | ValueProfileMap.ForEach([&](size_t Idx) { | 285 | 0 | HandleFeature(FirstFeature + Idx); | 286 | 0 | }); | 287 | 0 | FirstFeature += ValueProfileMap.SizeInBits(); | 288 | 0 | } | 289 | 16.2k | | 290 | 16.2k | // Step function, grows similar to 8 * Log_2(A). | 291 | 16.2k | auto StackDepthStepFunction = [](uint32_t A) -> uint32_t { | 292 | 16.2k | if (!A) return A; | 293 | 16.2k | uint32_t Log2 = Log(A); | 294 | 16.2k | if (Log2 < 3) return A; | 295 | 16.2k | Log2 -= 3; | 296 | 16.2k | return (Log2 + 1) * 8 + ((A >> Log2) & 7); | 297 | 16.2k | }; | 298 | 16.2k | assert(StackDepthStepFunction(1024) == 64); | 299 | 16.2k | assert(StackDepthStepFunction(1024 * 4) == 80); | 300 | 16.2k | assert(StackDepthStepFunction(1024 * 1024) == 144); | 301 | 16.2k | | 302 | 16.2k | if (auto MaxStackOffset = GetMaxStackOffset()) | 303 | 16.2k | HandleFeature(FirstFeature + StackDepthStepFunction(MaxStackOffset / 8)); | 304 | 16.2k | } |
Unexecuted instantiation: FuzzerMerge.cpp:void fuzzer::TracePC::CollectFeatures<fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1>(fuzzer::Fuzzer::CrashResistantMergeInternalStep(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1) const |
305 | | |
306 | | extern TracePC TPC; |
307 | | |
308 | | } // namespace fuzzer |
309 | | |
310 | | #endif // LLVM_FUZZER_TRACE_PC |