summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Fuzzer/FuzzerCorpus.h
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-09-30 01:19:56 +0000
committerKostya Serebryany <kcc@google.com>2016-09-30 01:19:56 +0000
commit2c55613a08b1b66eb337fc5a84fd2d6b086bb8b4 (patch)
treec57bbca017cacdb8989a06b5a4a6c2c8a5225856 /llvm/lib/Fuzzer/FuzzerCorpus.h
parentfce01788477ee62a4a65bee2dbc5b222117b64f3 (diff)
downloadbcm5719-llvm-2c55613a08b1b66eb337fc5a84fd2d6b086bb8b4.tar.gz
bcm5719-llvm-2c55613a08b1b66eb337fc5a84fd2d6b086bb8b4.zip
[libFuzzer] more the feature set to InputCorpus; on feature update, change the feature counter of the old best input
llvm-svn: 282829
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerCorpus.h')
-rw-r--r--llvm/lib/Fuzzer/FuzzerCorpus.h77
1 files changed, 75 insertions, 2 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerCorpus.h b/llvm/lib/Fuzzer/FuzzerCorpus.h
index b9a06655273..6438a6035f1 100644
--- a/llvm/lib/Fuzzer/FuzzerCorpus.h
+++ b/llvm/lib/Fuzzer/FuzzerCorpus.h
@@ -17,21 +17,26 @@
#include "FuzzerDefs.h"
#include "FuzzerRandom.h"
+#include "FuzzerTracePC.h"
namespace fuzzer {
struct InputInfo {
Unit U; // The actual input data.
uint8_t Sha1[kSHA1NumBytes]; // Checksum.
+ // Number of features that this input has and no smaller input has.
+ size_t NumFeatures = 0;
+ size_t Tmp = 0; // Used by ValidateFeatureSet.
// Stats.
- uintptr_t NumExecutedMutations = 0;
- uintptr_t NumSuccessfullMutations = 0;
+ size_t NumExecutedMutations = 0;
+ size_t NumSuccessfullMutations = 0;
};
class InputCorpus {
public:
InputCorpus() {
Inputs.reserve(1 << 14); // Avoid too many resizes.
+ memset(FeatureSet, 0, sizeof(FeatureSet));
}
size_t size() const { return Inputs.size(); }
bool empty() const { return Inputs.empty(); }
@@ -44,6 +49,7 @@ class InputCorpus {
InputInfo &II = Inputs.back();
II.U = U;
memcpy(II.Sha1, Hash, kSHA1NumBytes);
+ UpdateFeatureSet(Inputs.size() - 1);
UpdateCorpusDistribution();
}
@@ -74,8 +80,68 @@ class InputCorpus {
}
}
+ void PrintFeatureSet() {
+ Printf("Features [id: cnt idx sz] ");
+ for (size_t i = 0; i < kFeatureSetSize; i++) {
+ auto &Fe = FeatureSet[i];
+ if (!Fe.Count) continue;
+ Printf("[%zd: %zd %zd] ", i, Fe.SmallestElementIdx,
+ Fe.SmallestElementSize);
+ }
+ Printf("\n\t");
+ for (size_t i = 0; i < Inputs.size(); i++)
+ if (size_t N = Inputs[i].NumFeatures)
+ Printf(" %zd=>%zd ", i, N);
+ Printf("\n");
+ }
+
private:
+ static const bool FeatureDebug = false;
+ static const size_t kFeatureSetSize = TracePC::kFeatureSetSize;
+
+ void ValidateFeatureSet() {
+ for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) {
+ Feature &Fe = FeatureSet[Idx];
+ if(Fe.Count && Fe.SmallestElementSize)
+ Inputs[Fe.SmallestElementIdx].Tmp++;
+ }
+ for (auto &II: Inputs) {
+ assert(II.Tmp == II.NumFeatures);
+ II.Tmp = 0;
+ }
+ }
+
+ void UpdateFeatureSet(size_t CurrentElementIdx) {
+ auto &II = Inputs[CurrentElementIdx];
+ size_t Size = II.U.size();
+ if (!Size)
+ return;
+ bool Updated = false;
+ for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) {
+ if (!TPC.HasFeature(Idx))
+ continue;
+ Feature &Fe = FeatureSet[Idx];
+ Fe.Count++;
+ if (!Fe.SmallestElementSize ||
+ Fe.SmallestElementSize > Size) {
+ II.NumFeatures++;
+ if (Fe.SmallestElementSize > Size) {
+ auto &OlderII = Inputs[Fe.SmallestElementIdx];
+ assert(OlderII.NumFeatures > 0);
+ OlderII.NumFeatures--;
+ if (!OlderII.NumFeatures && FeatureDebug)
+ Printf("EVICTED %zd\n", Fe.SmallestElementIdx);
+ }
+ Fe.SmallestElementIdx = CurrentElementIdx;
+ Fe.SmallestElementSize = Size;
+ Updated = true;
+ }
+ }
+ if (Updated && FeatureDebug) PrintFeatureSet();
+ ValidateFeatureSet();
+ }
+
// Updates the probability distribution for the units in the corpus.
// Must be called whenever the corpus or unit weights are changed.
void UpdateCorpusDistribution() {
@@ -91,6 +157,13 @@ private:
std::unordered_set<std::string> Hashes;
std::vector<InputInfo> Inputs;
+
+ struct Feature {
+ size_t Count;
+ size_t SmallestElementIdx;
+ size_t SmallestElementSize;
+ };
+ Feature FeatureSet[kFeatureSetSize];
};
} // namespace fuzzer
OpenPOWER on IntegriCloud