[libFuzzer] make libFuzzer link if there is no sanitizer coverage instrumentation...
authorKostya Serebryany <kcc@google.com>
Mon, 9 Nov 2015 23:17:45 +0000 (23:17 +0000)
committerKostya Serebryany <kcc@google.com>
Mon, 9 Nov 2015 23:17:45 +0000 (23:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252533 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerLoop.cpp
lib/Fuzzer/test/CMakeLists.txt
lib/Fuzzer/test/fuzzer.test
lib/Fuzzer/test/uninstrumented/CMakeLists.txt [new file with mode: 0644]

index 2287623..e206fcc 100644 (file)
 #include <algorithm>
 
 extern "C" {
+// Re-declare some of the sanitizer functions as "weak" so that
+// libFuzzer can be linked w/o the sanitizers and sanitizer-coveragte
+// (in which case it will complain at start-up time).
 __attribute__((weak)) void __sanitizer_print_stack_trace();
 __attribute__((weak)) size_t __sanitizer_get_total_unique_caller_callee_pairs();
+__attribute__((weak)) size_t __sanitizer_get_total_unique_coverage();
+__attribute__((weak))
+void __sanitizer_set_death_callback(void (*callback)(void));
+__attribute__((weak)) size_t __sanitizer_get_number_of_counters();
+__attribute__((weak))
+uintptr_t __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);
 }
 
 namespace fuzzer {
 static const size_t kMaxUnitSizeToPrint = 256;
 
+static void MissingWeakApiFunction(const char *FnName) {
+  Printf("ERROR: %s is not defined. Exiting.\n"
+         "Did you use -fsanitize-coverage=... to build your code?\n", FnName);
+  exit(1);
+}
+
+#define CHECK_WEAK_API_FUNCTION(fn)                                            \
+  do {                                                                         \
+    if (!fn)                                                                   \
+      MissingWeakApiFunction(#fn);                                             \
+  } while (false)
+
 // Only one Fuzzer per process.
 static Fuzzer *F;
 
@@ -33,6 +54,7 @@ Fuzzer::Fuzzer(UserSuppliedFuzzer &USF, FuzzingOptions Options)
 }
 
 void Fuzzer::SetDeathCallback() {
+  CHECK_WEAK_API_FUNCTION(__sanitizer_set_death_callback);
   __sanitizer_set_death_callback(StaticDeathCallback);
 }
 
@@ -204,6 +226,7 @@ void Fuzzer::ExecuteCallback(const Unit &U) {
 }
 
 size_t Fuzzer::RecordBlockCoverage() {
+  CHECK_WEAK_API_FUNCTION(__sanitizer_get_total_unique_coverage);
   return LastRecordedBlockCoverage = __sanitizer_get_total_unique_coverage();
 }
 
index bb70e7e..1e02af1 100644 (file)
@@ -34,6 +34,10 @@ set(CustomMainTests
   UserSuppliedFuzzerTest
   )
 
+set(UninstrumentedTests
+  UninstrumentedTest
+  )
+
 
 set(TestBinaries)
 
@@ -89,6 +93,12 @@ foreach(Test ${DFSanTests})
   set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-DFSan)
 endforeach()
 
+add_subdirectory(uninstrumented)
+
+foreach(Test ${UninstrumentedTests})
+  set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-Uninstrumented)
+endforeach()
+
 
 set_target_properties(${TestBinaries}
   PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
index 94db0fe..0f1a6cc 100644 (file)
@@ -60,3 +60,6 @@ RUN:     LLVMFuzzer-SimpleDictionaryTest                    -seed=1 -runs=100000
 
 RUN: not LLVMFuzzer-SimpleHashTest -use_traces=1 -seed=1 -runs=100000  2>&1 | FileCheck %s
 RUN:     LLVMFuzzer-SimpleHashTest               -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+
+RUN: not LLVMFuzzer-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED
+UNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting.
diff --git a/lib/Fuzzer/test/uninstrumented/CMakeLists.txt b/lib/Fuzzer/test/uninstrumented/CMakeLists.txt
new file mode 100644 (file)
index 0000000..443ba37
--- /dev/null
@@ -0,0 +1,14 @@
+# These tests are not instrumented with coverage.
+
+set(CMAKE_CXX_FLAGS_RELEASE
+  "${LIBFUZZER_FLAGS_BASE} -O0 -fno-sanitize=all")
+
+foreach(Test ${UninstrumentedTests})
+  add_executable(LLVMFuzzer-${Test}-Uninstrumented
+    ../${Test}.cpp
+    )
+  target_link_libraries(LLVMFuzzer-${Test}-Uninstrumented
+    LLVMFuzzer
+    )
+endforeach()
+