Skip to content

Commit c98ef71

Browse files
committed
[libFuzzer] refactoring around PCMap, NFC
llvm-svn: 278825
1 parent 4893aff commit c98ef71

File tree

5 files changed

+81
-81
lines changed

5 files changed

+81
-81
lines changed

llvm/lib/Fuzzer/FuzzerInternal.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
#include "FuzzerExtFunctions.h"
3030
#include "FuzzerInterface.h"
31-
#include "FuzzerTracePC.h"
31+
#include "FuzzerValueBitMap.h"
3232

3333
// Platform detection.
3434
#ifdef __linux__
@@ -131,6 +131,9 @@ int NumberOfCpuCores();
131131
int GetPid();
132132
void SleepSeconds(int Seconds);
133133

134+
// See FuzzerTracePC.cpp
135+
size_t PCMapMergeFromCurrent(ValueBitMap &M);
136+
134137
class Random {
135138
public:
136139
Random(unsigned int seed) : R(seed) {}
@@ -349,10 +352,10 @@ class Fuzzer {
349352
void Reset() {
350353
BlockCoverage = 0;
351354
CallerCalleeCoverage = 0;
352-
PcMapBits = 0;
353355
CounterBitmapBits = 0;
354356
CounterBitmap.clear();
355357
PCMap.Reset();
358+
PCMapBits = 0;
356359
PcBufferPos = 0;
357360
}
358361

@@ -364,9 +367,8 @@ class Fuzzer {
364367
// Precalculated number of bits in CounterBitmap.
365368
size_t CounterBitmapBits;
366369
std::vector<uint8_t> CounterBitmap;
367-
// Precalculated number of bits in PCMap.
368-
size_t PcMapBits;
369-
PcCoverageMap PCMap;
370+
ValueBitMap PCMap;
371+
size_t PCMapBits;
370372
};
371373

372374
Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options);

llvm/lib/Fuzzer/FuzzerLoop.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static Fuzzer *F;
5656
// Only one CoverageController per process should be created.
5757
class CoverageController {
5858
public:
59-
explicit CoverageController(const FuzzingOptions &Options)
59+
explicit CoverageController(const FuzzingOptions &Options)
6060
: Options(Options) {
6161
if (Options.PrintNewCovPcs) {
6262
PcBufferLen = 1 << 24;
@@ -70,7 +70,6 @@ class CoverageController {
7070
void Reset() {
7171
CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage);
7272
EF->__sanitizer_reset_coverage();
73-
PcMapResetCurrent();
7473
}
7574

7675
void ResetCounters() {
@@ -117,10 +116,10 @@ class CoverageController {
117116
}
118117
}
119118

120-
uint64_t NewPcMapBits = PcMapMergeInto(&C->PCMap);
121-
if (NewPcMapBits > C->PcMapBits) {
119+
size_t NewPCMapBits = PCMapMergeFromCurrent(C->PCMap);
120+
if (NewPCMapBits > C->PCMapBits) {
122121
Res = true;
123-
C->PcMapBits = NewPcMapBits;
122+
C->PCMapBits = NewPCMapBits;
124123
}
125124

126125
if (EF->__sanitizer_get_coverage_pc_buffer_pos) {
@@ -306,8 +305,8 @@ void Fuzzer::PrintStats(const char *Where, const char *End) {
306305
Printf("#%zd\t%s", TotalNumberOfRuns, Where);
307306
if (MaxCoverage.BlockCoverage)
308307
Printf(" cov: %zd", MaxCoverage.BlockCoverage);
309-
if (MaxCoverage.PcMapBits)
310-
Printf(" path: %zd", MaxCoverage.PcMapBits);
308+
if (MaxCoverage.PCMapBits)
309+
Printf(" path: %zd", MaxCoverage.PCMapBits);
311310
if (auto TB = MaxCoverage.CounterBitmapBits)
312311
Printf(" bits: %zd", TB);
313312
if (MaxCoverage.CallerCalleeCoverage)
@@ -522,7 +521,7 @@ std::string Fuzzer::Coverage::DebugString() const {
522521
std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
523522
std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
524523
std::to_string(CounterBitmapBits) + " PcMapBits=" +
525-
std::to_string(PcMapBits) + "}";
524+
std::to_string(PCMapBits) + "}";
526525
return Result;
527526
}
528527

llvm/lib/Fuzzer/FuzzerTracePC.cpp

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,22 @@
1616

1717
namespace fuzzer {
1818

19-
void PcCoverageMap::Reset() { memset(Map, 0, sizeof(Map)); }
19+
static size_t PreviouslyComputedPCHash;
20+
static ValueBitMap CurrentPCMap;
2021

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;
26-
}
27-
28-
size_t PcCoverageMap::MergeFrom(const PcCoverageMap &Other) {
29-
uintptr_t Res = 0;
30-
for (size_t i = 0; i < kMapSizeInWords; i++)
31-
Res += __builtin_popcountl(Map[i] |= Other.Map[i]);
32-
return Res;
33-
}
34-
35-
static PcCoverageMap CurrentMap;
36-
static thread_local uintptr_t Prev;
37-
38-
void PcMapResetCurrent() {
39-
if (Prev) {
40-
Prev = 0;
41-
CurrentMap.Reset();
42-
}
43-
}
44-
45-
size_t PcMapMergeInto(PcCoverageMap *Map) {
46-
if (!Prev)
22+
// Merges CurrentPCMap into M, returns the number of new bits.
23+
size_t PCMapMergeFromCurrent(ValueBitMap &M) {
24+
if (!PreviouslyComputedPCHash)
4725
return 0;
48-
return Map->MergeFrom(CurrentMap);
26+
PreviouslyComputedPCHash = 0;
27+
return M.MergeFrom(CurrentPCMap);
4928
}
5029

5130
static void HandlePC(uint32_t PC) {
5231
// 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);
55-
Prev = Next;
32+
uintptr_t Next = (PreviouslyComputedPCHash << 5) ^ (PC & 4095);
33+
CurrentPCMap.AddValue(Next);
34+
PreviouslyComputedPCHash = Next;
5635
}
5736

5837
} // namespace fuzzer

llvm/lib/Fuzzer/FuzzerTracePC.h

Lines changed: 0 additions & 37 deletions
This file was deleted.

llvm/lib/Fuzzer/FuzzerValueBitMap.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===- FuzzerValueBitMap.h - INTERNAL - Bit map -----------------*- C++ -* ===//
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+
// ValueBitMap.
10+
//===----------------------------------------------------------------------===//
11+
12+
#ifndef LLVM_FUZZER_VALUE_BIT_MAP_H
13+
#define LLVM_FUZZER_VALUE_BIT_MAP_H
14+
15+
namespace fuzzer {
16+
17+
// A bit map containing kMapSizeInWords bits.
18+
struct ValueBitMap {
19+
static const size_t kMapSizeInBits = 65371; // Prime.
20+
static const size_t kMapSizeInBitsAligned = 65536; // 2^16
21+
static const size_t kBitsInWord = (sizeof(uintptr_t) * 8);
22+
static const size_t kMapSizeInWords = kMapSizeInBitsAligned / kBitsInWord;
23+
public:
24+
// Clears all bits.
25+
void Reset() { memset(Map, 0, sizeof(Map)); }
26+
27+
// Computed a hash function of Value and sets the corresponding bit.
28+
void AddValue(uintptr_t Value) {
29+
uintptr_t Idx = Value % kMapSizeInBits;
30+
uintptr_t WordIdx = Idx / kBitsInWord;
31+
uintptr_t BitIdx = Idx % kBitsInWord;
32+
Map[WordIdx] |= 1UL << BitIdx;
33+
}
34+
35+
// Merges 'Other' into 'this', clear Other,
36+
// returns the number of set bits in 'this'.
37+
size_t MergeFrom(ValueBitMap &Other) {
38+
uintptr_t Res = 0;
39+
for (size_t i = 0; i < kMapSizeInWords; i++) {
40+
auto O = Other.Map[i];
41+
auto M = Map[i];
42+
if (O) {
43+
Map[i] = (M |= O);
44+
Other.Map[i] = 0;
45+
}
46+
Res += __builtin_popcountl(M);
47+
}
48+
return Res;
49+
}
50+
51+
private:
52+
uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512)));
53+
};
54+
55+
} // namespace fuzzer
56+
57+
#endif // LLVM_FUZZER_VALUE_BIT_MAP_H

0 commit comments

Comments
 (0)