summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2017-03-30 01:27:20 +0000
committerKostya Serebryany <kcc@google.com>2017-03-30 01:27:20 +0000
commitd7d1d517ee13d8fad6279de29f236295bef10b58 (patch)
tree444b044407fec0c18b8219a39c0d8c274d0f424e
parentaf3a4e97d8627a32606ed32001583fe08f15b928 (diff)
downloadbcm5719-llvm-d7d1d517ee13d8fad6279de29f236295bef10b58.tar.gz
bcm5719-llvm-d7d1d517ee13d8fad6279de29f236295bef10b58.zip
[libFuzzer] best effort support for -fsanitize-coverage=trace-pc instrumentation. It is less efficient and precise than -fsanitize-coverage=trace-pc-guard, but still works
llvm-svn: 299046
-rw-r--r--llvm/lib/Fuzzer/FuzzerTracePC.cpp11
-rw-r--r--llvm/lib/Fuzzer/FuzzerTracePC.h6
-rw-r--r--llvm/lib/Fuzzer/test/CMakeLists.txt1
-rw-r--r--llvm/lib/Fuzzer/test/trace-pc.test2
-rw-r--r--llvm/lib/Fuzzer/test/trace-pc/CMakeLists.txt13
5 files changed, 32 insertions, 1 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
index c73008dccd3..ce0f7a47eee 100644
--- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp
+++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
@@ -287,6 +287,17 @@ void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
__sancov_trace_pc_guard_8bit_counters[Idx]++;
}
+// Best-effort support for -fsanitize-coverage=trace-pc, which is available
+// in both Clang and GCC.
+ATTRIBUTE_INTERFACE
+ATTRIBUTE_NO_SANITIZE_ALL
+void __sanitizer_cov_trace_pc() {
+ uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t Idx = PC & (((uintptr_t)1 << fuzzer::TracePC::kTracePcBits) - 1);
+ __sancov_trace_pc_pcs[Idx] = PC;
+ __sancov_trace_pc_guard_8bit_counters[Idx]++;
+}
+
ATTRIBUTE_INTERFACE
void __sanitizer_cov_trace_pc_guard_init(uint32_t *Start, uint32_t *Stop) {
fuzzer::TPC.HandleInit(Start, Stop);
diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.h b/llvm/lib/Fuzzer/FuzzerTracePC.h
index c7b8dfe3c3f..4c8a18f830f 100644
--- a/llvm/lib/Fuzzer/FuzzerTracePC.h
+++ b/llvm/lib/Fuzzer/FuzzerTracePC.h
@@ -48,6 +48,8 @@ struct TableOfRecentCompares {
class TracePC {
public:
static const size_t kNumPCs = 1 << 21;
+ // How many bits of PC are used from __sanitizer_cov_trace_pc.
+ static const size_t kTracePcBits = 18;
void HandleInit(uint32_t *start, uint32_t *stop);
void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
@@ -81,7 +83,9 @@ class TracePC {
void PrintNewPCs();
void InitializePrintNewPCs();
- size_t GetNumPCs() const { return Min(kNumPCs, NumGuards + 1); }
+ size_t GetNumPCs() const {
+ return NumGuards == 0 ? (1 << kTracePcBits) : Min(kNumPCs, NumGuards + 1);
+ }
uintptr_t GetPC(size_t Idx) {
assert(Idx < GetNumPCs());
return PCs()[Idx];
diff --git a/llvm/lib/Fuzzer/test/CMakeLists.txt b/llvm/lib/Fuzzer/test/CMakeLists.txt
index 8d4350514f7..f72bc3909a3 100644
--- a/llvm/lib/Fuzzer/test/CMakeLists.txt
+++ b/llvm/lib/Fuzzer/test/CMakeLists.txt
@@ -202,6 +202,7 @@ include_directories(..)
# add_subdirectory(uninstrumented)
add_subdirectory(no-coverage)
+add_subdirectory(trace-pc)
add_subdirectory(ubsan)
add_library(LLVMFuzzer-DSO1 SHARED DSO1.cpp)
diff --git a/llvm/lib/Fuzzer/test/trace-pc.test b/llvm/lib/Fuzzer/test/trace-pc.test
new file mode 100644
index 00000000000..3709677b71b
--- /dev/null
+++ b/llvm/lib/Fuzzer/test/trace-pc.test
@@ -0,0 +1,2 @@
+CHECK: BINGO
+RUN: LLVMFuzzer-SimpleTest-TracePC -runs=100000 -seed=1 2>&1 | FileCheck %s
diff --git a/llvm/lib/Fuzzer/test/trace-pc/CMakeLists.txt b/llvm/lib/Fuzzer/test/trace-pc/CMakeLists.txt
new file mode 100644
index 00000000000..e800f82cc5d
--- /dev/null
+++ b/llvm/lib/Fuzzer/test/trace-pc/CMakeLists.txt
@@ -0,0 +1,13 @@
+# These tests are not instrumented with coverage and don't
+# have coverage rt in the binary.
+
+set(CMAKE_CXX_FLAGS
+ "${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard -fsanitize-coverage=trace-pc")
+
+set(TracePCTests
+ SimpleTest
+ )
+
+foreach(Test ${TracePCTests})
+ add_libfuzzer_test(${Test}-TracePC SOURCES ../${Test}.cpp)
+endforeach()
OpenPOWER on IntegriCloud