1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00
llvm-mirror/lib/Fuzzer/FuzzerTracePC.cpp
Dan Liew 8d4b0fab3b [LibFuzzer] Provide stub implementation of __sanitizer_cov_trace_pc_indir
Calls to this function are currently injected by the
``SanitizerCoverageModule`` pass when the both the ``indirect-calls``
and ``trace-pc`` sanitizer coverage options are enabled and the code
being instrumented has indirect calls. Previously because LibFuzzer did
not define this function this would lead to link errors when building
some of the tests on OSX.

Differential Revision: http://reviews.llvm.org/D20946

llvm-svn: 271938
2016-06-06 20:27:09 +00:00

72 lines
1.8 KiB
C++

//===- FuzzerTracePC.cpp - PC tracing--------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Trace PCs.
// This module implements __sanitizer_cov_trace_pc, a callback required
// for -fsanitize-coverage=trace-pc instrumentation.
//
//===----------------------------------------------------------------------===//
#include "FuzzerInternal.h"
namespace fuzzer {
void PcCoverageMap::Reset() { memset(Map, 0, sizeof(Map)); }
void PcCoverageMap::Update(uintptr_t Addr) {
uintptr_t Idx = Addr % kMapSizeInBits;
uintptr_t WordIdx = Idx / kBitsInWord;
uintptr_t BitIdx = Idx % kBitsInWord;
Map[WordIdx] |= 1UL << BitIdx;
}
size_t PcCoverageMap::MergeFrom(const PcCoverageMap &Other) {
uintptr_t Res = 0;
for (size_t i = 0; i < kMapSizeInWords; i++)
Res += __builtin_popcountl(Map[i] |= Other.Map[i]);
return Res;
}
static PcCoverageMap CurrentMap;
static thread_local uintptr_t Prev;
void PcMapResetCurrent() {
if (Prev) {
Prev = 0;
CurrentMap.Reset();
}
}
size_t PcMapMergeInto(PcCoverageMap *Map) {
if (!Prev)
return 0;
return Map->MergeFrom(CurrentMap);
}
static void HandlePC(uint32_t PC) {
// We take 12 bits of PC and mix it with the previous PCs.
uintptr_t Next = (Prev << 5) ^ (PC & 4095);
CurrentMap.Update(Next);
Prev = Next;
}
} // namespace fuzzer
extern "C" {
void __sanitizer_cov_trace_pc() {
fuzzer::HandlePC(static_cast<uint32_t>(
reinterpret_cast<uintptr_t>(__builtin_return_address(0))));
}
void __sanitizer_cov_trace_pc_indir(int *) {
// Stub to allow linking with code built with
// -fsanitize=indirect-calls,trace-pc.
// This isn't used currently.
}
}