summaryrefslogtreecommitdiff
path: root/lib/Fuzzer/FuzzerTracePC.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Fuzzer/FuzzerTracePC.h')
-rw-r--r--lib/Fuzzer/FuzzerTracePC.h35
1 files changed, 30 insertions, 5 deletions
diff --git a/lib/Fuzzer/FuzzerTracePC.h b/lib/Fuzzer/FuzzerTracePC.h
index 6523fa06005c4..5ec8c590b4df6 100644
--- a/lib/Fuzzer/FuzzerTracePC.h
+++ b/lib/Fuzzer/FuzzerTracePC.h
@@ -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 *Begin, const uint8_t *End,
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 HandleFeature) const {
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)