12
12
#ifndef LLVM_FUZZER_CORPUS
13
13
#define LLVM_FUZZER_CORPUS
14
14
15
+ #include " FuzzerDataFlowTrace.h"
15
16
#include " FuzzerDefs.h"
16
17
#include " FuzzerIO.h"
17
18
#include " FuzzerRandom.h"
@@ -35,8 +36,9 @@ struct InputInfo {
35
36
size_t NumSuccessfullMutations = 0 ;
36
37
bool MayDeleteFile = false ;
37
38
bool Reduced = false ;
39
+ bool HasFocusFunction = false ;
38
40
Vector<uint32_t > UniqFeatureSet;
39
- float FeatureFrequencyScore = 1.0 ;
41
+ Vector< uint8_t > DataFlowTraceForFocusFunction ;
40
42
};
41
43
42
44
class InputCorpus {
@@ -45,7 +47,6 @@ class InputCorpus {
45
47
InputCorpus (const std::string &OutputCorpus) : OutputCorpus(OutputCorpus) {
46
48
memset (InputSizesPerFeature, 0 , sizeof (InputSizesPerFeature));
47
49
memset (SmallestElementPerFeature, 0 , sizeof (SmallestElementPerFeature));
48
- memset (FeatureFrequency, 0 , sizeof (FeatureFrequency));
49
50
}
50
51
~InputCorpus () {
51
52
for (auto II : Inputs)
@@ -70,10 +71,24 @@ class InputCorpus {
70
71
Res = std::max (Res, II->U .size ());
71
72
return Res;
72
73
}
74
+
75
+ size_t NumInputsThatTouchFocusFunction () {
76
+ return std::count_if (Inputs.begin (), Inputs.end (), [](const InputInfo *II) {
77
+ return II->HasFocusFunction ;
78
+ });
79
+ }
80
+
81
+ size_t NumInputsWithDataFlowTrace () {
82
+ return std::count_if (Inputs.begin (), Inputs.end (), [](const InputInfo *II) {
83
+ return !II->DataFlowTraceForFocusFunction .empty ();
84
+ });
85
+ }
86
+
73
87
bool empty () const { return Inputs.empty (); }
74
88
const Unit &operator [] (size_t Idx) const { return Inputs[Idx]->U ; }
75
89
void AddToCorpus (const Unit &U, size_t NumFeatures, bool MayDeleteFile,
76
- const Vector<uint32_t > &FeatureSet) {
90
+ bool HasFocusFunction, const Vector<uint32_t > &FeatureSet,
91
+ const DataFlowTrace &DFT, const InputInfo *BaseII) {
77
92
assert (!U.empty ());
78
93
if (FeatureDebug)
79
94
Printf (" ADD_TO_CORPUS %zd NF %zd\n " , Inputs.size (), NumFeatures);
@@ -83,9 +98,19 @@ class InputCorpus {
83
98
II.NumFeatures = NumFeatures;
84
99
II.MayDeleteFile = MayDeleteFile;
85
100
II.UniqFeatureSet = FeatureSet;
101
+ II.HasFocusFunction = HasFocusFunction;
86
102
std::sort (II.UniqFeatureSet .begin (), II.UniqFeatureSet .end ());
87
103
ComputeSHA1 (U.data (), U.size (), II.Sha1 );
88
- Hashes.insert (Sha1ToString (II.Sha1 ));
104
+ auto Sha1Str = Sha1ToString (II.Sha1 );
105
+ Hashes.insert (Sha1Str);
106
+ if (HasFocusFunction)
107
+ if (auto V = DFT.Get (Sha1Str))
108
+ II.DataFlowTraceForFocusFunction = *V;
109
+ // This is a gross heuristic.
110
+ // Ideally, when we add an element to a corpus we need to know its DFT.
111
+ // But if we don't, we'll use the DFT of its base input.
112
+ if (II.DataFlowTraceForFocusFunction .empty () && BaseII)
113
+ II.DataFlowTraceForFocusFunction = BaseII->DataFlowTraceForFocusFunction ;
89
114
UpdateCorpusDistribution ();
90
115
PrintCorpus ();
91
116
// ValidateFeatureSet();
@@ -157,9 +182,9 @@ class InputCorpus {
157
182
void PrintStats () {
158
183
for (size_t i = 0 ; i < Inputs.size (); i++) {
159
184
const auto &II = *Inputs[i];
160
- Printf (" [%zd %s]\t sz : %zd \t runs : %zd \t succ : %zd \n " , i,
185
+ Printf (" [% 3zd %s] sz : % 5zd runs : % 5zd succ : % 5zd focus: %d \n " , i,
161
186
Sha1ToString (II.Sha1 ).c_str (), II.U .size (),
162
- II.NumExecutedMutations , II.NumSuccessfullMutations );
187
+ II.NumExecutedMutations , II.NumSuccessfullMutations , II. HasFocusFunction );
163
188
}
164
189
}
165
190
@@ -213,18 +238,10 @@ class InputCorpus {
213
238
return false ;
214
239
}
215
240
216
- void UpdateFeatureFrequency (size_t Idx) {
217
- FeatureFrequency[Idx % kFeatureSetSize ]++;
218
- }
219
- float GetFeatureFrequency (size_t Idx) const {
220
- return FeatureFrequency[Idx % kFeatureSetSize ];
221
- }
222
- void UpdateFeatureFrequencyScore (InputInfo *II) {
223
- const float kMin = 0.01 , kMax = 100 .;
224
- II->FeatureFrequencyScore = kMin ;
225
- for (auto Idx : II->UniqFeatureSet )
226
- II->FeatureFrequencyScore += 1 . / (GetFeatureFrequency (Idx) + 1 .);
227
- II->FeatureFrequencyScore = Min (II->FeatureFrequencyScore , kMax );
241
+ bool IsFeatureNew (size_t Idx, uint32_t NewSize, bool Shrink) {
242
+ assert (NewSize);
243
+ uint32_t OldSize = GetFeature (Idx % kFeatureSetSize );
244
+ return OldSize == 0 || (Shrink && OldSize > NewSize);
228
245
}
229
246
230
247
size_t NumFeatures () const { return NumAddedFeatures; }
@@ -264,14 +281,11 @@ class InputCorpus {
264
281
std::iota (Intervals.begin (), Intervals.end (), 0 );
265
282
for (size_t i = 0 ; i < N; i++)
266
283
Weights[i] = Inputs[i]->NumFeatures
267
- ? (i + 1 ) * Inputs[i]->FeatureFrequencyScore
284
+ ? (i + 1 ) * ( Inputs[i]->HasFocusFunction ? 1000 : 1 )
268
285
: 0 .;
269
286
if (FeatureDebug) {
270
287
for (size_t i = 0 ; i < N; i++)
271
288
Printf (" %zd " , Inputs[i]->NumFeatures );
272
- Printf (" NUM\n " );
273
- for (size_t i = 0 ; i < N; i++)
274
- Printf (" %f " , Inputs[i]->FeatureFrequencyScore );
275
289
Printf (" SCORE\n " );
276
290
for (size_t i = 0 ; i < N; i++)
277
291
Printf (" %f " , Weights[i]);
@@ -292,7 +306,6 @@ class InputCorpus {
292
306
size_t NumUpdatedFeatures = 0 ;
293
307
uint32_t InputSizesPerFeature[kFeatureSetSize ];
294
308
uint32_t SmallestElementPerFeature[kFeatureSetSize ];
295
- float FeatureFrequency[kFeatureSetSize ];
296
309
297
310
std::string OutputCorpus;
298
311
};
0 commit comments