[libFuzzer] apply changes lost during the migration to compiler-rt

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer@311420 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 309a8b8..03cb7fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,5 @@
 set(LIBFUZZER_SOURCES
+  FuzzerClangCounters.cpp
   FuzzerCrossOver.cpp
   FuzzerDriver.cpp
   FuzzerExtFunctionsDlsym.cpp
diff --git a/FuzzerClangCounters.cpp b/FuzzerClangCounters.cpp
new file mode 100644
index 0000000..f69e922
--- /dev/null
+++ b/FuzzerClangCounters.cpp
@@ -0,0 +1,49 @@
+//===- FuzzerExtraCounters.cpp - Extra coverage counters ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Coverage counters from Clang's SourceBasedCodeCoverage.
+//===----------------------------------------------------------------------===//
+
+// Support for SourceBasedCodeCoverage is experimental:
+// * Works only for the main binary, not DSOs yet.
+// * Works only on Linux.
+// * Does not implement print_pcs/print_coverage yet.
+// * Is not fully evaluated for performance and sensitivity.
+//   We expect large performance drop due to 64-bit counters,
+//   and *maybe* better sensitivity due to more fine-grained counters.
+//   Preliminary comparison on a single benchmark (RE2) shows
+//   a bit worse sensitivity though.
+
+#include "FuzzerDefs.h"
+
+#if LIBFUZZER_LINUX
+__attribute__((weak)) extern uint64_t __start___llvm_prf_cnts;
+__attribute__((weak)) extern uint64_t __stop___llvm_prf_cnts;
+namespace fuzzer {
+uint64_t *ClangCountersBegin() { return &__start___llvm_prf_cnts; }
+uint64_t *ClangCountersEnd() { return &__stop___llvm_prf_cnts; }
+}  // namespace fuzzer
+#else
+// TODO: Implement on Mac (if the data shows it's worth it).
+//__attribute__((visibility("hidden")))
+//extern uint64_t CountersStart __asm("section$start$__DATA$__llvm_prf_cnts");
+//__attribute__((visibility("hidden")))
+//extern uint64_t CountersEnd __asm("section$end$__DATA$__llvm_prf_cnts");
+namespace fuzzer {
+uint64_t *ClangCountersBegin() { return nullptr; }
+uint64_t *ClangCountersEnd() { return  nullptr; }
+}  // namespace fuzzer
+#endif
+
+namespace fuzzer {
+ATTRIBUTE_NO_SANITIZE_ALL
+void ClearClangCounters() {  // hand-written memset, don't asan-ify.
+  for (auto P = ClangCountersBegin(); P < ClangCountersEnd(); P++)
+    *P = 0;
+}
+}
diff --git a/FuzzerDefs.h b/FuzzerDefs.h
index 27f5719..bbb4451 100644
--- a/FuzzerDefs.h
+++ b/FuzzerDefs.h
@@ -123,6 +123,10 @@
 uint8_t *ExtraCountersEnd();
 void ClearExtraCounters();
 
+uint64_t *ClangCountersBegin();
+uint64_t *ClangCountersEnd();
+void ClearClangCounters();
+
 }  // namespace fuzzer
 
 #endif  // LLVM_FUZZER_DEFS_H
diff --git a/FuzzerLoop.cpp b/FuzzerLoop.cpp
index 2064783..2349459 100644
--- a/FuzzerLoop.cpp
+++ b/FuzzerLoop.cpp
@@ -388,11 +388,12 @@
   uint8_t dummy;
   ExecuteCallback(&dummy, 0);
 
-  for (const auto &U : *InitialCorpus) {
+  for (auto &U : *InitialCorpus) {
     RunOne(U.data(), U.size());
     CheckExitOnSrcPosOrItem();
     TryDetectingAMemoryLeak(U.data(), U.size(),
                             /*DuringInitialCorpusExecution*/ true);
+    U.clear();
   }
   PrintStats("INITED");
   if (Corpus.empty()) {
diff --git a/FuzzerTracePC.cpp b/FuzzerTracePC.cpp
index d038374..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;
@@ -126,6 +129,8 @@
       _Exit(1);
     }
   }
+  if (size_t NumClangCounters = ClangCountersEnd() - ClangCountersBegin())
+    Printf("INFO: %zd Clang Coverage Counters\n", NumClangCounters);
 }
 
 ATTRIBUTE_NO_SANITIZE_ALL
@@ -137,13 +142,12 @@
 }
 
 void TracePC::UpdateObservedPCs() {
+  auto Observe = [&](uintptr_t PC) {
+    bool Inserted = ObservedPCs.insert(PC).second;
+    if (Inserted && DoPrintNewPCs)
+      PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PC + 1);
+  };
   if (NumPCsInPCTables) {
-    auto Observe = [&](uintptr_t PC) {
-      bool Inserted = ObservedPCs.insert(PC).second;
-      if (Inserted && DoPrintNewPCs)
-        PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PC + 1);
-    };
-
     if (NumInline8bitCounters == NumPCsInPCTables) {
       for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
         uint8_t *Beg = ModuleCounters[i].Start;
@@ -167,6 +171,13 @@
       }
     }
   }
+  if (size_t NumClangCounters =
+      ClangCountersEnd() - ClangCountersBegin()) {
+    auto P = ClangCountersBegin();
+    for (size_t Idx = 0; Idx < NumClangCounters; Idx++)
+      if (P[Idx])
+        Observe((uintptr_t)Idx);
+  }
 }
 
 inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) {
@@ -332,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" {
@@ -342,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 ea6794c..56f1820 100644
--- a/FuzzerTracePC.h
+++ b/FuzzerTracePC.h
@@ -91,6 +91,7 @@
       memset(Counters(), 0, GetNumPCs());
     ClearExtraCounters();
     ClearInlineCounters();
+    ClearClangCounters();
   }
 
   void ClearInlineCounters();
@@ -119,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) {
@@ -166,7 +156,7 @@
   std::set<uintptr_t> ObservedPCs;
 
   ValueBitMap ValueProfileMap;
-  uintptr_t InitialStack, LowestStack;  // Assume stack grows down.
+  uintptr_t InitialStack;
 };
 
 template <class Callback>
@@ -196,14 +186,9 @@
       Handle8bitCounter(FirstFeature, P - Begin, V);
 }
 
-template <class Callback>  // bool Callback(size_t Feature)
-ATTRIBUTE_NO_SANITIZE_ADDRESS
-__attribute__((noinline))
-void TracePC::CollectFeatures(Callback HandleFeature) const {
-  uint8_t *Counters = this->Counters();
-  size_t N = GetNumPCs();
-  auto Handle8bitCounter = [&](size_t FirstFeature,
-                               size_t Idx, uint8_t Counter) {
+// Given a non-zero Counters returns a number in [0,7].
+template<class T>
+unsigned CounterToFeature(T Counter) {
     assert(Counter);
     unsigned Bit = 0;
     /**/ if (Counter >= 128) Bit = 7;
@@ -213,7 +198,18 @@
     else if (Counter >= 4) Bit = 3;
     else if (Counter >= 3) Bit = 2;
     else if (Counter >= 2) Bit = 1;
-    HandleFeature(FirstFeature + Idx * 8 + Bit);
+    return Bit;
+}
+
+template <class Callback>  // bool Callback(size_t Feature)
+ATTRIBUTE_NO_SANITIZE_ADDRESS
+__attribute__((noinline))
+void TracePC::CollectFeatures(Callback HandleFeature) const {
+  uint8_t *Counters = this->Counters();
+  size_t N = GetNumPCs();
+  auto Handle8bitCounter = [&](size_t FirstFeature,
+                               size_t Idx, uint8_t Counter) {
+    HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Counter));
   };
 
   size_t FirstFeature = 0;
@@ -231,6 +227,14 @@
     }
   }
 
+  if (size_t NumClangCounters = ClangCountersEnd() - ClangCountersBegin()) {
+    auto P = ClangCountersBegin();
+    for (size_t Idx = 0; Idx < NumClangCounters; Idx++)
+      if (auto Cnt = P[Idx])
+        HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Cnt));
+    FirstFeature += NumClangCounters;
+  }
+
   ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(), FirstFeature,
                      Handle8bitCounter);
   FirstFeature += (ExtraCountersEnd() - ExtraCountersBegin()) * 8;