X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FFuzzer%2FFuzzerMutate.cpp;h=c425ae0c1cdd970f6316d0aa46dac7d41b89e062;hb=41bdb7ca96347b56769dc996aabd23d771a22c39;hp=66df98a66f5da71cfec7450097a0d978cea3e4b3;hpb=33a9a09cd77dfb4282da4c4e76d37f825c773a50;p=oota-llvm.git diff --git a/lib/Fuzzer/FuzzerMutate.cpp b/lib/Fuzzer/FuzzerMutate.cpp index 66df98a66f5..c425ae0c1cd 100644 --- a/lib/Fuzzer/FuzzerMutate.cpp +++ b/lib/Fuzzer/FuzzerMutate.cpp @@ -13,6 +13,8 @@ #include "FuzzerInternal.h" +#include + namespace fuzzer { static char FlipRandomBit(char X, FuzzerRandomBase &Rand) { @@ -33,6 +35,51 @@ static char RandCh(FuzzerRandomBase &Rand) { return Special[Rand(sizeof(Special) - 1)]; } +size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize, + FuzzerRandomBase &Rand) { + assert(Size); + size_t ShuffleAmount = Rand(std::min(Size, 8UL)) + 1; // [1,8] and <= Size. + size_t ShuffleStart = Rand(Size - ShuffleAmount); + assert(ShuffleStart + ShuffleAmount <= Size); + std::random_shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, + Rand); + return Size; +} + +size_t Mutate_EraseByte(uint8_t *Data, size_t Size, size_t MaxSize, + FuzzerRandomBase &Rand) { + assert(Size); + if (Size == 1) return Size; + size_t Idx = Rand(Size); + // Erase Data[Idx]. + memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1); + return Size - 1; +} + +size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize, + FuzzerRandomBase &Rand) { + if (Size == MaxSize) return Size; + size_t Idx = Rand(Size + 1); + // Insert new value at Data[Idx]. + memmove(Data + Idx + 1, Data + Idx, Size - Idx); + Data[Idx] = RandCh(Rand); + return Size + 1; +} + +size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize, + FuzzerRandomBase &Rand) { + size_t Idx = Rand(Size); + Data[Idx] = RandCh(Rand); + return Size; +} + +size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize, + FuzzerRandomBase &Rand) { + size_t Idx = Rand(Size); + Data[Idx] = FlipRandomBit(Data[Idx], Rand); + return Size; +} + // Mutates Data in place, returns new size. size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, FuzzerRandomBase &Rand) { @@ -44,26 +91,12 @@ size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, return MaxSize; } assert(Size > 0); - size_t Idx = Rand(Size); - switch (Rand(3)) { - case 0: - if (Size > 1) { - // Erase Data[Idx]. - memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1); - Size = Size - 1; - } - [[clang::fallthrough]]; - case 1: - if (Size < MaxSize) { - // Insert new value at Data[Idx]. - memmove(Data + Idx + 1, Data + Idx, Size - Idx); - Data[Idx] = RandCh(Rand); - } - Data[Idx] = RandCh(Rand); - break; - case 2: - Data[Idx] = FlipRandomBit(Data[Idx], Rand); - break; + switch (Rand(5)) { + case 0: Size = Mutate_EraseByte(Data, Size, MaxSize, Rand); break; + case 1: Size = Mutate_InsertByte(Data, Size, MaxSize, Rand); break; + case 2: Size = Mutate_ChangeByte(Data, Size, MaxSize, Rand); break; + case 3: Size = Mutate_ChangeBit(Data, Size, MaxSize, Rand); break; + case 4: Size = Mutate_ShuffleBytes(Data, Size, MaxSize, Rand); break; } assert(Size > 0); return Size;