LLVM  4.0.0
FuzzerTracePC.h
Go to the documentation of this file.
1 //===- FuzzerTracePC.h - Internal header for the Fuzzer ---------*- 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 // fuzzer::TracePC
10 //===----------------------------------------------------------------------===//
11 
12 #ifndef LLVM_FUZZER_TRACE_PC
13 #define LLVM_FUZZER_TRACE_PC
14 
15 #include "FuzzerDefs.h"
16 #include "FuzzerValueBitMap.h"
17 #include <set>
18 
19 namespace fuzzer {
20 
21 // TableOfRecentCompares (TORC) remembers the most recently performed
22 // comparisons of type T.
23 // We record the arguments of CMP instructions in this table unconditionally
24 // because it seems cheaper this way than to compute some expensive
25 // conditions inside __sanitizer_cov_trace_cmp*.
26 // After the unit has been executed we may decide to use the contents of
27 // this table to populate a Dictionary.
28 template<class T, size_t kSizeT>
30  static const size_t kSize = kSizeT;
31  struct Pair {
32  T A, B;
33  };
34  void Insert(size_t Idx, T Arg1, T Arg2) {
35  Idx = Idx % kSize;
36  Table[Idx].A = Arg1;
37  Table[Idx].B = Arg2;
38  }
39 
40  Pair Get(size_t I) { return Table[I % kSize]; }
41 
42  Pair Table[kSize];
43 };
44 
45 class TracePC {
46  public:
48 
49  void HandleTrace(uint32_t *guard, uintptr_t PC);
50  void HandleInit(uint32_t *start, uint32_t *stop);
51  void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
52  void HandleValueProfile(size_t Value) { ValueProfileMap.AddValue(Value); }
53  template <class T> void HandleCmp(void *PC, T Arg1, T Arg2);
54  size_t GetTotalPCCoverage();
55  void SetUseCounters(bool UC) { UseCounters = UC; }
56  void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
57  void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }
58  template <class Callback> size_t CollectFeatures(Callback CB);
59  bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {
60  return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap);
61  }
62 
63  void ResetMaps() {
64  ValueProfileMap.Reset();
65  memset(Counters, 0, sizeof(Counters));
66  }
67 
68  void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize);
69  void PrintFeatureSet();
70 
71  void PrintModuleInfo();
72 
73  void PrintCoverage();
74  void DumpCoverage();
75 
76  void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
77  size_t n);
78  void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,
79  size_t n);
80 
81  bool UsingTracePcGuard() const {return NumModules; }
82 
83  static const size_t kTORCSize = 1 << 5;
86 
87  void PrintNewPCs();
88  void InitializePrintNewPCs();
89  size_t GetNumPCs() const { return Min(kNumPCs, NumGuards + 1); }
90  uintptr_t GetPC(size_t Idx) {
91  assert(Idx < GetNumPCs());
92  return PCs[Idx];
93  }
94 
95 private:
96  bool UseCounters = false;
97  bool UseValueProfile = false;
98  bool DoPrintNewPCs = false;
99 
100  struct Module {
101  uint32_t *Start, *Stop;
102  };
103 
104  Module Modules[4096];
105  size_t NumModules; // linker-initialized.
106  size_t NumGuards; // linker-initialized.
107 
108  static const size_t kNumCounters = 1 << 14;
109  alignas(8) uint8_t Counters[kNumCounters];
110 
111  static const size_t kNumPCs = 1 << 24;
112  uintptr_t PCs[kNumPCs];
113 
114  std::set<uintptr_t> *PrintedPCs;
115 
116  ValueBitMap ValueProfileMap;
117 };
118 
119 template <class Callback>
120 size_t TracePC::CollectFeatures(Callback CB) {
121  if (!UsingTracePcGuard()) return 0;
122  size_t Res = 0;
123  const size_t Step = 8;
124  assert(reinterpret_cast<uintptr_t>(Counters) % Step == 0);
125  size_t N = Min(kNumCounters, NumGuards + 1);
126  N = (N + Step - 1) & ~(Step - 1); // Round up.
127  for (size_t Idx = 0; Idx < N; Idx += Step) {
128  uint64_t Bundle = *reinterpret_cast<uint64_t*>(&Counters[Idx]);
129  if (!Bundle) continue;
130  for (size_t i = Idx; i < Idx + Step; i++) {
131  uint8_t Counter = (Bundle >> ((i - Idx) * 8)) & 0xff;
132  if (!Counter) continue;
133  Counters[i] = 0;
134  unsigned Bit = 0;
135  /**/ if (Counter >= 128) Bit = 7;
136  else if (Counter >= 32) Bit = 6;
137  else if (Counter >= 16) Bit = 5;
138  else if (Counter >= 8) Bit = 4;
139  else if (Counter >= 4) Bit = 3;
140  else if (Counter >= 3) Bit = 2;
141  else if (Counter >= 2) Bit = 1;
142  size_t Feature = (i * 8 + Bit);
143  if (CB(Feature))
144  Res++;
145  }
146  }
147  if (UseValueProfile)
148  ValueProfileMap.ForEach([&](size_t Idx) {
149  if (CB(NumGuards * 8 + Idx))
150  Res++;
151  });
152  return Res;
153 }
154 
155 extern TracePC TPC;
156 
157 } // namespace fuzzer
158 
159 #endif // LLVM_FUZZER_TRACE_PC
void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2, size_t n)
void SetPrintNewPCs(bool P)
Definition: FuzzerTracePC.h:57
TableOfRecentCompares< uint32_t, kTORCSize > TORC4
Definition: FuzzerTracePC.h:84
size_t i
void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2, size_t n)
static int Counter
void ForEach(Callback CB)
void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee)
void HandleTrace(uint32_t *guard, uintptr_t PC)
static const size_t kSize
Definition: FuzzerTracePC.h:30
uintptr_t GetPC(size_t Idx)
Definition: FuzzerTracePC.h:90
bool AddValue(uintptr_t Value)
static const size_t kNumberOfItems
TracePC TPC
T Min(T a, T b)
Definition: FuzzerDefs.h:56
#define P(N)
void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize)
bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap)
Definition: FuzzerTracePC.h:59
void HandleValueProfile(size_t Value)
Definition: FuzzerTracePC.h:52
size_t GetTotalPCCoverage()
void HandleCmp(void *PC, T Arg1, T Arg2)
void SetUseCounters(bool UC)
Definition: FuzzerTracePC.h:55
void HandleInit(uint32_t *start, uint32_t *stop)
void PrintFeatureSet()
void Insert(size_t Idx, T Arg1, T Arg2)
Definition: FuzzerTracePC.h:34
size_t GetNumPCs() const
Definition: FuzzerTracePC.h:89
static const size_t kFeatureSetSize
Definition: FuzzerTracePC.h:47
bool UsingTracePcGuard() const
Definition: FuzzerTracePC.h:81
void InitializePrintNewPCs()
TableOfRecentCompares< uint64_t, kTORCSize > TORC8
Definition: FuzzerTracePC.h:85
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
uint64_t Arg2
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void SetUseValueProfile(bool VP)
Definition: FuzzerTracePC.h:56
ATTRIBUTE_TARGET_POPCNT bool MergeFrom(ValueBitMap &Other)
size_t CollectFeatures(Callback CB)
static const size_t kTORCSize
Definition: FuzzerTracePC.h:83
char * PC