diff --git a/compiler-rt/lib/fuzzer/FuzzerExtraCounters.cpp b/compiler-rt/lib/fuzzer/FuzzerExtraCounters.cpp --- a/compiler-rt/lib/fuzzer/FuzzerExtraCounters.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerExtraCounters.cpp @@ -11,6 +11,10 @@ #include "FuzzerPlatform.h" #include +#if LIBFUZZER_WINDOWS +#include +#endif + #if LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FREEBSD || \ LIBFUZZER_FUCHSIA || LIBFUZZER_EMSCRIPTEN __attribute__((weak)) extern uint8_t __start___libfuzzer_extra_counters; @@ -31,6 +35,71 @@ } // namespace fuzzer +#elif LIBFUZZER_WINDOWS + +namespace fuzzer { + +// +// The __start___libfuzzer_extra_counters variable is align 16, size 16 to +// ensure the padding between it and the next variable in this section (either +// __libfuzzer_extra_counters or __stop___libfuzzer_extra_counters) will be +// located at (__start___libfuzzer_extra_counters + +// sizeof(__start___libfuzzer_extra_counters)). Otherwise, the calculation of +// (stop - (start + sizeof(start))) might be skewed. +// +// The section name, __libfuzzer_extra_countaaa ends with "aaa", so it sorts +// before __libfuzzer_extra_counters alphabetically. We want the start symbol to +// be placed in the section just before the user supplied counters (if present). +// +#pragma section(".data$__libfuzzer_extra_countaaa") +ATTRIBUTE_ALIGNED(16) +__declspec(allocate(".data$__libfuzzer_extra_countaaa")) uint8_t + __start___libfuzzer_extra_counters[16] = {0}; + +// +// Example of what the user-supplied counters should look like. First, the +// pragma to create the section name. It will fall alphabetically between +// ".data$__libfuzzer_extra_countaaa" and ".data$__libfuzzer_extra_countzzz". +// Next, the declspec to allocate the variable inside the specified section. +// Finally, some array, struct, whatever that is used to track the counter data. +// The size of this variable is computed at runtime by finding the difference of +// __stop___libfuzzer_extra_counters and __start___libfuzzer_extra_counters + +// sizeof(__start___libfuzzer_extra_counters). +// + +// +// #pragma section(".data$__libfuzzer_extra_counters") +// __declspec(allocate(".data$__libfuzzer_extra_counters")) +// uint8_t any_name_variable[64 * 1024]; +// + +// +// Here, the section name, __libfuzzer_extra_countzzz ends with "zzz", so it +// sorts after __libfuzzer_extra_counters alphabetically. We want the stop +// symbol to be placed in the section just after the user supplied counters (if +// present). Align to 1 so there isn't any padding placed between this and the +// previous variable. +// +#pragma section(".data$__libfuzzer_extra_countzzz") +ATTRIBUTE_ALIGNED(1) +__declspec(allocate(".data$__libfuzzer_extra_countzzz")) uint8_t + __stop___libfuzzer_extra_counters = 0; + +uint8_t *ExtraCountersBegin() { + return __start___libfuzzer_extra_counters + + sizeof(__start___libfuzzer_extra_counters); +} + +uint8_t *ExtraCountersEnd() { return &__stop___libfuzzer_extra_counters; } + +ATTRIBUTE_NO_SANITIZE_ALL +void ClearExtraCounters() { + uint8_t *Beg = ExtraCountersBegin(); + SecureZeroMemory(Beg, ExtraCountersEnd() - Beg); +} + +} // namespace fuzzer + #else // TODO: implement for other platforms. namespace fuzzer { diff --git a/compiler-rt/test/fuzzer/TableLookupTest.cpp b/compiler-rt/test/fuzzer/TableLookupTest.cpp --- a/compiler-rt/test/fuzzer/TableLookupTest.cpp +++ b/compiler-rt/test/fuzzer/TableLookupTest.cpp @@ -25,6 +25,10 @@ #ifdef __linux__ __attribute__((section("__libfuzzer_extra_counters"))) #endif +#ifdef _WIN32 +#pragma section(".data$__libfuzzer_extra_counters") +__declspec(allocate(".data$__libfuzzer_extra_counters")) +#endif static uint8_t Counters[N]; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/compiler-rt/test/fuzzer/extra-counters.test b/compiler-rt/test/fuzzer/extra-counters.test --- a/compiler-rt/test/fuzzer/extra-counters.test +++ b/compiler-rt/test/fuzzer/extra-counters.test @@ -1,5 +1,3 @@ -REQUIRES: linux - RUN: %cpp_compiler %S/TableLookupTest.cpp -o %t-TableLookupTest RUN: not %run %t-TableLookupTest -print_final_stats=1 2>&1 | FileCheck %s CHECK: INFO: {{[0-9]+}} Extra Counters