aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Fuzzer/FuzzerMutate.cpp
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-08-15 17:48:28 +0000
committerKostya Serebryany <kcc@google.com>2016-08-15 17:48:28 +0000
commitdfbe59b03db728a0cdfdf1bf763439a511c5ee09 (patch)
treeaaf9658c1515c4d6dce4df3c2adc4717e1c1820d /llvm/lib/Fuzzer/FuzzerMutate.cpp
parentd09a44a2201d49a5a8965156035b8b19d610e252 (diff)
downloadllvm-dfbe59b03db728a0cdfdf1bf763439a511c5ee09.zip
llvm-dfbe59b03db728a0cdfdf1bf763439a511c5ee09.tar.gz
llvm-dfbe59b03db728a0cdfdf1bf763439a511c5ee09.tar.bz2
[libFuzzer] add InsertRepeatedBytes and EraseBytes.
New mutation: InsertRepeatedBytes. Updated mutation: EraseByte => EraseBytes. This helps https://github.com/google/sanitizers/issues/710 where libFuzzer was not able to find a known bug. Now it finds it in minutes. Hopefully, the change is general enough to help other targets. llvm-svn: 278687
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerMutate.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerMutate.cpp36
1 files changed, 29 insertions, 7 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp
index 65e1650..05ea39d 100644
--- a/llvm/lib/Fuzzer/FuzzerMutate.cpp
+++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp
@@ -24,8 +24,10 @@ MutationDispatcher::MutationDispatcher(Random &Rand,
DefaultMutators.insert(
DefaultMutators.begin(),
{
- {&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
+ {&MutationDispatcher::Mutate_EraseBytes, "EraseBytes"},
{&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
+ {&MutationDispatcher::Mutate_InsertRepeatedBytes,
+ "InsertRepeatedBytes"},
{&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
{&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
{&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
@@ -103,14 +105,17 @@ size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
return Size;
}
-size_t MutationDispatcher::Mutate_EraseByte(uint8_t *Data, size_t Size,
- size_t MaxSize) {
+size_t MutationDispatcher::Mutate_EraseBytes(uint8_t *Data, size_t Size,
+ size_t MaxSize) {
assert(Size);
if (Size == 1) return 0;
- size_t Idx = Rand(Size);
- // Erase Data[Idx].
- memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
- return Size - 1;
+ size_t N = Rand(Size / 2) + 1;
+ assert(N < Size);
+ size_t Idx = Rand(Size - N + 1);
+ // Erase Data[Idx:Idx+N].
+ memmove(Data + Idx, Data + Idx + N, Size - Idx - N);
+ // Printf("Erase: %zd %zd => %zd; Idx %zd\n", N, Size, Size - N, Idx);
+ return Size - N;
}
size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
@@ -123,6 +128,23 @@ size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
return Size + 1;
}
+size_t MutationDispatcher::Mutate_InsertRepeatedBytes(uint8_t *Data,
+ size_t Size,
+ size_t MaxSize) {
+ const size_t kMinBytesToInsert = 3;
+ if (Size + kMinBytesToInsert >= MaxSize) return 0;
+ size_t MaxBytesToInsert = std::min(MaxSize - Size, (size_t)128);
+ size_t N = Rand(MaxBytesToInsert - kMinBytesToInsert + 1) + kMinBytesToInsert;
+ assert(Size + N <= MaxSize && N);
+ size_t Idx = Rand(Size + 1);
+ // Insert new values at Data[Idx].
+ memmove(Data + Idx + N, Data + Idx, Size - Idx);
+ uint8_t Byte = RandCh(Rand);
+ for (size_t i = 0; i < N; i++)
+ Data[Idx + i] = Byte;
+ return Size + N;
+}
+
size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
size_t MaxSize) {
size_t Idx = Rand(Size);