mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 11:02:59 +02:00
[libFuzzer] new experimental feature: value profiling. Profiles values that affect control flow and treats new values as new coverage.
llvm-svn: 278839
This commit is contained in:
parent
e89e3eda62
commit
8a3b057601
@ -1,6 +1,6 @@
|
|||||||
set(LIBFUZZER_FLAGS_BASE "${CMAKE_CXX_FLAGS}")
|
set(LIBFUZZER_FLAGS_BASE "${CMAKE_CXX_FLAGS}")
|
||||||
# Disable the coverage and sanitizer instrumentation for the fuzzer itself.
|
# Disable the coverage and sanitizer instrumentation for the fuzzer itself.
|
||||||
set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -fno-sanitize=all -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters -Werror")
|
set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -mpopcnt -fno-sanitize=all -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters -Werror")
|
||||||
if( LLVM_USE_SANITIZE_COVERAGE )
|
if( LLVM_USE_SANITIZE_COVERAGE )
|
||||||
if(NOT "${LLVM_USE_SANITIZER}" STREQUAL "Address")
|
if(NOT "${LLVM_USE_SANITIZER}" STREQUAL "Address")
|
||||||
message(FATAL_ERROR
|
message(FATAL_ERROR
|
||||||
|
@ -339,6 +339,9 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||||||
Options.TruncateUnits = Flags.truncate_units;
|
Options.TruncateUnits = Flags.truncate_units;
|
||||||
Options.PruneCorpus = Flags.prune_corpus;
|
Options.PruneCorpus = Flags.prune_corpus;
|
||||||
|
|
||||||
|
if (Flags.use_value_profile)
|
||||||
|
EnableValueProfile();
|
||||||
|
|
||||||
unsigned Seed = Flags.seed;
|
unsigned Seed = Flags.seed;
|
||||||
// Initialize Seed.
|
// Initialize Seed.
|
||||||
if (Seed == 0)
|
if (Seed == 0)
|
||||||
|
@ -44,6 +44,8 @@ FUZZER_FLAG_INT(use_memcmp, 1,
|
|||||||
"Use hints from intercepting memcmp, strcmp, etc")
|
"Use hints from intercepting memcmp, strcmp, etc")
|
||||||
FUZZER_FLAG_INT(use_memmem, 1,
|
FUZZER_FLAG_INT(use_memmem, 1,
|
||||||
"Use hints from intercepting memmem, strstr, etc")
|
"Use hints from intercepting memmem, strstr, etc")
|
||||||
|
FUZZER_FLAG_INT(use_value_profile, 0,
|
||||||
|
"Experimental. Use value profile to guide fuzzing.")
|
||||||
FUZZER_FLAG_INT(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
|
FUZZER_FLAG_INT(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
|
||||||
" this number of jobs in separate worker processes"
|
" this number of jobs in separate worker processes"
|
||||||
" with stdout/stderr redirected to fuzz-JOB.log.")
|
" with stdout/stderr redirected to fuzz-JOB.log.")
|
||||||
|
@ -134,6 +134,10 @@ void SleepSeconds(int Seconds);
|
|||||||
// See FuzzerTracePC.cpp
|
// See FuzzerTracePC.cpp
|
||||||
size_t PCMapMergeFromCurrent(ValueBitMap &M);
|
size_t PCMapMergeFromCurrent(ValueBitMap &M);
|
||||||
|
|
||||||
|
// See FuzzerTraceState.cpp
|
||||||
|
void EnableValueProfile();
|
||||||
|
size_t VPMapMergeFromCurrent(ValueBitMap &M);
|
||||||
|
|
||||||
class Random {
|
class Random {
|
||||||
public:
|
public:
|
||||||
Random(unsigned int seed) : R(seed) {}
|
Random(unsigned int seed) : R(seed) {}
|
||||||
@ -356,6 +360,8 @@ public:
|
|||||||
CounterBitmap.clear();
|
CounterBitmap.clear();
|
||||||
PCMap.Reset();
|
PCMap.Reset();
|
||||||
PCMapBits = 0;
|
PCMapBits = 0;
|
||||||
|
VPMap.Reset();
|
||||||
|
VPMapBits = 0;
|
||||||
PcBufferPos = 0;
|
PcBufferPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,6 +375,8 @@ public:
|
|||||||
std::vector<uint8_t> CounterBitmap;
|
std::vector<uint8_t> CounterBitmap;
|
||||||
ValueBitMap PCMap;
|
ValueBitMap PCMap;
|
||||||
size_t PCMapBits;
|
size_t PCMapBits;
|
||||||
|
ValueBitMap VPMap;
|
||||||
|
size_t VPMapBits;
|
||||||
};
|
};
|
||||||
|
|
||||||
Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options);
|
Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options);
|
||||||
|
@ -122,6 +122,12 @@ class CoverageController {
|
|||||||
C->PCMapBits = NewPCMapBits;
|
C->PCMapBits = NewPCMapBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t NewVPMapBits = VPMapMergeFromCurrent(C->VPMap);
|
||||||
|
if (NewVPMapBits > C->VPMapBits) {
|
||||||
|
Res = true;
|
||||||
|
C->VPMapBits = NewVPMapBits;
|
||||||
|
}
|
||||||
|
|
||||||
if (EF->__sanitizer_get_coverage_pc_buffer_pos) {
|
if (EF->__sanitizer_get_coverage_pc_buffer_pos) {
|
||||||
uint64_t NewPcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos();
|
uint64_t NewPcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos();
|
||||||
if (NewPcBufferPos > C->PcBufferPos) {
|
if (NewPcBufferPos > C->PcBufferPos) {
|
||||||
@ -307,6 +313,8 @@ void Fuzzer::PrintStats(const char *Where, const char *End) {
|
|||||||
Printf(" cov: %zd", MaxCoverage.BlockCoverage);
|
Printf(" cov: %zd", MaxCoverage.BlockCoverage);
|
||||||
if (MaxCoverage.PCMapBits)
|
if (MaxCoverage.PCMapBits)
|
||||||
Printf(" path: %zd", MaxCoverage.PCMapBits);
|
Printf(" path: %zd", MaxCoverage.PCMapBits);
|
||||||
|
if (MaxCoverage.VPMapBits)
|
||||||
|
Printf(" vp: %zd", MaxCoverage.VPMapBits);
|
||||||
if (auto TB = MaxCoverage.CounterBitmapBits)
|
if (auto TB = MaxCoverage.CounterBitmapBits)
|
||||||
Printf(" bits: %zd", TB);
|
Printf(" bits: %zd", TB);
|
||||||
if (MaxCoverage.CallerCalleeCoverage)
|
if (MaxCoverage.CallerCalleeCoverage)
|
||||||
@ -520,8 +528,9 @@ std::string Fuzzer::Coverage::DebugString() const {
|
|||||||
std::string("Coverage{") + "BlockCoverage=" +
|
std::string("Coverage{") + "BlockCoverage=" +
|
||||||
std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
|
std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
|
||||||
std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
|
std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
|
||||||
std::to_string(CounterBitmapBits) + " PcMapBits=" +
|
std::to_string(CounterBitmapBits) + " PCMapBits=" +
|
||||||
std::to_string(PCMapBits) + "}";
|
std::to_string(PCMapBits) + " VPMapBits " +
|
||||||
|
std::to_string(VPMapBits) + "}";
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +173,7 @@ struct TraceBasedMutation {
|
|||||||
static bool RecordingTraces = false;
|
static bool RecordingTraces = false;
|
||||||
static bool RecordingMemcmp = false;
|
static bool RecordingMemcmp = false;
|
||||||
static bool RecordingMemmem = false;
|
static bool RecordingMemmem = false;
|
||||||
|
static bool RecordingValueProfile = false;
|
||||||
static bool DoingMyOwnMemmem = false;
|
static bool DoingMyOwnMemmem = false;
|
||||||
|
|
||||||
struct ScopedDoingMyOwnMemmem {
|
struct ScopedDoingMyOwnMemmem {
|
||||||
@ -529,11 +530,60 @@ static size_t InternalStrnlen(const char *S, size_t MaxLen) {
|
|||||||
return Len;
|
return Len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value profile.
|
||||||
|
// We keep track of various values that affect control flow.
|
||||||
|
// These values are inserted into a bit-set-based hash map (ValueBitMap VP).
|
||||||
|
// Every new bit in the map is treated as a new coverage.
|
||||||
|
//
|
||||||
|
// For memcmp/strcmp/etc the interesting value is the length of the common
|
||||||
|
// prefix of the parameters.
|
||||||
|
// For cmp instructions the interesting value is a XOR of the parameters.
|
||||||
|
// The interesting value is mixed up with the PC and is then added to the map.
|
||||||
|
static ValueBitMap VP;
|
||||||
|
|
||||||
|
void EnableValueProfile() { RecordingValueProfile = true; }
|
||||||
|
|
||||||
|
size_t VPMapMergeFromCurrent(ValueBitMap &M) {
|
||||||
|
if (!RecordingValueProfile) return 0;
|
||||||
|
return M.MergeFrom(VP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
|
||||||
|
size_t n) {
|
||||||
|
if (!n) return;
|
||||||
|
size_t Len = std::min(n, (size_t)32);
|
||||||
|
const char *A1 = reinterpret_cast<const char *>(s1);
|
||||||
|
const char *A2 = reinterpret_cast<const char *>(s2);
|
||||||
|
size_t LastSameByte = 0;
|
||||||
|
for (; LastSameByte < Len; LastSameByte++)
|
||||||
|
if (A1[LastSameByte] != A2[LastSameByte])
|
||||||
|
break;
|
||||||
|
size_t PC = reinterpret_cast<size_t>(caller_pc);
|
||||||
|
VP.AddValue((PC & 4095) | (LastSameByte << 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,
|
||||||
|
size_t n) {
|
||||||
|
if (!n) return;
|
||||||
|
size_t Len = std::min(n, (size_t)32);
|
||||||
|
size_t LastSameByte = 0;
|
||||||
|
for (; LastSameByte < Len; LastSameByte++)
|
||||||
|
if (s1[LastSameByte] != s2[LastSameByte] || s1[LastSameByte] == 0)
|
||||||
|
break;
|
||||||
|
size_t PC = reinterpret_cast<size_t>(caller_pc);
|
||||||
|
VP.AddValue((PC & 4095) | (LastSameByte << 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddValueForCmp(uintptr_t PC, uint64_t Arg1, uint64_t Arg2) {
|
||||||
|
VP.AddValue((PC & 4095) | (__builtin_popcountl(Arg1 ^ Arg2) << 12));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fuzzer
|
} // namespace fuzzer
|
||||||
|
|
||||||
using fuzzer::TS;
|
using fuzzer::TS;
|
||||||
using fuzzer::RecordingTraces;
|
using fuzzer::RecordingTraces;
|
||||||
using fuzzer::RecordingMemcmp;
|
using fuzzer::RecordingMemcmp;
|
||||||
|
using fuzzer::RecordingValueProfile;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void __dfsw___sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
|
void __dfsw___sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
|
||||||
@ -597,6 +647,8 @@ void dfsan_weak_hook_strcmp(void *caller_pc, const char *s1, const char *s2,
|
|||||||
#if LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
|
#if LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
|
||||||
void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
|
void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
|
||||||
const void *s2, size_t n, int result) {
|
const void *s2, size_t n, int result) {
|
||||||
|
if (RecordingValueProfile)
|
||||||
|
fuzzer::AddValueForMemcmp(caller_pc, s1, s2, n);
|
||||||
if (!RecordingMemcmp) return;
|
if (!RecordingMemcmp) return;
|
||||||
if (result == 0) return; // No reason to mutate.
|
if (result == 0) return; // No reason to mutate.
|
||||||
if (n <= 1) return; // Not interesting.
|
if (n <= 1) return; // Not interesting.
|
||||||
@ -606,6 +658,8 @@ void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
|
|||||||
|
|
||||||
void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
|
void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
|
||||||
const char *s2, size_t n, int result) {
|
const char *s2, size_t n, int result) {
|
||||||
|
if (RecordingValueProfile)
|
||||||
|
fuzzer::AddValueForStrcmp(caller_pc, s1, s2, n);
|
||||||
if (!RecordingMemcmp) return;
|
if (!RecordingMemcmp) return;
|
||||||
if (result == 0) return; // No reason to mutate.
|
if (result == 0) return; // No reason to mutate.
|
||||||
size_t Len1 = fuzzer::InternalStrnlen(s1, n);
|
size_t Len1 = fuzzer::InternalStrnlen(s1, n);
|
||||||
@ -619,6 +673,8 @@ void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
|
|||||||
|
|
||||||
void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
|
void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
|
||||||
const char *s2, int result) {
|
const char *s2, int result) {
|
||||||
|
if (RecordingValueProfile)
|
||||||
|
fuzzer::AddValueForStrcmp(caller_pc, s1, s2, 64);
|
||||||
if (!RecordingMemcmp) return;
|
if (!RecordingMemcmp) return;
|
||||||
if (result == 0) return; // No reason to mutate.
|
if (result == 0) return; // No reason to mutate.
|
||||||
size_t Len1 = strlen(s1);
|
size_t Len1 = strlen(s1);
|
||||||
@ -656,11 +712,15 @@ void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
|
|||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
void __sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
|
void __sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
|
||||||
uint64_t Arg2) {
|
uint64_t Arg2) {
|
||||||
if (!RecordingTraces) return;
|
if (RecordingTraces) {
|
||||||
uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
|
uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
|
||||||
uint64_t CmpSize = (SizeAndType >> 32) / 8;
|
uint64_t CmpSize = (SizeAndType >> 32) / 8;
|
||||||
uint64_t Type = (SizeAndType << 32) >> 32;
|
uint64_t Type = (SizeAndType << 32) >> 32;
|
||||||
TS->TraceCmpCallback(PC, CmpSize, Type, Arg1, Arg2);
|
TS->TraceCmpCallback(PC, CmpSize, Type, Arg1, Arg2);
|
||||||
|
}
|
||||||
|
if (RecordingValueProfile)
|
||||||
|
fuzzer::AddValueForCmp(
|
||||||
|
reinterpret_cast<uintptr_t>(__builtin_return_address(0)), Arg1, Arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
|
@ -32,7 +32,7 @@ struct ValueBitMap {
|
|||||||
Map[WordIdx] |= 1UL << BitIdx;
|
Map[WordIdx] |= 1UL << BitIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merges 'Other' into 'this', clear Other,
|
// Merges 'Other' into 'this', clears 'Other',
|
||||||
// returns the number of set bits in 'this'.
|
// returns the number of set bits in 'this'.
|
||||||
size_t MergeFrom(ValueBitMap &Other) {
|
size_t MergeFrom(ValueBitMap &Other) {
|
||||||
uintptr_t Res = 0;
|
uintptr_t Res = 0;
|
||||||
@ -43,7 +43,8 @@ struct ValueBitMap {
|
|||||||
Map[i] = (M |= O);
|
Map[i] = (M |= O);
|
||||||
Other.Map[i] = 0;
|
Other.Map[i] = 0;
|
||||||
}
|
}
|
||||||
Res += __builtin_popcountl(M);
|
if (M)
|
||||||
|
Res += __builtin_popcountl(M);
|
||||||
}
|
}
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,9 @@ set(Tests
|
|||||||
SimpleHashTest
|
SimpleHashTest
|
||||||
SimpleTest
|
SimpleTest
|
||||||
SimpleThreadedTest
|
SimpleThreadedTest
|
||||||
|
SingleMemcmpTest
|
||||||
|
SingleStrcmpTest
|
||||||
|
SingleStrncmpTest
|
||||||
SpamyTest
|
SpamyTest
|
||||||
StrcmpTest
|
StrcmpTest
|
||||||
StrncmpTest
|
StrncmpTest
|
||||||
|
17
lib/Fuzzer/test/SingleMemcmpTest.cpp
Normal file
17
lib/Fuzzer/test/SingleMemcmpTest.cpp
Normal file
@ -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 <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
|
char *S = (char*)Data;
|
||||||
|
if (Size >= 6 && !memcmp(S, "qwerty", 6)) {
|
||||||
|
fprintf(stderr, "BINGO\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
17
lib/Fuzzer/test/SingleStrcmpTest.cpp
Normal file
17
lib/Fuzzer/test/SingleStrcmpTest.cpp
Normal file
@ -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 <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
|
char *S = (char*)Data;
|
||||||
|
if (Size >= 7 && !strcmp(S, "qwerty")) {
|
||||||
|
fprintf(stderr, "BINGO\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
17
lib/Fuzzer/test/SingleStrncmpTest.cpp
Normal file
17
lib/Fuzzer/test/SingleStrncmpTest.cpp
Normal file
@ -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 <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
|
char *S = (char*)Data;
|
||||||
|
if (Size >= 6 && !strncmp(S, "qwerty", 6)) {
|
||||||
|
fprintf(stderr, "BINGO\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -17,7 +17,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||||||
if (Size >= 8 && strncmp(S, "01234567", 8) == 0) {
|
if (Size >= 8 && strncmp(S, "01234567", 8) == 0) {
|
||||||
if (Size >= 12 && strncmp(S + 8, "ABCD", 4) == 0) {
|
if (Size >= 12 && strncmp(S + 8, "ABCD", 4) == 0) {
|
||||||
if (Size >= 14 && strncmp(S + 12, "XY", 2) == 0) {
|
if (Size >= 14 && strncmp(S + 12, "XY", 2) == 0) {
|
||||||
if (Size >= 16 && strncmp(S + 14, "KLM", 3) == 0) {
|
if (Size >= 17 && strncmp(S + 14, "KLM", 3) == 0) {
|
||||||
fprintf(stderr, "BINGO\n");
|
fprintf(stderr, "BINGO\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
3
lib/Fuzzer/test/value-profile-cmp.test
Normal file
3
lib/Fuzzer/test/value-profile-cmp.test
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
CHECK: BINGO
|
||||||
|
RUN: not LLVMFuzzer-SimpleCmpTest -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
|
||||||
|
|
4
lib/Fuzzer/test/value-profile-mem.test
Normal file
4
lib/Fuzzer/test/value-profile-mem.test
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CHECK: BINGO
|
||||||
|
RUN: not LLVMFuzzer-SingleMemcmpTest -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
|
||||||
|
RUN: not LLVMFuzzer-SingleStrcmpTest -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
|
||||||
|
RUN: not LLVMFuzzer-SingleStrncmpTest -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
|
3
lib/Fuzzer/test/value-profile-set.test
Normal file
3
lib/Fuzzer/test/value-profile-set.test
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
CHECK: BINGO
|
||||||
|
RUN: not LLVMFuzzer-FourIndependentBranchesTest -seed=1 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
|
||||||
|
|
Loading…
Reference in New Issue
Block a user