summaryrefslogtreecommitdiff
path: root/lib/Fuzzer
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2017-07-20 01:35:17 +0000
committerKostya Serebryany <kcc@google.com>2017-07-20 01:35:17 +0000
commite53191708261f52cdd5d1dc73a89064481b09e9b (patch)
tree972af01826e6c97f86e0717af19afb418fa555f5 /lib/Fuzzer
parent01337d5a1434f46548c52a6e339d3eba80d9dce7 (diff)
[libFuzzer] prototype implementation of recursion-depth coverage features (commented out; real implementation needs to use inlined instrumentation)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308577 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Fuzzer')
-rw-r--r--lib/Fuzzer/FuzzerLoop.cpp1
-rw-r--r--lib/Fuzzer/FuzzerTracePC.cpp2
-rw-r--r--lib/Fuzzer/FuzzerTracePC.h25
-rw-r--r--lib/Fuzzer/FuzzerValueBitMap.h2
-rw-r--r--lib/Fuzzer/test/DeepRecursionTest.cpp4
5 files changed, 30 insertions, 4 deletions
diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp
index 8ac7a847aef..37adb1e0a5a 100644
--- a/lib/Fuzzer/FuzzerLoop.cpp
+++ b/lib/Fuzzer/FuzzerLoop.cpp
@@ -456,6 +456,7 @@ static bool LooseMemeq(const uint8_t *A, const uint8_t *B, size_t Size) {
}
void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
+ TPC.RecordInitialStack();
TotalNumberOfRuns++;
assert(InFuzzingThread());
if (SMR.IsClient())
diff --git a/lib/Fuzzer/FuzzerTracePC.cpp b/lib/Fuzzer/FuzzerTracePC.cpp
index ced0a213334..07be441244c 100644
--- a/lib/Fuzzer/FuzzerTracePC.cpp
+++ b/lib/Fuzzer/FuzzerTracePC.cpp
@@ -319,6 +319,8 @@ void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
uint32_t Idx = *Guard;
__sancov_trace_pc_pcs[Idx] = PC;
__sancov_trace_pc_guard_8bit_counters[Idx]++;
+ // Uncomment the following line to get stack-depth profiling.
+ // fuzzer::TPC.RecordCurrentStack();
}
// Best-effort support for -fsanitize-coverage=trace-pc, which is available
diff --git a/lib/Fuzzer/FuzzerTracePC.h b/lib/Fuzzer/FuzzerTracePC.h
index b36c4f54306..26e1d09e482 100644
--- a/lib/Fuzzer/FuzzerTracePC.h
+++ b/lib/Fuzzer/FuzzerTracePC.h
@@ -115,6 +115,20 @@ class TracePC {
return PCs()[Idx];
}
+ void RecordCurrentStack() {
+ uintptr_t Stack = GetCurrentStack();
+ if (Stack < LowestStack)
+ LowestStack = Stack;
+ }
+ void RecordInitialStack() {
+ InitialStack = GetCurrentStack();
+ LowestStack = InitialStack;
+ }
+ uintptr_t GetCurrentStack() const {
+ return reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
+ }
+ uintptr_t GetMaxStackOffset() const { return InitialStack - LowestStack; }
+
private:
bool UseCounters = false;
bool UseValueProfile = false;
@@ -138,6 +152,7 @@ private:
std::set<uintptr_t> *PrintedPCs;
ValueBitMap ValueProfileMap;
+ uintptr_t InitialStack, LowestStack; // Assume stack grows down.
};
template <class Callback> // void Callback(size_t Idx, uint8_t Value);
@@ -196,11 +211,17 @@ void TracePC::CollectFeatures(Callback HandleFeature) const {
ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(), FirstFeature,
Handle8bitCounter);
+ FirstFeature += (ExtraCountersEnd() - ExtraCountersBegin()) * 8;
- if (UseValueProfile)
+ if (UseValueProfile) {
ValueProfileMap.ForEach([&](size_t Idx) {
- HandleFeature(N * 8 + Idx);
+ HandleFeature(FirstFeature + Idx);
});
+ FirstFeature += ValueProfileMap.SizeInBits();
+ }
+
+ if (auto MaxStackOffset = GetMaxStackOffset())
+ HandleFeature(FirstFeature + MaxStackOffset);
}
extern TracePC TPC;
diff --git a/lib/Fuzzer/FuzzerValueBitMap.h b/lib/Fuzzer/FuzzerValueBitMap.h
index 8f7ff74300f..f11de68252d 100644
--- a/lib/Fuzzer/FuzzerValueBitMap.h
+++ b/lib/Fuzzer/FuzzerValueBitMap.h
@@ -52,6 +52,8 @@ struct ValueBitMap {
return Map[WordIdx] & (1UL << BitIdx);
}
+ size_t SizeInBits() const { return kMapSizeInBits; }
+
size_t GetNumBitsSinceLastMerge() const { return NumBits; }
// Merges 'Other' into 'this', clears 'Other', updates NumBits,
diff --git a/lib/Fuzzer/test/DeepRecursionTest.cpp b/lib/Fuzzer/test/DeepRecursionTest.cpp
index 39a1602d7ac..bf4621d0492 100644
--- a/lib/Fuzzer/test/DeepRecursionTest.cpp
+++ b/lib/Fuzzer/test/DeepRecursionTest.cpp
@@ -3,7 +3,7 @@
// Simple test for a fuzzer. The fuzzer must find the deep recursion.
// To generate a crashy input:
-// for((i=0;i<100;i++)); do echo -n ABCDEFGHIJKLMNOPQRSTUVWXYZ >> INPUT; done
+// for((i=0;i<110;i++)); do echo -n ABCDEFGHIJ >> INPUT; done
#include <cstddef>
#include <cstdint>
#include <cstdlib>
@@ -13,7 +13,7 @@ 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 % 26))
+ if (*Data == ('A' + Depth % 10))
Recursive(Data + 1, Size - 1, Depth + 1);
Sink++;
}