Index: lib/fuzzer/FuzzerTracePC.h =================================================================== --- lib/fuzzer/FuzzerTracePC.h +++ lib/fuzzer/FuzzerTracePC.h @@ -246,7 +246,16 @@ } ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(), FirstFeature, - Handle8bitCounter); + [&](size_t FirstFeature, size_t Idx, uint8_t Counter) { + assert(Counter); + // Convert to Counter to a Feature. This is similar to the + // `CounterToFeature()` function but here each bit in the counter + // is treated as a distinct feature. + unsigned int MSBit = sizeof(unsigned int) * 8 - __builtin_clz(Counter); + assert(MSBit >=0 && MSBit < 8); + size_t Feature = MSBit -1; + HandleFeature(FirstFeature + Idx * 8 + Feature); + }); FirstFeature += (ExtraCountersEnd() - ExtraCountersBegin()) * 8; if (UseValueProfile) { Index: test/fuzzer/SingleExtraCounterTest.cpp =================================================================== --- /dev/null +++ test/fuzzer/SingleExtraCounterTest.cpp @@ -0,0 +1,31 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +#include +#include +#include + +#ifdef __linux__ +__attribute__((section("__libfuzzer_extra_counters"))) +#endif + static uint8_t Counters[1]; + +// This tests that every bit inside a counter is used as a signal +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + static int RunCount = 0; + fprintf(stderr, "Doing run: #%d\n", RunCount); + // FIXME: The is fragile, why two runs before init is done? + // The first two runs of this function are for LibFuzzers init so + // don't modify counters until after they are done. + if (RunCount < 2) { + ++RunCount; + return 0; + } + int BitToSet = RunCount - 2; + assert(BitToSet >= 0 & BitToSet <= 7); + // LibFuzzer should reset this for every call + assert(Counters[0] == 0); + fprintf(stderr, "Setting bit: %d\n", BitToSet); + Counters[0] = (1 << BitToSet); + ++RunCount; + return 0; +} Index: test/fuzzer/single-extra-counter.test =================================================================== --- /dev/null +++ test/fuzzer/single-extra-counter.test @@ -0,0 +1,23 @@ +REQUIRES: linux +RUN: %cpp_compiler %S/SingleExtraCounterTest.cpp -o %t-SingleExtraCounterTest +RUN: %t-SingleExtraCounterTest -max_len=1 -seed=0 -runs=10 -print_final_stats=1 2>&1 | FileCheck %s + +CHECK: Setting bit: 0 +CHECK-NEXT: #3 {{ *}}NEW +CHECK: Setting bit: 1 +CHECK-NEXT: #4 {{ *}}NEW +CHECK: Setting bit: 2 +CHECK-NEXT: #5 {{ *}}NEW +CHECK: Setting bit: 3 +CHECK-NEXT: #6 {{ *}}NEW +CHECK: Setting bit: 4 +CHECK-NEXT: #7 {{ *}}NEW +CHECK: Setting bit: 5 +CHECK-NEXT: #8 {{ *}}NEW +CHECK: Setting bit: 6 +CHECK-NEXT: #9 {{ *}}NEW +CHECK: Setting bit: 7 +CHECK-NEXT: #10 {{ *}}NEW + +CHECK: number_of_executed_units:{{ *}}10 +CHECK: new_units_added:{{ *}}8