summaryrefslogtreecommitdiff
path: root/test/fuzzer
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2017-08-21 23:25:50 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2017-08-21 23:25:50 +0000
commit0c8339c8aab25f1156558e9e2082b4b124dc2327 (patch)
tree4f04d28abce4cbaa73fbba2b64f56af353e0f08b /test/fuzzer
parent1a32c939c5eece22f3ca6cf70bd05a1527bc0970 (diff)
Move libFuzzer to compiler_rt.
Resulting library binaries will be named libclang_rt.fuzzer*, and will be placed in Clang toolchain, allowing redistribution. Differential Revision: https://reviews.llvm.org/D36908 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@311407 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/fuzzer')
-rw-r--r--test/fuzzer/AFLDriverTest.cpp28
-rw-r--r--test/fuzzer/AbsNegAndConstant64Test.cpp24
-rw-r--r--test/fuzzer/AbsNegAndConstantTest.cpp24
-rw-r--r--test/fuzzer/AccumulateAllocationsTest.cpp17
-rw-r--r--test/fuzzer/BadStrcmpTest.cpp19
-rw-r--r--test/fuzzer/BogusInitializeTest.cpp15
-rw-r--r--test/fuzzer/BufferOverflowOnInput.cpp24
-rw-r--r--test/fuzzer/CMakeLists.txt40
-rw-r--r--test/fuzzer/CallerCalleeTest.cpp59
-rw-r--r--test/fuzzer/CleanseTest.cpp16
-rw-r--r--test/fuzzer/CounterTest.cpp18
-rw-r--r--test/fuzzer/CustomCrossOverAndMutateTest.cpp34
-rw-r--r--test/fuzzer/CustomCrossOverTest.cpp64
-rw-r--r--test/fuzzer/CustomMutatorTest.cpp39
-rw-r--r--test/fuzzer/CxxStringEqTest.cpp25
-rw-r--r--test/fuzzer/DSO1.cpp14
-rw-r--r--test/fuzzer/DSO2.cpp14
-rw-r--r--test/fuzzer/DSOTestExtra.cpp11
-rw-r--r--test/fuzzer/DSOTestMain.cpp31
-rw-r--r--test/fuzzer/DeepRecursionTest.cpp25
-rw-r--r--test/fuzzer/DivTest.cpp20
-rw-r--r--test/fuzzer/EmptyTest.cpp11
-rw-r--r--test/fuzzer/EquivalenceATest.cpp17
-rw-r--r--test/fuzzer/EquivalenceBTest.cpp27
-rw-r--r--test/fuzzer/FlagsTest.cpp32
-rw-r--r--test/fuzzer/FourIndependentBranchesTest.cpp22
-rw-r--r--test/fuzzer/FullCoverageSetTest.cpp24
-rw-r--r--test/fuzzer/InitializeTest.cpp28
-rw-r--r--test/fuzzer/LargeTest.cpp37
-rw-r--r--test/fuzzer/LeakTest.cpp17
-rw-r--r--test/fuzzer/LeakTimeoutTest.cpp17
-rw-r--r--test/fuzzer/LoadTest.cpp22
-rw-r--r--test/fuzzer/Memcmp64BytesTest.cpp20
-rw-r--r--test/fuzzer/MemcmpTest.cpp31
-rw-r--r--test/fuzzer/NotinstrumentedTest.cpp11
-rw-r--r--test/fuzzer/NthRunCrashTest.cpp19
-rw-r--r--test/fuzzer/NullDerefOnEmptyTest.cpp19
-rw-r--r--test/fuzzer/NullDerefTest.cpp26
-rw-r--r--test/fuzzer/OneHugeAllocTest.cpp28
-rw-r--r--test/fuzzer/OutOfMemorySingleLargeMallocTest.cpp27
-rw-r--r--test/fuzzer/OutOfMemoryTest.cpp31
-rw-r--r--test/fuzzer/OverwriteInputTest.cpp13
-rw-r--r--test/fuzzer/RepeatedBytesTest.cpp31
-rw-r--r--test/fuzzer/RepeatedMemcmp.cpp24
-rw-r--r--test/fuzzer/ShrinkControlFlowSimpleTest.cpp19
-rw-r--r--test/fuzzer/ShrinkControlFlowTest.cpp31
-rw-r--r--test/fuzzer/ShrinkValueProfileTest.cpp22
-rw-r--r--test/fuzzer/SignedIntOverflowTest.cpp28
-rw-r--r--test/fuzzer/SimpleCmpTest.cpp47
-rw-r--r--test/fuzzer/SimpleDictionaryTest.cpp30
-rw-r--r--test/fuzzer/SimpleHashTest.cpp40
-rw-r--r--test/fuzzer/SimpleTest.cpp28
-rw-r--r--test/fuzzer/SimpleThreadedTest.cpp26
-rw-r--r--test/fuzzer/SingleByteInputTest.cpp17
-rw-r--r--test/fuzzer/SingleMemcmpTest.cpp17
-rw-r--r--test/fuzzer/SingleStrcmpTest.cpp21
-rw-r--r--test/fuzzer/SingleStrncmpTest.cpp18
-rw-r--r--test/fuzzer/SpamyTest.cpp21
-rw-r--r--test/fuzzer/StrcmpTest.cpp32
-rw-r--r--test/fuzzer/StrncmpOOBTest.cpp21
-rw-r--r--test/fuzzer/StrncmpTest.cpp28
-rw-r--r--test/fuzzer/StrstrTest.cpp28
-rw-r--r--test/fuzzer/SwapCmpTest.cpp35
-rw-r--r--test/fuzzer/Switch2Test.cpp35
-rw-r--r--test/fuzzer/SwitchTest.cpp58
-rw-r--r--test/fuzzer/TableLookupTest.cpp44
-rw-r--r--test/fuzzer/ThreadedLeakTest.cpp18
-rw-r--r--test/fuzzer/ThreadedTest.cpp26
-rw-r--r--test/fuzzer/TimeoutEmptyTest.cpp14
-rw-r--r--test/fuzzer/TimeoutTest.cpp26
-rw-r--r--test/fuzzer/TraceMallocTest.cpp27
-rw-r--r--test/fuzzer/TwoDifferentBugsTest.cpp22
-rw-r--r--test/fuzzer/afl-driver-extra-stats.test30
-rw-r--r--test/fuzzer/afl-driver-stderr.test12
-rw-r--r--test/fuzzer/afl-driver.test29
-rw-r--r--test/fuzzer/bad-strcmp.test2
-rw-r--r--test/fuzzer/caller-callee.test3
-rw-r--r--test/fuzzer/cleanse.test4
-rw-r--r--test/fuzzer/coverage.test21
-rw-r--r--test/fuzzer/cxxstring.test6
-rw-r--r--test/fuzzer/dict1.txt4
-rw-r--r--test/fuzzer/disable-leaks.test5
-rw-r--r--test/fuzzer/dump_coverage.test20
-rw-r--r--test/fuzzer/equivalence-signals.test9
-rw-r--r--test/fuzzer/equivalence.test9
-rw-r--r--test/fuzzer/exit-report.test6
-rw-r--r--test/fuzzer/exit_on_src_pos.test8
-rw-r--r--test/fuzzer/extra-counters.test7
-rw-r--r--test/fuzzer/fuzzer-customcrossover.test12
-rw-r--r--test/fuzzer/fuzzer-customcrossoverandmutate.test2
-rw-r--r--test/fuzzer/fuzzer-custommutator.test5
-rw-r--r--test/fuzzer/fuzzer-dict.test8
-rw-r--r--test/fuzzer/fuzzer-dirs.test21
-rw-r--r--test/fuzzer/fuzzer-fdmask.test32
-rw-r--r--test/fuzzer/fuzzer-finalstats.test12
-rw-r--r--test/fuzzer/fuzzer-flags.test19
-rw-r--r--test/fuzzer/fuzzer-leak.test37
-rw-r--r--test/fuzzer/fuzzer-oom-with-profile.test7
-rw-r--r--test/fuzzer/fuzzer-oom.test20
-rw-r--r--test/fuzzer/fuzzer-printcovpcs.test9
-rw-r--r--test/fuzzer/fuzzer-runs.test9
-rw-r--r--test/fuzzer/fuzzer-seed.test4
-rw-r--r--test/fuzzer/fuzzer-segv.test8
-rw-r--r--test/fuzzer/fuzzer-singleinputs.test19
-rw-r--r--test/fuzzer/fuzzer-threaded.test8
-rw-r--r--test/fuzzer/fuzzer-timeout.test21
-rw-r--r--test/fuzzer/fuzzer-ubsan.test5
-rw-r--r--test/fuzzer/fuzzer.test70
-rw-r--r--test/fuzzer/hi.txt1
-rw-r--r--test/fuzzer/inline-8bit-counters.test5
-rw-r--r--test/fuzzer/lit.cfg80
-rw-r--r--test/fuzzer/lit.site.cfg.in17
-rw-r--r--test/fuzzer/memcmp.test3
-rw-r--r--test/fuzzer/memcmp64.test3
-rw-r--r--test/fuzzer/merge-posix.test23
-rw-r--r--test/fuzzer/merge-summary.test17
-rw-r--r--test/fuzzer/merge.test55
-rw-r--r--test/fuzzer/minimize_crash.test16
-rw-r--r--test/fuzzer/minimize_two_crashes.test18
-rw-r--r--test/fuzzer/overwrite-input.test3
-rw-r--r--test/fuzzer/recommended-dictionary.test6
-rw-r--r--test/fuzzer/reduce_inputs.test16
-rw-r--r--test/fuzzer/repeated-bytes.test3
-rw-r--r--test/fuzzer/shrink.test10
-rw-r--r--test/fuzzer/simple-cmp.test3
-rw-r--r--test/fuzzer/standalone.test8
-rw-r--r--test/fuzzer/strcmp.test4
-rw-r--r--test/fuzzer/strncmp.test4
-rw-r--r--test/fuzzer/strstr.test4
-rw-r--r--test/fuzzer/swap-cmp.test3
-rw-r--r--test/fuzzer/trace-malloc-2.test10
-rw-r--r--test/fuzzer/trace-malloc.test7
-rw-r--r--test/fuzzer/trace-pc.test3
-rw-r--r--test/fuzzer/ulimit.test3
-rw-r--r--test/fuzzer/unit/lit.site.cfg.in9
-rw-r--r--test/fuzzer/value-profile-cmp.test3
-rw-r--r--test/fuzzer/value-profile-cmp2.test3
-rw-r--r--test/fuzzer/value-profile-cmp3.test3
-rw-r--r--test/fuzzer/value-profile-cmp4.test3
-rw-r--r--test/fuzzer/value-profile-div.test4
-rw-r--r--test/fuzzer/value-profile-load.test3
-rw-r--r--test/fuzzer/value-profile-mem.test3
-rw-r--r--test/fuzzer/value-profile-set.test4
-rw-r--r--test/fuzzer/value-profile-strcmp.test3
-rw-r--r--test/fuzzer/value-profile-strncmp.test3
-rw-r--r--test/fuzzer/value-profile-switch.test5
146 files changed, 2748 insertions, 0 deletions
diff --git a/test/fuzzer/AFLDriverTest.cpp b/test/fuzzer/AFLDriverTest.cpp
new file mode 100644
index 000000000..b949adc7d
--- /dev/null
+++ b/test/fuzzer/AFLDriverTest.cpp
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Contains dummy functions used to avoid dependency on AFL.
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C" void __afl_manual_init() {}
+
+extern "C" int __afl_persistent_loop(unsigned int N) {
+ static int Count = N;
+ fprintf(stderr, "__afl_persistent_loop calle, Count = %d\n", Count);
+ if (Count--) return 1;
+ return 0;
+}
+
+// This declaration exists to prevent the Darwin linker
+// from complaining about this being a missing weak symbol.
+extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ fprintf(stderr, "LLVMFuzzerInitialize called\n");
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ fprintf(stderr, "LLVMFuzzerTestOneInput called; Size = %zd\n", Size);
+ return 0;
+}
diff --git a/test/fuzzer/AbsNegAndConstant64Test.cpp b/test/fuzzer/AbsNegAndConstant64Test.cpp
new file mode 100644
index 000000000..abeb784e9
--- /dev/null
+++ b/test/fuzzer/AbsNegAndConstant64Test.cpp
@@ -0,0 +1,24 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// abs(x) < 0 and y == Const puzzle, 64-bit variant.
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 16) return 0;
+ int64_t x;
+ uint64_t y;
+ memcpy(&x, Data, sizeof(x));
+ memcpy(&y, Data + sizeof(x), sizeof(y));
+ if (llabs(x) < 0 && y == 0xbaddcafedeadbeefULL) {
+ printf("BINGO; Found the target, exiting; x = 0x%lx y 0x%lx\n", x, y);
+ fflush(stdout);
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/AbsNegAndConstantTest.cpp b/test/fuzzer/AbsNegAndConstantTest.cpp
new file mode 100644
index 000000000..049db0a60
--- /dev/null
+++ b/test/fuzzer/AbsNegAndConstantTest.cpp
@@ -0,0 +1,24 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// abs(x) < 0 and y == Const puzzle.
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 8) return 0;
+ int x;
+ unsigned y;
+ memcpy(&x, Data, sizeof(x));
+ memcpy(&y, Data + sizeof(x), sizeof(y));
+ if (abs(x) < 0 && y == 0xbaddcafe) {
+ printf("BINGO; Found the target, exiting; x = 0x%x y 0x%x\n", x, y);
+ fflush(stdout);
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/AccumulateAllocationsTest.cpp b/test/fuzzer/AccumulateAllocationsTest.cpp
new file mode 100644
index 000000000..e9acd7ccb
--- /dev/null
+++ b/test/fuzzer/AccumulateAllocationsTest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test with a more mallocs than frees, but no leak.
+#include <cstddef>
+#include <cstdint>
+
+const int kAllocatedPointersSize = 10000;
+int NumAllocatedPointers = 0;
+int *AllocatedPointers[kAllocatedPointersSize];
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (NumAllocatedPointers < kAllocatedPointersSize)
+ AllocatedPointers[NumAllocatedPointers++] = new int;
+ return 0;
+}
+
diff --git a/test/fuzzer/BadStrcmpTest.cpp b/test/fuzzer/BadStrcmpTest.cpp
new file mode 100644
index 000000000..ba2b068f7
--- /dev/null
+++ b/test/fuzzer/BadStrcmpTest.cpp
@@ -0,0 +1,19 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that we don't creash in case of bad strcmp params.
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size != 10) return 0;
+ // Data is not zero-terminated, so this call is bad.
+ // Still, there are cases when such calles appear, see e.g.
+ // https://bugs.llvm.org/show_bug.cgi?id=32357
+ Sink = strcmp(reinterpret_cast<const char*>(Data), "123456789");
+ return 0;
+}
+
diff --git a/test/fuzzer/BogusInitializeTest.cpp b/test/fuzzer/BogusInitializeTest.cpp
new file mode 100644
index 000000000..c7e81a547
--- /dev/null
+++ b/test/fuzzer/BogusInitializeTest.cpp
@@ -0,0 +1,15 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Make sure LLVMFuzzerInitialize does not change argv[0].
+#include <stddef.h>
+#include <stdint.h>
+
+extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ ***argv = 'X';
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ return 0;
+}
diff --git a/test/fuzzer/BufferOverflowOnInput.cpp b/test/fuzzer/BufferOverflowOnInput.cpp
new file mode 100644
index 000000000..159da92d4
--- /dev/null
+++ b/test/fuzzer/BufferOverflowOnInput.cpp
@@ -0,0 +1,24 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <ostream>
+
+static volatile bool SeedLargeBuffer;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size >= 4)
+ SeedLargeBuffer = true;
+ if (Size == 3 && SeedLargeBuffer && Data[3]) {
+ std::cout << "Woops, reading Data[3] w/o crashing\n" << std::flush;
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/CMakeLists.txt b/test/fuzzer/CMakeLists.txt
new file mode 100644
index 000000000..339978a82
--- /dev/null
+++ b/test/fuzzer/CMakeLists.txt
@@ -0,0 +1,40 @@
+set(LIBFUZZER_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+if (NOT COMPILER_RT_STANDALONE_BUILD)
+ list(APPEND LIBFUZZER_TEST_DEPS fuzzer asan)
+endif()
+
+if(COMPILER_RT_INCLUDE_TESTS)
+ list(APPEND LIBFUZZER_TEST_DEPS FuzzerUnitTests)
+endif()
+
+set(LIBFUZZER_TESTSUITES)
+
+
+if(COMPILER_RT_INCLUDE_TESTS)
+ # libFuzzer unit tests.
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg)
+ list(APPEND LIBFUZZER_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/unit)
+endif()
+
+foreach(arch ${FUZZER_SUPPORTED_ARCH})
+ set(LIBFUZZER_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER})
+ get_test_cc_for_arch(${arch} LIBFUZZER_TEST_COMPILER LIBFUZZER_TEST_FLAGS)
+
+ string(TOUPPER ${arch} ARCH_UPPER_CASE)
+ set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
+
+ # LIT-based libFuzzer tests.
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
+ )
+ list(APPEND LIBFUZZER_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+
+endforeach()
+
+add_lit_testsuite(check-fuzzer "Running Fuzzer tests"
+ ${LIBFUZZER_TESTSUITES}
+ DEPENDS ${LIBFUZZER_TEST_DEPS})
+set_target_properties(check-fuzzer PROPERTIES FOLDER "Compiler-RT Tests")
diff --git a/test/fuzzer/CallerCalleeTest.cpp b/test/fuzzer/CallerCalleeTest.cpp
new file mode 100644
index 000000000..ed9f37cc1
--- /dev/null
+++ b/test/fuzzer/CallerCalleeTest.cpp
@@ -0,0 +1,59 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer.
+// Try to find the target using the indirect caller-callee pairs.
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+typedef void (*F)();
+static F t[256];
+
+void f34() {
+ std::cerr << "BINGO\n";
+ exit(1);
+}
+void f23() { t[(unsigned)'d'] = f34;}
+void f12() { t[(unsigned)'c'] = f23;}
+void f01() { t[(unsigned)'b'] = f12;}
+void f00() {}
+
+static F t0[256] = {
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+ f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 4) return 0;
+ // Spoof the counters.
+ for (int i = 0; i < 200; i++) {
+ f23();
+ f12();
+ f01();
+ }
+ memcpy(t, t0, sizeof(t));
+ t[(unsigned)'a'] = f01;
+ t[Data[0]]();
+ t[Data[1]]();
+ t[Data[2]]();
+ t[Data[3]]();
+ return 0;
+}
+
diff --git a/test/fuzzer/CleanseTest.cpp b/test/fuzzer/CleanseTest.cpp
new file mode 100644
index 000000000..ee1845701
--- /dev/null
+++ b/test/fuzzer/CleanseTest.cpp
@@ -0,0 +1,16 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test the the fuzzer is able to 'cleanse' the reproducer
+// by replacing all irrelevant bytes with garbage.
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size >= 20 && Data[1] == '1' && Data[5] == '5' && Data[10] == 'A' &&
+ Data[19] == 'Z')
+ abort();
+ return 0;
+}
+
diff --git a/test/fuzzer/CounterTest.cpp b/test/fuzzer/CounterTest.cpp
new file mode 100644
index 000000000..4917934c6
--- /dev/null
+++ b/test/fuzzer/CounterTest.cpp
@@ -0,0 +1,18 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test for a fuzzer: must find the case where a particular basic block is
+// executed many times.
+#include <iostream>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ int Num = 0;
+ for (size_t i = 0; i < Size; i++)
+ if (Data[i] == 'A' + i)
+ Num++;
+ if (Num >= 4) {
+ std::cerr << "BINGO!\n";
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/CustomCrossOverAndMutateTest.cpp b/test/fuzzer/CustomCrossOverAndMutateTest.cpp
new file mode 100644
index 000000000..74fc93953
--- /dev/null
+++ b/test/fuzzer/CustomCrossOverAndMutateTest.cpp
@@ -0,0 +1,34 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that libFuzzer does not crash when LLVMFuzzerMutate called from
+// LLVMFuzzerCustomCrossOver.
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <string.h>
+#include <string>
+#include <vector>
+
+#include "FuzzerInterface.h"
+
+static volatile int sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ std::string Str(reinterpret_cast<const char *>(Data), Size);
+ if (Size && Data[0] == '0')
+ sink++;
+ return 0;
+}
+
+extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
+ const uint8_t *Data2, size_t Size2,
+ uint8_t *Out, size_t MaxOutSize,
+ unsigned int Seed) {
+ std::vector<uint8_t> Buffer(MaxOutSize * 10);
+ LLVMFuzzerMutate(Buffer.data(), Buffer.size(), Buffer.size());
+ size_t Size = std::min(Size1, MaxOutSize);
+ memcpy(Out, Data1, Size);
+ return Size;
+}
diff --git a/test/fuzzer/CustomCrossOverTest.cpp b/test/fuzzer/CustomCrossOverTest.cpp
new file mode 100644
index 000000000..58059c9c1
--- /dev/null
+++ b/test/fuzzer/CustomCrossOverTest.cpp
@@ -0,0 +1,64 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a cutom mutator.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <ostream>
+#include <random>
+#include <string.h>
+
+#include "FuzzerInterface.h"
+
+static const char *Separator = "-_^_-";
+static const char *Target = "012-_^_-abc";
+
+static volatile int sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ std::string Str(reinterpret_cast<const char *>(Data), Size);
+
+ // Ensure that two different elements exist in the corpus.
+ if (Size && Data[0] == '0') sink++;
+ if (Size && Data[0] == 'a') sink--;
+
+ if (Str.find(Target) != std::string::npos) {
+ std::cout << "BINGO; Found the target, exiting\n" << std::flush;
+ exit(1);
+ }
+ return 0;
+}
+
+extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
+ const uint8_t *Data2, size_t Size2,
+ uint8_t *Out, size_t MaxOutSize,
+ unsigned int Seed) {
+ static bool Printed;
+ static size_t SeparatorLen = strlen(Separator);
+
+ if (!Printed) {
+ std::cerr << "In LLVMFuzzerCustomCrossover\n";
+ Printed = true;
+ }
+
+ std::mt19937 R(Seed);
+
+ size_t Offset1 = 0;
+ size_t Len1 = R() % (Size1 - Offset1);
+ size_t Offset2 = 0;
+ size_t Len2 = R() % (Size2 - Offset2);
+ size_t Size = Len1 + Len2 + SeparatorLen;
+
+ if (Size > MaxOutSize)
+ return 0;
+
+ memcpy(Out, Data1 + Offset1, Len1);
+ memcpy(Out + Len1, Separator, SeparatorLen);
+ memcpy(Out + Len1 + SeparatorLen, Data2 + Offset2, Len2);
+
+ return Len1 + Len2 + SeparatorLen;
+}
diff --git a/test/fuzzer/CustomMutatorTest.cpp b/test/fuzzer/CustomMutatorTest.cpp
new file mode 100644
index 000000000..b2adb9408
--- /dev/null
+++ b/test/fuzzer/CustomMutatorTest.cpp
@@ -0,0 +1,39 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a cutom mutator.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <ostream>
+
+#include "FuzzerInterface.h"
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size > 0 && Data[0] == 'H') {
+ Sink = 1;
+ if (Size > 1 && Data[1] == 'i') {
+ Sink = 2;
+ if (Size > 2 && Data[2] == '!') {
+ std::cout << "BINGO; Found the target, exiting\n" << std::flush;
+ exit(1);
+ }
+ }
+ }
+ return 0;
+}
+
+extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
+ size_t MaxSize, unsigned int Seed) {
+ static bool Printed;
+ if (!Printed) {
+ std::cerr << "In LLVMFuzzerCustomMutator\n";
+ Printed = true;
+ }
+ return LLVMFuzzerMutate(Data, Size, MaxSize);
+}
diff --git a/test/fuzzer/CxxStringEqTest.cpp b/test/fuzzer/CxxStringEqTest.cpp
new file mode 100644
index 000000000..924851c5a
--- /dev/null
+++ b/test/fuzzer/CxxStringEqTest.cpp
@@ -0,0 +1,25 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. Must find a specific string
+// used in std::string operator ==.
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ std::string Str((const char*)Data, Size);
+ bool Eq = Str == "FooBar";
+ Sink = Str == "123456"; // Try to confuse the fuzzer
+ if (Eq) {
+ std::cout << "BINGO; Found the target, exiting\n";
+ std::cout.flush();
+ abort();
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/DSO1.cpp b/test/fuzzer/DSO1.cpp
new file mode 100644
index 000000000..72a5ec4a0
--- /dev/null
+++ b/test/fuzzer/DSO1.cpp
@@ -0,0 +1,14 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Source code for a simple DSO.
+#ifdef _WIN32
+__declspec( dllexport )
+#endif
+int DSO1(int a) {
+ if (a < 123456)
+ return 0;
+ return 1;
+}
+
+void Uncovered1() { }
diff --git a/test/fuzzer/DSO2.cpp b/test/fuzzer/DSO2.cpp
new file mode 100644
index 000000000..2967055dc
--- /dev/null
+++ b/test/fuzzer/DSO2.cpp
@@ -0,0 +1,14 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Source code for a simple DSO.
+#ifdef _WIN32
+__declspec( dllexport )
+#endif
+int DSO2(int a) {
+ if (a < 3598235)
+ return 0;
+ return 1;
+}
+
+void Uncovered2() {}
diff --git a/test/fuzzer/DSOTestExtra.cpp b/test/fuzzer/DSOTestExtra.cpp
new file mode 100644
index 000000000..a2274d070
--- /dev/null
+++ b/test/fuzzer/DSOTestExtra.cpp
@@ -0,0 +1,11 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Source code for a simple DSO.
+
+int DSOTestExtra(int a) {
+ if (a < 452345)
+ return 0;
+ return 1;
+}
+
diff --git a/test/fuzzer/DSOTestMain.cpp b/test/fuzzer/DSOTestMain.cpp
new file mode 100644
index 000000000..e0c857d4f
--- /dev/null
+++ b/test/fuzzer/DSOTestMain.cpp
@@ -0,0 +1,31 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Source code for a simple DSO.
+
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+extern int DSO1(int a);
+extern int DSO2(int a);
+extern int DSOTestExtra(int a);
+
+static volatile int *nil = 0;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ int x, y, z;
+ if (Size < sizeof(int) * 3) {
+ x = y = z = 0;
+ } else {
+ memcpy(&x, Data + 0 * sizeof(int), sizeof(int));
+ memcpy(&y, Data + 1 * sizeof(int), sizeof(int));
+ memcpy(&z, Data + 2 * sizeof(int), sizeof(int));
+ }
+ int sum = DSO1(x) + DSO2(y) + (z ? DSOTestExtra(z) : 0);
+ if (sum == 3) {
+ fprintf(stderr, "BINGO %d %d %d\n", x, y, z);
+ *nil = 0;
+ }
+ return 0;
+}
diff --git a/test/fuzzer/DeepRecursionTest.cpp b/test/fuzzer/DeepRecursionTest.cpp
new file mode 100644
index 000000000..bf4621d04
--- /dev/null
+++ b/test/fuzzer/DeepRecursionTest.cpp
@@ -0,0 +1,25 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the deep recursion.
+// To generate a crashy input:
+// for((i=0;i<110;i++)); do echo -n ABCDEFGHIJ >> INPUT; done
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+
+static volatile int Sink;
+
+void Recursive(const uint8_t *Data, size_t Size, int Depth) {
+ if (Depth > 1000) abort();
+ if (!Size) return;
+ if (*Data == ('A' + Depth % 10))
+ Recursive(Data + 1, Size - 1, Depth + 1);
+ Sink++;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ Recursive(Data, Size, 0);
+ return 0;
+}
+
diff --git a/test/fuzzer/DivTest.cpp b/test/fuzzer/DivTest.cpp
new file mode 100644
index 000000000..bce13feb7
--- /dev/null
+++ b/test/fuzzer/DivTest.cpp
@@ -0,0 +1,20 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer: find the interesting argument for div.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 4) return 0;
+ int a;
+ memcpy(&a, Data, 4);
+ Sink = 12345678 / (987654 - a);
+ return 0;
+}
+
diff --git a/test/fuzzer/EmptyTest.cpp b/test/fuzzer/EmptyTest.cpp
new file mode 100644
index 000000000..5e843308f
--- /dev/null
+++ b/test/fuzzer/EmptyTest.cpp
@@ -0,0 +1,11 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// A fuzzer with empty target function.
+
+#include <cstdint>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ return 0;
+}
diff --git a/test/fuzzer/EquivalenceATest.cpp b/test/fuzzer/EquivalenceATest.cpp
new file mode 100644
index 000000000..7d1ebb0f6
--- /dev/null
+++ b/test/fuzzer/EquivalenceATest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+// Test for libFuzzer's "equivalence" fuzzing, part A.
+extern "C" void LLVMFuzzerAnnounceOutput(const uint8_t *Data, size_t Size);
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ // fprintf(stderr, "A %zd\n", Size);
+ uint8_t Result[50];
+ if (Size > 50) Size = 50;
+ for (size_t i = 0; i < Size; i++)
+ Result[Size - i - 1] = Data[i];
+ LLVMFuzzerAnnounceOutput(Result, Size);
+ return 0;
+}
diff --git a/test/fuzzer/EquivalenceBTest.cpp b/test/fuzzer/EquivalenceBTest.cpp
new file mode 100644
index 000000000..b1de208b5
--- /dev/null
+++ b/test/fuzzer/EquivalenceBTest.cpp
@@ -0,0 +1,27 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+// Test for libFuzzer's "equivalence" fuzzing, part B.
+extern "C" void LLVMFuzzerAnnounceOutput(const uint8_t *Data, size_t Size);
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ // fprintf(stderr, "B %zd\n", Size);
+ uint8_t Result[50];
+ if (Size > 50) Size = 50;
+ for (size_t i = 0; i < Size; i++)
+ Result[Size - i - 1] = Data[i];
+
+ // Be a bit different from EquivalenceATest
+ if (Size > 10 && Data[5] == 'B' && Data[6] == 'C' && Data[7] == 'D') {
+ static int c;
+ if (!c)
+ fprintf(stderr, "ZZZZZZZ\n");
+ c = 1;
+ Result[2]++;
+ }
+
+ LLVMFuzzerAnnounceOutput(Result, Size);
+ return 0;
+}
diff --git a/test/fuzzer/FlagsTest.cpp b/test/fuzzer/FlagsTest.cpp
new file mode 100644
index 000000000..ac64b9d48
--- /dev/null
+++ b/test/fuzzer/FlagsTest.cpp
@@ -0,0 +1,32 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Parse some flags
+#include <string>
+#include <vector>
+
+static std::vector<std::string> Flags;
+
+extern "C" int LLVMFuzzerInitialize(int *Argc, char ***Argv) {
+ // Parse --flags and anything after -ignore_remaining_args=1 is passed.
+ int I = 1;
+ while (I < *Argc) {
+ std::string S((*Argv)[I++]);
+ if (S == "-ignore_remaining_args=1")
+ break;
+ if (S.substr(0, 2) == "--")
+ Flags.push_back(S);
+ }
+ while (I < *Argc)
+ Flags.push_back(std::string((*Argv)[I++]));
+
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ fprintf(stderr, "BINGO ");
+ for (auto Flag : Flags)
+ fprintf(stderr, "%s ", Flag.c_str());
+ fprintf(stderr, "\n");
+ exit(0);
+}
diff --git a/test/fuzzer/FourIndependentBranchesTest.cpp b/test/fuzzer/FourIndependentBranchesTest.cpp
new file mode 100644
index 000000000..bbf5ea235
--- /dev/null
+++ b/test/fuzzer/FourIndependentBranchesTest.cpp
@@ -0,0 +1,22 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "FUZZ".
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ int bits = 0;
+ if (Size > 0 && Data[0] == 'F') bits |= 1;
+ if (Size > 1 && Data[1] == 'U') bits |= 2;
+ if (Size > 2 && Data[2] == 'Z') bits |= 4;
+ if (Size > 3 && Data[3] == 'Z') bits |= 8;
+ if (bits == 15) {
+ std::cerr << "BINGO!\n";
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/FullCoverageSetTest.cpp b/test/fuzzer/FullCoverageSetTest.cpp
new file mode 100644
index 000000000..6d7e48fe5
--- /dev/null
+++ b/test/fuzzer/FullCoverageSetTest.cpp
@@ -0,0 +1,24 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "FUZZER".
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ int bits = 0;
+ if (Size > 0 && Data[0] == 'F') bits |= 1;
+ if (Size > 1 && Data[1] == 'U') bits |= 2;
+ if (Size > 2 && Data[2] == 'Z') bits |= 4;
+ if (Size > 3 && Data[3] == 'Z') bits |= 8;
+ if (Size > 4 && Data[4] == 'E') bits |= 16;
+ if (Size > 5 && Data[5] == 'R') bits |= 32;
+ if (bits == 63) {
+ std::cerr << "BINGO!\n";
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/InitializeTest.cpp b/test/fuzzer/InitializeTest.cpp
new file mode 100644
index 000000000..d640a8d10
--- /dev/null
+++ b/test/fuzzer/InitializeTest.cpp
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Make sure LLVMFuzzerInitialize is called.
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *argv0;
+
+extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ assert(*argc > 0);
+ argv0 = **argv;
+ fprintf(stderr, "LLVMFuzzerInitialize: %s\n", argv0);
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size == strlen(argv0) &&
+ !memmem(Data, Size, argv0, Size)) {
+ fprintf(stderr, "BINGO %s\n", argv0);
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/LargeTest.cpp b/test/fuzzer/LargeTest.cpp
new file mode 100644
index 000000000..83ed61971
--- /dev/null
+++ b/test/fuzzer/LargeTest.cpp
@@ -0,0 +1,37 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// A fuzz target with lots of edges.
+#include <cstdint>
+#include <cstdlib>
+
+static inline void break_optimization(const void *arg) {
+ __asm__ __volatile__("" : : "r" (arg) : "memory");
+}
+
+#define A \
+ do { \
+ i++; \
+ c++; \
+ if (Data[(i + __LINE__) % Size] == (c % 256)) \
+ break_optimization(Data); \
+ else \
+ break_optimization(0); \
+ } while (0)
+
+// for (int i = 0, n = Data[(__LINE__ - 1) % Size] % 16; i < n; i++)
+
+#define B do{A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; }while(0)
+#define C do{B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; }while(0)
+#define D do{C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; }while(0)
+#define E do{D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; }while(0)
+
+volatile int sink;
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (!Size) return 0;
+ int c = 0;
+ int i = 0;
+ D;
+ return 0;
+}
+
diff --git a/test/fuzzer/LeakTest.cpp b/test/fuzzer/LeakTest.cpp
new file mode 100644
index 000000000..ea89e3901
--- /dev/null
+++ b/test/fuzzer/LeakTest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test with a leak.
+#include <cstddef>
+#include <cstdint>
+
+static volatile void *Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && *Data == 'H') {
+ Sink = new int;
+ Sink = nullptr;
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/LeakTimeoutTest.cpp b/test/fuzzer/LeakTimeoutTest.cpp
new file mode 100644
index 000000000..92526194a
--- /dev/null
+++ b/test/fuzzer/LeakTimeoutTest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test with a leak.
+#include <cstddef>
+#include <cstdint>
+
+static volatile int *Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (!Size) return 0;
+ Sink = new int;
+ Sink = new int;
+ while (Sink) *Sink = 0; // Infinite loop.
+ return 0;
+}
+
diff --git a/test/fuzzer/LoadTest.cpp b/test/fuzzer/LoadTest.cpp
new file mode 100644
index 000000000..67a28c7cb
--- /dev/null
+++ b/test/fuzzer/LoadTest.cpp
@@ -0,0 +1,22 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer: find interesting value of array index.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+
+static volatile int Sink;
+const int kArraySize = 1234567;
+int array[kArraySize];
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 8) return 0;
+ uint64_t a = 0;
+ memcpy(&a, Data, 8);
+ Sink = array[a % (kArraySize + 1)];
+ return 0;
+}
+
diff --git a/test/fuzzer/Memcmp64BytesTest.cpp b/test/fuzzer/Memcmp64BytesTest.cpp
new file mode 100644
index 000000000..5b6cb7071
--- /dev/null
+++ b/test/fuzzer/Memcmp64BytesTest.cpp
@@ -0,0 +1,20 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cassert>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ const char kString64Bytes[] =
+ "123456789 123456789 123456789 123456789 123456789 123456789 1234";
+ assert(sizeof(kString64Bytes) == 65);
+ if (Size >= 64 && memcmp(Data, kString64Bytes, 64) == 0) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/MemcmpTest.cpp b/test/fuzzer/MemcmpTest.cpp
new file mode 100644
index 000000000..8dbb7d84f
--- /dev/null
+++ b/test/fuzzer/MemcmpTest.cpp
@@ -0,0 +1,31 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ // TODO: check other sizes.
+ if (Size >= 8 && memcmp(Data, "01234567", 8) == 0) {
+ if (Size >= 12 && memcmp(Data + 8, "ABCD", 4) == 0) {
+ if (Size >= 14 && memcmp(Data + 12, "XY", 2) == 0) {
+ if (Size >= 17 && memcmp(Data + 14, "KLM", 3) == 0) {
+ if (Size >= 27 && memcmp(Data + 17, "ABCDE-GHIJ", 10) == 0){
+ fprintf(stderr, "BINGO %zd\n", Size);
+ for (size_t i = 0; i < Size; i++) {
+ uint8_t C = Data[i];
+ if (C >= 32 && C < 127)
+ fprintf(stderr, "%c", C);
+ }
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
diff --git a/test/fuzzer/NotinstrumentedTest.cpp b/test/fuzzer/NotinstrumentedTest.cpp
new file mode 100644
index 000000000..91418990b
--- /dev/null
+++ b/test/fuzzer/NotinstrumentedTest.cpp
@@ -0,0 +1,11 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// This test should not be instrumented.
+#include <cstddef>
+#include <cstdint>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ return 0;
+}
+
diff --git a/test/fuzzer/NthRunCrashTest.cpp b/test/fuzzer/NthRunCrashTest.cpp
new file mode 100644
index 000000000..26cdc8f17
--- /dev/null
+++ b/test/fuzzer/NthRunCrashTest.cpp
@@ -0,0 +1,19 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Crash on the N-th execution.
+#include <cstddef>
+#include <cstdint>
+#include <iostream>
+#include <ostream>
+
+static int Counter;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Counter++ == 1000) {
+ std::cout << "BINGO; Found the target, exiting\n" << std::flush;
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/NullDerefOnEmptyTest.cpp b/test/fuzzer/NullDerefOnEmptyTest.cpp
new file mode 100644
index 000000000..459db51f8
--- /dev/null
+++ b/test/fuzzer/NullDerefOnEmptyTest.cpp
@@ -0,0 +1,19 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the empty string.
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+static volatile int *Null = 0;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size == 0) {
+ std::cout << "Found the target, dereferencing NULL\n";
+ *Null = 1;
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/NullDerefTest.cpp b/test/fuzzer/NullDerefTest.cpp
new file mode 100644
index 000000000..1b44b682a
--- /dev/null
+++ b/test/fuzzer/NullDerefTest.cpp
@@ -0,0 +1,26 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+static volatile int Sink;
+static volatile int *Null = 0;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && Data[0] == 'H') {
+ Sink = 1;
+ if (Size > 1 && Data[1] == 'i') {
+ Sink = 2;
+ if (Size > 2 && Data[2] == '!') {
+ std::cout << "Found the target, dereferencing NULL\n";
+ *Null = 1;
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/OneHugeAllocTest.cpp b/test/fuzzer/OneHugeAllocTest.cpp
new file mode 100644
index 000000000..32a557871
--- /dev/null
+++ b/test/fuzzer/OneHugeAllocTest.cpp
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Tests OOM handling when there is a single large allocation.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+static volatile char *SinkPtr;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && Data[0] == 'H') {
+ if (Size > 1 && Data[1] == 'i') {
+ if (Size > 2 && Data[2] == '!') {
+ size_t kSize = (size_t)1 << 31;
+ char *p = new char[kSize];
+ memset(p, 0, kSize);
+ SinkPtr = p;
+ delete [] p;
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/OutOfMemorySingleLargeMallocTest.cpp b/test/fuzzer/OutOfMemorySingleLargeMallocTest.cpp
new file mode 100644
index 000000000..a07795a08
--- /dev/null
+++ b/test/fuzzer/OutOfMemorySingleLargeMallocTest.cpp
@@ -0,0 +1,27 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Tests OOM handling.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+static volatile char *SinkPtr;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && Data[0] == 'H') {
+ if (Size > 1 && Data[1] == 'i') {
+ if (Size > 2 && Data[2] == '!') {
+ size_t kSize = 0x20000000U;
+ char *p = new char[kSize];
+ SinkPtr = p;
+ delete [] p;
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/OutOfMemoryTest.cpp b/test/fuzzer/OutOfMemoryTest.cpp
new file mode 100644
index 000000000..5e59bde09
--- /dev/null
+++ b/test/fuzzer/OutOfMemoryTest.cpp
@@ -0,0 +1,31 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Tests OOM handling.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <thread>
+
+static volatile char *SinkPtr;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && Data[0] == 'H') {
+ if (Size > 1 && Data[1] == 'i') {
+ if (Size > 2 && Data[2] == '!') {
+ while (true) {
+ size_t kSize = 1 << 28;
+ char *p = new char[kSize];
+ memset(p, 0, kSize);
+ SinkPtr = p;
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ }
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/OverwriteInputTest.cpp b/test/fuzzer/OverwriteInputTest.cpp
new file mode 100644
index 000000000..e68868234
--- /dev/null
+++ b/test/fuzzer/OverwriteInputTest.cpp
@@ -0,0 +1,13 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. Make sure we abort if Data is overwritten.
+#include <cstdint>
+#include <iostream>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size)
+ *const_cast<uint8_t*>(Data) = 1;
+ return 0;
+}
+
diff --git a/test/fuzzer/RepeatedBytesTest.cpp b/test/fuzzer/RepeatedBytesTest.cpp
new file mode 100644
index 000000000..31868cf8c
--- /dev/null
+++ b/test/fuzzer/RepeatedBytesTest.cpp
@@ -0,0 +1,31 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find repeated bytes.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <ostream>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ // Looking for AAAAAAAAAAAAAAAAAAAAAA or some such.
+ size_t CurA = 0, MaxA = 0;
+ for (size_t i = 0; i < Size; i++) {
+ // Make sure there are no conditionals in the loop so that
+ // coverage can't help the fuzzer.
+ int EQ = Data[i] == 'A';
+ CurA = EQ * (CurA + 1);
+ int GT = CurA > MaxA;
+ MaxA = GT * CurA + (!GT) * MaxA;
+ }
+ if (MaxA >= 20) {
+ std::cout << "BINGO; Found the target (Max: " << MaxA << "), exiting\n"
+ << std::flush;
+ exit(0);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/RepeatedMemcmp.cpp b/test/fuzzer/RepeatedMemcmp.cpp
new file mode 100644
index 000000000..18369deac
--- /dev/null
+++ b/test/fuzzer/RepeatedMemcmp.cpp
@@ -0,0 +1,24 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ int Matches1 = 0;
+ for (size_t i = 0; i + 2 < Size; i += 3)
+ if (!memcmp(Data + i, "foo", 3))
+ Matches1++;
+ int Matches2 = 0;
+ for (size_t i = 0; i + 2 < Size; i += 3)
+ if (!memcmp(Data + i, "bar", 3))
+ Matches2++;
+
+ if (Matches1 > 10 && Matches2 > 10) {
+ fprintf(stderr, "BINGO!\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/ShrinkControlFlowSimpleTest.cpp b/test/fuzzer/ShrinkControlFlowSimpleTest.cpp
new file mode 100644
index 000000000..0afd26df2
--- /dev/null
+++ b/test/fuzzer/ShrinkControlFlowSimpleTest.cpp
@@ -0,0 +1,19 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that we can find the minimal item in the corpus (3 bytes: "FUZ").
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 2) return 0;
+ if (Data[0] == 'F' && Data[Size / 2] == 'U' && Data[Size - 1] == 'Z')
+ Sink++;
+ return 0;
+}
+
diff --git a/test/fuzzer/ShrinkControlFlowTest.cpp b/test/fuzzer/ShrinkControlFlowTest.cpp
new file mode 100644
index 000000000..1957c1f90
--- /dev/null
+++ b/test/fuzzer/ShrinkControlFlowTest.cpp
@@ -0,0 +1,31 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that we can find the minimal item in the corpus (3 bytes: "FUZ").
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+static volatile int Sink;
+
+void Foo() {
+ Sink++;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ int8_t Ids[256];
+ memset(Ids, -1, sizeof(Ids));
+ for (size_t i = 0; i < Size; i++)
+ if (Ids[Data[i]] == -1)
+ Ids[Data[i]] = i;
+ int F = Ids[(unsigned char)'F'];
+ int U = Ids[(unsigned char)'U'];
+ int Z = Ids[(unsigned char)'Z'];
+ if (F >= 0 && U > F && Z > U) {
+ Foo();
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/ShrinkValueProfileTest.cpp b/test/fuzzer/ShrinkValueProfileTest.cpp
new file mode 100644
index 000000000..86e4e3cb0
--- /dev/null
+++ b/test/fuzzer/ShrinkValueProfileTest.cpp
@@ -0,0 +1,22 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that we can find the minimal item in the corpus (3 bytes: "FUZ").
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+static volatile uint32_t Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < sizeof(uint32_t)) return 0;
+ uint32_t X, Y;
+ size_t Offset = Size < 8 ? 0 : Size / 2;
+ memcpy(&X, Data + Offset, sizeof(uint32_t));
+ memcpy(&Y, "FUZZ", sizeof(uint32_t));
+ Sink = X == Y;
+ return 0;
+}
+
diff --git a/test/fuzzer/SignedIntOverflowTest.cpp b/test/fuzzer/SignedIntOverflowTest.cpp
new file mode 100644
index 000000000..d80060207
--- /dev/null
+++ b/test/fuzzer/SignedIntOverflowTest.cpp
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test for signed-integer-overflow.
+#include <assert.h>
+#include <climits>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+static volatile int Sink;
+static int Large = INT_MAX;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size > 0 && Data[0] == 'H') {
+ Sink = 1;
+ if (Size > 1 && Data[1] == 'i') {
+ Sink = 2;
+ if (Size > 2 && Data[2] == '!') {
+ Large++; // int overflow.
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/SimpleCmpTest.cpp b/test/fuzzer/SimpleCmpTest.cpp
new file mode 100644
index 000000000..8acad4ac7
--- /dev/null
+++ b/test/fuzzer/SimpleCmpTest.cpp
@@ -0,0 +1,47 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find several narrow ranges.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern int AllLines[];
+
+bool PrintOnce(int Line) {
+ if (!AllLines[Line])
+ fprintf(stderr, "Seen line %d\n", Line);
+ AllLines[Line] = 1;
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size != 22) return 0;
+ uint64_t x = 0;
+ int64_t y = 0;
+ int32_t z = 0;
+ uint16_t a = 0;
+ memcpy(&x, Data, 8); // 8
+ memcpy(&y, Data + 8, 8); // 16
+ memcpy(&z, Data + 16, sizeof(z)); // 20
+ memcpy(&a, Data + 20, sizeof(a)); // 22
+ const bool k32bit = sizeof(void*) == 4;
+
+ if ((k32bit || x > 1234567890) && PrintOnce(__LINE__) &&
+ (k32bit || x < 1234567895) && PrintOnce(__LINE__) &&
+ a == 0x4242 && PrintOnce(__LINE__) &&
+ (k32bit || y >= 987654321) && PrintOnce(__LINE__) &&
+ (k32bit || y <= 987654325) && PrintOnce(__LINE__) &&
+ z < -10000 && PrintOnce(__LINE__) &&
+ z >= -10005 && PrintOnce(__LINE__) &&
+ z != -10003 && PrintOnce(__LINE__) &&
+ true) {
+ fprintf(stderr, "BINGO; Found the target: size %zd (%zd, %zd, %d, %d), exiting.\n",
+ Size, x, y, z, a);
+ exit(1);
+ }
+ return 0;
+}
+
+int AllLines[__LINE__ + 1]; // Must be the last line.
diff --git a/test/fuzzer/SimpleDictionaryTest.cpp b/test/fuzzer/SimpleDictionaryTest.cpp
new file mode 100644
index 000000000..ffa2e4137
--- /dev/null
+++ b/test/fuzzer/SimpleDictionaryTest.cpp
@@ -0,0 +1,30 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer.
+// The fuzzer must find a string based on dictionary words:
+// "Elvis"
+// "Presley"
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <ostream>
+
+static volatile int Zero = 0;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ const char *Expected = "ElvisPresley";
+ if (Size < strlen(Expected)) return 0;
+ size_t Match = 0;
+ for (size_t i = 0; Expected[i]; i++)
+ if (Expected[i] + Zero == Data[i])
+ Match++;
+ if (Match == strlen(Expected)) {
+ std::cout << "BINGO; Found the target, exiting\n" << std::flush;
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/SimpleHashTest.cpp b/test/fuzzer/SimpleHashTest.cpp
new file mode 100644
index 000000000..99e96cb25
--- /dev/null
+++ b/test/fuzzer/SimpleHashTest.cpp
@@ -0,0 +1,40 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// This test computes a checksum of the data (all but the last 4 bytes),
+// and then compares the last 4 bytes with the computed value.
+// A fuzzer with cmp traces is expected to defeat this check.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+// A modified jenkins_one_at_a_time_hash initialized by non-zero,
+// so that simple_hash(0) != 0. See also
+// https://en.wikipedia.org/wiki/Jenkins_hash_function
+static uint32_t simple_hash(const uint8_t *Data, size_t Size) {
+ uint32_t Hash = 0x12039854;
+ for (uint32_t i = 0; i < Size; i++) {
+ Hash += Data[i];
+ Hash += (Hash << 10);
+ Hash ^= (Hash >> 6);
+ }
+ Hash += (Hash << 3);
+ Hash ^= (Hash >> 11);
+ Hash += (Hash << 15);
+ return Hash;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 14)
+ return 0;
+
+ uint32_t Hash = simple_hash(&Data[0], Size - 4);
+ uint32_t Want = reinterpret_cast<const uint32_t *>(&Data[Size - 4])[0];
+ if (Hash != Want)
+ return 0;
+ fprintf(stderr, "BINGO; simple_hash defeated: %x == %x\n", (unsigned int)Hash,
+ (unsigned int)Want);
+ exit(1);
+ return 0;
+}
diff --git a/test/fuzzer/SimpleTest.cpp b/test/fuzzer/SimpleTest.cpp
new file mode 100644
index 000000000..3882a842b
--- /dev/null
+++ b/test/fuzzer/SimpleTest.cpp
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <ostream>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size > 0 && Data[0] == 'H') {
+ Sink = 1;
+ if (Size > 1 && Data[1] == 'i') {
+ Sink = 2;
+ if (Size > 2 && Data[2] == '!') {
+ std::cout << "BINGO; Found the target, exiting\n" << std::flush;
+ exit(0);
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/SimpleThreadedTest.cpp b/test/fuzzer/SimpleThreadedTest.cpp
new file mode 100644
index 000000000..deeae756a
--- /dev/null
+++ b/test/fuzzer/SimpleThreadedTest.cpp
@@ -0,0 +1,26 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Threaded test for a fuzzer. The fuzzer should find "H"
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <ostream>
+#include <thread>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ auto C = [&] {
+ if (Size >= 2 && Data[0] == 'H') {
+ std::cout << "BINGO; Found the target, exiting\n" << std::flush;
+ abort();
+ }
+ };
+ std::thread T[] = {std::thread(C), std::thread(C), std::thread(C),
+ std::thread(C), std::thread(C), std::thread(C)};
+ for (auto &X : T)
+ X.join();
+ return 0;
+}
+
diff --git a/test/fuzzer/SingleByteInputTest.cpp b/test/fuzzer/SingleByteInputTest.cpp
new file mode 100644
index 000000000..72b58ba91
--- /dev/null
+++ b/test/fuzzer/SingleByteInputTest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer, need just one byte to crash.
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && Data[Size/2] == 42) {
+ fprintf(stderr, "BINGO\n");
+ abort();
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/SingleMemcmpTest.cpp b/test/fuzzer/SingleMemcmpTest.cpp
new file mode 100644
index 000000000..19781ba4c
--- /dev/null
+++ b/test/fuzzer/SingleMemcmpTest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ const char *S = (const char*)Data;
+ if (Size >= 6 && !memcmp(S, "qwerty", 6)) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/SingleStrcmpTest.cpp b/test/fuzzer/SingleStrcmpTest.cpp
new file mode 100644
index 000000000..149073444
--- /dev/null
+++ b/test/fuzzer/SingleStrcmpTest.cpp
@@ -0,0 +1,21 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size >= 7) {
+ char Copy[7];
+ memcpy(Copy, Data, 6);
+ Copy[6] = 0;
+ if (!strcmp(Copy, "qwerty")) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ }
+ return 0;
+}
diff --git a/test/fuzzer/SingleStrncmpTest.cpp b/test/fuzzer/SingleStrncmpTest.cpp
new file mode 100644
index 000000000..47298763f
--- /dev/null
+++ b/test/fuzzer/SingleStrncmpTest.cpp
@@ -0,0 +1,18 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ const char *S = (const char*)Data;
+ volatile auto Strncmp = &(strncmp); // Make sure strncmp is not inlined.
+ if (Size >= 6 && !Strncmp(S, "qwerty", 6)) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/SpamyTest.cpp b/test/fuzzer/SpamyTest.cpp
new file mode 100644
index 000000000..721134e18
--- /dev/null
+++ b/test/fuzzer/SpamyTest.cpp
@@ -0,0 +1,21 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// The test spams to stderr and stdout.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <iostream>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ printf("PRINTF_STDOUT\n");
+ fflush(stdout);
+ fprintf(stderr, "PRINTF_STDERR\n");
+ std::cout << "STREAM_COUT\n";
+ std::cout.flush();
+ std::cerr << "STREAM_CERR\n";
+ return 0;
+}
+
diff --git a/test/fuzzer/StrcmpTest.cpp b/test/fuzzer/StrcmpTest.cpp
new file mode 100644
index 000000000..81f041d91
--- /dev/null
+++ b/test/fuzzer/StrcmpTest.cpp
@@ -0,0 +1,32 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Break through a series of strcmp.
+#include <cassert>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+bool Eq(const uint8_t *Data, size_t Size, const char *Str) {
+ char Buff[1024];
+ size_t Len = strlen(Str);
+ if (Size < Len) return false;
+ if (Len >= sizeof(Buff)) return false;
+ memcpy(Buff, (const char*)Data, Len);
+ Buff[Len] = 0;
+ int res = strcmp(Buff, Str);
+ return res == 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Eq(Data, Size, "ABC") &&
+ Size >= 3 && Eq(Data + 3, Size - 3, "QWER") &&
+ Size >= 7 && Eq(Data + 7, Size - 7, "ZXCVN") &&
+ Size >= 14 && Data[13] == 42
+ ) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/StrncmpOOBTest.cpp b/test/fuzzer/StrncmpOOBTest.cpp
new file mode 100644
index 000000000..4ed71d9d0
--- /dev/null
+++ b/test/fuzzer/StrncmpOOBTest.cpp
@@ -0,0 +1,21 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that libFuzzer itself does not read out of bounds.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 5) return 0;
+ const char *Ch = reinterpret_cast<const char *>(Data);
+ if (Ch[Size - 3] == 'a')
+ Sink = strncmp(Ch + Size - 3, "abcdefg", 6);
+ return 0;
+}
+
diff --git a/test/fuzzer/StrncmpTest.cpp b/test/fuzzer/StrncmpTest.cpp
new file mode 100644
index 000000000..a40e05690
--- /dev/null
+++ b/test/fuzzer/StrncmpTest.cpp
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+static volatile int sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ // TODO: check other sizes.
+ const char *S = (const char*)Data;
+ if (Size >= 8 && strncmp(S, "123", 8))
+ sink = 1;
+ if (Size >= 8 && strncmp(S, "01234567", 8) == 0) {
+ if (Size >= 12 && strncmp(S + 8, "ABCD", 4) == 0) {
+ if (Size >= 14 && strncmp(S + 12, "XY", 2) == 0) {
+ if (Size >= 17 && strncmp(S + 14, "KLM", 3) == 0) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ }
+ }
+ }
+ return 0;
+}
diff --git a/test/fuzzer/StrstrTest.cpp b/test/fuzzer/StrstrTest.cpp
new file mode 100644
index 000000000..a3ea4e03b
--- /dev/null
+++ b/test/fuzzer/StrstrTest.cpp
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test strstr and strcasestr hooks.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <string.h>
+#include <string>
+
+// Windows does not have strcasestr and memmem, so we are not testing them.
+#ifdef _WIN32
+#define strcasestr strstr
+#define memmem(a, b, c, d) true
+#endif
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 4) return 0;
+ std::string s(reinterpret_cast<const char*>(Data), Size);
+ if (strstr(s.c_str(), "FUZZ") &&
+ strcasestr(s.c_str(), "aBcD") &&
+ memmem(s.data(), s.size(), "kuku", 4)
+ ) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/test/fuzzer/SwapCmpTest.cpp b/test/fuzzer/SwapCmpTest.cpp
new file mode 100644
index 000000000..bbfbefe6a
--- /dev/null
+++ b/test/fuzzer/SwapCmpTest.cpp
@@ -0,0 +1,35 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// The fuzzer must find several constants with swapped bytes.
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 14) return 0;
+ uint64_t x = 0;
+ uint32_t y = 0;
+ uint16_t z = 0;
+ memcpy(&x, Data, sizeof(x));
+ memcpy(&y, Data + Size / 2, sizeof(y));
+ memcpy(&z, Data + Size - sizeof(z), sizeof(z));
+
+ x = __builtin_bswap64(x);
+ y = __builtin_bswap32(y);
+ z = __builtin_bswap16(z);
+ const bool k32bit = sizeof(void*) == 4;
+
+ if ((k32bit || x == 0x46555A5A5A5A5546ULL) &&
+ z == 0x4F4B &&
+ y == 0x66757A7A &&
+ true
+ ) {
+ if (Data[Size - 3] == 'z') {
+ fprintf(stderr, "BINGO; Found the target\n");
+ exit(1);
+ }
+ }
+ return 0;
+}
diff --git a/test/fuzzer/Switch2Test.cpp b/test/fuzzer/Switch2Test.cpp
new file mode 100644
index 000000000..5f66ac8b4
--- /dev/null
+++ b/test/fuzzer/Switch2Test.cpp
@@ -0,0 +1,35 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the interesting switch value.
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+int Switch(int a) {
+ switch(a) {
+ case 100001: return 1;
+ case 100002: return 2;
+ case 100003: return 4;
+ }
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ const int N = 3;
+ if (Size < N * sizeof(int)) return 0;
+ int Res = 0;
+ for (int i = 0; i < N; i++) {
+ int X;
+ memcpy(&X, Data + i * sizeof(int), sizeof(int));
+ Res += Switch(X);
+ }
+ if (Res == 5 || Res == 3 || Res == 6 || Res == 7) {
+ fprintf(stderr, "BINGO; Found the target, exiting; Res=%d\n", Res);
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/SwitchTest.cpp b/test/fuzzer/SwitchTest.cpp
new file mode 100644
index 000000000..86944cad2
--- /dev/null
+++ b/test/fuzzer/SwitchTest.cpp
@@ -0,0 +1,58 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the interesting switch value.
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+static volatile int Sink;
+
+template<class T>
+bool Switch(const uint8_t *Data, size_t Size) {
+ T X;
+ if (Size < sizeof(X)) return false;
+ memcpy(&X, Data, sizeof(X));
+ switch (X) {
+ case 1: Sink = __LINE__; break;
+ case 101: Sink = __LINE__; break;
+ case 1001: Sink = __LINE__; break;
+ case 10001: Sink = __LINE__; break;
+ case 100001: Sink = __LINE__; break;
+ case 1000001: Sink = __LINE__; break;
+ case 10000001: Sink = __LINE__; break;
+ case 100000001: return true;
+ }
+ return false;
+}
+
+bool ShortSwitch(const uint8_t *Data, size_t Size) {
+ short X;
+ if (Size < sizeof(short)) return false;
+ memcpy(&X, Data, sizeof(short));
+ switch(X) {
+ case 42: Sink = __LINE__; break;
+ case 402: Sink = __LINE__; break;
+ case 4002: Sink = __LINE__; break;
+ case 5002: Sink = __LINE__; break;
+ case 7002: Sink = __LINE__; break;
+ case 9002: Sink = __LINE__; break;
+ case 14002: Sink = __LINE__; break;
+ case 21402: return true;
+ }
+ return false;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size >= 4 && Switch<int>(Data, Size) &&
+ Size >= 12 && Switch<uint64_t>(Data + 4, Size - 4) &&
+ Size >= 14 && ShortSwitch(Data + 12, 2)
+ ) {
+ fprintf(stderr, "BINGO; Found the target, exiting\n");
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/TableLookupTest.cpp b/test/fuzzer/TableLookupTest.cpp
new file mode 100644
index 000000000..4d8ab0611
--- /dev/null
+++ b/test/fuzzer/TableLookupTest.cpp
@@ -0,0 +1,44 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Make sure the fuzzer eventually finds all possible values of a variable
+// within a range.
+#include <cassert>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <set>
+
+const size_t N = 1 << 12;
+
+// Define an array of counters that will be understood by libFuzzer
+// as extra coverage signal. The array must be:
+// * uint8_t
+// * in the section named __libfuzzer_extra_counters.
+// The target code may declare more than one such array.
+//
+// Use either `Counters[Idx] = 1` or `Counters[Idx]++;`
+// depending on whether multiple occurrences of the event 'Idx'
+// is important to distinguish from one occurrence.
+#ifdef __linux__
+__attribute__((section("__libfuzzer_extra_counters")))
+#endif
+static uint8_t Counters[N];
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ static std::set<uint16_t> SeenIdx;
+ if (Size != 4) return 0;
+ uint32_t Idx;
+ memcpy(&Idx, Data, 4);
+ Idx %= N;
+ assert(Counters[Idx] == 0); // libFuzzer should reset these between the runs.
+ // Or Counters[Idx]=1 if we don't care how many times this happened.
+ Counters[Idx]++;
+ SeenIdx.insert(Idx);
+ if (SeenIdx.size() == N) {
+ fprintf(stderr, "BINGO: found all values\n");
+ abort();
+ }
+ return 0;
+}
diff --git a/test/fuzzer/ThreadedLeakTest.cpp b/test/fuzzer/ThreadedLeakTest.cpp
new file mode 100644
index 000000000..538d3b434
--- /dev/null
+++ b/test/fuzzer/ThreadedLeakTest.cpp
@@ -0,0 +1,18 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// The fuzzer should find a leak in a non-main thread.
+#include <cstddef>
+#include <cstdint>
+#include <thread>
+
+static volatile int *Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size == 0) return 0;
+ if (Data[0] != 'F') return 0;
+ std::thread T([&] { Sink = new int; });
+ T.join();
+ return 0;
+}
+
diff --git a/test/fuzzer/ThreadedTest.cpp b/test/fuzzer/ThreadedTest.cpp
new file mode 100644
index 000000000..bb51ba764
--- /dev/null
+++ b/test/fuzzer/ThreadedTest.cpp
@@ -0,0 +1,26 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Threaded test for a fuzzer. The fuzzer should not crash.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <thread>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 8) return 0;
+ assert(Data);
+ auto C = [&] {
+ size_t Res = 0;
+ for (size_t i = 0; i < Size / 2; i++)
+ Res += memcmp(Data, Data + Size / 2, 4);
+ return Res;
+ };
+ std::thread T[] = {std::thread(C), std::thread(C), std::thread(C),
+ std::thread(C), std::thread(C), std::thread(C)};
+ for (auto &X : T)
+ X.join();
+ return 0;
+}
+
diff --git a/test/fuzzer/TimeoutEmptyTest.cpp b/test/fuzzer/TimeoutEmptyTest.cpp
new file mode 100644
index 000000000..1ddf1fa34
--- /dev/null
+++ b/test/fuzzer/TimeoutEmptyTest.cpp
@@ -0,0 +1,14 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the empty string.
+#include <cstddef>
+#include <cstdint>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ static volatile int Zero = 0;
+ if (!Size)
+ while(!Zero)
+ ;
+ return 0;
+}
diff --git a/test/fuzzer/TimeoutTest.cpp b/test/fuzzer/TimeoutTest.cpp
new file mode 100644
index 000000000..e3cdba3ee
--- /dev/null
+++ b/test/fuzzer/TimeoutTest.cpp
@@ -0,0 +1,26 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && Data[0] == 'H') {
+ Sink = 1;
+ if (Size > 1 && Data[1] == 'i') {
+ Sink = 2;
+ if (Size > 2 && Data[2] == '!') {
+ Sink = 2;
+ while (Sink)
+ ;
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/TraceMallocTest.cpp b/test/fuzzer/TraceMallocTest.cpp
new file mode 100644
index 000000000..af9975603
--- /dev/null
+++ b/test/fuzzer/TraceMallocTest.cpp
@@ -0,0 +1,27 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Tests -trace_malloc
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+int *Ptr;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (!Size) return 0;
+ if (*Data == 1) {
+ delete Ptr;
+ Ptr = nullptr;
+ } else if (*Data == 2) {
+ delete Ptr;
+ Ptr = new int;
+ } else if (*Data == 3) {
+ if (!Ptr)
+ Ptr = new int;
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/TwoDifferentBugsTest.cpp b/test/fuzzer/TwoDifferentBugsTest.cpp
new file mode 100644
index 000000000..77d2cb1a2
--- /dev/null
+++ b/test/fuzzer/TwoDifferentBugsTest.cpp
@@ -0,0 +1,22 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. This test may trigger two different bugs.
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+static volatile int *Null = 0;
+
+void Foo() { Null[1] = 0; }
+void Bar() { Null[2] = 0; }
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 10 && Data[0] == 'H')
+ Foo();
+ if (Size >= 10 && Data[0] == 'H')
+ Bar();
+ return 0;
+}
+
diff --git a/test/fuzzer/afl-driver-extra-stats.test b/test/fuzzer/afl-driver-extra-stats.test
new file mode 100644
index 000000000..a6de53302
--- /dev/null
+++ b/test/fuzzer/afl-driver-extra-stats.test
@@ -0,0 +1,30 @@
+RUN: %no_fuzzer_cpp_compiler -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
+
+; Test that not specifying an extra stats file isn't broken.
+RUN: unset AFL_DRIVER_EXTRA_STATS_FILENAME
+RUN: %t-AFLDriverTest
+
+; Test that specifying an invalid extra stats file causes a crash.
+RUN: ASAN_OPTIONS= AFL_DRIVER_EXTRA_STATS_FILENAME=%T not --crash %t-AFLDriverTest
+
+; Test that specifying a corrupted stats file causes a crash.
+echo "peak_rss_mb :0" > %t
+ASAN_OPTIONS= AFL_DRIVER_EXTRA_STATS_FILENAME=%t not --crash %t-AFLDriverTest
+
+; Test that specifying a valid nonexistent stats file works.
+RUN: rm -f %t
+RUN: AFL_DRIVER_EXTRA_STATS_FILENAME=%t %t-AFLDriverTest
+RUN: [[ $(grep "peak_rss_mb\|slowest_unit_time_sec" %t | wc -l) -eq 2 ]]
+
+; Test that specifying a valid preexisting stats file works.
+RUN: printf "peak_rss_mb : 0\nslowest_unit_time_sec: 0\n" > %t
+RUN: AFL_DRIVER_EXTRA_STATS_FILENAME=%t %t-AFLDriverTest
+; Check that both lines were printed.
+RUN: [[ $(grep "peak_rss_mb\|slowest_unit_time_sec" %t | wc -l) -eq 2 ]]
+
+; Test that peak_rss_mb and slowest_unit_time_in_secs are only updated when necessary.
+; Check that both lines have 9999 since there's no way we have exceeded that
+; amount of time or virtual memory.
+RUN: printf "peak_rss_mb : 9999\nslowest_unit_time_sec: 9999\n" > %t
+RUN: AFL_DRIVER_EXTRA_STATS_FILENAME=%t %t-AFLDriverTest
+RUN: [[ $(grep "9999" %t | wc -l) -eq 2 ]]
diff --git a/test/fuzzer/afl-driver-stderr.test b/test/fuzzer/afl-driver-stderr.test
new file mode 100644
index 000000000..be0efaa8f
--- /dev/null
+++ b/test/fuzzer/afl-driver-stderr.test
@@ -0,0 +1,12 @@
+RUN: %no_fuzzer_cpp_compiler -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
+
+; Test that not specifying a stderr file isn't broken.
+RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME
+RUN: %t-AFLDriverTest
+
+; Test that specifying an invalid file causes a crash.
+RUN: ASAN_OPTIONS= AFL_DRIVER_STDERR_DUPLICATE_FILENAME="%T" not --crash %t-AFLDriverTest
+
+; Test that a file is created when specified as the duplicate stderr.
+RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME=%t %t-AFLDriverTest
+RUN: stat %t
diff --git a/test/fuzzer/afl-driver.test b/test/fuzzer/afl-driver.test
new file mode 100644
index 000000000..32e7d03b4
--- /dev/null
+++ b/test/fuzzer/afl-driver.test
@@ -0,0 +1,29 @@
+REQUIRES: linux
+
+RUN: %no_fuzzer_cpp_compiler -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
+
+RUN: echo -n "abc" > %t.file3
+RUN: echo -n "abcd" > %t.file4
+
+RUN: %t-AFLDriverTest < %t.file3 2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: __afl_persistent_loop calle, Count = 1000
+CHECK1: LLVMFuzzerTestOneInput called; Size = 3
+
+
+RUN: %t-AFLDriverTest < %t.file3 -42 2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: __afl_persistent_loop calle, Count = 42
+CHECK2: LLVMFuzzerTestOneInput called; Size = 3
+
+
+RUN: %t-AFLDriverTest < %t.file3 666 2>&1 | FileCheck %s --check-prefix=CHECK3
+CHECK3: WARNING: using the deprecated call style
+CHECK3: __afl_persistent_loop calle, Count = 666
+CHECK3: LLVMFuzzerTestOneInput called; Size = 3
+
+
+RUN: %t-AFLDriverTest %t.file3 2>&1 | FileCheck %s --check-prefix=CHECK4
+CHECK4: LLVMFuzzerTestOneInput called; Size = 3
+
+RUN: %t-AFLDriverTest %t.file3 %t.file4 2>&1 | FileCheck %s --check-prefix=CHECK5
+CHECK5: LLVMFuzzerTestOneInput called; Size = 3
+CHECK5: LLVMFuzzerTestOneInput called; Size = 4
diff --git a/test/fuzzer/bad-strcmp.test b/test/fuzzer/bad-strcmp.test
new file mode 100644
index 000000000..fd1621a4e
--- /dev/null
+++ b/test/fuzzer/bad-strcmp.test
@@ -0,0 +1,2 @@
+RUN: %cpp_compiler %S/BadStrcmpTest.cpp -o %t-BadStrcmpTest
+RUN: %t-BadStrcmpTest -runs=100000
diff --git a/test/fuzzer/caller-callee.test b/test/fuzzer/caller-callee.test
new file mode 100644
index 000000000..e4eccdc30
--- /dev/null
+++ b/test/fuzzer/caller-callee.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/CallerCalleeTest.cpp -o %t-CallerCalleeTest
+CHECK: BINGO
+RUN: not %t-CallerCalleeTest -use_value_profile=1 -cross_over=0 -seed=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/cleanse.test b/test/fuzzer/cleanse.test
new file mode 100644
index 000000000..8e45dc77d
--- /dev/null
+++ b/test/fuzzer/cleanse.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/CleanseTest.cpp -o %t-CleanseTest
+RUN: echo -n 0123456789ABCDEFGHIZ > %t-in
+RUN: %t-CleanseTest -cleanse_crash=1 %t-in -exact_artifact_path=%t-out
+RUN: echo -n ' 1 5 A Z' | diff - %t-out
diff --git a/test/fuzzer/coverage.test b/test/fuzzer/coverage.test
new file mode 100644
index 000000000..9a2179d91
--- /dev/null
+++ b/test/fuzzer/coverage.test
@@ -0,0 +1,21 @@
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/NullDerefTest.cpp -o %t-NullDerefTest
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO1.cpp -fPIC -shared -o %t-DSO1.so
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO2.cpp -fPIC -shared -o %t-DSO2.so
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
+
+CHECK: COVERAGE:
+CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
+CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14
+CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16
+RUN: not %t-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
+
+RUN: %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
+DSO: COVERAGE:
+DSO-DAG: COVERED:{{.*}}DSO1{{.*}}DSO1.cpp
+DSO-DAG: COVERED:{{.*}}DSO2{{.*}}DSO2.cpp
+DSO-DAG: COVERED:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain
+DSO-DAG: UNCOVERED_LINE:{{.*}}DSO1{{.*}}DSO1.cpp
+DSO-DAG: UNCOVERED_LINE:{{.*}}DSO2{{.*}}DSO2.cpp
+DSO-DAG: UNCOVERED_FUNC: in Uncovered1
+DSO-DAG: UNCOVERED_FUNC: in Uncovered2
+DSO-DAG: UNCOVERED_LINE: in LLVMFuzzerTestOneInput
diff --git a/test/fuzzer/cxxstring.test b/test/fuzzer/cxxstring.test
new file mode 100644
index 000000000..7bb341ba2
--- /dev/null
+++ b/test/fuzzer/cxxstring.test
@@ -0,0 +1,6 @@
+UNSUPPORTED: windows
+
+RUN: %cpp_compiler %S/CxxStringEqTest.cpp -o %t-CxxStringEqTest
+
+RUN: not %t-CxxStringEqTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
+CHECK: BINGO
diff --git a/test/fuzzer/dict1.txt b/test/fuzzer/dict1.txt
new file mode 100644
index 000000000..520d0cc7b
--- /dev/null
+++ b/test/fuzzer/dict1.txt
@@ -0,0 +1,4 @@
+# Dictionary for SimpleDictionaryTest
+
+a="Elvis"
+b="Presley"
diff --git a/test/fuzzer/disable-leaks.test b/test/fuzzer/disable-leaks.test
new file mode 100644
index 000000000..bc120d98b
--- /dev/null
+++ b/test/fuzzer/disable-leaks.test
@@ -0,0 +1,5 @@
+REQUIRES: lsan
+RUN: %cpp_compiler %S/AccumulateAllocationsTest.cpp -o %t-AccumulateAllocationsTest
+RUN: %t-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS
+ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation
+
diff --git a/test/fuzzer/dump_coverage.test b/test/fuzzer/dump_coverage.test
new file mode 100644
index 000000000..a733355ee
--- /dev/null
+++ b/test/fuzzer/dump_coverage.test
@@ -0,0 +1,20 @@
+RUN: %cpp_compiler %S/DSO1.cpp -fPIC -shared -o %t-DSO1.so
+RUN: %cpp_compiler %S/DSO2.cpp -fPIC -shared -o %t-DSO2.so
+RUN: %cpp_compiler %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
+
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+
+RUN: rm -rf %t_workdir && mkdir -p %t_workdir
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %t-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s
+RUN: sancov -covered-functions %t-NullDerefTest* %t_workdir/*.sancov | FileCheck %s --check-prefix=SANCOV
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' %t-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %t-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV
+
+CHECK: SanitizerCoverage: {{.*}}NullDerefTest.{{.*}}.sancov: {{.*}} PCs written
+SANCOV: LLVMFuzzerTestOneInput
+
+DSO: SanitizerCoverage: {{.*}}DSOTest.{{.*}}.sancov: {{.*}} PCs written
+DSO-DAG: SanitizerCoverage: {{.*}}DSO1.{{.*}}.sancov: {{.*}} PCs written
+DSO-DAG: SanitizerCoverage: {{.*}}DSO2.{{.*}}.sancov: {{.*}} PCs written
+
+NOCOV-NOT: SanitizerCoverage: {{.*}} PCs written
diff --git a/test/fuzzer/equivalence-signals.test b/test/fuzzer/equivalence-signals.test
new file mode 100644
index 000000000..7951636e8
--- /dev/null
+++ b/test/fuzzer/equivalence-signals.test
@@ -0,0 +1,9 @@
+# Run EquivalenceATest against itself with a small timeout
+# to stress the signal handling and ensure that shmem doesn't mind
+# the signals.
+
+RUN: %cpp_compiler %S/EquivalenceATest.cpp -o %t-EquivalenceATest
+RUN: %t-EquivalenceATest -timeout=1 -run_equivalence_server=EQUIV_SIG_TEST & export APID=$!
+RUN: sleep 3
+RUN: %t-EquivalenceATest -timeout=1 -use_equivalence_server=EQUIV_SIG_TEST -runs=500000 2>&1
+RUN: kill -9 $APID
diff --git a/test/fuzzer/equivalence.test b/test/fuzzer/equivalence.test
new file mode 100644
index 000000000..12964f478
--- /dev/null
+++ b/test/fuzzer/equivalence.test
@@ -0,0 +1,9 @@
+RUN: %cpp_compiler %S/EquivalenceATest.cpp -o %t-EquivalenceATest
+RUN: %cpp_compiler %S/EquivalenceBTest.cpp -o %t-EquivalenceBTest
+
+RUN: %t-EquivalenceATest -run_equivalence_server=EQUIV_TEST & export APID=$!
+RUN: sleep 3
+RUN: not %t-EquivalenceBTest -use_equivalence_server=EQUIV_TEST -max_len=4096 2>&1 | FileCheck %s
+CHECK: ERROR: libFuzzer: equivalence-mismatch. Sizes: {{.*}}; offset 2
+CHECK: SUMMARY: libFuzzer: equivalence-mismatch
+RUN: kill -9 $APID
diff --git a/test/fuzzer/exit-report.test b/test/fuzzer/exit-report.test
new file mode 100644
index 000000000..f754c1376
--- /dev/null
+++ b/test/fuzzer/exit-report.test
@@ -0,0 +1,6 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+RUN: not %t-SimpleTest 2>&1 | FileCheck %s
+
+CHECK: ERROR: libFuzzer: fuzz target exited
+CHECK: SUMMARY: libFuzzer: fuzz target exited
+CHECK: Test unit written to
diff --git a/test/fuzzer/exit_on_src_pos.test b/test/fuzzer/exit_on_src_pos.test
new file mode 100644
index 000000000..6a42c7ae9
--- /dev/null
+++ b/test/fuzzer/exit_on_src_pos.test
@@ -0,0 +1,8 @@
+# Temporary use -mllvm -use-unknown-locations=Disable so that
+# all instructions have debug info (file line numbers) attached.
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest -mllvm -use-unknown-locations=Disable
+RUN: %cpp_compiler %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest
+
+RUN: %t-SimpleTest -exit_on_src_pos=SimpleTest.cpp:18 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
+RUN: %t-ShrinkControlFlowTest -exit_on_src_pos=Foo 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
+EXIT_ON_SRC_POS: INFO: found line matching '{{.*}}', exiting.
diff --git a/test/fuzzer/extra-counters.test b/test/fuzzer/extra-counters.test
new file mode 100644
index 000000000..230f74a1b
--- /dev/null
+++ b/test/fuzzer/extra-counters.test
@@ -0,0 +1,7 @@
+REQUIRES: linux
+
+RUN: %cpp_compiler %S/TableLookupTest.cpp -o %t-TableLookupTest
+RUN: not %t-TableLookupTest -print_final_stats=1 2>&1 | FileCheck %s
+CHECK: BINGO
+// Expecting >= 4096 new_units_added
+CHECK: stat::new_units_added:{{.*[4][0-9][0-9][0-9]}}
diff --git a/test/fuzzer/fuzzer-customcrossover.test b/test/fuzzer/fuzzer-customcrossover.test
new file mode 100644
index 000000000..8f74cd98f
--- /dev/null
+++ b/test/fuzzer/fuzzer-customcrossover.test
@@ -0,0 +1,12 @@
+RUN: %cpp_compiler %S/CustomCrossOverTest.cpp -o %t-CustomCrossOverTest
+
+RUN: rm -rf %t/CustomCrossover
+RUN: mkdir -p %t/CustomCrossover
+RUN: echo "0123456789" > %t/CustomCrossover/digits
+RUN: echo "abcdefghij" > %t/CustomCrossover/chars
+RUN: not %t-CustomCrossOverTest -seed=1 -runs=100000 %t/CustomCrossover 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomCrossover
+RUN: rm -rf %t/CustomCrossover
+
+LLVMFuzzerCustomCrossover: In LLVMFuzzerCustomCrossover
+LLVMFuzzerCustomCrossover: BINGO
+
diff --git a/test/fuzzer/fuzzer-customcrossoverandmutate.test b/test/fuzzer/fuzzer-customcrossoverandmutate.test
new file mode 100644
index 000000000..4a7dfba2a
--- /dev/null
+++ b/test/fuzzer/fuzzer-customcrossoverandmutate.test
@@ -0,0 +1,2 @@
+RUN: %cpp_compiler %S/CustomCrossOverAndMutateTest.cpp -o %t-CustomCrossOverAndMutateTest
+RUN: %t-CustomCrossOverAndMutateTest -seed=1 -runs=100000
diff --git a/test/fuzzer/fuzzer-custommutator.test b/test/fuzzer/fuzzer-custommutator.test
new file mode 100644
index 000000000..7a693cd47
--- /dev/null
+++ b/test/fuzzer/fuzzer-custommutator.test
@@ -0,0 +1,5 @@
+RUN: %cpp_compiler %S/CustomMutatorTest.cpp -o %t-CustomMutatorTest
+RUN: not %t-CustomMutatorTest 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomMutator
+LLVMFuzzerCustomMutator: In LLVMFuzzerCustomMutator
+LLVMFuzzerCustomMutator: BINGO
+
diff --git a/test/fuzzer/fuzzer-dict.test b/test/fuzzer/fuzzer-dict.test
new file mode 100644
index 000000000..48c91dc1d
--- /dev/null
+++ b/test/fuzzer/fuzzer-dict.test
@@ -0,0 +1,8 @@
+RUN: %cpp_compiler %S/SimpleDictionaryTest.cpp -o %t-SimpleDictionaryTest
+
+CHECK: BINGO
+Done1000000: Done 1000000 runs in
+
+RUN: not %t-SimpleDictionaryTest -dict=%S/dict1.txt -seed=1 -runs=1000003 2>&1 | FileCheck %s
+RUN: %t-SimpleDictionaryTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
diff --git a/test/fuzzer/fuzzer-dirs.test b/test/fuzzer/fuzzer-dirs.test
new file mode 100644
index 000000000..ef0888f3b
--- /dev/null
+++ b/test/fuzzer/fuzzer-dirs.test
@@ -0,0 +1,21 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+
+RUN: rm -rf %t/SUB1
+RUN: mkdir -p %t/SUB1/SUB2/SUB3
+RUN: echo a > %t/SUB1/a
+RUN: echo b > %t/SUB1/SUB2/b
+RUN: echo c > %t/SUB1/SUB2/SUB3/c
+RUN: %t-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=SUBDIRS
+SUBDIRS: READ units: 3
+RUN: echo -n zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz > %t/SUB1/f64
+RUN: cat %t/SUB1/f64 %t/SUB1/f64 %t/SUB1/f64 %t/SUB1/f64 > %t/SUB1/f256
+RUN: cat %t/SUB1/f256 %t/SUB1/f256 %t/SUB1/f256 %t/SUB1/f256 > %t/SUB1/f1024
+RUN: cat %t/SUB1/f1024 %t/SUB1/f1024 %t/SUB1/f1024 %t/SUB1/f1024 > %t/SUB1/f4096
+RUN: cat %t/SUB1/f4096 %t/SUB1/f4096 > %t/SUB1/f8192
+RUN: %t-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=LONG
+LONG: INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 8192 bytes
+RUN: rm -rf %t/SUB1
+
+RUN: not %t-SimpleTest NONEXISTENT_DIR 2>&1 | FileCheck %s --check-prefix=NONEXISTENT_DIR
+NONEXISTENT_DIR: No such directory: NONEXISTENT_DIR; exiting
+
diff --git a/test/fuzzer/fuzzer-fdmask.test b/test/fuzzer/fuzzer-fdmask.test
new file mode 100644
index 000000000..3f04993b5
--- /dev/null
+++ b/test/fuzzer/fuzzer-fdmask.test
@@ -0,0 +1,32 @@
+RUN: %cpp_compiler %S/SpamyTest.cpp -o %t-SpamyTest
+
+RUN: %t-SpamyTest -runs=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_0
+RUN: %t-SpamyTest -runs=1 -close_fd_mask=0 2>&1 | FileCheck %s --check-prefix=FD_MASK_0
+RUN: %t-SpamyTest -runs=1 -close_fd_mask=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_1
+RUN: %t-SpamyTest -runs=1 -close_fd_mask=2 2>&1 | FileCheck %s --check-prefix=FD_MASK_2
+RUN: %t-SpamyTest -runs=1 -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=FD_MASK_3
+
+FD_MASK_0: PRINTF_STDOUT
+FD_MASK_0: PRINTF_STDERR
+FD_MASK_0: STREAM_COUT
+FD_MASK_0: STREAM_CERR
+FD_MASK_0: INITED
+
+FD_MASK_1-NOT: PRINTF_STDOUT
+FD_MASK_1: PRINTF_STDERR
+FD_MASK_1-NOT: STREAM_COUT
+FD_MASK_1: STREAM_CERR
+FD_MASK_1: INITED
+
+FD_MASK_2: PRINTF_STDOUT
+FD_MASK_2-NOT: PRINTF_STDERR
+FD_MASK_2: STREAM_COUT
+FD_MASK_2-NOTE: STREAM_CERR
+FD_MASK_2: INITED
+
+FD_MASK_3-NOT: PRINTF_STDOUT
+FD_MASK_3-NOT: PRINTF_STDERR
+FD_MASK_3-NOT: STREAM_COUT
+FD_MASK_3-NOT: STREAM_CERR
+FD_MASK_3: INITED
+
diff --git a/test/fuzzer/fuzzer-finalstats.test b/test/fuzzer/fuzzer-finalstats.test
new file mode 100644
index 000000000..4f983bea8
--- /dev/null
+++ b/test/fuzzer/fuzzer-finalstats.test
@@ -0,0 +1,12 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+RUN: %t-SimpleTest -seed=1 -runs=77 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS
+FINAL_STATS: stat::number_of_executed_units: 77
+FINAL_STATS: stat::average_exec_per_sec: 0
+FINAL_STATS: stat::new_units_added:
+FINAL_STATS: stat::slowest_unit_time_sec: 0
+FINAL_STATS: stat::peak_rss_mb:
+
+RUN: %t-SimpleTest %S/dict1.txt -runs=33 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS1
+FINAL_STATS1: stat::number_of_executed_units: 33
+FINAL_STATS1: stat::peak_rss_mb:
+
diff --git a/test/fuzzer/fuzzer-flags.test b/test/fuzzer/fuzzer-flags.test
new file mode 100644
index 000000000..2f9a31063
--- /dev/null
+++ b/test/fuzzer/fuzzer-flags.test
@@ -0,0 +1,19 @@
+RUN: %cpp_compiler %S/FlagsTest.cpp -o %t-FlagsTest
+RUN: not %t-FlagsTest -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR
+FOO_BAR: WARNING: unrecognized flag '-foo_bar=1'; use -help=1 to list all flags
+FOO_BAR: BINGO
+
+RUN: not %t-FlagsTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH
+DASH_DASH: WARNING: did you mean '-max_len=100' (single dash)?
+DASH_DASH: INFO: A corpus is not provided, starting from an empty corpus
+
+RUN: %t-FlagsTest -help=1 2>&1 | FileCheck %s --check-prefix=NO_INTERNAL
+NO_INTERNAL-NOT: internal flag
+
+RUN: not %t-FlagsTest --foo-bar -runs=10 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU
+PASSTHRU: BINGO --foo-bar --baz -help=1 test
+
+RUN: mkdir -p %t/T0 %t/T1
+RUN: touch %t/T1/empty
+RUN: not %t-FlagsTest --foo-bar -merge=1 %t/T0 %t/T1 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU-MERGE
+PASSTHRU-MERGE: BINGO --foo-bar --baz -help=1 test
diff --git a/test/fuzzer/fuzzer-leak.test b/test/fuzzer/fuzzer-leak.test
new file mode 100644
index 000000000..f8e99ce3f
--- /dev/null
+++ b/test/fuzzer/fuzzer-leak.test
@@ -0,0 +1,37 @@
+REQUIRES: lsan
+RUN: %cpp_compiler %S/LeakTest.cpp -o %t-LeakTest
+RUN: %cpp_compiler %S/ThreadedLeakTest.cpp -o %t-ThreadedLeakTest
+RUN: %cpp_compiler %S/LeakTimeoutTest.cpp -o %t-LeakTimeoutTest
+
+RUN: not %t-LeakTest -runs=100000 -detect_leaks=1 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
+LEAK_DURING: ERROR: LeakSanitizer: detected memory leaks
+LEAK_DURING: Direct leak of 4 byte(s) in 1 object(s) allocated from:
+LEAK_DURING: INFO: to ignore leaks on libFuzzer side use -detect_leaks=0
+LEAK_DURING: Test unit written to ./leak-
+LEAK_DURING-NOT: DONE
+LEAK_DURING-NOT: Done
+
+RUN: not %t-LeakTest -runs=0 -detect_leaks=1 %S 2>&1 | FileCheck %s --check-prefix=LEAK_IN_CORPUS
+LEAK_IN_CORPUS: ERROR: LeakSanitizer: detected memory leaks
+LEAK_IN_CORPUS: INFO: a leak has been found in the initial corpus.
+
+RUN: not %t-LeakTest -runs=100000000 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=MULTI_RUN_LEAK
+MULTI_RUN_LEAK-NOT: pulse
+MULTI_RUN_LEAK: LeakSanitizer: detected memory leaks
+
+RUN: not %t-LeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER
+RUN: not %t-LeakTest -runs=100000 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
+RUN: not %t-ThreadedLeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER
+RUN: not %t-ThreadedLeakTest -runs=100000 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
+LEAK_AFTER: Done 100000 runs in
+LEAK_AFTER: ERROR: LeakSanitizer: detected memory leaks
+
+RUN: not %t-LeakTest -runs=100000 -max_len=1 2>&1 | FileCheck %s --check-prefix=MAX_LEN_1
+MAX_LEN_1: Test unit written to ./leak-7cf184f4c67ad58283ecb19349720b0cae756829
+
+RUN: not %t-LeakTimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=LEAK_TIMEOUT
+LEAK_TIMEOUT: ERROR: libFuzzer: timeout after
+LEAK_TIMEOUT-NOT: LeakSanitizer
+
+
+RUN: %t-LeakTest -error_exitcode=0
diff --git a/test/fuzzer/fuzzer-oom-with-profile.test b/test/fuzzer/fuzzer-oom-with-profile.test
new file mode 100644
index 000000000..75cf48430
--- /dev/null
+++ b/test/fuzzer/fuzzer-oom-with-profile.test
@@ -0,0 +1,7 @@
+REQUIRES: linux
+RUN: %cpp_compiler %S/OutOfMemoryTest.cpp -o %t-OutOfMemoryTest
+RUN: not %t-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
+CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)
+CHECK: Live Heap Allocations
+CHECK: Test unit written to ./oom-
+SUMMARY: libFuzzer: out-of-memory
diff --git a/test/fuzzer/fuzzer-oom.test b/test/fuzzer/fuzzer-oom.test
new file mode 100644
index 000000000..9ef7c485d
--- /dev/null
+++ b/test/fuzzer/fuzzer-oom.test
@@ -0,0 +1,20 @@
+RUN: %cpp_compiler %S/OutOfMemoryTest.cpp -o %t-OutOfMemoryTest
+RUN: %cpp_compiler %S/OutOfMemorySingleLargeMallocTest.cpp -o %t-OutOfMemorySingleLargeMallocTest
+RUN: %cpp_compiler %S/AccumulateAllocationsTest.cpp -o %t-AccumulateAllocationsTest
+
+RUN: not %t-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
+
+CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)
+CHECK: Test unit written to ./oom-
+SUMMARY: libFuzzer: out-of-memory
+
+RUN: not %t-OutOfMemorySingleLargeMallocTest -rss_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
+
+We used to check for "out-of-memory (malloc(53{{.*}}))", but that would fail
+sometimes, so now we accept any OOM message.
+
+SINGLE_LARGE_MALLOC: libFuzzer: out-of-memory
+SINGLE_LARGE_MALLOC: in LLVMFuzzerTestOneInput
+
+# Check that -rss_limit_mb=0 means no limit.
+RUN: %t-AccumulateAllocationsTest -runs=1000 -rss_limit_mb=0
diff --git a/test/fuzzer/fuzzer-printcovpcs.test b/test/fuzzer/fuzzer-printcovpcs.test
new file mode 100644
index 000000000..e55ce14aa
--- /dev/null
+++ b/test/fuzzer/fuzzer-printcovpcs.test
@@ -0,0 +1,9 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+RUN: not %t-SimpleTest -print_pcs=1 -seed=1 2>&1 | FileCheck %s --check-prefix=PCS
+PCS-NOT: NEW_PC
+PCS:INITED
+PCS:NEW_PC: {{0x[a-f0-9]+}}
+PCS:NEW_PC: {{0x[a-f0-9]+}}
+PCS:NEW
+PCS:BINGO
+
diff --git a/test/fuzzer/fuzzer-runs.test b/test/fuzzer/fuzzer-runs.test
new file mode 100644
index 000000000..04987eee5
--- /dev/null
+++ b/test/fuzzer/fuzzer-runs.test
@@ -0,0 +1,9 @@
+RUN: mkdir -p %t
+RUN: %cpp_compiler %S/NthRunCrashTest.cpp -o %t-NthRunCrashTest
+RUN: echo abcd > %t/NthRunCrashTest.in
+RUN: %t-NthRunCrashTest %t/NthRunCrashTest.in
+RUN: %t-NthRunCrashTest %t/NthRunCrashTest.in -runs=10
+RUN: not %t-NthRunCrashTest %t/NthRunCrashTest.in -runs=10000 2>&1 | FileCheck %s
+RUN: rm %t/NthRunCrashTest.in
+CHECK: BINGO
+
diff --git a/test/fuzzer/fuzzer-seed.test b/test/fuzzer/fuzzer-seed.test
new file mode 100644
index 000000000..a69ea5432
--- /dev/null
+++ b/test/fuzzer/fuzzer-seed.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-SimpleCmpTest
+RUN: %t-SimpleCmpTest -seed=-1 -runs=0 2>&1 | FileCheck %s --check-prefix=CHECK_SEED_MINUS_ONE
+CHECK_SEED_MINUS_ONE: Seed: 4294967295
+
diff --git a/test/fuzzer/fuzzer-segv.test b/test/fuzzer/fuzzer-segv.test
new file mode 100644
index 000000000..4d3c7575f
--- /dev/null
+++ b/test/fuzzer/fuzzer-segv.test
@@ -0,0 +1,8 @@
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+RUN: env ASAN_OPTIONS=handle_segv=0 not %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
+LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal
+LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal
+LIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash-
+
+RUN: env ASAN_OPTIONS=handle_segv=1 not %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_ASAN_SEGV_HANDLER
+LIBFUZZER_ASAN_SEGV_HANDLER: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address
diff --git a/test/fuzzer/fuzzer-singleinputs.test b/test/fuzzer/fuzzer-singleinputs.test
new file mode 100644
index 000000000..468da5622
--- /dev/null
+++ b/test/fuzzer/fuzzer-singleinputs.test
@@ -0,0 +1,19 @@
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+
+RUN: not %t-NullDerefTest %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInput
+SingleInput-NOT: Test unit written to ./crash-
+
+RUN: rm -rf %tmp/SINGLE_INPUTS
+RUN: mkdir -p %tmp/SINGLE_INPUTS
+RUN: echo aaa > %tmp/SINGLE_INPUTS/aaa
+RUN: echo bbb > %tmp/SINGLE_INPUTS/bbb
+RUN: %t-SimpleTest %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
+RUN: %t-SimpleTest -max_len=2 %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
+RUN: rm -rf %tmp/SINGLE_INPUTS
+SINGLE_INPUTS: SimpleTest{{.*}}: Running 2 inputs 1 time(s) each.
+SINGLE_INPUTS: aaa in
+SINGLE_INPUTS: bbb in
+SINGLE_INPUTS: NOTE: fuzzing was not performed, you have only
+SINGLE_INPUTS: executed the target code on a fixed set of inputs.
+
diff --git a/test/fuzzer/fuzzer-threaded.test b/test/fuzzer/fuzzer-threaded.test
new file mode 100644
index 000000000..572ed5a35
--- /dev/null
+++ b/test/fuzzer/fuzzer-threaded.test
@@ -0,0 +1,8 @@
+CHECK: Done 1000 runs in
+RUN: %cpp_compiler %S/ThreadedTest.cpp -o %t-ThreadedTest
+
+RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+
diff --git a/test/fuzzer/fuzzer-timeout.test b/test/fuzzer/fuzzer-timeout.test
new file mode 100644
index 000000000..41f4ba364
--- /dev/null
+++ b/test/fuzzer/fuzzer-timeout.test
@@ -0,0 +1,21 @@
+RUN: %cpp_compiler %S/TimeoutTest.cpp -o %t-TimeoutTest
+RUN: %cpp_compiler %S/TimeoutEmptyTest.cpp -o %t-TimeoutEmptyTest
+RUN: not %t-TimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutTest
+TimeoutTest: ALARM: working on the last Unit for
+TimeoutTest: Test unit written to ./timeout-
+TimeoutTest: == ERROR: libFuzzer: timeout after
+TimeoutTest: #0
+TimeoutTest: #1
+TimeoutTest: #2
+TimeoutTest: SUMMARY: libFuzzer: timeout
+
+RUN: not %t-TimeoutTest -timeout=1 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInputTimeoutTest
+SingleInputTimeoutTest: ALARM: working on the last Unit for {{[1-3]}} seconds
+SingleInputTimeoutTest-NOT: Test unit written to ./timeout-
+
+RUN: %t-TimeoutTest -timeout=1 -timeout_exitcode=0
+
+RUN: not %t-TimeoutEmptyTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutEmptyTest
+TimeoutEmptyTest: ALARM: working on the last Unit for
+TimeoutEmptyTest: == ERROR: libFuzzer: timeout after
+TimeoutEmptyTest: SUMMARY: libFuzzer: timeout
diff --git a/test/fuzzer/fuzzer-ubsan.test b/test/fuzzer/fuzzer-ubsan.test
new file mode 100644
index 000000000..49c190cd0
--- /dev/null
+++ b/test/fuzzer/fuzzer-ubsan.test
@@ -0,0 +1,5 @@
+RUN: %cpp_compiler -fsanitize=undefined -fno-sanitize-recover=all %S/SignedIntOverflowTest.cpp -o %t-SignedIntOverflowTest-Ubsan
+RUN: not %t-SignedIntOverflowTest-Ubsan 2>&1 | FileCheck %s
+CHECK: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
+CHECK: Test unit written to ./crash-
+
diff --git a/test/fuzzer/fuzzer.test b/test/fuzzer/fuzzer.test
new file mode 100644
index 000000000..e506fcbee
--- /dev/null
+++ b/test/fuzzer/fuzzer.test
@@ -0,0 +1,70 @@
+CHECK: BINGO
+Done1000000: Done 1000000 runs in
+RUN: %cpp_compiler %S/BogusInitializeTest.cpp -o %t-BogusInitializeTest
+RUN: %cpp_compiler %S/BufferOverflowOnInput.cpp -o %t-BufferOverflowOnInput
+RUN: %cpp_compiler %S/CounterTest.cpp -o %t-CounterTest
+RUN: %cpp_compiler %S/DSO1.cpp -fPIC -shared -o %t-DSO1.so
+RUN: %cpp_compiler %S/DSO2.cpp -fPIC -shared -o %t-DSO2.so
+RUN: %cpp_compiler %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
+RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
+RUN: %cpp_compiler %S/InitializeTest.cpp -o %t-InitializeTest
+RUN: %cpp_compiler %S/NotinstrumentedTest.cpp -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard -o %t-NotinstrumentedTest-NoCoverage
+RUN: %cpp_compiler %S/NullDerefOnEmptyTest.cpp -o %t-NullDerefOnEmptyTest
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+RUN: %cpp_compiler %S/StrncmpOOBTest.cpp -o %t-StrncmpOOBTest
+
+RUN: not %t-SimpleTest 2>&1 | FileCheck %s
+
+# only_ascii mode. Will perform some minimal self-validation.
+RUN: not %t-SimpleTest -only_ascii=1 2>&1
+
+RUN: %t-SimpleCmpTest -max_total_time=1 -use_cmp=0 2>&1 | FileCheck %s --check-prefix=MaxTotalTime
+MaxTotalTime: Done {{.*}} runs in {{.}} second(s)
+
+RUN: not %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest
+RUN: not %t-NullDerefTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=NullDerefTest
+NullDerefTest: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address
+NullDerefTest: Test unit written to ./crash-
+RUN: not %t-NullDerefTest -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix
+NullDerefTestPrefix: Test unit written to ZZZcrash-
+RUN: not %t-NullDerefTest -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=NullDerefTestExactPath
+NullDerefTestExactPath: Test unit written to FOOBAR
+
+RUN: not %t-NullDerefOnEmptyTest -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=NULL_DEREF_ON_EMPTY
+NULL_DEREF_ON_EMPTY: stat::number_of_executed_units:
+
+#not %t-FullCoverageSetTest -timeout=15 -seed=1 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s
+
+RUN: not %t-CounterTest -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS
+
+COUNTERS: INITED {{.*}} {{bits:|ft:}}
+COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}
+COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}
+COUNTERS: BINGO
+
+# Don't run UninstrumentedTest for now since we build libFuzzer itself with asan.
+DISABLED: not %t-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED
+UNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting.
+
+RUN: not %t-NotinstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE
+NO_COVERAGE: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting
+
+RUN: not %t-BufferOverflowOnInput 2>&1 | FileCheck %s --check-prefix=OOB
+OOB: AddressSanitizer: heap-buffer-overflow
+OOB: is located 0 bytes to the right of 3-byte region
+
+RUN: not %t-InitializeTest -use_value_profile=1 2>&1 | FileCheck %s
+
+RUN: not %t-DSOTest 2>&1 | FileCheck %s --check-prefix=DSO
+DSO: INFO: Loaded 3 modules
+DSO: BINGO
+
+RUN: env ASAN_OPTIONS=strict_string_checks=1 not %t-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP
+STRNCMP: AddressSanitizer: heap-buffer-overflow
+STRNCMP-NOT: __sanitizer_weak_hook_strncmp
+STRNCMP: in LLVMFuzzerTestOneInput
+
+RUN: not %t-BogusInitializeTest 2>&1 | FileCheck %s --check-prefix=BOGUS_INITIALIZE
+BOGUS_INITIALIZE: argv[0] has been modified in LLVMFuzzerInitialize
diff --git a/test/fuzzer/hi.txt b/test/fuzzer/hi.txt
new file mode 100644
index 000000000..2f9031f0e
--- /dev/null
+++ b/test/fuzzer/hi.txt
@@ -0,0 +1 @@
+Hi! \ No newline at end of file
diff --git a/test/fuzzer/inline-8bit-counters.test b/test/fuzzer/inline-8bit-counters.test
new file mode 100644
index 000000000..5723c70b1
--- /dev/null
+++ b/test/fuzzer/inline-8bit-counters.test
@@ -0,0 +1,5 @@
+REQUIRES: linux
+RUN: %cpp_compiler %S/SimpleTest.cpp -fno-sanitize-coverage=trace-pc-guard -fsanitize-coverage=inline-8bit-counters -o %t-SimpleTest-Inline8bitCounters
+CHECK: INFO: Loaded 1 modules ({{.*}} inline 8-bit counters)
+CHECK: BINGO
+RUN: not %t-SimpleTest-Inline8bitCounters -runs=1000000 -seed=1 2>&1 | FileCheck %s
diff --git a/test/fuzzer/lit.cfg b/test/fuzzer/lit.cfg
new file mode 100644
index 000000000..a82ca23b9
--- /dev/null
+++ b/test/fuzzer/lit.cfg
@@ -0,0 +1,80 @@
+import lit.formats
+import sys
+import os
+
+config.name = "LLVMFuzzer"
+config.test_format = lit.formats.ShTest(True)
+config.suffixes = ['.test']
+config.test_source_root = os.path.dirname(__file__)
+
+# Choose between lit's internal shell pipeline runner and a real shell. If
+# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
+use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
+if use_lit_shell:
+ # 0 is external, "" is default, and everything else is internal.
+ execute_external = (use_lit_shell == "0")
+else:
+ # Otherwise we default to internal on Windows and external elsewhere, as
+ # bash on Windows is usually very slow.
+ execute_external = (not sys.platform in ['win32'])
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(execute_external)
+
+# LeakSanitizer is not supported on OSX right now.
+if sys.platform.startswith('darwin'):
+ lit_config.note('lsan feature unavailable')
+else:
+ lit_config.note('lsan feature available')
+ config.available_features.add('lsan')
+
+if sys.platform.startswith('win') or sys.platform.startswith('cygwin'):
+ config.available_features.add('windows')
+
+if sys.platform.startswith('darwin'):
+ config.available_features.add('darwin')
+
+if sys.platform.startswith('linux'):
+ # Note the value of ``sys.platform`` is not consistent
+ # between python 2 and 3, hence the use of ``.startswith()``.
+ lit_config.note('linux feature available')
+ config.available_features.add('linux')
+else:
+ lit_config.note('linux feature unavailable')
+
+config.substitutions.append(('%build_dir', config.cmake_binary_dir))
+libfuzzer_src_root = os.path.join(config.compiler_rt_src_root, "lib", "fuzzer")
+config.substitutions.append(('%libfuzzer_src', libfuzzer_src_root))
+
+def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True):
+ compiler_cmd = config.c_compiler
+ link_cmd = '-lc++' if 'darwin' in config.target_triple else '-lstdc++'
+ std_cmd = '-std=c++11' if is_cpp else ''
+ sanitizers = ['address']
+ if fuzzer_enabled:
+ sanitizers.append('fuzzer')
+ sanitizers_cmd = ('-fsanitize=%s' % ','.join(sanitizers))
+ isysroot_cmd = ('-isysroot %s' % config.osx_sysroot
+ ) if 'darwin' in config.target_triple else ''
+ include_cmd = '-I%s' % libfuzzer_src_root
+ return '%s %s %s -gline-tables-only %s %s %s' % (
+ compiler_cmd, std_cmd, link_cmd, isysroot_cmd, sanitizers_cmd, include_cmd)
+
+config.substitutions.append(('%cpp_compiler',
+ generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True)
+ ))
+
+config.substitutions.append(('%c_compiler',
+ generate_compiler_cmd(is_cpp=False, fuzzer_enabled=True)
+ ))
+
+config.substitutions.append(('%no_fuzzer_cpp_compiler',
+ generate_compiler_cmd(is_cpp=True, fuzzer_enabled=False)
+ ))
+
+config.substitutions.append(('%no_fuzzer_c_compiler',
+ generate_compiler_cmd(is_cpp=False, fuzzer_enabled=False)
+ ))
diff --git a/test/fuzzer/lit.site.cfg.in b/test/fuzzer/lit.site.cfg.in
new file mode 100644
index 000000000..3f1957511
--- /dev/null
+++ b/test/fuzzer/lit.site.cfg.in
@@ -0,0 +1,17 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
+
+config.cpp_compiler = "@LIBFUZZER_TEST_COMPILER@"
+config.target_flags = "@LIBFUZZER_TEST_FLAGS@"
+config.c_compiler = "@LIBFUZZER_TEST_COMPILER@"
+
+config.osx_sysroot = "@CMAKE_OSX_SYSROOT@"
+config.cmake_binary_dir = "@CMAKE_BINARY_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+
+# Load common config for all compiler-rt lit tests.
+lit_config.load_config(config,
+ "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
diff --git a/test/fuzzer/memcmp.test b/test/fuzzer/memcmp.test
new file mode 100644
index 000000000..3431a524c
--- /dev/null
+++ b/test/fuzzer/memcmp.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/MemcmpTest.cpp -o %t-MemcmpTest
+RUN: not %t-MemcmpTest -seed=1 -runs=10000000 2>&1 | FileCheck %s
+CHECK: BINGO
diff --git a/test/fuzzer/memcmp64.test b/test/fuzzer/memcmp64.test
new file mode 100644
index 000000000..223c3bd42
--- /dev/null
+++ b/test/fuzzer/memcmp64.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/Memcmp64BytesTest.cpp -o %t-Memcmp64BytesTest
+RUN: not %t-Memcmp64BytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
+CHECK: BINGO
diff --git a/test/fuzzer/merge-posix.test b/test/fuzzer/merge-posix.test
new file mode 100644
index 000000000..e34e3a325
--- /dev/null
+++ b/test/fuzzer/merge-posix.test
@@ -0,0 +1,23 @@
+RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
+
+RUN: rm -rf %tmp/T1 %tmp/T2
+RUN: mkdir -p %tmp/T1 %tmp/T2
+
+RUN: echo F..... > %tmp/T1/1
+RUN: echo .U.... > %tmp/T1/2
+RUN: echo ..Z... > %tmp/T1/3
+
+RUN: echo .....F > %tmp/T2/1
+RUN: echo ....U. > %tmp/T2/2
+RUN: echo ...Z.. > %tmp/T2/3
+RUN: echo ...Z.. > %tmp/T2/4
+RUN: echo ....E. > %tmp/T2/5
+RUN: echo .....R > %tmp/T2/6
+
+# Check that we can report an error if file size exceeded
+RUN: (ulimit -f 1; not %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ)
+SIGXFSZ: ERROR: libFuzzer: file size exceeded
+
+# Check that we honor TMPDIR
+RUN: TMPDIR=DIR_DOES_NOT_EXIST not %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR
+TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp
diff --git a/test/fuzzer/merge-summary.test b/test/fuzzer/merge-summary.test
new file mode 100644
index 000000000..3e21c23ef
--- /dev/null
+++ b/test/fuzzer/merge-summary.test
@@ -0,0 +1,17 @@
+RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
+
+RUN: rm -rf %t/T1 %t/T2
+RUN: mkdir -p %t/T0 %t/T1 %t/T2
+RUN: echo ...Z.. > %t/T2/1
+RUN: echo ....E. > %t/T2/2
+RUN: echo .....R > %t/T2/3
+RUN: echo F..... > %t/T2/a
+RUN: echo .U.... > %t/T2/b
+RUN: echo ..Z... > %t/T2/c
+
+RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -save_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=SAVE_SUMMARY
+SAVE_SUMMARY: MERGE-OUTER: writing coverage summary for 6 files to {{.*}}SUMMARY
+RUN: rm %t/T1/*
+RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -load_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=LOAD_SUMMARY
+LOAD_SUMMARY: MERGE-OUTER: coverage summary loaded from {{.*}}SUMMAR
+LOAD_SUMMARY: MERGE-OUTER: 0 new files with 0 new features added
diff --git a/test/fuzzer/merge.test b/test/fuzzer/merge.test
new file mode 100644
index 000000000..30e27b8d2
--- /dev/null
+++ b/test/fuzzer/merge.test
@@ -0,0 +1,55 @@
+CHECK: BINGO
+
+RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
+
+RUN: rm -rf %tmp/T0 %tmp/T1 %tmp/T2
+RUN: mkdir -p %tmp/T0 %tmp/T1 %tmp/T2
+RUN: echo F..... > %tmp/T0/1
+RUN: echo .U.... > %tmp/T0/2
+RUN: echo ..Z... > %tmp/T0/3
+
+# T1 has 3 elements, T2 is empty.
+RUN: cp %tmp/T0/* %tmp/T1/
+RUN: %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: MERGE-OUTER: 3 files, 3 in the initial corpus
+CHECK1: MERGE-OUTER: 0 new files with 0 new features added
+
+RUN: echo ...Z.. > %tmp/T2/1
+RUN: echo ....E. > %tmp/T2/2
+RUN: echo .....R > %tmp/T2/3
+RUN: echo F..... > %tmp/T2/a
+RUN: echo .U.... > %tmp/T2/b
+RUN: echo ..Z... > %tmp/T2/c
+
+# T1 has 3 elements, T2 has 6 elements, only 3 are new.
+RUN: %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: MERGE-OUTER: 9 files, 3 in the initial corpus
+CHECK2: MERGE-OUTER: 3 new files with 3 new features added
+
+# Now, T1 has 6 units and T2 has no new interesting units.
+RUN: %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+CHECK3: MERGE-OUTER: 12 files, 6 in the initial corpus
+CHECK3: MERGE-OUTER: 0 new files with 0 new features added
+
+# Check that we respect max_len during the merge and don't crash.
+RUN: rm %tmp/T1/*
+RUN: cp %tmp/T0/* %tmp/T1/
+RUN: echo looooooooong > %tmp/T2/looooooooong
+RUN: %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=6 2>&1 | FileCheck %s --check-prefix=MAX_LEN
+MAX_LEN: MERGE-OUTER: 3 new files
+
+# Check that merge tolerates failures.
+RUN: rm %tmp/T1/*
+RUN: cp %tmp/T0/* %tmp/T1/
+RUN: echo 'FUZZER' > %tmp/T2/FUZZER
+RUN: %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=MERGE_WITH_CRASH
+MERGE_WITH_CRASH: MERGE-OUTER: succesfull in 2 attempt(s)
+MERGE_WITH_CRASH: MERGE-OUTER: 3 new files
+
+# Check that we actually limit the size with max_len
+RUN: %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5
+MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s)
+
+RUN: rm -rf %tmp/T1/* %tmp/T2/*
+RUN: not %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=EMPTY
+EMPTY: MERGE-OUTER: zero succesfull attempts, exiting
diff --git a/test/fuzzer/minimize_crash.test b/test/fuzzer/minimize_crash.test
new file mode 100644
index 000000000..77ab370fa
--- /dev/null
+++ b/test/fuzzer/minimize_crash.test
@@ -0,0 +1,16 @@
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+RUN: %cpp_compiler %S/SingleByteInputTest.cpp -o %t-SingleByteInputTest
+
+RUN: echo 'Hi!rv349f34t3gg' > not_minimal_crash
+RUN: %t-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s
+CHECK: CRASH_MIN: failed to minimize beyond ./minimized-from-{{.*}} (3 bytes), exiting
+RUN: %t-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT
+CHECK_EXACT: CRASH_MIN: failed to minimize beyond exact_minimized_path (3 bytes), exiting
+RUN: rm not_minimal_crash minimized-from-* exact_minimized_path
+
+RUN: echo -n 'abcd*xyz' > not_minimal_crash
+RUN: %t-SingleByteInputTest -minimize_crash=1 not_minimal_crash -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=MIN1
+MIN1: Test unit written to exact_minimized_path
+MIN1: Test unit written to exact_minimized_path
+MIN1: INFO: The input is small enough, exiting
+MIN1: CRASH_MIN: failed to minimize beyond exact_minimized_path (1 bytes), exiting
diff --git a/test/fuzzer/minimize_two_crashes.test b/test/fuzzer/minimize_two_crashes.test
new file mode 100644
index 000000000..e6ff9990f
--- /dev/null
+++ b/test/fuzzer/minimize_two_crashes.test
@@ -0,0 +1,18 @@
+# Test that the minimizer stops when it sees a differe bug.
+
+RUN: %cpp_compiler %S/TwoDifferentBugsTest.cpp -o %t-TwoDifferentBugsTest
+
+RUN: rm -rf %t && mkdir %t
+RUN: echo H12345678901234667888090 > %t/long_crash
+RUN: env ASAN_OPTIONS=dedup_token_length=3 %t-TwoDifferentBugsTest -seed=1 -minimize_crash=1 %t/long_crash -exact_artifact_path=%t/result 2>&1 | FileCheck %s
+
+CHECK: DedupToken1: DEDUP_TOKEN: Bar
+CHECK: DedupToken2: DEDUP_TOKEN: Bar
+CHECK: DedupToken1: DEDUP_TOKEN: Bar
+CHECK: DedupToken2: DEDUP_TOKEN: Foo
+CHECK: CRASH_MIN: mismatch in dedup tokens
+
+RUN: not %t-TwoDifferentBugsTest %t/result 2>&1 | FileCheck %s --check-prefix=VERIFY
+
+VERIFY: ERROR: AddressSanitizer:
+VERIFY: in Bar
diff --git a/test/fuzzer/overwrite-input.test b/test/fuzzer/overwrite-input.test
new file mode 100644
index 000000000..3695622d0
--- /dev/null
+++ b/test/fuzzer/overwrite-input.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/OverwriteInputTest.cpp -o %t-OverwriteInputTest
+RUN: not %t-OverwriteInputTest 2>&1 | FileCheck %s
+CHECK: ERROR: libFuzzer: fuzz target overwrites it's const input
diff --git a/test/fuzzer/recommended-dictionary.test b/test/fuzzer/recommended-dictionary.test
new file mode 100644
index 000000000..41b62c924
--- /dev/null
+++ b/test/fuzzer/recommended-dictionary.test
@@ -0,0 +1,6 @@
+RUN: %cpp_compiler %S/RepeatedMemcmp.cpp -o %t-RepeatedMemcmp
+RUN: %t-RepeatedMemcmp -seed=11 -runs=100000 -max_len=20 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
+RECOMMENDED_DICT:###### Recommended dictionary. ######
+RECOMMENDED_DICT-DAG: "foo"
+RECOMMENDED_DICT-DAG: "bar"
+RECOMMENDED_DICT:###### End of recommended dictionary. ######
diff --git a/test/fuzzer/reduce_inputs.test b/test/fuzzer/reduce_inputs.test
new file mode 100644
index 000000000..02e090ebd
--- /dev/null
+++ b/test/fuzzer/reduce_inputs.test
@@ -0,0 +1,16 @@
+# Test -reduce_inputs=1
+
+RUN: rm -rf %t/C
+RUN: mkdir -p %t/C
+RUN: %cpp_compiler %S/ShrinkControlFlowSimpleTest.cpp -o %t-ShrinkControlFlowSimpleTest
+RUN: %cpp_compiler %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest
+RUN: %t-ShrinkControlFlowSimpleTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 %t/C 2>&1 | FileCheck %s
+CHECK: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60'
+
+# Test that reduce_inputs deletes redundant files in the corpus.
+RUN: %t-ShrinkControlFlowSimpleTest -runs=0 %t/C 2>&1 | FileCheck %s --check-prefix=COUNT
+COUNT: READ units: 4
+
+# a bit longer test
+RUN: %t-ShrinkControlFlowTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -seed=1 -runs=1000000 2>&1 | FileCheck %s
+
diff --git a/test/fuzzer/repeated-bytes.test b/test/fuzzer/repeated-bytes.test
new file mode 100644
index 000000000..0bba2a916
--- /dev/null
+++ b/test/fuzzer/repeated-bytes.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/RepeatedBytesTest.cpp -o %t-RepeatedBytesTest
+CHECK: BINGO
+RUN: not %t-RepeatedBytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/shrink.test b/test/fuzzer/shrink.test
new file mode 100644
index 000000000..2988d4bbb
--- /dev/null
+++ b/test/fuzzer/shrink.test
@@ -0,0 +1,10 @@
+RUN: %cpp_compiler %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest
+RUN: %cpp_compiler %S/ShrinkValueProfileTest.cpp -o %t-ShrinkValueProfileTest
+RUN: %t-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=1 -reduce_inputs=0 2>&1 | FileCheck %s --check-prefix=SHRINK1
+# Limit max_len to run this negative test faster.
+RUN: %t-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=0 -reduce_inputs=0 -max_len=64 2>&1 | FileCheck %s --check-prefix=SHRINK0
+RUN: %t-ShrinkValueProfileTest -seed=1 -exit_on_item=aea2e3923af219a8956f626558ef32f30a914ebc -runs=100000 -shrink=1 -reduce_inputs=0 -use_value_profile=1 2>&1 | FileCheck %s --check-prefix=SHRINK1_VP
+
+SHRINK0: Done 1000000 runs in
+SHRINK1: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60', exiting.
+SHRINK1_VP: INFO: found item with checksum 'aea2e3923af219a8956f626558ef32f30a914ebc', exiting
diff --git a/test/fuzzer/simple-cmp.test b/test/fuzzer/simple-cmp.test
new file mode 100644
index 000000000..08123ed3a
--- /dev/null
+++ b/test/fuzzer/simple-cmp.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest
+CHECK: BINGO
+RUN: not %t-SimpleCmpTest -seed=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/standalone.test b/test/fuzzer/standalone.test
new file mode 100644
index 000000000..e6483703f
--- /dev/null
+++ b/test/fuzzer/standalone.test
@@ -0,0 +1,8 @@
+RUN: %no_fuzzer_c_compiler %libfuzzer_src/standalone/StandaloneFuzzTargetMain.c -c -o %t_1.o
+RUN: %no_fuzzer_cpp_compiler %S/InitializeTest.cpp -c -o %t_2.o
+
+RUN: %no_fuzzer_cpp_compiler %t_1.o %t_2.o -o %t-StandaloneInitializeTest
+RUN: %t-StandaloneInitializeTest %S/hi.txt %S/dict1.txt 2>&1 | FileCheck %s
+CHECK: StandaloneFuzzTargetMain: running 2 inputs
+CHECK: Done: {{.*}}hi.txt: (3 bytes)
+CHECK: Done: {{.*}}dict1.txt: (61 bytes)
diff --git a/test/fuzzer/strcmp.test b/test/fuzzer/strcmp.test
new file mode 100644
index 000000000..47ad8f9ba
--- /dev/null
+++ b/test/fuzzer/strcmp.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/StrcmpTest.cpp -o %t-StrcmpTest
+RUN: not %t-StrcmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
+CHECK: BINGO
+
diff --git a/test/fuzzer/strncmp.test b/test/fuzzer/strncmp.test
new file mode 100644
index 000000000..49693c8de
--- /dev/null
+++ b/test/fuzzer/strncmp.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/StrncmpTest.cpp -o %t-StrncmpTest
+RUN: not %t-StrncmpTest -seed=2 -runs=10000000 2>&1 | FileCheck %s
+CHECK: BINGO
+
diff --git a/test/fuzzer/strstr.test b/test/fuzzer/strstr.test
new file mode 100644
index 000000000..c39d5801a
--- /dev/null
+++ b/test/fuzzer/strstr.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/StrstrTest.cpp -o %t-StrstrTest
+RUN: not %t-StrstrTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
+CHECK: BINGO
+
diff --git a/test/fuzzer/swap-cmp.test b/test/fuzzer/swap-cmp.test
new file mode 100644
index 000000000..5c2379cde
--- /dev/null
+++ b/test/fuzzer/swap-cmp.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/SwapCmpTest.cpp -o %t-SwapCmpTest
+CHECK: BINGO
+RUN: not %t-SwapCmpTest -seed=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/trace-malloc-2.test b/test/fuzzer/trace-malloc-2.test
new file mode 100644
index 000000000..56f16d786
--- /dev/null
+++ b/test/fuzzer/trace-malloc-2.test
@@ -0,0 +1,10 @@
+// FIXME: This test infinite loops on darwin because it crashes
+// printing a stack trace repeatedly
+UNSUPPORTED: darwin
+
+RUN: %cpp_compiler %S/TraceMallocTest.cpp -o %t-TraceMallocTest
+
+RUN: %t-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2
+TRACE2-DAG: FREE[0]
+TRACE2-DAG: MALLOC[0]
+TRACE2-DAG: in LLVMFuzzerTestOneInput
diff --git a/test/fuzzer/trace-malloc.test b/test/fuzzer/trace-malloc.test
new file mode 100644
index 000000000..979be99b7
--- /dev/null
+++ b/test/fuzzer/trace-malloc.test
@@ -0,0 +1,7 @@
+RUN: %cpp_compiler %S/TraceMallocTest.cpp -o %t-TraceMallocTest
+
+RUN: %t-TraceMallocTest -seed=1 -trace_malloc=1 -runs=10000 2>&1 | FileCheck %s
+CHECK-DAG: MallocFreeTracer: STOP 0 0 (same)
+CHECK-DAG: MallocFreeTracer: STOP 0 1 (DIFFERENT)
+CHECK-DAG: MallocFreeTracer: STOP 1 0 (DIFFERENT)
+CHECK-DAG: MallocFreeTracer: STOP 1 1 (same)
diff --git a/test/fuzzer/trace-pc.test b/test/fuzzer/trace-pc.test
new file mode 100644
index 000000000..eaa0cb08a
--- /dev/null
+++ b/test/fuzzer/trace-pc.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard -fsanitize-coverage=trace-pc -o %t-SimpleTest-TracePC
+CHECK: BINGO
+RUN: not %t-SimpleTest-TracePC -runs=1000000 -seed=1 2>&1 | FileCheck %s
diff --git a/test/fuzzer/ulimit.test b/test/fuzzer/ulimit.test
new file mode 100644
index 000000000..8772caa2d
--- /dev/null
+++ b/test/fuzzer/ulimit.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+RUN: ulimit -s 1000
+RUN: not %t-SimpleTest
diff --git a/test/fuzzer/unit/lit.site.cfg.in b/test/fuzzer/unit/lit.site.cfg.in
new file mode 100644
index 000000000..bab2824e4
--- /dev/null
+++ b/test/fuzzer/unit/lit.site.cfg.in
@@ -0,0 +1,9 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+config.name = "LLVMFuzzer-Unittest"
+# Load common config for all compiler-rt unit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.unit.configured")
+
+config.test_exec_root = os.path.join("@COMPILER_RT_BINARY_DIR@",
+ "lib", "fuzzer", "tests")
+config.test_source_root = config.test_exec_root
diff --git a/test/fuzzer/value-profile-cmp.test b/test/fuzzer/value-profile-cmp.test
new file mode 100644
index 000000000..64244297c
--- /dev/null
+++ b/test/fuzzer/value-profile-cmp.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest
+RUN: not %t-SimpleCmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-cmp2.test b/test/fuzzer/value-profile-cmp2.test
new file mode 100644
index 000000000..43dd8f9dd
--- /dev/null
+++ b/test/fuzzer/value-profile-cmp2.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/SimpleHashTest.cpp -o %t-SimpleHashTest
+RUN: not %t-SimpleHashTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 -max_len=64 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-cmp3.test b/test/fuzzer/value-profile-cmp3.test
new file mode 100644
index 000000000..d2284750b
--- /dev/null
+++ b/test/fuzzer/value-profile-cmp3.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/AbsNegAndConstantTest.cpp -o %t-AbsNegAndConstantTest
+RUN: not %t-AbsNegAndConstantTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-cmp4.test b/test/fuzzer/value-profile-cmp4.test
new file mode 100644
index 000000000..bcbc67b18
--- /dev/null
+++ b/test/fuzzer/value-profile-cmp4.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/AbsNegAndConstant64Test.cpp -o %t-AbsNegAndConstant64Test
+RUN: not %t-AbsNegAndConstant64Test -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-div.test b/test/fuzzer/value-profile-div.test
new file mode 100644
index 000000000..8711a2546
--- /dev/null
+++ b/test/fuzzer/value-profile-div.test
@@ -0,0 +1,4 @@
+CHECK: AddressSanitizer: {{FPE|int-divide-by-zero}}
+RUN: %cpp_compiler %S/DivTest.cpp -fsanitize-coverage=trace-div -o %t-DivTest
+RUN: not %t-DivTest -seed=1 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
+
diff --git a/test/fuzzer/value-profile-load.test b/test/fuzzer/value-profile-load.test
new file mode 100644
index 000000000..3bf2a658a
--- /dev/null
+++ b/test/fuzzer/value-profile-load.test
@@ -0,0 +1,3 @@
+CHECK: AddressSanitizer: global-buffer-overflow
+RUN: %cpp_compiler %S/LoadTest.cpp -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-gep,trace-div,trace-cmp -o %t-LoadTest
+RUN: not %t-LoadTest -seed=2 -use_cmp=0 -use_value_profile=1 -runs=20000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-mem.test b/test/fuzzer/value-profile-mem.test
new file mode 100644
index 000000000..0b0c21d68
--- /dev/null
+++ b/test/fuzzer/value-profile-mem.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/SingleMemcmpTest.cpp -o %t-SingleMemcmpTest
+RUN: not %t-SingleMemcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-set.test b/test/fuzzer/value-profile-set.test
new file mode 100644
index 000000000..e2e3fb47f
--- /dev/null
+++ b/test/fuzzer/value-profile-set.test
@@ -0,0 +1,4 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/FourIndependentBranchesTest.cpp -o %t-FourIndependentBranchesTest
+RUN: not %t-FourIndependentBranchesTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
+
diff --git a/test/fuzzer/value-profile-strcmp.test b/test/fuzzer/value-profile-strcmp.test
new file mode 100644
index 000000000..f5c766a65
--- /dev/null
+++ b/test/fuzzer/value-profile-strcmp.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/SingleStrcmpTest.cpp -o %t-SingleStrcmpTest
+RUN: not %t-SingleStrcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-strncmp.test b/test/fuzzer/value-profile-strncmp.test
new file mode 100644
index 000000000..2dfe43c4a
--- /dev/null
+++ b/test/fuzzer/value-profile-strncmp.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/SingleStrncmpTest.cpp -o %t-SingleStrncmpTest
+RUN: not %t-SingleStrncmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-switch.test b/test/fuzzer/value-profile-switch.test
new file mode 100644
index 000000000..7edb312a0
--- /dev/null
+++ b/test/fuzzer/value-profile-switch.test
@@ -0,0 +1,5 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/SwitchTest.cpp -o %t-SwitchTest
+RUN: %cpp_compiler %S/Switch2Test.cpp -o %t-Switch2Test
+RUN: not %t-SwitchTest -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s
+RUN: not %t-Switch2Test -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s