summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Fuzzer/FuzzerMutate.cpp
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-02-13 03:37:24 +0000
committerKostya Serebryany <kcc@google.com>2016-02-13 03:37:24 +0000
commit292cf0379c2656177361b9be7ee1f3bd316dca8d (patch)
treec5dab3408328b67336e20a869d671d4d82c75fcd /llvm/lib/Fuzzer/FuzzerMutate.cpp
parent7ec0c56e07eb9fa7b571274214e2452c33adaabc (diff)
downloadbcm5719-llvm-292cf0379c2656177361b9be7ee1f3bd316dca8d.tar.gz
bcm5719-llvm-292cf0379c2656177361b9be7ee1f3bd316dca8d.zip
[libFuzzer] get rid of MutationDispatcher::Impl (simplify the code; NFC)
llvm-svn: 260799
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerMutate.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerMutate.cpp169
1 files changed, 37 insertions, 132 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp
index d5eece68aac..ff099f17636 100644
--- a/llvm/lib/Fuzzer/FuzzerMutate.cpp
+++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp
@@ -13,107 +13,11 @@
#include "FuzzerInternal.h"
-#include <algorithm>
namespace fuzzer {
-struct Mutator {
- size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
- const char *Name;
-};
-
-class DictionaryEntry {
- public:
- DictionaryEntry() {}
- DictionaryEntry(Word W) : W(W) {}
- DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
- const Word &GetW() const { return W; }
-
- bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); }
- size_t GetPositionHint() const {
- assert(HasPositionHint());
- return PositionHint;
- }
- void IncUseCount() { UseCount++; }
- void IncSuccessCount() { SuccessCount++; }
- size_t GetUseCount() const { return UseCount; }
- size_t GetSuccessCount() const {return SuccessCount; }
-
-private:
- Word W;
- size_t PositionHint = std::numeric_limits<size_t>::max();
- size_t UseCount = 0;
- size_t SuccessCount = 0;
-};
-
-class Dictionary {
- public:
- static const size_t kMaxDictSize = 1 << 14;
-
- bool ContainsWord(const Word &W) const {
- return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {
- return DE.GetW() == W;
- });
- }
- const DictionaryEntry *begin() const { return &DE[0]; }
- const DictionaryEntry *end() const { return begin() + Size; }
- DictionaryEntry & operator[] (size_t Idx) {
- assert(Idx < Size);
- return DE[Idx];
- }
- void push_back(DictionaryEntry DE) {
- if (Size < kMaxDictSize)
- this->DE[Size++] = DE;
- }
- void clear() { Size = 0; }
- bool empty() const { return Size == 0; }
- size_t size() const { return Size; }
-
-private:
- DictionaryEntry DE[kMaxDictSize];
- size_t Size = 0;
-};
-
const size_t Dictionary::kMaxDictSize;
-
-struct MutationDispatcher::Impl {
- // Dictionary provided by the user via -dict=DICT_FILE.
- Dictionary ManualDictionary;
- // Temporary dictionary modified by the fuzzer itself,
- // recreated periodically.
- Dictionary TempAutoDictionary;
- // Persistent dictionary modified by the fuzzer, consists of
- // entries that led to successfull discoveries in the past mutations.
- Dictionary PersistentAutoDictionary;
-
- std::vector<Mutator> Mutators;
- std::vector<Mutator> CurrentMutatorSequence;
- std::vector<DictionaryEntry *> CurrentDictionaryEntrySequence;
- const std::vector<Unit> *Corpus = nullptr;
- Random &Rand;
-
- void Add(Mutator M) { Mutators.push_back(M); }
- Impl(Random &Rand) : Rand(Rand) {
- Add({&MutationDispatcher::Mutate_EraseByte, "EraseByte"});
- Add({&MutationDispatcher::Mutate_InsertByte, "InsertByte"});
- Add({&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"});
- Add({&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"});
- Add({&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"});
- Add({&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"});
- Add({&MutationDispatcher::Mutate_CrossOver, "CrossOver"});
- Add({&MutationDispatcher::Mutate_AddWordFromManualDictionary,
- "AddFromManualDict"});
- Add({&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
- "AddFromTempAutoDict"});
- Add({&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
- "AddFromPersAutoDict"});
- }
- void SetCorpus(const std::vector<Unit> *Corpus) { this->Corpus = Corpus; }
- size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
- size_t MaxSize);
-};
-
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) {
Random R(Seed);
MutationDispatcher MD(R);
@@ -187,26 +91,21 @@ size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
size_t MutationDispatcher::Mutate_AddWordFromManualDictionary(uint8_t *Data,
size_t Size,
size_t MaxSize) {
- return MDImpl->AddWordFromDictionary(MDImpl->ManualDictionary, Data, Size,
- MaxSize);
+ return AddWordFromDictionary(ManualDictionary, Data, Size, MaxSize);
}
size_t MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary(
uint8_t *Data, size_t Size, size_t MaxSize) {
- return MDImpl->AddWordFromDictionary(MDImpl->TempAutoDictionary, Data, Size,
- MaxSize);
+ return AddWordFromDictionary(TempAutoDictionary, Data, Size, MaxSize);
}
size_t MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary(
uint8_t *Data, size_t Size, size_t MaxSize) {
- return MDImpl->AddWordFromDictionary(MDImpl->PersistentAutoDictionary, Data, Size,
- MaxSize);
+ return AddWordFromDictionary(PersistentAutoDictionary, Data, Size, MaxSize);
}
-size_t MutationDispatcher::Impl::AddWordFromDictionary(Dictionary &D,
- uint8_t *Data,
- size_t Size,
- size_t MaxSize) {
+size_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,
+ size_t Size, size_t MaxSize) {
if (D.empty()) return 0;
DictionaryEntry &DE = D[Rand(D.size())];
const Word &W = DE.GetW();
@@ -263,7 +162,6 @@ size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
size_t MaxSize) {
- auto Corpus = MDImpl->Corpus;
if (!Corpus || Corpus->size() < 2 || Size == 0) return 0;
size_t Idx = Rand(Corpus->size());
const Unit &Other = (*Corpus)[Idx];
@@ -278,25 +176,25 @@ size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
}
void MutationDispatcher::StartMutationSequence() {
- MDImpl->CurrentMutatorSequence.clear();
- MDImpl->CurrentDictionaryEntrySequence.clear();
+ CurrentMutatorSequence.clear();
+ CurrentDictionaryEntrySequence.clear();
}
// Copy successful dictionary entries to PersistentAutoDictionary.
void MutationDispatcher::RecordSuccessfulMutationSequence() {
- for (auto DE : MDImpl->CurrentDictionaryEntrySequence) {
- // MDImpl->PersistentAutoDictionary.AddWithSuccessCountOne(DE);
+ for (auto DE : CurrentDictionaryEntrySequence) {
+ // PersistentAutoDictionary.AddWithSuccessCountOne(DE);
DE->IncSuccessCount();
// Linear search is fine here as this happens seldom.
- if (!MDImpl->PersistentAutoDictionary.ContainsWord(DE->GetW()))
- MDImpl->PersistentAutoDictionary.push_back({DE->GetW(), 1});
+ if (!PersistentAutoDictionary.ContainsWord(DE->GetW()))
+ PersistentAutoDictionary.push_back({DE->GetW(), 1});
}
}
void MutationDispatcher::PrintRecommendedDictionary() {
std::vector<DictionaryEntry> V;
- for (auto &DE : MDImpl->PersistentAutoDictionary)
- if (!MDImpl->ManualDictionary.ContainsWord(DE.GetW()))
+ for (auto &DE : PersistentAutoDictionary)
+ if (!ManualDictionary.ContainsWord(DE.GetW()))
V.push_back(DE);
if (V.empty()) return;
Printf("###### Recommended dictionary. ######\n");
@@ -309,12 +207,12 @@ void MutationDispatcher::PrintRecommendedDictionary() {
}
void MutationDispatcher::PrintMutationSequence() {
- Printf("MS: %zd ", MDImpl->CurrentMutatorSequence.size());
- for (auto M : MDImpl->CurrentMutatorSequence)
+ Printf("MS: %zd ", CurrentMutatorSequence.size());
+ for (auto M : CurrentMutatorSequence)
Printf("%s-", M.Name);
- if (!MDImpl->CurrentDictionaryEntrySequence.empty()) {
+ if (!CurrentDictionaryEntrySequence.empty()) {
Printf(" DE: ");
- for (auto DE : MDImpl->CurrentDictionaryEntrySequence) {
+ for (auto DE : CurrentDictionaryEntrySequence) {
Printf("\"");
PrintASCII(DE->GetW(), "\"-");
}
@@ -335,41 +233,48 @@ size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
// in which case they will return 0.
// Try several times before returning un-mutated data.
for (int Iter = 0; Iter < 10; Iter++) {
- size_t MutatorIdx = Rand(MDImpl->Mutators.size());
- auto M = MDImpl->Mutators[MutatorIdx];
+ size_t MutatorIdx = Rand(Mutators.size());
+ auto M = Mutators[MutatorIdx];
size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
if (NewSize) {
- MDImpl->CurrentMutatorSequence.push_back(M);
+ CurrentMutatorSequence.push_back(M);
return NewSize;
}
}
return Size;
}
-void MutationDispatcher::SetCorpus(const std::vector<Unit> *Corpus) {
- MDImpl->SetCorpus(Corpus);
-}
-
void MutationDispatcher::AddWordToManualDictionary(const Word &W) {
- MDImpl->ManualDictionary.push_back(
+ ManualDictionary.push_back(
{W, std::numeric_limits<size_t>::max()});
}
void MutationDispatcher::AddWordToAutoDictionary(const Word &W,
size_t PositionHint) {
static const size_t kMaxAutoDictSize = 1 << 14;
- if (MDImpl->TempAutoDictionary.size() >= kMaxAutoDictSize) return;
- MDImpl->TempAutoDictionary.push_back({W, PositionHint});
+ if (TempAutoDictionary.size() >= kMaxAutoDictSize) return;
+ TempAutoDictionary.push_back({W, PositionHint});
}
void MutationDispatcher::ClearAutoDictionary() {
- MDImpl->TempAutoDictionary.clear();
+ TempAutoDictionary.clear();
}
MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) {
- MDImpl = new Impl(Rand);
+ Add({&MutationDispatcher::Mutate_EraseByte, "EraseByte"});
+ Add({&MutationDispatcher::Mutate_InsertByte, "InsertByte"});
+ Add({&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"});
+ Add({&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"});
+ Add({&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"});
+ Add({&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"});
+ Add({&MutationDispatcher::Mutate_CrossOver, "CrossOver"});
+ Add({&MutationDispatcher::Mutate_AddWordFromManualDictionary,
+ "AddFromManualDict"});
+ Add({&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
+ "AddFromTempAutoDict"});
+ Add({&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
+ "AddFromPersAutoDict"});
}
-MutationDispatcher::~MutationDispatcher() { delete MDImpl; }
} // namespace fuzzer
OpenPOWER on IntegriCloud