1 //===- FuzzerTracePC.cpp - PC tracing--------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This module implements __sanitizer_cov_trace_pc, a callback required
11 // for -fsanitize-coverage=trace-pc instrumentation.
13 //===----------------------------------------------------------------------===//
15 #include "FuzzerInternal.h"
19 void PcCoverageMap::Reset() { memset(Map, 0, sizeof(Map)); }
21 void PcCoverageMap::Update(uintptr_t Addr) {
22 uintptr_t Idx = Addr % kMapSizeInBits;
23 uintptr_t WordIdx = Idx / kBitsInWord;
24 uintptr_t BitIdx = Idx % kBitsInWord;
25 Map[WordIdx] |= 1UL << BitIdx;
28 size_t PcCoverageMap::MergeFrom(const PcCoverageMap &Other) {
30 for (size_t i = 0; i < kMapSizeInWords; i++)
31 Res += __builtin_popcountl(Map[i] |= Other.Map[i]);
35 static PcCoverageMap CurrentMap;
36 static thread_local uintptr_t Prev;
38 void PcMapResetCurrent() {
45 size_t PcMapMergeInto(PcCoverageMap *Map) {
48 return Map->MergeFrom(CurrentMap);
51 static void HandlePC(uint32_t PC) {
52 // We take 12 bits of PC and mix it with the previous PCs.
53 uintptr_t Next = (Prev << 5) ^ (PC & 4095);
54 CurrentMap.Update(Next);
61 void __sanitizer_cov_trace_pc() {
62 fuzzer::HandlePC(static_cast<uint32_t>(
63 reinterpret_cast<uintptr_t>(__builtin_return_address(0))));
66 void __sanitizer_cov_trace_pc_indir(int *) {
67 // Stub to allow linking with code built with
68 // -fsanitize=indirect-calls,trace-pc.
69 // This isn't used currently.