From d32bc3ee385e67cafa45d948737f3f2fbdf6485a Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Wed, 19 Apr 2017 22:24:03 +0000 Subject: [PATCH] [sanitizer-coverage] remove run-time support for -fsanitize-coverage=indirect-calls llvm-svn: 300775 --- .../include/sanitizer/coverage_interface.h | 2 - compiler-rt/lib/dfsan/done_abilist.txt | 4 - .../sanitizer_coverage_interface.inc | 2 - .../sanitizer_coverage_libcdep.cc | 105 ------------------ .../TestCases/Posix/coverage-caller-callee.cc | 75 ------------- .../coverage-caller-callee-total-count.cc | 42 ------- 6 files changed, 230 deletions(-) delete mode 100644 compiler-rt/test/asan/TestCases/Posix/coverage-caller-callee.cc delete mode 100644 compiler-rt/test/asan/TestCases/coverage-caller-callee-total-count.cc diff --git a/compiler-rt/include/sanitizer/coverage_interface.h b/compiler-rt/include/sanitizer/coverage_interface.h index c6ea0e674f13..adf0960d2321 100644 --- a/compiler-rt/include/sanitizer/coverage_interface.h +++ b/compiler-rt/include/sanitizer/coverage_interface.h @@ -35,8 +35,6 @@ extern "C" { // Get the number of unique covered blocks (or edges). // This can be useful for coverage-directed in-process fuzzers. uintptr_t __sanitizer_get_total_unique_coverage(); - // Get the number of unique indirect caller-callee pairs. - uintptr_t __sanitizer_get_total_unique_caller_callee_pairs(); // Reset the basic-block (edge) coverage to the initial state. // Useful for in-process fuzzing to start collecting coverage from scratch. diff --git a/compiler-rt/lib/dfsan/done_abilist.txt b/compiler-rt/lib/dfsan/done_abilist.txt index 95a5af55946a..d3ac553db2c5 100644 --- a/compiler-rt/lib/dfsan/done_abilist.txt +++ b/compiler-rt/lib/dfsan/done_abilist.txt @@ -285,10 +285,6 @@ fun:__sanitizer_cov_module_init=uninstrumented fun:__sanitizer_cov_module_init=discard fun:__sanitizer_cov_with_check=uninstrumented fun:__sanitizer_cov_with_check=discard -fun:__sanitizer_cov_indir_call16=uninstrumented -fun:__sanitizer_cov_indir_call16=discard -fun:__sanitizer_cov_indir_call16=uninstrumented -fun:__sanitizer_cov_indir_call16=discard fun:__sanitizer_reset_coverage=uninstrumented fun:__sanitizer_reset_coverage=discard fun:__sanitizer_set_death_callback=uninstrumented diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc index 04726f5b247c..139a8b989c5f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc @@ -10,14 +10,12 @@ //===----------------------------------------------------------------------===// INTERFACE_FUNCTION(__sanitizer_cov) INTERFACE_FUNCTION(__sanitizer_cov_dump) -INTERFACE_FUNCTION(__sanitizer_cov_indir_call16) INTERFACE_FUNCTION(__sanitizer_cov_init) INTERFACE_FUNCTION(__sanitizer_cov_module_init) INTERFACE_FUNCTION(__sanitizer_cov_with_check) INTERFACE_FUNCTION(__sanitizer_dump_coverage) INTERFACE_FUNCTION(__sanitizer_dump_trace_pc_guard_coverage) INTERFACE_FUNCTION(__sanitizer_get_coverage_guards) -INTERFACE_FUNCTION(__sanitizer_get_total_unique_caller_callee_pairs) INTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage) INTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file) INTERFACE_FUNCTION(__sanitizer_reset_coverage) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc index c056b0668840..d3447a553739 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc @@ -57,11 +57,9 @@ static const u64 kMagic = SANITIZER_WORDSIZE == 64 ? kMagic64 : kMagic32; static atomic_uint32_t dump_once_guard; // Ensure that CovDump runs only once. static atomic_uintptr_t coverage_counter; -static atomic_uintptr_t caller_callee_counter; static void ResetGlobalCounters() { return atomic_store(&coverage_counter, 0, memory_order_relaxed); - return atomic_store(&caller_callee_counter, 0, memory_order_relaxed); } // pc_array is the array containing the covered PCs. @@ -90,9 +88,6 @@ class CoverageData { void AfterFork(int child_pid); void Extend(uptr npcs); void Add(uptr pc, u32 *guard); - void IndirCall(uptr caller, uptr callee, uptr callee_cache[], - uptr cache_size); - void DumpCallerCalleePairs(); void DumpAsBitSet(); void DumpOffsets(); void DumpAll(); @@ -142,12 +137,6 @@ class CoverageData { InternalMmapVectorNoCtor comp_unit_name_vec; InternalMmapVectorNoCtor module_name_vec; - // Caller-Callee (cc) array, size and current index. - static const uptr kCcArrayMaxSize = FIRST_32_SECOND_64(1 << 18, 1 << 24); - uptr **cc_array; - atomic_uintptr_t cc_array_index; - atomic_uintptr_t cc_array_size; - StaticSpinMutex mu; }; @@ -184,11 +173,6 @@ void CoverageData::Enable() { } else { atomic_store(&pc_array_size, kPcArrayMaxSize, memory_order_relaxed); } - - cc_array = reinterpret_cast(MmapNoReserveOrDie( - sizeof(uptr *) * kCcArrayMaxSize, "CovInit::cc_array")); - atomic_store(&cc_array_size, kCcArrayMaxSize, memory_order_relaxed); - atomic_store(&cc_array_index, 0, memory_order_relaxed); } void CoverageData::InitializeGuardArray(s32 *guards) { @@ -206,10 +190,6 @@ void CoverageData::Disable() { UnmapOrDie(pc_array, sizeof(uptr) * kPcArrayMaxSize); pc_array = nullptr; } - if (cc_array) { - UnmapOrDie(cc_array, sizeof(uptr *) * kCcArrayMaxSize); - cc_array = nullptr; - } if (pc_fd != kInvalidFd) { CloseFile(pc_fd); pc_fd = kInvalidFd; @@ -363,40 +343,6 @@ void CoverageData::Add(uptr pc, u32 *guard) { pc_array[idx] = BundlePcAndCounter(pc, counter); } -// Registers a pair caller=>callee. -// When a given caller is seen for the first time, the callee_cache is added -// to the global array cc_array, callee_cache[0] is set to caller and -// callee_cache[1] is set to cache_size. -// Then we are trying to add callee to callee_cache [2,cache_size) if it is -// not there yet. -// If the cache is full we drop the callee (may want to fix this later). -void CoverageData::IndirCall(uptr caller, uptr callee, uptr callee_cache[], - uptr cache_size) { - if (!cc_array) return; - atomic_uintptr_t *atomic_callee_cache = - reinterpret_cast(callee_cache); - uptr zero = 0; - if (atomic_compare_exchange_strong(&atomic_callee_cache[0], &zero, caller, - memory_order_seq_cst)) { - uptr idx = atomic_fetch_add(&cc_array_index, 1, memory_order_relaxed); - CHECK_LT(idx * sizeof(uptr), - atomic_load(&cc_array_size, memory_order_acquire)); - callee_cache[1] = cache_size; - cc_array[idx] = callee_cache; - } - CHECK_EQ(atomic_load(&atomic_callee_cache[0], memory_order_relaxed), caller); - for (uptr i = 2; i < cache_size; i++) { - uptr was = 0; - if (atomic_compare_exchange_strong(&atomic_callee_cache[i], &was, callee, - memory_order_seq_cst)) { - atomic_fetch_add(&caller_callee_counter, 1, memory_order_relaxed); - return; - } - if (was == callee) // Already have this callee. - return; - } -} - uptr *CoverageData::data() { return pc_array; } @@ -477,46 +423,6 @@ static fd_t CovOpenFile(InternalScopedString *path, bool packed, return fd; } -// This function dumps the caller=>callee pairs into a file as a sequence of -// lines like "module_name offset". -void CoverageData::DumpCallerCalleePairs() { - uptr max_idx = atomic_load(&cc_array_index, memory_order_relaxed); - if (!max_idx) return; - auto sym = Symbolizer::GetOrInit(); - if (!sym) - return; - InternalScopedString out(32 << 20); - uptr total = 0; - for (uptr i = 0; i < max_idx; i++) { - uptr *cc_cache = cc_array[i]; - CHECK(cc_cache); - uptr caller = cc_cache[0]; - uptr n_callees = cc_cache[1]; - const char *caller_module_name = ""; - uptr caller_module_address = 0; - sym->GetModuleNameAndOffsetForPC(caller, &caller_module_name, - &caller_module_address); - for (uptr j = 2; j < n_callees; j++) { - uptr callee = cc_cache[j]; - if (!callee) break; - total++; - const char *callee_module_name = ""; - uptr callee_module_address = 0; - sym->GetModuleNameAndOffsetForPC(callee, &callee_module_name, - &callee_module_address); - out.append("%s 0x%zx\n%s 0x%zx\n", caller_module_name, - caller_module_address, callee_module_name, - callee_module_address); - } - } - InternalScopedString path(kMaxPathLength); - fd_t fd = CovOpenFile(&path, false, "caller-callee"); - if (fd == kInvalidFd) return; - WriteToFile(fd, out.data(), out.length()); - CloseFile(fd); - VReport(1, " CovDump: %zd caller-callee pairs written\n", total); -} - void CoverageData::DumpAsBitSet() { if (!common_flags()->coverage_bitset) return; if (!size()) return; @@ -665,7 +571,6 @@ void CoverageData::DumpAll() { return; DumpAsBitSet(); DumpOffsets(); - DumpCallerCalleePairs(); } void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) { @@ -739,11 +644,6 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_with_check(u32 *guard) { coverage_data.Add(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()), guard); } -SANITIZER_INTERFACE_ATTRIBUTE void -__sanitizer_cov_indir_call16(uptr callee, uptr callee_cache16[]) { - coverage_data.IndirCall(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()), - callee, callee_cache16, 16); -} SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() { coverage_enabled = true; coverage_dir = common_flags()->coverage_dir; @@ -774,11 +674,6 @@ uptr __sanitizer_get_total_unique_coverage() { return atomic_load(&coverage_counter, memory_order_relaxed); } -SANITIZER_INTERFACE_ATTRIBUTE -uptr __sanitizer_get_total_unique_caller_callee_pairs() { - return atomic_load(&caller_callee_counter, memory_order_relaxed); -} - SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_reset_coverage() { ResetGlobalCounters(); diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage-caller-callee.cc b/compiler-rt/test/asan/TestCases/Posix/coverage-caller-callee.cc deleted file mode 100644 index fb8b9bf92af2..000000000000 --- a/compiler-rt/test/asan/TestCases/Posix/coverage-caller-callee.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Test caller-callee coverage with large number of threads -// and various numbers of callers and callees. - -// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t -// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 10 1 2>&1 | FileCheck %s --check-prefix=CHECK-10-1 -// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 9 2 2>&1 | FileCheck %s --check-prefix=CHECK-9-2 -// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 7 3 2>&1 | FileCheck %s --check-prefix=CHECK-7-3 -// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 17 1 2>&1 | FileCheck %s --check-prefix=CHECK-17-1 -// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 15 2 2>&1 | FileCheck %s --check-prefix=CHECK-15-2 -// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 18 3 2>&1 | FileCheck %s --check-prefix=CHECK-18-3 -// RUN: rm -f caller-callee*.sancov -// -// REQUIRES: asan-64-bits -// UNSUPPORTED: android -// -// CHECK-10-1: CovDump: 10 caller-callee pairs written -// CHECK-9-2: CovDump: 18 caller-callee pairs written -// CHECK-7-3: CovDump: 21 caller-callee pairs written -// CHECK-17-1: CovDump: 14 caller-callee pairs written -// CHECK-15-2: CovDump: 28 caller-callee pairs written -// CHECK-18-3: CovDump: 42 caller-callee pairs written - -#include -#include -#include -int P = 0; -struct Foo {virtual void f() {if (P) printf("Foo::f()\n");}}; -struct Foo1 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo2 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo3 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo4 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo5 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo6 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo7 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo8 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo9 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo10 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo11 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo12 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo13 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo14 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo15 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo16 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo17 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo18 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo19 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; - -Foo *foo[20] = { - new Foo, new Foo1, new Foo2, new Foo3, new Foo4, new Foo5, new Foo6, - new Foo7, new Foo8, new Foo9, new Foo10, new Foo11, new Foo12, new Foo13, - new Foo14, new Foo15, new Foo16, new Foo17, new Foo18, new Foo19, -}; - -int n_functions = 10; -int n_callers = 2; - -void *Thread(void *arg) { - if (n_callers >= 1) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f(); - if (n_callers >= 2) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f(); - if (n_callers >= 3) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f(); - return arg; -} - -int main(int argc, char **argv) { - if (argc >= 2) - n_functions = atoi(argv[1]); - if (argc >= 3) - n_callers = atoi(argv[2]); - const int kNumThreads = 16; - pthread_t t[kNumThreads]; - for (int i = 0; i < kNumThreads; i++) - pthread_create(&t[i], 0, Thread, 0); - for (int i = 0; i < kNumThreads; i++) - pthread_join(t[i], 0); -} diff --git a/compiler-rt/test/asan/TestCases/coverage-caller-callee-total-count.cc b/compiler-rt/test/asan/TestCases/coverage-caller-callee-total-count.cc deleted file mode 100644 index 955ffe5a9040..000000000000 --- a/compiler-rt/test/asan/TestCases/coverage-caller-callee-total-count.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Test __sanitizer_get_total_unique_coverage for caller-callee coverage - -// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t -// RUN: %env_asan_opts=coverage=1 %run %t -// RUN: rm -f caller-callee*.sancov -// -// REQUIRES: asan-64-bits - -#include -#include -#include -int P = 0; -struct Foo {virtual void f() {if (P) printf("Foo::f()\n");}}; -struct Foo1 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; -struct Foo2 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; - -Foo *foo[3] = {new Foo, new Foo1, new Foo2}; - -uintptr_t CheckNewTotalUniqueCoverageIsLargerAndReturnIt(uintptr_t old_total) { - uintptr_t new_total = __sanitizer_get_total_unique_caller_callee_pairs(); - fprintf(stderr, "Caller-Callee: old %zd new %zd\n", old_total, new_total); - assert(new_total > old_total); - return new_total; -} - -int main(int argc, char **argv) { - uintptr_t total = __sanitizer_get_total_unique_caller_callee_pairs(); - foo[0]->f(); - total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total); - foo[1]->f(); - total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total); - foo[2]->f(); - total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total); - // Ok, called every function once. - // Now call them again from another call site. Should get new coverage. - foo[0]->f(); - total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total); - foo[1]->f(); - total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total); - foo[2]->f(); - total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total); -}