blob: b6f29957c4db8a43d65891f7a84b224359bef9d5 [file] [log] [blame]
Kostya Serebryanyda63c1d2016-02-26 21:33:56 +00001//===- FuzzerTracePC.cpp - PC tracing--------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9// Trace PCs.
10// This module implements __sanitizer_cov_trace_pc, a callback required
11// for -fsanitize-coverage=trace-pc instrumentation.
12//
13// Experimental and not yet tuned for performance.
14//===----------------------------------------------------------------------===//
15
16#include "FuzzerInternal.h"
17
18namespace fuzzer {
19static const size_t kMapSize = 65371; // Prime.
20static uint8_t CurMap[kMapSize];
21static uint8_t CombinedMap[kMapSize];
22static size_t CombinedMapSize;
23static thread_local uintptr_t Prev;
24
25void PcMapResetCurrent() {
26 if (Prev) {
27 Prev = 0;
28 memset(CurMap, 0, sizeof(CurMap));
29 }
30}
31
32// TODO: speed this up.
33void PcMapMergeCurrentToCombined() {
34 if (!Prev) return;
35 uintptr_t Res = 0;
36 for (size_t i = 0; i < kMapSize; i++) {
37 uint8_t p = (CombinedMap[i] |= CurMap[i]);
38 CurMap[i] = 0;
39 Res += p != 0;
40 }
41 CombinedMapSize = Res;
42}
43
44size_t PcMapCombinedSize() { return CombinedMapSize; }
45
46static void HandlePC(uintptr_t PC) {
47 // We take 12 bits of PC and mix it with the previous PCs.
48 uintptr_t Idx = (Prev << 5) ^ (PC & 4095);
49 CurMap[Idx % kMapSize] = 1;
50 Prev = Idx;
51}
52
53} // namespace fuzzer
54
55extern "C" void __sanitizer_cov_trace_pc() {
56 fuzzer::HandlePC(reinterpret_cast<uintptr_t>(__builtin_return_address(0)));
57}
58//uintptr_t __sanitizer_get_total_unique_coverage() { return 0; }
59//uintptr_t __sanitizer_get_number_of_counters() { return 0; }