[compiler-rt] r256804 - [sancov] coverage pc buffer

Mike Aizatsky via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 4 17:49:39 PST 2016


Author: aizatsky
Date: Mon Jan  4 19:49:39 2016
New Revision: 256804

URL: http://llvm.org/viewvc/llvm-project?rev=256804&view=rev
Log:
[sancov] coverage pc buffer

Differential Revision: http://reviews.llvm.org/D15871

Added:
    compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc
Modified:
    compiler-rt/trunk/include/sanitizer/coverage_interface.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc

Modified: compiler-rt/trunk/include/sanitizer/coverage_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/coverage_interface.h?rev=256804&r1=256803&r2=256804&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/coverage_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/coverage_interface.h Mon Jan  4 19:49:39 2016
@@ -41,6 +41,13 @@ extern "C" {
   // Some of the entries in *data will be zero.
   uintptr_t __sanitizer_get_coverage_guards(uintptr_t **data);
 
+  // Set *data to the growing buffer with covered PCs and return the size
+  // of the buffer. The entries are never zero.
+  // When only unique pcs are collected, the size is equal to
+  // __sanitizer_get_total_unique_coverage.
+  // WARNING: EXPERIMENTAL API.
+  uintptr_t __sanitizer_get_coverage_pc_buffer(uintptr_t **data);
+
   // The coverage instrumentation may optionally provide imprecise counters.
   // Rather than exposing the counter values to the user we instead map
   // the counters to a bitset.

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=256804&r1=256803&r2=256804&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc Mon Jan  4 19:49:39 2016
@@ -108,6 +108,7 @@ class CoverageData {
 
   uptr *data();
   uptr size();
+  uptr *buffer() const { return pc_buffer; }
 
  private:
   void DirectOpen();
@@ -133,6 +134,8 @@ class CoverageData {
   // Descriptor of the file mapped pc array.
   fd_t pc_fd;
 
+  uptr *pc_buffer;
+
   // Vector of coverage guard arrays, protected by mu.
   InternalMmapVectorNoCtor<s32*> guard_array_vec;
 
@@ -209,6 +212,11 @@ void CoverageData::Enable() {
     atomic_store(&pc_array_size, kPcArrayMaxSize, memory_order_relaxed);
   }
 
+  pc_buffer = nullptr;
+  if (common_flags()->coverage_pc_buffer)
+    pc_buffer = reinterpret_cast<uptr *>(MmapNoReserveOrDie(
+        sizeof(uptr) * kPcArrayMaxSize, "CovInit::pc_buffer"));
+
   cc_array = reinterpret_cast<uptr **>(MmapNoReserveOrDie(
       sizeof(uptr *) * kCcArrayMaxSize, "CovInit::cc_array"));
   atomic_store(&cc_array_size, kCcArrayMaxSize, memory_order_relaxed);
@@ -246,6 +254,10 @@ void CoverageData::Disable() {
     UnmapOrDie(cc_array, sizeof(uptr *) * kCcArrayMaxSize);
     cc_array = nullptr;
   }
+  if (pc_buffer) {
+    UnmapOrDie(pc_buffer, sizeof(uptr) * kPcArrayMaxSize);
+    pc_buffer = nullptr;
+  }
   if (tr_event_array) {
     UnmapOrDie(tr_event_array,
                sizeof(tr_event_array[0]) * kTrEventArrayMaxSize +
@@ -414,6 +426,7 @@ void CoverageData::Add(uptr pc, u32 *gua
            atomic_load(&pc_array_size, memory_order_acquire));
   uptr counter = atomic_fetch_add(&coverage_counter, 1, memory_order_relaxed);
   pc_array[idx] = BundlePcAndCounter(pc, counter);
+  if (pc_buffer) pc_buffer[counter] = pc;
 }
 
 // Registers a pair caller=>callee.
@@ -944,6 +957,12 @@ uptr __sanitizer_get_coverage_guards(upt
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE
+uptr __sanitizer_get_coverage_pc_buffer(uptr **data) {
+  *data = coverage_data.buffer();
+  return __sanitizer_get_total_unique_coverage();
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
 uptr __sanitizer_get_number_of_counters() {
   return coverage_data.GetNumberOf8bitCounters();
 }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc?rev=256804&r1=256803&r2=256804&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc Mon Jan  4 19:49:39 2016
@@ -144,6 +144,9 @@ COMMON_FLAG(bool, coverage_direct, SANIT
 COMMON_FLAG(const char *, coverage_dir, ".",
             "Target directory for coverage dumps. Defaults to the current "
             "directory.")
+COMMON_FLAG(bool, coverage_pc_buffer, true,
+            "If set (and if 'coverage' is set too), the pcs would be collected "
+            "in a buffer.")
 COMMON_FLAG(bool, full_address_space, false,
             "Sanitize complete address space; "
             "by default kernel area on 32-bit platforms will not be sanitized")

Added: compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc?rev=256804&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc Mon Jan  4 19:49:39 2016
@@ -0,0 +1,48 @@
+// Test __sanitizer_coverage_pc_buffer().
+
+// RUN: %clangxx_asan -fsanitize-coverage=edge %s -o %t && %run %t
+
+// UNSUPPORTED: android
+
+#include <assert.h>
+#include <sanitizer/coverage_interface.h>
+#include <stdio.h>
+
+static volatile int sink;
+__attribute__((noinline)) void bar() { sink = 2; }
+__attribute__((noinline)) void foo() { sink = 1; }
+
+void assertNotZeroPcs(uintptr_t *buf, uintptr_t size) {
+  assert(buf);
+  for (uintptr_t i = 0; i < size; ++i)
+    assert(buf[i]);
+}
+
+int main() {
+  uintptr_t *buf = NULL;
+  uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+  assertNotZeroPcs(buf, sz);
+  assert(sz);
+
+  foo();
+  bar();
+  uintptr_t *buf1 = NULL;
+  uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
+  assertNotZeroPcs(buf1, sz1);
+  assert(buf1 == buf);
+  assert(sz1 > sz);
+
+  bar();
+  uintptr_t *buf2 = NULL;
+  uintptr_t sz2 = __sanitizer_get_coverage_pc_buffer(&buf2);
+  assertNotZeroPcs(buf2, sz2);
+  assert(buf2 == buf);
+  assert(sz2 > sz1);
+
+  __sanitizer_reset_coverage();
+  uintptr_t *buf3 = NULL;
+  uintptr_t sz3 = __sanitizer_get_coverage_pc_buffer(&buf3);
+  assertNotZeroPcs(buf3, sz3);
+  assert(buf3 == buf);
+  assert(sz3 < sz2);
+}




More information about the llvm-commits mailing list