diff options
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerMutate.cpp')
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerMutate.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp index 8f1b1c6db97..e25a00d84ac 100644 --- a/llvm/lib/Fuzzer/FuzzerMutate.cpp +++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp @@ -41,6 +41,10 @@ MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) { Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"}); else Mutators = DefaultMutators; + + if (EF.LLVMFuzzerCustomCrossOver) + Mutators.push_back( + {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"}); } static char FlipRandomBit(char X, Random &Rand) { @@ -66,6 +70,25 @@ size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size, return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand()); } +size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size, + size_t MaxSize) { + if (!Corpus || Corpus->size() < 2 || Size == 0) + return 0; + size_t Idx = Rand(Corpus->size()); + const Unit &Other = (*Corpus)[Idx]; + if (Other.empty()) + return 0; + MutateInPlaceHere.resize(MaxSize); + auto &U = MutateInPlaceHere; + size_t NewSize = EF.LLVMFuzzerCustomCrossOver( + Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand()); + if (!NewSize) + return 0; + assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit"); + memcpy(Data, U.data(), NewSize); + return NewSize; +} + size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize) { assert(Size); |