[sanitizer-coverage] Add new coverage dump interface 43/128843/11 accepted/tizen/base/20170602.151755 submit/tizen_base/20170524.085448
authorDmitriy Nikiforov <d.nikiforov@partner.samsung.com>
Thu, 11 May 2017 14:37:27 +0000 (17:37 +0300)
committerDmitriy Nikiforov <d.nikiforov@partner.samsung.com>
Tue, 23 May 2017 10:36:11 +0000 (13:36 +0300)
libsanitizer/
* include/santizer/coverage_interface.h
(__sanitizer_dump_coverage): New function.
* sanitizer_common/sanitizer_interface_internal.h
(__sanitizer_dump_coverage): Likewise.
* sanitizer_common/sanitizer_coverage_libcdep_new.cc: New file.
* sanitizer/Makefile.am: Updated.
* sanitzer/Makefile.in: Updated.

Partially backported from LLVM mainline r289498, r291267, r291736, r289851.

Change-Id: I6c13ca8e6e7cfb3c98596970c8ba243296464eeb
Signed-off-by: Dmitriy Nikiforov <d.nikiforov@partner.samsung.com>
libsanitizer/include/sanitizer/coverage_interface.h
libsanitizer/sanitizer_common/Makefile.am
libsanitizer/sanitizer_common/Makefile.in
libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc [new file with mode: 0644]
libsanitizer/sanitizer_common/sanitizer_interface_internal.h

index 37c133a..d6e83d6 100644 (file)
@@ -21,6 +21,9 @@ extern "C" {
   void __sanitizer_cov_init();
   // Record and dump coverage info.
   void __sanitizer_cov_dump();
+  // Dump collected coverage info. Sorts pcs by module into individual
+  // .sancov files.
+  void __sanitizer_dump_coverage(const uintptr_t *pcs, uintptr_t len);
   // Open <name>.sancov.packed in the coverage directory and return the file
   // descriptor. Returns -1 on failure, or if coverage dumping is disabled.
   // This is intended for use by sandboxing code.
index ee7a3f1..e66295f 100644 (file)
@@ -23,6 +23,7 @@ sanitizer_common_files = \
        sanitizer_common.cc \
        sanitizer_common_libcdep.cc \
        sanitizer_coverage_libcdep.cc \
+       sanitizer_coverage_libcdep_new.cc \
        sanitizer_coverage_mapping_libcdep.cc \
        sanitizer_deadlock_detector1.cc \
        sanitizer_deadlock_detector2.cc \
index 765efd1..8924f20 100644 (file)
@@ -82,6 +82,7 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
 libsanitizer_common_la_LIBADD =
 am__objects_1 = sanitizer_allocator.lo sanitizer_common.lo \
        sanitizer_common_libcdep.lo sanitizer_coverage_libcdep.lo \
+       sanitizer_coverage_libcdep_new.lo \
        sanitizer_coverage_mapping_libcdep.lo \
        sanitizer_deadlock_detector1.lo \
        sanitizer_deadlock_detector2.lo sanitizer_flags.lo \
@@ -288,6 +289,7 @@ sanitizer_common_files = \
        sanitizer_common.cc \
        sanitizer_common_libcdep.cc \
        sanitizer_coverage_libcdep.cc \
+       sanitizer_coverage_libcdep_new.cc \
        sanitizer_coverage_mapping_libcdep.cc \
        sanitizer_deadlock_detector1.cc \
        sanitizer_deadlock_detector2.cc \
@@ -422,6 +424,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_common.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_common_libcdep.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_coverage_libcdep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_coverage_libcdep_new.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_coverage_mapping_libcdep.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_deadlock_detector1.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_deadlock_detector2.Plo@am__quote@
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc
new file mode 100644 (file)
index 0000000..dcb305c
--- /dev/null
@@ -0,0 +1,113 @@
+//===-- sanitizer_coverage_libcdep_new.cc ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Sanitizer Coverage Controller for Trace PC Guard.
+
+#include "sanitizer_allocator_internal.h"
+#include "sanitizer_atomic.h"
+#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
+#include "sanitizer_symbolizer.h"
+
+using namespace __sanitizer;
+
+using AddressRange = LoadedModule::AddressRange;
+
+namespace __sancov {
+namespace {
+
+static const u64 Magic64 = 0xC0BFFFFFFFFFFF64ULL;
+static const u64 Magic32 = 0xC0BFFFFFFFFFFF32ULL;
+static const u64 Magic = SANITIZER_WORDSIZE == 64 ? Magic64 : Magic32;
+
+static fd_t OpenFile(const char *path) {
+  error_t err;
+  fd_t fd = OpenFile(path, WrOnly, &err);
+  if (fd == kInvalidFd)
+    Report("SanitizerCoverage: failed to open %s for writing (reason: %d)\n",
+           path, err);
+  return fd;
+}
+
+static void GetCoverageFilename(char *path, const char *name,
+                                const char *extension) {
+  CHECK(name);
+  internal_snprintf(path, kMaxPathLength, "%s/%s.%zd.%s",
+                    common_flags()->coverage_dir, name, internal_getpid(),
+                    extension);
+}
+
+static void WriteModuleCoverage(char *file_path, const char *module_name,
+                                const uptr *pcs, uptr len) {
+  GetCoverageFilename(file_path, StripModuleName(module_name), "sancov");
+  fd_t fd = OpenFile(file_path);
+  WriteToFile(fd, &Magic, sizeof(Magic));
+  WriteToFile(fd, pcs, len * sizeof(*pcs));
+  CloseFile(fd);
+  Printf("SanitizerCoverage: %s %zd PCs written\n", file_path, len);
+}
+
+static void SanitizerDumpCoverage(const uptr *unsorted_pcs, uptr len) {
+  if (!len)
+    return;
+
+  char *file_path = static_cast<char *>(InternalAlloc(kMaxPathLength));
+  char *module_name = static_cast<char *>(InternalAlloc(kMaxPathLength));
+  uptr *pcs = static_cast<uptr *>(InternalAlloc(len * sizeof(uptr)));
+
+  internal_memcpy(pcs, unsorted_pcs, len * sizeof(uptr));
+  SortArray(pcs, len);
+
+  bool module_found = false;
+  uptr last_base = 0;
+  uptr module_start_idx = 0;
+
+  for (uptr i = 0; i < len; ++i) {
+    const uptr pc = pcs[i];
+    if (!pc)
+      continue;
+
+    if (!__sanitizer_get_module_and_offset_for_pc(pc, nullptr, 0, &pcs[i])) {
+      Printf("ERROR: bad pc %x\n", pc);
+      continue;
+    }
+    uptr module_base = pc - pcs[i];
+
+    if (module_base != last_base || !module_found) {
+      if (module_found) {
+        WriteModuleCoverage(file_path, module_name, &pcs[module_start_idx],
+                            i - module_start_idx);
+      }
+
+      last_base = module_base;
+      module_start_idx = i;
+      module_found = true;
+      __sanitizer_get_module_and_offset_for_pc(pc, module_name, kMaxPathLength,
+                                               &pcs[i]);
+    }
+  }
+
+  if (module_found) {
+    WriteModuleCoverage(file_path, module_name, &pcs[module_start_idx],
+                        len - module_start_idx);
+  }
+
+  InternalFree(file_path);
+  InternalFree(module_name);
+  InternalFree(pcs);
+}
+
+} // namespace
+} // namespace __sancov
+
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage( // NOLINT
+    const uptr *pcs, uptr len) {
+  return __sancov::SanitizerDumpCoverage(pcs, len);
+}
+} // extern "C"
index 9d2d3d0..fe740c9 100644 (file)
@@ -41,6 +41,9 @@ extern "C" {
   void __sanitizer_report_error_summary(const char *error_summary);
 
   SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump();
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __sanitizer_dump_coverage(const __sanitizer::uptr *pcs,
+                                 const __sanitizer::uptr len);
   SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init();
   SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(__sanitizer::u32 *guard);
   SANITIZER_INTERFACE_ATTRIBUTE