[llvm] r305331 - [libFuzzer] initial support of -fsanitize-coverage=inline-8bit-counters in libFuzzer. This is not fully functional yet, but simple tests work

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 13 15:31:21 PDT 2017


Author: kcc
Date: Tue Jun 13 17:31:21 2017
New Revision: 305331

URL: http://llvm.org/viewvc/llvm-project?rev=305331&view=rev
Log:
[libFuzzer] initial support of -fsanitize-coverage=inline-8bit-counters in libFuzzer. This is not fully functional yet, but simple tests work 

Added:
    llvm/trunk/lib/Fuzzer/test/inline-8bit-counters/
    llvm/trunk/lib/Fuzzer/test/inline-8bit-counters.test
    llvm/trunk/lib/Fuzzer/test/inline-8bit-counters/CMakeLists.txt
Modified:
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.h
    llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
    llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
    llvm/trunk/lib/Fuzzer/test/TableLookupTest.cpp
    llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=305331&r1=305330&r2=305331&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp Tue Jun 13 17:31:21 2017
@@ -53,6 +53,17 @@ size_t TracePC::GetTotalPCCoverage() {
   return Res;
 }
 
+
+void TracePC::HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop) {
+  if (Start == Stop) return;
+  if (NumModulesWithInline8bitCounters &&
+      ModuleCounters[NumModulesWithInline8bitCounters-1].Start == Start) return;
+  assert(NumModulesWithInline8bitCounters <
+         sizeof(ModuleCounters) / sizeof(ModuleCounters[0]));
+  ModuleCounters[NumModulesWithInline8bitCounters++] = {Start, Stop};
+  NumInline8bitCounters += Stop - Start;
+}
+
 void TracePC::HandleInit(uint32_t *Start, uint32_t *Stop) {
   if (Start == Stop || *Start) return;
   assert(NumModules < sizeof(Modules) / sizeof(Modules[0]));
@@ -76,6 +87,13 @@ void TracePC::PrintModuleInfo() {
   for (size_t i = 0; i < NumModules; i++)
     Printf("[%p, %p), ", Modules[i].Start, Modules[i].Stop);
   Printf("\n");
+  if (NumModulesWithInline8bitCounters) {
+    Printf("INFO: Loaded %zd modules with %zd inline 8-bit counters\n",
+           NumModulesWithInline8bitCounters, NumInline8bitCounters);
+    for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++)
+      Printf("[%p, %p), ", ModuleCounters[i].Start, ModuleCounters[i].Stop);
+    Printf("\n");
+  }
 }
 
 ATTRIBUTE_NO_SANITIZE_ALL
@@ -304,6 +322,11 @@ void __sanitizer_cov_trace_pc_guard_init
 }
 
 ATTRIBUTE_INTERFACE
+void __sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop) {
+  fuzzer::TPC.HandleInline8bitCountersInit(Start, Stop);
+}
+
+ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) {
   uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.h?rev=305331&r1=305330&r2=305331&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.h Tue Jun 13 17:31:21 2017
@@ -51,7 +51,8 @@ class TracePC {
   // 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 HandleInit(uint32_t *Start, uint32_t *Stop);
+  void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop);
   void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
   template <class T> void HandleCmp(uintptr_t PC, T Arg1, T Arg2);
   size_t GetTotalPCCoverage();
@@ -104,6 +105,10 @@ private:
   size_t NumModules;  // linker-initialized.
   size_t NumGuards;  // linker-initialized.
 
+  struct { uint8_t *Start, *Stop; } ModuleCounters[4096];
+  size_t NumModulesWithInline8bitCounters;  // linker-initialized.
+  size_t NumInline8bitCounters;
+
   uint8_t *Counters() const;
   uintptr_t *PCs() const;
 
@@ -118,12 +123,24 @@ void ForEachNonZeroByte(const uint8_t *B
                         size_t FirstFeature, Callback Handle8bitCounter) {
   typedef uintptr_t LargeType;
   const size_t Step = sizeof(LargeType) / sizeof(uint8_t);
-  assert(!(reinterpret_cast<uintptr_t>(Begin) % 64));
-  for (auto P = Begin; P < End; P += Step)
+  const size_t StepMask = Step - 1;
+  auto P = Begin;
+  // Iterate by 1 byte until either the alignment boundary or the end.
+  for (; reinterpret_cast<uintptr_t>(P) & StepMask && P < End; P++)
+    if (uint8_t V = *P)
+      Handle8bitCounter(FirstFeature + P - Begin, V);
+
+  // Iterate by Step bytes at a time.
+  for (; P < End; P += Step)
     if (LargeType Bundle = *reinterpret_cast<const LargeType *>(P))
       for (size_t I = 0; I < Step; I++, Bundle >>= 8)
         if (uint8_t V = Bundle & 0xff)
           Handle8bitCounter(FirstFeature + P - Begin + I, V);
+
+  // Iterate by 1 byte until the end.
+  for (; P < End; P++)
+    if (uint8_t V = *P)
+      Handle8bitCounter(FirstFeature + P - Begin, V);
 }
 
 template <class Callback>  // bool Callback(size_t Feature)
@@ -145,8 +162,16 @@ void TracePC::CollectFeatures(Callback H
     HandleFeature(Idx * 8 + Bit);
   };
 
-  ForEachNonZeroByte(Counters, Counters + N, 0, Handle8bitCounter);
-  ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(), N * 8,
+  size_t FirstFeature = 0;
+  ForEachNonZeroByte(Counters, Counters + N, FirstFeature, Handle8bitCounter);
+  FirstFeature += N * 8;
+  for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
+    ForEachNonZeroByte(ModuleCounters[i].Start, ModuleCounters[i].Stop,
+                       FirstFeature, Handle8bitCounter);
+    FirstFeature += 8 * (ModuleCounters[i].Stop - ModuleCounters[i].Start);
+  }
+
+  ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(), FirstFeature,
                      Handle8bitCounter);
 
   if (UseValueProfile)

Modified: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/CMakeLists.txt?rev=305331&r1=305330&r2=305331&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt (original)
+++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt Tue Jun 13 17:31:21 2017
@@ -205,6 +205,7 @@ include_directories(..)
 # add_subdirectory(uninstrumented)
 add_subdirectory(no-coverage)
 add_subdirectory(trace-pc)
+add_subdirectory(inline-8bit-counters)
 add_subdirectory(ubsan)
 
 add_library(LLVMFuzzer-DSO1 SHARED DSO1.cpp)

Modified: llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=305331&r1=305330&r2=305331&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp Tue Jun 13 17:31:21 2017
@@ -772,4 +772,16 @@ TEST(Fuzzer, ForEachNonZeroByte) {
   Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
               {135, 5}, {137, 6}, {146, 7}, {163, 8}};
   EXPECT_EQ(Res, Expected);
+
+  Res.clear();
+  ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
+  Expected = {          {109, 2}, {118, 3}, {120, 4},
+              {135, 5}, {137, 6}, {146, 7}, {163, 8}};
+  EXPECT_EQ(Res, Expected);
+
+  Res.clear();
+  ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
+  Expected = {          {109, 2}, {118, 3}, {120, 4},
+              {135, 5}, {137, 6}, {146, 7}};
+  EXPECT_EQ(Res, Expected);
 }

Modified: llvm/trunk/lib/Fuzzer/test/TableLookupTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/TableLookupTest.cpp?rev=305331&r1=305330&r2=305331&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/TableLookupTest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/TableLookupTest.cpp Tue Jun 13 17:31:21 2017
@@ -15,7 +15,6 @@ const size_t N = 1 << 12;
 // Define an array of counters that will be understood by libFuzzer
 // as extra coverage signal. The array must be:
 //  * uint8_t
-//  * aligned by 64
 //  * in the section named __libfuzzer_extra_counters.
 // The target code may declare more than one such array.
 //
@@ -23,7 +22,7 @@ const size_t N = 1 << 12;
 // depending on whether multiple occurrences of the event 'Idx'
 // is important to distinguish from one occurrence.
 #ifdef __linux__
-alignas(64) __attribute__((section("__libfuzzer_extra_counters")))
+__attribute__((section("__libfuzzer_extra_counters")))
 #endif
 static uint8_t Counters[N];
 

Added: llvm/trunk/lib/Fuzzer/test/inline-8bit-counters.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/inline-8bit-counters.test?rev=305331&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/inline-8bit-counters.test (added)
+++ llvm/trunk/lib/Fuzzer/test/inline-8bit-counters.test Tue Jun 13 17:31:21 2017
@@ -0,0 +1,3 @@
+CHECK: INFO: Loaded 1 modules with {{.*}} inline 8-bit counters
+CHECK: BINGO
+RUN: LLVMFuzzer-SimpleTest-Inline8bitCounters -runs=100000 -seed=1 2>&1 | FileCheck %s

Added: llvm/trunk/lib/Fuzzer/test/inline-8bit-counters/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/inline-8bit-counters/CMakeLists.txt?rev=305331&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/inline-8bit-counters/CMakeLists.txt (added)
+++ llvm/trunk/lib/Fuzzer/test/inline-8bit-counters/CMakeLists.txt Tue Jun 13 17:31:21 2017
@@ -0,0 +1,12 @@
+# These tests are instrumented with -fsanitize-coverage=inline-8bit-counters
+
+set(CMAKE_CXX_FLAGS
+  "${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=trace-pc-guard -fsanitize-coverage=inline-8bit-counters")
+
+set(Inline8bitCounterTests
+  SimpleTest
+  )
+
+foreach(Test ${Inline8bitCounterTests})
+  add_libfuzzer_test(${Test}-Inline8bitCounters SOURCES ../${Test}.cpp)
+endforeach()

Modified: llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt?rev=305331&r1=305330&r2=305331&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt (original)
+++ llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt Tue Jun 13 17:31:21 2017
@@ -1,5 +1,4 @@
-# These tests are not instrumented with coverage and don't
-# have coverage rt in the binary.
+# These tests are instrumented with -fsanitize-coverage=trace-pc
 
 set(CMAKE_CXX_FLAGS
   "${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard -fsanitize-coverage=trace-pc")




More information about the llvm-commits mailing list