summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Fuzzer/test
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/Fuzzer/test')
-rw-r--r--gnu/llvm/lib/Fuzzer/test/CMakeLists.txt118
-rw-r--r--gnu/llvm/lib/Fuzzer/test/CallerCalleeTest.cpp56
-rw-r--r--gnu/llvm/lib/Fuzzer/test/CounterTest.cpp15
-rw-r--r--gnu/llvm/lib/Fuzzer/test/FourIndependentBranchesTest.cpp19
-rw-r--r--gnu/llvm/lib/Fuzzer/test/FullCoverageSetTest.cpp21
-rw-r--r--gnu/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp402
-rw-r--r--gnu/llvm/lib/Fuzzer/test/MemcmpTest.cpp28
-rw-r--r--gnu/llvm/lib/Fuzzer/test/NullDerefTest.cpp23
-rw-r--r--gnu/llvm/lib/Fuzzer/test/SimpleCmpTest.cpp31
-rw-r--r--gnu/llvm/lib/Fuzzer/test/SimpleDictionaryTest.cpp26
-rw-r--r--gnu/llvm/lib/Fuzzer/test/SimpleHashTest.cpp37
-rw-r--r--gnu/llvm/lib/Fuzzer/test/SimpleTest.cpp24
-rw-r--r--gnu/llvm/lib/Fuzzer/test/StrcmpTest.cpp29
-rw-r--r--gnu/llvm/lib/Fuzzer/test/StrncmpTest.cpp25
-rw-r--r--gnu/llvm/lib/Fuzzer/test/SwitchTest.cpp55
-rw-r--r--gnu/llvm/lib/Fuzzer/test/ThreadedTest.cpp23
-rw-r--r--gnu/llvm/lib/Fuzzer/test/TimeoutTest.cpp23
-rw-r--r--gnu/llvm/lib/Fuzzer/test/UninstrumentedTest.cpp8
-rw-r--r--gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp51
-rw-r--r--gnu/llvm/lib/Fuzzer/test/dfsan/CMakeLists.txt14
-rw-r--r--gnu/llvm/lib/Fuzzer/test/dict1.txt4
-rw-r--r--gnu/llvm/lib/Fuzzer/test/fuzzer-dfsan.test23
-rw-r--r--gnu/llvm/lib/Fuzzer/test/fuzzer-dict.test6
-rw-r--r--gnu/llvm/lib/Fuzzer/test/fuzzer-drill.test8
-rw-r--r--gnu/llvm/lib/Fuzzer/test/fuzzer-threaded.test7
-rw-r--r--gnu/llvm/lib/Fuzzer/test/fuzzer-timeout.test13
-rw-r--r--gnu/llvm/lib/Fuzzer/test/fuzzer-traces.test20
-rw-r--r--gnu/llvm/lib/Fuzzer/test/fuzzer.test36
-rw-r--r--gnu/llvm/lib/Fuzzer/test/hi.txt1
-rw-r--r--gnu/llvm/lib/Fuzzer/test/lit.cfg15
-rw-r--r--gnu/llvm/lib/Fuzzer/test/lit.site.cfg.in3
-rw-r--r--gnu/llvm/lib/Fuzzer/test/merge.test29
-rw-r--r--gnu/llvm/lib/Fuzzer/test/trace-bb/CMakeLists.txt14
-rw-r--r--gnu/llvm/lib/Fuzzer/test/uninstrumented/CMakeLists.txt14
-rw-r--r--gnu/llvm/lib/Fuzzer/test/unit/lit.cfg7
-rw-r--r--gnu/llvm/lib/Fuzzer/test/unit/lit.site.cfg.in2
36 files changed, 1230 insertions, 0 deletions
diff --git a/gnu/llvm/lib/Fuzzer/test/CMakeLists.txt b/gnu/llvm/lib/Fuzzer/test/CMakeLists.txt
new file mode 100644
index 00000000000..cd0b167eb38
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/CMakeLists.txt
@@ -0,0 +1,118 @@
+# Build all these tests with -O0, otherwise optimizations may merge some
+# basic blocks and we'll fail to discover the targets.
+# Also enable the coverage instrumentation back (it is disabled
+# for the Fuzzer lib)
+set(CMAKE_CXX_FLAGS_RELEASE "${LIBFUZZER_FLAGS_BASE} -O0 -fsanitize-coverage=edge,indirect-calls")
+
+set(DFSanTests
+ MemcmpTest
+ SimpleCmpTest
+ StrcmpTest
+ StrncmpTest
+ SwitchTest
+ )
+
+set(Tests
+ CallerCalleeTest
+ CounterTest
+ FourIndependentBranchesTest
+ FullCoverageSetTest
+ MemcmpTest
+ NullDerefTest
+ SimpleCmpTest
+ SimpleDictionaryTest
+ SimpleHashTest
+ SimpleTest
+ StrcmpTest
+ StrncmpTest
+ SwitchTest
+ ThreadedTest
+ TimeoutTest
+ )
+
+set(CustomMainTests
+ UserSuppliedFuzzerTest
+ )
+
+set(UninstrumentedTests
+ UninstrumentedTest
+ )
+
+set(TraceBBTests
+ SimpleTest
+ )
+
+set(TestBinaries)
+
+foreach(Test ${Tests})
+ add_executable(LLVMFuzzer-${Test}
+ ${Test}.cpp
+ )
+ target_link_libraries(LLVMFuzzer-${Test}
+ LLVMFuzzer
+ )
+ set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test})
+endforeach()
+
+foreach(Test ${CustomMainTests})
+ add_executable(LLVMFuzzer-${Test}
+ ${Test}.cpp
+ )
+ target_link_libraries(LLVMFuzzer-${Test}
+ LLVMFuzzerNoMain
+ )
+ set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test})
+endforeach()
+
+
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ )
+
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg
+ )
+
+include_directories(..)
+include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include)
+
+add_executable(LLVMFuzzer-Unittest
+ FuzzerUnittest.cpp
+ $<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>
+ )
+
+target_link_libraries(LLVMFuzzer-Unittest
+ gtest
+ gtest_main
+ )
+
+set(TestBinaries ${TestBinaries} LLVMFuzzer-Unittest)
+
+add_subdirectory(dfsan)
+
+foreach(Test ${DFSanTests})
+ set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-DFSan)
+endforeach()
+
+add_subdirectory(uninstrumented)
+
+foreach(Test ${UninstrumentedTests})
+ set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-Uninstrumented)
+endforeach()
+
+add_subdirectory(trace-bb)
+
+foreach(Test ${TraceBBTests})
+ set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-TraceBB)
+endforeach()
+
+set_target_properties(${TestBinaries}
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+add_lit_testsuite(check-fuzzer "Running Fuzzer tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${TestBinaries} FileCheck not
+ )
diff --git a/gnu/llvm/lib/Fuzzer/test/CallerCalleeTest.cpp b/gnu/llvm/lib/Fuzzer/test/CallerCalleeTest.cpp
new file mode 100644
index 00000000000..150b2fc0405
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/CallerCalleeTest.cpp
@@ -0,0 +1,56 @@
+// Simple test for a fuzzer.
+// Try to find the target using the indirect caller-callee pairs.
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#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/gnu/llvm/lib/Fuzzer/test/CounterTest.cpp b/gnu/llvm/lib/Fuzzer/test/CounterTest.cpp
new file mode 100644
index 00000000000..b61f419c499
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/CounterTest.cpp
@@ -0,0 +1,15 @@
+// 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/gnu/llvm/lib/Fuzzer/test/FourIndependentBranchesTest.cpp b/gnu/llvm/lib/Fuzzer/test/FourIndependentBranchesTest.cpp
new file mode 100644
index 00000000000..6007dd4a027
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/FourIndependentBranchesTest.cpp
@@ -0,0 +1,19 @@
+// Simple test for a fuzzer. The fuzzer must find the string "FUZZ".
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#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/gnu/llvm/lib/Fuzzer/test/FullCoverageSetTest.cpp b/gnu/llvm/lib/Fuzzer/test/FullCoverageSetTest.cpp
new file mode 100644
index 00000000000..a868084a0ce
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/FullCoverageSetTest.cpp
@@ -0,0 +1,21 @@
+// Simple test for a fuzzer. The fuzzer must find the string "FUZZER".
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#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/gnu/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp b/gnu/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp
new file mode 100644
index 00000000000..b33e0c96145
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp
@@ -0,0 +1,402 @@
+#include "FuzzerInternal.h"
+#include "gtest/gtest.h"
+#include <set>
+
+using namespace fuzzer;
+
+// For now, have LLVMFuzzerTestOneInput just to make it link.
+// Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
+extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ abort();
+}
+
+TEST(Fuzzer, CrossOver) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ Unit A({0, 1, 2}), B({5, 6, 7});
+ Unit C;
+ Unit Expected[] = {
+ { 0 },
+ { 0, 1 },
+ { 0, 5 },
+ { 0, 1, 2 },
+ { 0, 1, 5 },
+ { 0, 5, 1 },
+ { 0, 5, 6 },
+ { 0, 1, 2, 5 },
+ { 0, 1, 5, 2 },
+ { 0, 1, 5, 6 },
+ { 0, 5, 1, 2 },
+ { 0, 5, 1, 6 },
+ { 0, 5, 6, 1 },
+ { 0, 5, 6, 7 },
+ { 0, 1, 2, 5, 6 },
+ { 0, 1, 5, 2, 6 },
+ { 0, 1, 5, 6, 2 },
+ { 0, 1, 5, 6, 7 },
+ { 0, 5, 1, 2, 6 },
+ { 0, 5, 1, 6, 2 },
+ { 0, 5, 1, 6, 7 },
+ { 0, 5, 6, 1, 2 },
+ { 0, 5, 6, 1, 7 },
+ { 0, 5, 6, 7, 1 },
+ { 0, 1, 2, 5, 6, 7 },
+ { 0, 1, 5, 2, 6, 7 },
+ { 0, 1, 5, 6, 2, 7 },
+ { 0, 1, 5, 6, 7, 2 },
+ { 0, 5, 1, 2, 6, 7 },
+ { 0, 5, 1, 6, 2, 7 },
+ { 0, 5, 1, 6, 7, 2 },
+ { 0, 5, 6, 1, 2, 7 },
+ { 0, 5, 6, 1, 7, 2 },
+ { 0, 5, 6, 7, 1, 2 }
+ };
+ for (size_t Len = 1; Len < 8; Len++) {
+ std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
+ for (int Iter = 0; Iter < 3000; Iter++) {
+ C.resize(Len);
+ size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(),
+ C.data(), C.size());
+ C.resize(NewSize);
+ FoundUnits.insert(C);
+ }
+ for (const Unit &U : Expected)
+ if (U.size() <= Len)
+ ExpectedUnitsWitThisLength.insert(U);
+ EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
+ }
+}
+
+TEST(Fuzzer, Hash) {
+ uint8_t A[] = {'a', 'b', 'c'};
+ fuzzer::Unit U(A, A + sizeof(A));
+ EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
+ U.push_back('d');
+ EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
+}
+
+typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
+ size_t MaxSize);
+
+void TestEraseByte(Mutator M, int NumIter) {
+ uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
+ uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
+ uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
+ uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
+ uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ int FoundMask = 0;
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));
+ if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
+ if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
+ if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
+ if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
+ if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
+ if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
+ if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
+ if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
+ }
+ EXPECT_EQ(FoundMask, 255);
+}
+
+TEST(FuzzerMutate, EraseByte1) {
+ TestEraseByte(&MutationDispatcher::Mutate_EraseByte, 100);
+}
+TEST(FuzzerMutate, EraseByte2) {
+ TestEraseByte(&MutationDispatcher::Mutate, 1000);
+}
+
+void TestInsertByte(Mutator M, int NumIter) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ int FoundMask = 0;
+ uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+ uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+ uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
+ uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
+ uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
+ uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
+ uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
+ uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+ size_t NewSize = (MD.*M)(T, 7, 8);
+ if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
+ if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
+ if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
+ if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
+ if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
+ if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
+ if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
+ if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
+ }
+ EXPECT_EQ(FoundMask, 255);
+}
+
+TEST(FuzzerMutate, InsertByte1) {
+ TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
+}
+TEST(FuzzerMutate, InsertByte2) {
+ TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
+}
+
+void TestChangeByte(Mutator M, int NumIter) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ int FoundMask = 0;
+ uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
+ uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
+ uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
+ uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ size_t NewSize = (MD.*M)(T, 8, 9);
+ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
+ if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
+ if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
+ if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
+ if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
+ if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
+ if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
+ if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
+ }
+ EXPECT_EQ(FoundMask, 255);
+}
+
+TEST(FuzzerMutate, ChangeByte1) {
+ TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
+}
+TEST(FuzzerMutate, ChangeByte2) {
+ TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
+}
+
+void TestChangeBit(Mutator M, int NumIter) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ int FoundMask = 0;
+ uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
+ uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
+ uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
+ uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
+ uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+ size_t NewSize = (MD.*M)(T, 8, 9);
+ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
+ if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
+ if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
+ if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
+ if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
+ if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
+ if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
+ if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
+ }
+ EXPECT_EQ(FoundMask, 255);
+}
+
+TEST(FuzzerMutate, ChangeBit1) {
+ TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
+}
+TEST(FuzzerMutate, ChangeBit2) {
+ TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
+}
+
+void TestShuffleBytes(Mutator M, int NumIter) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ int FoundMask = 0;
+ uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
+ uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
+ uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
+ uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
+ uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+ size_t NewSize = (MD.*M)(T, 7, 7);
+ if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
+ if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
+ if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
+ if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
+ if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
+ }
+ EXPECT_EQ(FoundMask, 31);
+}
+
+TEST(FuzzerMutate, ShuffleBytes1) {
+ TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 15);
+}
+TEST(FuzzerMutate, ShuffleBytes2) {
+ TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 19);
+}
+
+void TestAddWordFromDictionary(Mutator M, int NumIter) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
+ uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
+ MD.AddWordToManualDictionary(Unit(Word1, Word1 + sizeof(Word1)));
+ MD.AddWordToManualDictionary(Unit(Word2, Word2 + sizeof(Word2)));
+ int FoundMask = 0;
+ uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
+ uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
+ uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
+ uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
+ uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
+ uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
+ uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
+ uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[7] = {0x00, 0x11, 0x22};
+ size_t NewSize = (MD.*M)(T, 3, 7);
+ if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
+ if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
+ if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
+ if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
+ if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
+ if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
+ if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
+ if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
+ }
+ EXPECT_EQ(FoundMask, 255);
+}
+
+TEST(FuzzerMutate, AddWordFromDictionary1) {
+ TestAddWordFromDictionary(
+ &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
+}
+
+TEST(FuzzerMutate, AddWordFromDictionary2) {
+ TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
+}
+
+void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+ uint8_t Word[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};
+ size_t PosHint = 7777;
+ MD.AddWordToAutoDictionary(Unit(Word, Word + sizeof(Word)), PosHint);
+ int FoundMask = 0;
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[10000];
+ memset(T, 0, sizeof(T));
+ size_t NewSize = (MD.*M)(T, 9000, 10000);
+ if (NewSize >= PosHint + sizeof(Word) &&
+ !memcmp(Word, T + PosHint, sizeof(Word)))
+ FoundMask = 1;
+ }
+ EXPECT_EQ(FoundMask, 1);
+}
+
+TEST(FuzzerMutate, AddWordFromDictionaryWithHint1) {
+ TestAddWordFromDictionaryWithHint(
+ &MutationDispatcher::Mutate_AddWordFromAutoDictionary, 1 << 5);
+}
+
+TEST(FuzzerMutate, AddWordFromDictionaryWithHint2) {
+ TestAddWordFromDictionaryWithHint(&MutationDispatcher::Mutate, 1 << 10);
+}
+
+void TestChangeASCIIInteger(Mutator M, int NumIter) {
+ FuzzerRandomLibc Rand(0);
+ MutationDispatcher MD(Rand);
+
+ uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
+ uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
+ uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
+ uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
+ int FoundMask = 0;
+ for (int i = 0; i < NumIter; i++) {
+ uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
+ size_t NewSize = (MD.*M)(T, 8, 8);
+ /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
+ else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
+ else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
+ else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
+ else if (NewSize == 8) FoundMask |= 1 << 4;
+ }
+ EXPECT_EQ(FoundMask, 31);
+}
+
+TEST(FuzzerMutate, ChangeASCIIInteger1) {
+ TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
+ 1 << 15);
+}
+
+TEST(FuzzerMutate, ChangeASCIIInteger2) {
+ TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
+}
+
+
+TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
+ Unit U;
+ EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
+ EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
+ EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U));
+ EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U));
+ EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U));
+ EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U));
+ EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U));
+ EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
+ EXPECT_EQ(U, Unit({'a'}));
+ EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
+ EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
+ EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
+ EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
+ EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
+ EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
+ EXPECT_EQ(U, Unit({'\\'}));
+ EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
+ EXPECT_EQ(U, Unit({0xAB}));
+ EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
+ EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
+ EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
+ EXPECT_EQ(U, Unit({'#'}));
+ EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
+ EXPECT_EQ(U, Unit({'"'}));
+}
+
+TEST(FuzzerDictionary, ParseDictionaryFile) {
+ std::vector<Unit> Units;
+ EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
+ EXPECT_FALSE(ParseDictionaryFile("", &Units));
+ EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
+ EXPECT_EQ(Units.size(), 0U);
+ EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
+ EXPECT_EQ(Units.size(), 0U);
+ EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
+ EXPECT_EQ(Units.size(), 0U);
+ EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
+ EXPECT_EQ(Units.size(), 0U);
+ EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units));
+ EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));
+ EXPECT_TRUE(
+ ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
+ EXPECT_EQ(Units,
+ std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
+}
+
+TEST(FuzzerUtil, Base64) {
+ EXPECT_EQ("", Base64({}));
+ EXPECT_EQ("YQ==", Base64({'a'}));
+ EXPECT_EQ("eA==", Base64({'x'}));
+ EXPECT_EQ("YWI=", Base64({'a', 'b'}));
+ EXPECT_EQ("eHk=", Base64({'x', 'y'}));
+ EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
+ EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
+ EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
+ EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
+ EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
+}
diff --git a/gnu/llvm/lib/Fuzzer/test/MemcmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/MemcmpTest.cpp
new file mode 100644
index 00000000000..c19c95717bb
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/MemcmpTest.cpp
@@ -0,0 +1,28 @@
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cstring>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+
+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 >= 16 && 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/gnu/llvm/lib/Fuzzer/test/NullDerefTest.cpp b/gnu/llvm/lib/Fuzzer/test/NullDerefTest.cpp
new file mode 100644
index 00000000000..200c56ccbbc
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/NullDerefTest.cpp
@@ -0,0 +1,23 @@
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#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/gnu/llvm/lib/Fuzzer/test/SimpleCmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/SimpleCmpTest.cpp
new file mode 100644
index 00000000000..8568c737efb
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/SimpleCmpTest.cpp
@@ -0,0 +1,31 @@
+// Simple test for a fuzzer. The fuzzer must find several narrow ranges.
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <cstdio>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 14) return 0;
+ uint64_t x = 0;
+ int64_t y = 0;
+ int z = 0;
+ unsigned short a = 0;
+ memcpy(&x, Data, 8);
+ memcpy(&y, Data + Size - 8, 8);
+ memcpy(&z, Data + Size / 2, sizeof(z));
+ memcpy(&a, Data + Size / 2 + 4, sizeof(a));
+
+ if (x > 1234567890 &&
+ x < 1234567895 &&
+ y >= 987654321 &&
+ y <= 987654325 &&
+ z < -10000 &&
+ z >= -10005 &&
+ z != -10003 &&
+ a == 4242) {
+ fprintf(stderr, "BINGO; Found the target: size %zd (%zd, %zd, %d, %d), exiting.\n",
+ Size, x, y, z, a);
+ exit(1);
+ }
+ return 0;
+}
diff --git a/gnu/llvm/lib/Fuzzer/test/SimpleDictionaryTest.cpp b/gnu/llvm/lib/Fuzzer/test/SimpleDictionaryTest.cpp
new file mode 100644
index 00000000000..b9cb2f0270a
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/SimpleDictionaryTest.cpp
@@ -0,0 +1,26 @@
+// Simple test for a fuzzer.
+// The fuzzer must find a string based on dictionary words:
+// "Elvis"
+// "Presley"
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#include <cstring>
+#include <iostream>
+
+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";
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/gnu/llvm/lib/Fuzzer/test/SimpleHashTest.cpp b/gnu/llvm/lib/Fuzzer/test/SimpleHashTest.cpp
new file mode 100644
index 00000000000..5bab3fa7f64
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/SimpleHashTest.cpp
@@ -0,0 +1,37 @@
+// 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 <cstdlib>
+#include <cstring>
+#include <cstdio>
+
+// 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/gnu/llvm/lib/Fuzzer/test/SimpleTest.cpp b/gnu/llvm/lib/Fuzzer/test/SimpleTest.cpp
new file mode 100644
index 00000000000..04225a889f5
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/SimpleTest.cpp
@@ -0,0 +1,24 @@
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <assert.h>
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#include <iostream>
+
+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";
+ exit(0);
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/gnu/llvm/lib/Fuzzer/test/StrcmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/StrcmpTest.cpp
new file mode 100644
index 00000000000..835819ae2f4
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/StrcmpTest.cpp
@@ -0,0 +1,29 @@
+// Break through a series of strcmp.
+#include <cstring>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cassert>
+
+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, (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, "AAA") &&
+ Size >= 3 && Eq(Data + 3, Size - 3, "BBBB") &&
+ Size >= 7 && Eq(Data + 7, Size - 7, "CCCCCC") &&
+ Size >= 14 && Data[13] == 42
+ ) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/gnu/llvm/lib/Fuzzer/test/StrncmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/StrncmpTest.cpp
new file mode 100644
index 00000000000..55344d75e0b
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/StrncmpTest.cpp
@@ -0,0 +1,25 @@
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cstring>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+
+static volatile int sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ // TODO: check other sizes.
+ char *S = (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 >= 16 && strncmp(S + 14, "KLM", 3) == 0) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ }
+ }
+ }
+ return 0;
+}
diff --git a/gnu/llvm/lib/Fuzzer/test/SwitchTest.cpp b/gnu/llvm/lib/Fuzzer/test/SwitchTest.cpp
new file mode 100644
index 00000000000..5de7fff7452
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/SwitchTest.cpp
@@ -0,0 +1,55 @@
+// Simple test for a fuzzer. The fuzzer must find the interesting switch value.
+#include <cstdint>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#include <cstddef>
+
+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/gnu/llvm/lib/Fuzzer/test/ThreadedTest.cpp b/gnu/llvm/lib/Fuzzer/test/ThreadedTest.cpp
new file mode 100644
index 00000000000..7aa114a41f3
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/ThreadedTest.cpp
@@ -0,0 +1,23 @@
+// Threaded test for a fuzzer. The fuzzer should not crash.
+#include <assert.h>
+#include <cstdint>
+#include <cstddef>
+#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/gnu/llvm/lib/Fuzzer/test/TimeoutTest.cpp b/gnu/llvm/lib/Fuzzer/test/TimeoutTest.cpp
new file mode 100644
index 00000000000..71790ded95a
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/TimeoutTest.cpp
@@ -0,0 +1,23 @@
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#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/gnu/llvm/lib/Fuzzer/test/UninstrumentedTest.cpp b/gnu/llvm/lib/Fuzzer/test/UninstrumentedTest.cpp
new file mode 100644
index 00000000000..c1730198d83
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/UninstrumentedTest.cpp
@@ -0,0 +1,8 @@
+// This test should not be instrumented.
+#include <cstdint>
+#include <cstddef>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ return 0;
+}
+
diff --git a/gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp b/gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp
new file mode 100644
index 00000000000..59f83b57bfa
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp
@@ -0,0 +1,51 @@
+// Simple test for a fuzzer.
+// The fuzzer must find the string "Hi!" preceded by a magic value.
+// Uses UserSuppliedFuzzer which ensures that the magic is present.
+#include <cstdint>
+#include <cassert>
+#include <cstdlib>
+#include <cstddef>
+#include <cstring>
+#include <iostream>
+
+#include "FuzzerInterface.h"
+
+static const uint64_t kMagic = 8860221463604ULL;
+
+class MyFuzzer : public fuzzer::UserSuppliedFuzzer {
+ public:
+ MyFuzzer(fuzzer::FuzzerRandomBase *Rand)
+ : fuzzer::UserSuppliedFuzzer(Rand) {}
+ int TargetFunction(const uint8_t *Data, size_t Size) {
+ if (Size <= 10) return 0;
+ if (memcmp(Data, &kMagic, sizeof(kMagic))) return 0;
+ // It's hard to get here w/o advanced fuzzing techniques (e.g. cmp tracing).
+ // So, we simply 'fix' the data in the custom mutator.
+ if (Data[8] == 'H') {
+ if (Data[9] == 'i') {
+ if (Data[10] == '!') {
+ std::cout << "BINGO; Found the target, exiting\n";
+ exit(1);
+ }
+ }
+ }
+ return 0;
+ }
+ // Custom mutator.
+ virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
+ assert(MaxSize > sizeof(kMagic));
+ if (Size < sizeof(kMagic))
+ Size = sizeof(kMagic);
+ // "Fix" the data, then mutate.
+ memcpy(Data, &kMagic, std::min(MaxSize, sizeof(kMagic)));
+ return fuzzer::UserSuppliedFuzzer::Mutate(
+ Data + sizeof(kMagic), Size - sizeof(kMagic), MaxSize - sizeof(kMagic));
+ }
+ // No need to redefine CrossOver() here.
+};
+
+int main(int argc, char **argv) {
+ fuzzer::FuzzerRandomLibc Rand(0);
+ MyFuzzer F(&Rand);
+ fuzzer::FuzzerDriver(argc, argv, F);
+}
diff --git a/gnu/llvm/lib/Fuzzer/test/dfsan/CMakeLists.txt b/gnu/llvm/lib/Fuzzer/test/dfsan/CMakeLists.txt
new file mode 100644
index 00000000000..2b49831fcdb
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/dfsan/CMakeLists.txt
@@ -0,0 +1,14 @@
+# These tests depend on both coverage and dfsan instrumentation.
+
+set(CMAKE_CXX_FLAGS_RELEASE
+ "${LIBFUZZER_FLAGS_BASE} -O0 -fno-sanitize=all -fsanitize=dataflow")
+
+foreach(Test ${DFSanTests})
+ add_executable(LLVMFuzzer-${Test}-DFSan
+ ../${Test}.cpp
+ )
+ target_link_libraries(LLVMFuzzer-${Test}-DFSan
+ LLVMFuzzer
+ )
+endforeach()
+
diff --git a/gnu/llvm/lib/Fuzzer/test/dict1.txt b/gnu/llvm/lib/Fuzzer/test/dict1.txt
new file mode 100644
index 00000000000..520d0cc7b7d
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/dict1.txt
@@ -0,0 +1,4 @@
+# Dictionary for SimpleDictionaryTest
+
+a="Elvis"
+b="Presley"
diff --git a/gnu/llvm/lib/Fuzzer/test/fuzzer-dfsan.test b/gnu/llvm/lib/Fuzzer/test/fuzzer-dfsan.test
new file mode 100644
index 00000000000..567086ed65a
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/fuzzer-dfsan.test
@@ -0,0 +1,23 @@
+CHECK1: BINGO
+CHECK2: BINGO
+CHECK3: BINGO
+CHECK4: BINGO
+
+CHECK_DFSanCmpCallback: DFSanCmpCallback: PC
+CHECK_DFSanSwitchCallback: DFSanSwitchCallback: PC
+CHECK_DFSanMemcmpCallback: DFSanMemcmpCallback: Pos
+
+RUN: not LLVMFuzzer-SimpleCmpTest-DFSan -use_traces=1 -seed=1 -runs=1000000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: LLVMFuzzer-SimpleCmpTest-DFSan -use_traces=1 -seed=1 -runs=100 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanCmpCallback
+
+RUN: not LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK2
+RUN: LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanMemcmpCallback
+
+RUN: not LLVMFuzzer-StrncmpTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: LLVMFuzzer-StrncmpTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanMemcmpCallback
+
+RUN: not LLVMFuzzer-StrcmpTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: LLVMFuzzer-StrcmpTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanMemcmpCallback
+
+RUN: not LLVMFuzzer-SwitchTest-DFSan -use_traces=1 -seed=1 -runs=100000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK4
+RUN: LLVMFuzzer-SwitchTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanSwitchCallback
diff --git a/gnu/llvm/lib/Fuzzer/test/fuzzer-dict.test b/gnu/llvm/lib/Fuzzer/test/fuzzer-dict.test
new file mode 100644
index 00000000000..dec002f6a37
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/fuzzer-dict.test
@@ -0,0 +1,6 @@
+CHECK: BINGO
+Done1000000: Done 1000000 runs in
+
+RUN: not LLVMFuzzer-SimpleDictionaryTest -dict=%S/dict1.txt -seed=1 -runs=1000003 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-SimpleDictionaryTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
diff --git a/gnu/llvm/lib/Fuzzer/test/fuzzer-drill.test b/gnu/llvm/lib/Fuzzer/test/fuzzer-drill.test
new file mode 100644
index 00000000000..b2fc1fecd27
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/fuzzer-drill.test
@@ -0,0 +1,8 @@
+CHECK: BINGO
+RUN: rm -rf FourIndependentBranchesTestCORPUS
+RUN: mkdir FourIndependentBranchesTestCORPUS
+RUN: LLVMFuzzer-FourIndependentBranchesTest -seed=1 -runs=100000 FourIndependentBranchesTestCORPUS
+RUN: not LLVMFuzzer-FourIndependentBranchesTest -runs=100000 -drill=1 -jobs=200 FourIndependentBranchesTestCORPUS 2>&1 | FileCheck %s
+RUN: rm -rf FourIndependentBranchesTestCORPUS
+
+
diff --git a/gnu/llvm/lib/Fuzzer/test/fuzzer-threaded.test b/gnu/llvm/lib/Fuzzer/test/fuzzer-threaded.test
new file mode 100644
index 00000000000..c58a33456cc
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/fuzzer-threaded.test
@@ -0,0 +1,7 @@
+CHECK: Done 1000 runs in
+
+RUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+
diff --git a/gnu/llvm/lib/Fuzzer/test/fuzzer-timeout.test b/gnu/llvm/lib/Fuzzer/test/fuzzer-timeout.test
new file mode 100644
index 00000000000..c3a9e8a3a9e
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/fuzzer-timeout.test
@@ -0,0 +1,13 @@
+RUN: not LLVMFuzzer-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 LLVMFuzzer-TimeoutTest -timeout=1 -test_single_input=%S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInputTimeoutTest
+SingleInputTimeoutTest: ALARM: working on the last Unit for
+SingleInputTimeoutTest-NOT: Test unit written to ./timeout-
+
diff --git a/gnu/llvm/lib/Fuzzer/test/fuzzer-traces.test b/gnu/llvm/lib/Fuzzer/test/fuzzer-traces.test
new file mode 100644
index 00000000000..3b8639b8e94
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/fuzzer-traces.test
@@ -0,0 +1,20 @@
+CHECK: BINGO
+Done1000000: Done 1000000 runs in
+Done10000000: Done 10000000 runs in
+
+RUN: not LLVMFuzzer-SimpleCmpTest -use_traces=1 -seed=1 -runs=10000001 2>&1 | FileCheck %s
+
+RUN: not LLVMFuzzer-MemcmpTest -use_traces=1 -seed=4294967295 -runs=100000 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-MemcmpTest -seed=4294967295 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
+RUN: not LLVMFuzzer-StrncmpTest -use_traces=1 -seed=1 -runs=100000 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-StrncmpTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
+RUN: not LLVMFuzzer-StrcmpTest -use_traces=1 -seed=1 -runs=200000 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-StrcmpTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
+RUN: not LLVMFuzzer-SwitchTest -use_traces=1 -seed=1 -runs=1000002 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-SwitchTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
+RUN: not LLVMFuzzer-SimpleHashTest -use_traces=1 -seed=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: LLVMFuzzer-SimpleHashTest -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=Done10000000
diff --git a/gnu/llvm/lib/Fuzzer/test/fuzzer.test b/gnu/llvm/lib/Fuzzer/test/fuzzer.test
new file mode 100644
index 00000000000..c63014f59d6
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/fuzzer.test
@@ -0,0 +1,36 @@
+CHECK: BINGO
+Done1000000: Done 1000000 runs in
+
+RUN: LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-NullDerefTest -test_single_input=%S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInput
+SingleInput-NOT: Test unit written to ./crash-
+
+RUN: LLVMFuzzer-SimpleCmpTest -max_total_time=1 2>&1 | FileCheck %s --check-prefix=MaxTotalTime
+MaxTotalTime: Done {{.*}} runs in {{.}} second(s)
+
+RUN: not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest
+NullDerefTest: Test unit written to ./crash-
+RUN: not LLVMFuzzer-NullDerefTest -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix
+NullDerefTestPrefix: Test unit written to ZZZcrash-
+RUN: not LLVMFuzzer-NullDerefTest -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=NullDerefTestExactPath
+NullDerefTestExactPath: Test unit written to FOOBAR
+
+#not LLVMFuzzer-FullCoverageSetTest -timeout=15 -seed=1 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s
+
+RUN: not LLVMFuzzer-CounterTest -use_counters=1 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s
+
+RUN: not LLVMFuzzer-CallerCalleeTest -cross_over=0 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s
+# This one is flaky, may actually find the goal even w/o use_indir_calls.
+# LLVMFuzzer-CallerCalleeTest -use_indir_calls=0 -cross_over=0 -max_len=6 -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
+
+RUN: not LLVMFuzzer-UserSuppliedFuzzerTest -seed=1 -timeout=15 2>&1 | FileCheck %s
+
+RUN: not LLVMFuzzer-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED
+UNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting.
+
+RUN: LLVMFuzzer-SimpleTest -print_new_cov_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
+PCS:{{^0x[a-f0-9]+}}
+PCS:NEW
+PCS:BINGO
+
diff --git a/gnu/llvm/lib/Fuzzer/test/hi.txt b/gnu/llvm/lib/Fuzzer/test/hi.txt
new file mode 100644
index 00000000000..2f9031f0ec7
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/hi.txt
@@ -0,0 +1 @@
+Hi! \ No newline at end of file
diff --git a/gnu/llvm/lib/Fuzzer/test/lit.cfg b/gnu/llvm/lib/Fuzzer/test/lit.cfg
new file mode 100644
index 00000000000..2140a97668b
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/lit.cfg
@@ -0,0 +1,15 @@
+import lit.formats
+
+config.name = "LLVMFuzzer"
+config.test_format = lit.formats.ShTest(True)
+config.suffixes = ['.test']
+config.test_source_root = os.path.dirname(__file__)
+
+# Tweak PATH to include llvm tools dir and current exec dir.
+llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
+if (not llvm_tools_dir) or (not os.path.exists(llvm_tools_dir)):
+ lit_config.fatal("Invalid llvm_tools_dir config attribute: %r" % llvm_tools_dir)
+path = os.path.pathsep.join((llvm_tools_dir, config.test_exec_root,
+ config.environment['PATH']))
+config.environment['PATH'] = path
+
diff --git a/gnu/llvm/lib/Fuzzer/test/lit.site.cfg.in b/gnu/llvm/lib/Fuzzer/test/lit.site.cfg.in
new file mode 100644
index 00000000000..e520db8e881
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/lit.site.cfg.in
@@ -0,0 +1,3 @@
+config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
diff --git a/gnu/llvm/lib/Fuzzer/test/merge.test b/gnu/llvm/lib/Fuzzer/test/merge.test
new file mode 100644
index 00000000000..57ecc141bbf
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/merge.test
@@ -0,0 +1,29 @@
+CHECK: BINGO
+
+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
+
+# T1 has 3 elements, T2 is empty.
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: Merge: running the initial corpus {{.*}} of 3 units
+CHECK1: Merge: written 0 out of 0 units
+
+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: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: Merge: running the initial corpus {{.*}} of 3 units
+CHECK2: Merge: written 3 out of 6 units
+
+# Now, T1 has 6 units and T2 has no new interesting units.
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+CHECK3: Merge: running the initial corpus {{.*}} of 6 units
+CHECK3: Merge: written 0 out of 6 units
diff --git a/gnu/llvm/lib/Fuzzer/test/trace-bb/CMakeLists.txt b/gnu/llvm/lib/Fuzzer/test/trace-bb/CMakeLists.txt
new file mode 100644
index 00000000000..99af019565b
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/trace-bb/CMakeLists.txt
@@ -0,0 +1,14 @@
+# These tests are not instrumented with coverage.
+
+set(CMAKE_CXX_FLAGS_RELEASE
+ "${LIBFUZZER_FLAGS_BASE} -fsanitize-coverage=edge,trace-bb")
+
+foreach(Test ${TraceBBTests})
+ add_executable(LLVMFuzzer-${Test}-TraceBB
+ ../${Test}.cpp
+ )
+ target_link_libraries(LLVMFuzzer-${Test}-TraceBB
+ LLVMFuzzer
+ )
+endforeach()
+
diff --git a/gnu/llvm/lib/Fuzzer/test/uninstrumented/CMakeLists.txt b/gnu/llvm/lib/Fuzzer/test/uninstrumented/CMakeLists.txt
new file mode 100644
index 00000000000..443ba3716f6
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/uninstrumented/CMakeLists.txt
@@ -0,0 +1,14 @@
+# These tests are not instrumented with coverage.
+
+set(CMAKE_CXX_FLAGS_RELEASE
+ "${LIBFUZZER_FLAGS_BASE} -O0 -fno-sanitize=all")
+
+foreach(Test ${UninstrumentedTests})
+ add_executable(LLVMFuzzer-${Test}-Uninstrumented
+ ../${Test}.cpp
+ )
+ target_link_libraries(LLVMFuzzer-${Test}-Uninstrumented
+ LLVMFuzzer
+ )
+endforeach()
+
diff --git a/gnu/llvm/lib/Fuzzer/test/unit/lit.cfg b/gnu/llvm/lib/Fuzzer/test/unit/lit.cfg
new file mode 100644
index 00000000000..0cc31939c55
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/unit/lit.cfg
@@ -0,0 +1,7 @@
+import lit.formats
+
+config.name = "LLVMFuzzer-Unittest"
+print config.test_exec_root
+config.test_format = lit.formats.GoogleTest(".", "Unittest")
+config.suffixes = []
+config.test_source_root = config.test_exec_root
diff --git a/gnu/llvm/lib/Fuzzer/test/unit/lit.site.cfg.in b/gnu/llvm/lib/Fuzzer/test/unit/lit.site.cfg.in
new file mode 100644
index 00000000000..114daf474b6
--- /dev/null
+++ b/gnu/llvm/lib/Fuzzer/test/unit/lit.site.cfg.in
@@ -0,0 +1,2 @@
+config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/unit/lit.cfg")