1212#ifndef LLVM_FUZZER_CORPUS
1313#define LLVM_FUZZER_CORPUS
1414
15+ #include " FuzzerDataFlowTrace.h"
1516#include " FuzzerDefs.h"
1617#include " FuzzerIO.h"
1718#include " FuzzerRandom.h"
@@ -35,8 +36,9 @@ struct InputInfo {
3536 size_t NumSuccessfullMutations = 0 ;
3637 bool MayDeleteFile = false ;
3738 bool Reduced = false ;
39+ bool HasFocusFunction = false ;
3840 Vector<uint32_t > UniqFeatureSet;
39- float FeatureFrequencyScore = 1.0 ;
41+ Vector< uint8_t > DataFlowTraceForFocusFunction ;
4042};
4143
4244class InputCorpus {
@@ -45,7 +47,6 @@ class InputCorpus {
4547 InputCorpus (const std::string &OutputCorpus) : OutputCorpus(OutputCorpus) {
4648 memset (InputSizesPerFeature, 0 , sizeof (InputSizesPerFeature));
4749 memset (SmallestElementPerFeature, 0 , sizeof (SmallestElementPerFeature));
48- memset (FeatureFrequency, 0 , sizeof (FeatureFrequency));
4950 }
5051 ~InputCorpus () {
5152 for (auto II : Inputs)
@@ -70,10 +71,24 @@ class InputCorpus {
7071 Res = std::max (Res, II->U .size ());
7172 return Res;
7273 }
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+
7387 bool empty () const { return Inputs.empty (); }
7488 const Unit &operator [] (size_t Idx) const { return Inputs[Idx]->U ; }
7589 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) {
7792 assert (!U.empty ());
7893 if (FeatureDebug)
7994 Printf (" ADD_TO_CORPUS %zd NF %zd\n " , Inputs.size (), NumFeatures);
@@ -83,9 +98,19 @@ class InputCorpus {
8398 II.NumFeatures = NumFeatures;
8499 II.MayDeleteFile = MayDeleteFile;
85100 II.UniqFeatureSet = FeatureSet;
101+ II.HasFocusFunction = HasFocusFunction;
86102 std::sort (II.UniqFeatureSet .begin (), II.UniqFeatureSet .end ());
87103 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 ;
89114 UpdateCorpusDistribution ();
90115 PrintCorpus ();
91116 // ValidateFeatureSet();
@@ -157,9 +182,9 @@ class InputCorpus {
157182 void PrintStats () {
158183 for (size_t i = 0 ; i < Inputs.size (); i++) {
159184 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,
161186 Sha1ToString (II.Sha1 ).c_str (), II.U .size (),
162- II.NumExecutedMutations , II.NumSuccessfullMutations );
187+ II.NumExecutedMutations , II.NumSuccessfullMutations , II. HasFocusFunction );
163188 }
164189 }
165190
@@ -213,18 +238,10 @@ class InputCorpus {
213238 return false ;
214239 }
215240
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);
228245 }
229246
230247 size_t NumFeatures () const { return NumAddedFeatures; }
@@ -264,14 +281,11 @@ class InputCorpus {
264281 std::iota (Intervals.begin (), Intervals.end (), 0 );
265282 for (size_t i = 0 ; i < N; i++)
266283 Weights[i] = Inputs[i]->NumFeatures
267- ? (i + 1 ) * Inputs[i]->FeatureFrequencyScore
284+ ? (i + 1 ) * ( Inputs[i]->HasFocusFunction ? 1000 : 1 )
268285 : 0 .;
269286 if (FeatureDebug) {
270287 for (size_t i = 0 ; i < N; i++)
271288 Printf (" %zd " , Inputs[i]->NumFeatures );
272- Printf (" NUM\n " );
273- for (size_t i = 0 ; i < N; i++)
274- Printf (" %f " , Inputs[i]->FeatureFrequencyScore );
275289 Printf (" SCORE\n " );
276290 for (size_t i = 0 ; i < N; i++)
277291 Printf (" %f " , Weights[i]);
@@ -292,7 +306,6 @@ class InputCorpus {
292306 size_t NumUpdatedFeatures = 0 ;
293307 uint32_t InputSizesPerFeature[kFeatureSetSize ];
294308 uint32_t SmallestElementPerFeature[kFeatureSetSize ];
295- float FeatureFrequency[kFeatureSetSize ];
296309
297310 std::string OutputCorpus;
298311};
0 commit comments