[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