[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>