mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-02 22:32:08 +00:00
[fuzzer] one more experimental search mode: -use_coverage_pairs=1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fa5fd07866
commit
f7c1020041
@ -159,6 +159,7 @@ int FuzzerDriver(int argc, char **argv, UserCallback Callback) {
|
||||
Options.MutateDepth = Flags.mutate_depth;
|
||||
Options.ExitOnFirst = Flags.exit_on_first;
|
||||
Options.UseFullCoverageSet = Flags.use_full_coverage_set;
|
||||
Options.UseCoveragePairs = Flags.use_coverage_pairs;
|
||||
Options.PreferSmallDuringInitialShuffle =
|
||||
Flags.prefer_small_during_initial_shuffle;
|
||||
if (Flags.runs >= 0)
|
||||
|
@ -33,9 +33,11 @@ FUZZER_FLAG(
|
||||
int, save_minimized_corpus, 0,
|
||||
"If 1, the minimized corpus is saved into the first input directory")
|
||||
FUZZER_FLAG(int, use_full_coverage_set, 0,
|
||||
"Maximize the number of different full"
|
||||
"Experimental: Maximize the number of different full"
|
||||
" coverage sets as opposed to maximizing the total coverage."
|
||||
" This is potentially MUCH slower, but may discover more paths.")
|
||||
FUZZER_FLAG(int, use_coverage_pairs, 0,
|
||||
"Experimental: Maximize the number of different coverage pairs.")
|
||||
FUZZER_FLAG(int, jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
|
||||
" this number of jobs in separate worker processes"
|
||||
" with stdout/stderr redirected to fuzz-JOB.log.")
|
||||
|
@ -49,6 +49,7 @@ class Fuzzer {
|
||||
int MutateDepth = 5;
|
||||
bool ExitOnFirst = false;
|
||||
bool UseFullCoverageSet = false;
|
||||
bool UseCoveragePairs = false;
|
||||
int PreferSmallDuringInitialShuffle = -1;
|
||||
size_t MaxNumberOfRuns = ULONG_MAX;
|
||||
std::string OutputCorpus;
|
||||
@ -81,6 +82,7 @@ class Fuzzer {
|
||||
size_t RunOne(const Unit &U);
|
||||
size_t RunOneMaximizeTotalCoverage(const Unit &U);
|
||||
size_t RunOneMaximizeFullCoverageSet(const Unit &U);
|
||||
size_t RunOneMaximizeCoveragePairs(const Unit &U);
|
||||
void WriteToOutputCorpus(const Unit &U);
|
||||
static void WriteToCrash(const Unit &U, const char *Prefix);
|
||||
|
||||
@ -92,6 +94,7 @@ class Fuzzer {
|
||||
|
||||
std::vector<Unit> Corpus;
|
||||
std::unordered_set<uintptr_t> FullCoverageSets;
|
||||
std::unordered_set<uint64_t> CoveragePairs;
|
||||
UserCallback Callback;
|
||||
FuzzingOptions Options;
|
||||
system_clock::time_point ProcessStartTime = system_clock::now();
|
||||
|
@ -86,6 +86,8 @@ size_t Fuzzer::RunOne(const Unit &U) {
|
||||
TotalNumberOfRuns++;
|
||||
if (Options.UseFullCoverageSet)
|
||||
return RunOneMaximizeFullCoverageSet(U);
|
||||
if (Options.UseCoveragePairs)
|
||||
return RunOneMaximizeCoveragePairs(U);
|
||||
return RunOneMaximizeTotalCoverage(U);
|
||||
}
|
||||
|
||||
@ -97,6 +99,29 @@ static uintptr_t HashOfArrayOfPCs(uintptr_t *PCs, uintptr_t NumPCs) {
|
||||
return Res;
|
||||
}
|
||||
|
||||
// Experimental. Does not yet scale.
|
||||
// Fuly reset the current coverage state, run a single unit,
|
||||
// collect all coverage pairs and return non-zero if a new pair is observed.
|
||||
size_t Fuzzer::RunOneMaximizeCoveragePairs(const Unit &U) {
|
||||
__sanitizer_reset_coverage();
|
||||
Callback(U.data(), U.size());
|
||||
uintptr_t *PCs;
|
||||
uintptr_t NumPCs = __sanitizer_get_coverage_guards(&PCs);
|
||||
bool HasNewPairs = false;
|
||||
for (uintptr_t i = 0; i < NumPCs; i++) {
|
||||
if (!PCs[i]) continue;
|
||||
for (uintptr_t j = 0; j < NumPCs; j++) {
|
||||
if (!PCs[j]) continue;
|
||||
uint64_t Pair = (i << 32) | j;
|
||||
HasNewPairs |= CoveragePairs.insert(Pair).second;
|
||||
}
|
||||
}
|
||||
if (HasNewPairs)
|
||||
return CoveragePairs.size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Experimental.
|
||||
// Fuly reset the current coverage state, run a single unit,
|
||||
// compute a hash function from the full coverage set,
|
||||
// return non-zero if the hash value is new.
|
||||
|
@ -5,6 +5,7 @@
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O0 -fsanitize-coverage=4")
|
||||
|
||||
set(Tests
|
||||
FourIndependentBranchesTest
|
||||
FullCoverageSetTest
|
||||
InfiniteTest
|
||||
NullDerefTest
|
||||
|
18
lib/Fuzzer/test/FourIndependentBranchesTest.cpp
Normal file
18
lib/Fuzzer/test/FourIndependentBranchesTest.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Simple test for a fuzzer. The fuzzer must find the string "FUZZ".
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
extern "C" void TestOneInput(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);
|
||||
}
|
||||
}
|
||||
|
@ -12,5 +12,8 @@ TimeoutTest: CRASHED; file written to timeout
|
||||
RUN: not ./LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest
|
||||
NullDerefTest: CRASHED; file written to crash-
|
||||
|
||||
RUN: not ./LLVMFuzzer-FullCoverageSetTest -timeout=15 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s --check-prefix=FullCoverageSetTest
|
||||
RUN: not ./LLVMFuzzer-FullCoverageSetTest -timeout=15 -seed=1 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s --check-prefix=FullCoverageSetTest
|
||||
FullCoverageSetTest: BINGO
|
||||
|
||||
RUN: not ./LLVMFuzzer-FourIndependentBranchesTest -timeout=15 -seed=1 -use_coverage_pairs=1 2>&1 | FileCheck %s --check-prefix=FourIndependentBranchesTest
|
||||
FourIndependentBranchesTest: BINGO
|
||||
|
Loading…
x
Reference in New Issue
Block a user