mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-26 14:16:12 +00:00
[libfuzzer] hiding custom mutator handling in MutationDispatcher.
Summary: Refactoring, no functional changes. Differential Revision: http://reviews.llvm.org/D20975 llvm-svn: 271740
This commit is contained in:
parent
0670f91a65
commit
e89c6e8b16
@ -205,7 +205,7 @@ private:
|
||||
|
||||
class MutationDispatcher {
|
||||
public:
|
||||
MutationDispatcher(Random &Rand) : Rand(Rand) {}
|
||||
MutationDispatcher(Random &Rand);
|
||||
~MutationDispatcher() {}
|
||||
/// Indicate that we are about to start a new sequence of mutations.
|
||||
void StartMutationSequence();
|
||||
@ -213,6 +213,8 @@ public:
|
||||
void PrintMutationSequence();
|
||||
/// Indicate that the current sequence of mutations was successfull.
|
||||
void RecordSuccessfulMutationSequence();
|
||||
/// Mutates data by invoking user-provided mutator.
|
||||
size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
/// Mutates data by shuffling bytes.
|
||||
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
/// Mutates data by erasing a byte.
|
||||
@ -242,9 +244,12 @@ public:
|
||||
/// CrossOver Data with some other element of the corpus.
|
||||
size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
|
||||
/// Applies one of the above mutations.
|
||||
/// Applies one of the configured mutations.
|
||||
/// Returns the new size of data which could be up to MaxSize.
|
||||
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
/// Applies one of the default mutations. Provided as a service
|
||||
/// to mutation authors.
|
||||
size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
|
||||
/// Creates a cross-over of two pieces of Data, returns its size.
|
||||
size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
|
||||
@ -269,6 +274,11 @@ private:
|
||||
|
||||
size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
|
||||
size_t MaxSize);
|
||||
size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
|
||||
const std::vector<Mutator> &Mutators);
|
||||
|
||||
// Interface to functions that may or may not be available.
|
||||
const ExternalFunctions EF;
|
||||
|
||||
Random &Rand;
|
||||
// Dictionary provided by the user via -dict=DICT_FILE.
|
||||
@ -284,7 +294,8 @@ private:
|
||||
const std::vector<Unit> *Corpus = nullptr;
|
||||
std::vector<uint8_t> MutateInPlaceHere;
|
||||
|
||||
static Mutator Mutators[];
|
||||
std::vector<Mutator> Mutators;
|
||||
std::vector<Mutator> DefaultMutators;
|
||||
};
|
||||
|
||||
class Fuzzer {
|
||||
@ -471,7 +482,8 @@ private:
|
||||
static thread_local bool IsMyThread;
|
||||
|
||||
// Interface to functions that may or may not be available.
|
||||
ExternalFunctions EF;
|
||||
// For future use, currently not used.
|
||||
const ExternalFunctions EF;
|
||||
};
|
||||
|
||||
}; // namespace fuzzer
|
||||
|
@ -692,11 +692,7 @@ void Fuzzer::MutateAndTestOne() {
|
||||
|
||||
for (int i = 0; i < Options.MutateDepth; i++) {
|
||||
size_t NewSize = 0;
|
||||
if (EF.LLVMFuzzerCustomMutator)
|
||||
NewSize = EF.LLVMFuzzerCustomMutator(CurrentUnitData, Size,
|
||||
Options.MaxLen, MD.GetRand().Rand());
|
||||
else
|
||||
NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
|
||||
NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
|
||||
assert(NewSize > 0 && "Mutator returned empty unit");
|
||||
assert(NewSize <= Options.MaxLen &&
|
||||
"Mutator return overisized unit");
|
||||
@ -816,6 +812,6 @@ extern "C" {
|
||||
|
||||
size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
|
||||
assert(fuzzer::F);
|
||||
return fuzzer::F->GetMD().Mutate(Data, Size, MaxSize);
|
||||
return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
|
||||
}
|
||||
} // extern "C"
|
||||
|
@ -18,21 +18,30 @@ namespace fuzzer {
|
||||
|
||||
const size_t Dictionary::kMaxDictSize;
|
||||
|
||||
MutationDispatcher::Mutator MutationDispatcher::Mutators[] = {
|
||||
{&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
|
||||
{&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
|
||||
{&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
|
||||
{&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
|
||||
{&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
|
||||
{&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
|
||||
{&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
|
||||
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
|
||||
"AddFromManualDict"},
|
||||
{&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
|
||||
"AddFromTempAutoDict"},
|
||||
{&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
|
||||
"AddFromPersAutoDict"},
|
||||
};
|
||||
MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) {
|
||||
DefaultMutators.insert(
|
||||
DefaultMutators.begin(),
|
||||
{
|
||||
{&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
|
||||
{&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
|
||||
{&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
|
||||
{&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
|
||||
{&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
|
||||
{&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
|
||||
{&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
|
||||
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
|
||||
"AddFromManualDict"},
|
||||
{&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
|
||||
"AddFromTempAutoDict"},
|
||||
{&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
|
||||
"AddFromPersAutoDict"},
|
||||
});
|
||||
|
||||
if (EF.LLVMFuzzerCustomMutator)
|
||||
Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
|
||||
else
|
||||
Mutators = DefaultMutators;
|
||||
}
|
||||
|
||||
static char FlipRandomBit(char X, Random &Rand) {
|
||||
int Bit = Rand(8);
|
||||
@ -52,6 +61,11 @@ static char RandCh(Random &Rand) {
|
||||
return Special[Rand(sizeof(Special) - 1)];
|
||||
}
|
||||
|
||||
size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize) {
|
||||
return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
|
||||
}
|
||||
|
||||
size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize) {
|
||||
assert(Size);
|
||||
@ -230,8 +244,19 @@ void MutationDispatcher::PrintMutationSequence() {
|
||||
}
|
||||
}
|
||||
|
||||
// Mutates Data in place, returns new size.
|
||||
size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
|
||||
return MutateImpl(Data, Size, MaxSize, Mutators);
|
||||
}
|
||||
|
||||
size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize) {
|
||||
return MutateImpl(Data, Size, MaxSize, DefaultMutators);
|
||||
}
|
||||
|
||||
// Mutates Data in place, returns new size.
|
||||
size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize,
|
||||
const std::vector<Mutator> &Mutators) {
|
||||
assert(MaxSize > 0);
|
||||
assert(Size <= MaxSize);
|
||||
if (Size == 0) {
|
||||
@ -244,9 +269,7 @@ 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 NumMutators = sizeof(Mutators) / sizeof(Mutators[0]);
|
||||
size_t MutatorIdx = Rand(NumMutators);
|
||||
auto M = Mutators[MutatorIdx];
|
||||
auto M = Mutators[Rand(Mutators.size())];
|
||||
size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
|
||||
if (NewSize) {
|
||||
CurrentMutatorSequence.push_back(M);
|
||||
|
Loading…
x
Reference in New Issue
Block a user