summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Fuzzer/FuzzerMutate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerMutate.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerMutate.cpp72
1 files changed, 59 insertions, 13 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp
index 30e5b43c083..4ea8265dfb8 100644
--- a/llvm/lib/Fuzzer/FuzzerMutate.cpp
+++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp
@@ -27,12 +27,28 @@ struct DictionaryEntry {
size_t PositionHint;
};
+struct Dictionary : public std::vector<DictionaryEntry>{
+ bool ContainsWord(const Unit &W) const {
+ return end() !=
+ std::find_if(begin(), end(), [&](const DictionaryEntry &DE) {
+ return DE.Word == W;
+ });
+ }
+};
+
struct MutationDispatcher::Impl {
- std::vector<DictionaryEntry> ManualDictionary;
- std::vector<DictionaryEntry> AutoDictionary;
+ // 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;
+ Dictionary CurrentDictionaryEntrySequence;
const std::vector<Unit> *Corpus = nullptr;
FuzzerRandomBase &Rand;
@@ -47,8 +63,10 @@ struct MutationDispatcher::Impl {
Add({&MutationDispatcher::Mutate_CrossOver, "CrossOver"});
Add({&MutationDispatcher::Mutate_AddWordFromManualDictionary,
"AddFromManualDict"});
- Add({&MutationDispatcher::Mutate_AddWordFromAutoDictionary,
- "AddFromAutoDict"});
+ Add({&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
+ "AddFromTempAutoDict"});
+ Add({&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
+ "AddFromPersAutoDict"});
}
void SetCorpus(const std::vector<Unit> *Corpus) { this->Corpus = Corpus; }
size_t AddWordFromDictionary(const std::vector<DictionaryEntry> &D,
@@ -126,10 +144,15 @@ size_t MutationDispatcher::Mutate_AddWordFromManualDictionary(uint8_t *Data,
MaxSize);
}
-size_t MutationDispatcher::Mutate_AddWordFromAutoDictionary(uint8_t *Data,
- size_t Size,
- size_t MaxSize) {
- return MDImpl->AddWordFromDictionary(MDImpl->AutoDictionary, Data, Size,
+size_t MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary(
+ uint8_t *Data, size_t Size, size_t MaxSize) {
+ return MDImpl->AddWordFromDictionary(MDImpl->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);
}
@@ -211,13 +234,36 @@ void MutationDispatcher::StartMutationSequence() {
MDImpl->CurrentDictionaryEntrySequence.clear();
}
+// Copy successful dictionary entries to PersistentAutoDictionary.
+void MutationDispatcher::RecordSuccessfulMutationSequence() {
+ for (auto &DE : MDImpl->CurrentDictionaryEntrySequence)
+ // Linear search is fine here as this happens seldom.
+ if (!MDImpl->PersistentAutoDictionary.ContainsWord(DE.Word))
+ MDImpl->PersistentAutoDictionary.push_back(
+ {DE.Word, std::numeric_limits<size_t>::max()});
+}
+
+void MutationDispatcher::PrintRecommendedDictionary() {
+ std::vector<Unit> V;
+ for (auto &DE : MDImpl->PersistentAutoDictionary)
+ if (!MDImpl->ManualDictionary.ContainsWord(DE.Word))
+ V.push_back(DE.Word);
+ if (V.empty()) return;
+ Printf("###### Recommended dictionary. ######\n");
+ for (auto &U: V) {
+ Printf("\"");
+ PrintASCII(U, "\"\n");
+ }
+ Printf("###### End of recommended dictionary. ######\n");
+}
+
void MutationDispatcher::PrintMutationSequence() {
Printf("MS: %zd ", MDImpl->CurrentMutatorSequence.size());
for (auto M : MDImpl->CurrentMutatorSequence)
Printf("%s-", M.Name);
if (!MDImpl->CurrentDictionaryEntrySequence.empty()) {
Printf(" DE: ");
- for (auto DE : MDImpl->CurrentDictionaryEntrySequence) {
+ for (auto &DE : MDImpl->CurrentDictionaryEntrySequence) {
Printf("\"");
PrintASCII(DE.Word, "\"-");
}
@@ -261,12 +307,12 @@ void MutationDispatcher::AddWordToManualDictionary(const Unit &Word) {
void MutationDispatcher::AddWordToAutoDictionary(const Unit &Word,
size_t PositionHint) {
static const size_t kMaxAutoDictSize = 1 << 14;
- if (MDImpl->AutoDictionary.size() >= kMaxAutoDictSize) return;
- MDImpl->AutoDictionary.push_back({Word, PositionHint});
+ if (MDImpl->TempAutoDictionary.size() >= kMaxAutoDictSize) return;
+ MDImpl->TempAutoDictionary.push_back({Word, PositionHint});
}
void MutationDispatcher::ClearAutoDictionary() {
- MDImpl->AutoDictionary.clear();
+ MDImpl->TempAutoDictionary.clear();
}
MutationDispatcher::MutationDispatcher(FuzzerRandomBase &Rand) : Rand(Rand) {
OpenPOWER on IntegriCloud