summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Fuzzer/FuzzerCorpus.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerCorpus.h')
-rw-r--r--llvm/lib/Fuzzer/FuzzerCorpus.h110
1 files changed, 55 insertions, 55 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerCorpus.h b/llvm/lib/Fuzzer/FuzzerCorpus.h
index ea4f0c706c7..a46f1dccb45 100644
--- a/llvm/lib/Fuzzer/FuzzerCorpus.h
+++ b/llvm/lib/Fuzzer/FuzzerCorpus.h
@@ -34,9 +34,11 @@ struct InputInfo {
class InputCorpus {
public:
+ static const size_t kFeatureSetSize = 1 << 16;
InputCorpus() {
Inputs.reserve(1 << 14); // Avoid too many resizes.
- memset(FeatureSet, 0, sizeof(FeatureSet));
+ memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));
+ memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));
}
size_t size() const { return Inputs.size(); }
size_t SizeInBytes() const {
@@ -53,17 +55,20 @@ class InputCorpus {
}
bool empty() const { return Inputs.empty(); }
const Unit &operator[] (size_t Idx) const { return Inputs[Idx].U; }
- void AddToCorpus(const Unit &U) {
+ void AddToCorpus(const Unit &U, size_t NumFeatures) {
assert(!U.empty());
uint8_t Hash[kSHA1NumBytes];
+ if (FeatureDebug)
+ Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures);
ComputeSHA1(U.data(), U.size(), Hash);
- if (!Hashes.insert(Sha1ToString(Hash)).second) return;
+ Hashes.insert(Sha1ToString(Hash));
Inputs.push_back(InputInfo());
InputInfo &II = Inputs.back();
II.U = U;
+ II.NumFeatures = NumFeatures;
memcpy(II.Sha1, Hash, kSHA1NumBytes);
- UpdateFeatureSet(Inputs.size() - 1);
UpdateCorpusDistribution();
+ ValidateFeatureSet();
}
typedef const std::vector<InputInfo>::const_iterator ConstIter;
@@ -97,12 +102,9 @@ class InputCorpus {
}
void PrintFeatureSet() {
- Printf("Features [id: 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);
+ if(size_t Sz = GetFeature(i))
+ Printf("[%zd: id %zd sz%zd] ", i, SmallestElementPerFeature[i], Sz);
}
Printf("\n\t");
for (size_t i = 0; i < Inputs.size(); i++)
@@ -111,57 +113,59 @@ class InputCorpus {
Printf("\n");
}
+ bool AddFeature(size_t Idx, uint32_t NewSize, bool Shrink) {
+ assert(NewSize);
+ Idx = Idx % kFeatureSetSize;
+ uint32_t OldSize = GetFeature(Idx);
+ if (OldSize == 0 || (Shrink && OldSize > NewSize)) {
+ if (OldSize > 0) {
+ InputInfo &II = Inputs[SmallestElementPerFeature[Idx]];
+ assert(II.NumFeatures > 0);
+ II.NumFeatures--;
+ if (II.NumFeatures == 0) {
+ II.U.clear();
+ if (FeatureDebug)
+ Printf("EVICTED %zd\n", SmallestElementPerFeature[Idx]);
+ }
+ }
+ if (FeatureDebug)
+ Printf("ADD FEATURE %zd sz %d\n", Idx, NewSize);
+ SmallestElementPerFeature[Idx] = Inputs.size();
+ InputSizesPerFeature[Idx] = NewSize;
+ CountingFeatures = true;
+ return true;
+ }
+ return false;
+ }
+
+ size_t NumFeatures() const {
+ size_t Res = 0;
+ for (size_t i = 0; i < kFeatureSetSize; i++)
+ Res += GetFeature(i) != 0;
+ return Res;
+ }
+
private:
static const bool FeatureDebug = false;
- static const size_t kFeatureSetSize = TracePC::kFeatureSetSize;
+
+ size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; }
void ValidateFeatureSet() {
- for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) {
- Feature &Fe = FeatureSet[Idx];
- if(Fe.Count && Fe.SmallestElementSize)
- Inputs[Fe.SmallestElementIdx].Tmp++;
- }
+ if (!CountingFeatures) return;
+ if (FeatureDebug)
+ PrintFeatureSet();
+ for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++)
+ if (GetFeature(Idx))
+ Inputs[SmallestElementPerFeature[Idx]].Tmp++;
for (auto &II: Inputs) {
+ if (II.Tmp != II.NumFeatures)
+ Printf("ZZZ %zd %zd\n", II.Tmp, II.NumFeatures);
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++;
- CountingFeatures = true;
- if (Fe.SmallestElementSize > Size) {
- auto &OlderII = Inputs[Fe.SmallestElementIdx];
- assert(OlderII.NumFeatures > 0);
- OlderII.NumFeatures--;
- if (!OlderII.NumFeatures) {
- OlderII.U.clear(); // Will be never used again.
- if (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() {
@@ -185,13 +189,9 @@ private:
std::unordered_set<std::string> Hashes;
std::vector<InputInfo> Inputs;
- struct Feature {
- size_t Count;
- size_t SmallestElementIdx;
- size_t SmallestElementSize;
- };
bool CountingFeatures = false;
- Feature FeatureSet[kFeatureSetSize];
+ uint32_t InputSizesPerFeature[kFeatureSetSize];
+ uint32_t SmallestElementPerFeature[kFeatureSetSize];
};
} // namespace fuzzer
OpenPOWER on IntegriCloud