[SanitizerCoverage] Add stack depth tracing instrumentation.
Summary:
Augment SanitizerCoverage to insert maximum stack depth tracing for
use by libFuzzer. The new instrumentation is enabled by the flag
-fsanitize-coverage=stack-depth and is compatible with the existing
trace-pc-guard coverage. The user must also declare the following
global variable in their code:
thread_local uintptr_t __sancov_lowest_stack
https://bugs.llvm.org/show_bug.cgi?id=33857
Reviewers: vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: kubamracek, hiraditya, cfe-commits, llvm-commits
Differential Revision: https://reviews.llvm.org/D36839
git-svn-id: svn://svn.chromium.org/llvm-project/llvm/trunk/lib/Fuzzer@311186 0b72dbe1-c17f-4bc7-b9db-2b4152be0356
diff --git a/FuzzerTracePC.cpp b/FuzzerTracePC.cpp
index a54a8c1..ebd33d3 100644
--- a/FuzzerTracePC.cpp
+++ b/FuzzerTracePC.cpp
@@ -31,6 +31,9 @@
ATTRIBUTE_INTERFACE
uintptr_t __sancov_trace_pc_pcs[fuzzer::TracePC::kNumPCs];
+// Used by -fsanitize-coverage=stack-depth to track stack depth
+ATTRIBUTE_INTERFACE thread_local uintptr_t __sancov_lowest_stack;
+
namespace fuzzer {
TracePC TPC;
@@ -340,6 +343,14 @@
}
}
+void TracePC::RecordInitialStack() {
+ InitialStack = __sancov_lowest_stack;
+}
+
+uintptr_t TracePC::GetMaxStackOffset() const {
+ return InitialStack - __sancov_lowest_stack; // Stack grows down
+}
+
} // namespace fuzzer
extern "C" {
@@ -350,8 +361,6 @@
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/FuzzerTracePC.h b/FuzzerTracePC.h
index 40827b3..56f1820 100644
--- a/FuzzerTracePC.h
+++ b/FuzzerTracePC.h
@@ -120,19 +120,8 @@
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; }
+ void RecordInitialStack();
+ uintptr_t GetMaxStackOffset() const;
template<class CallBack>
void ForEachObservedPC(CallBack CB) {
@@ -167,7 +156,7 @@
std::set<uintptr_t> ObservedPCs;
ValueBitMap ValueProfileMap;
- uintptr_t InitialStack, LowestStack; // Assume stack grows down.
+ uintptr_t InitialStack;
};
template <class Callback>