LLVM  4.0.0
FuzzerMutate.cpp
Go to the documentation of this file.
1 //===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//
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 // Mutate a test input.
10 //===----------------------------------------------------------------------===//
11 
12 #include "FuzzerCorpus.h"
13 #include "FuzzerDefs.h"
14 #include "FuzzerExtFunctions.h"
15 #include "FuzzerIO.h"
16 #include "FuzzerMutate.h"
17 #include "FuzzerOptions.h"
18 
19 namespace fuzzer {
20 
21 const size_t Dictionary::kMaxDictSize;
22 
23 static void PrintASCII(const Word &W, const char *PrintAfter) {
24  PrintASCII(W.data(), W.size(), PrintAfter);
25 }
26 
28  const FuzzingOptions &Options)
29  : Rand(Rand), Options(Options) {
30  DefaultMutators.insert(
31  DefaultMutators.begin(),
32  {
36  "InsertRepeatedBytes"},
39  {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
45  "ManualDict"},
47  "TempAutoDict"},
49  "PersAutoDict"},
50  });
51  if(Options.UseCmp)
52  DefaultMutators.push_back(
54 
55  if (EF->LLVMFuzzerCustomMutator)
56  Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
57  else
58  Mutators = DefaultMutators;
59 
60  if (EF->LLVMFuzzerCustomCrossOver)
61  Mutators.push_back(
62  {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
63 }
64 
65 static char RandCh(Random &Rand) {
66  if (Rand.RandBool()) return Rand(256);
67  const char *Special = "!*'();:@&=+$,/?%#[]012Az-`~.\xff\x00";
68  return Special[Rand(sizeof(Special) - 1)];
69 }
70 
71 size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
72  size_t MaxSize) {
73  return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
74 }
75 
76 size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
77  size_t MaxSize) {
78  if (!Corpus || Corpus->size() < 2 || Size == 0)
79  return 0;
80  size_t Idx = Rand(Corpus->size());
81  const Unit &Other = (*Corpus)[Idx];
82  if (Other.empty())
83  return 0;
84  MutateInPlaceHere.resize(MaxSize);
85  auto &U = MutateInPlaceHere;
86  size_t NewSize = EF->LLVMFuzzerCustomCrossOver(
87  Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand());
88  if (!NewSize)
89  return 0;
90  assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit");
91  memcpy(Data, U.data(), NewSize);
92  return NewSize;
93 }
94 
95 size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
96  size_t MaxSize) {
97  if (Size > MaxSize) return 0;
98  assert(Size);
99  size_t ShuffleAmount =
100  Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.
101  size_t ShuffleStart = Rand(Size - ShuffleAmount);
102  assert(ShuffleStart + ShuffleAmount <= Size);
103  std::random_shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount,
104  Rand);
105  return Size;
106 }
107 
108 size_t MutationDispatcher::Mutate_EraseBytes(uint8_t *Data, size_t Size,
109  size_t MaxSize) {
110  assert(Size);
111  if (Size == 1) return 0;
112  size_t N = Rand(Size / 2) + 1;
113  assert(N < Size);
114  size_t Idx = Rand(Size - N + 1);
115  // Erase Data[Idx:Idx+N].
116  memmove(Data + Idx, Data + Idx + N, Size - Idx - N);
117  // Printf("Erase: %zd %zd => %zd; Idx %zd\n", N, Size, Size - N, Idx);
118  return Size - N;
119 }
120 
121 size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
122  size_t MaxSize) {
123  if (Size >= MaxSize) return 0;
124  size_t Idx = Rand(Size + 1);
125  // Insert new value at Data[Idx].
126  memmove(Data + Idx + 1, Data + Idx, Size - Idx);
127  Data[Idx] = RandCh(Rand);
128  return Size + 1;
129 }
130 
132  size_t Size,
133  size_t MaxSize) {
134  const size_t kMinBytesToInsert = 3;
135  if (Size + kMinBytesToInsert >= MaxSize) return 0;
136  size_t MaxBytesToInsert = std::min(MaxSize - Size, (size_t)128);
137  size_t N = Rand(MaxBytesToInsert - kMinBytesToInsert + 1) + kMinBytesToInsert;
138  assert(Size + N <= MaxSize && N);
139  size_t Idx = Rand(Size + 1);
140  // Insert new values at Data[Idx].
141  memmove(Data + Idx + N, Data + Idx, Size - Idx);
142  // Give preference to 0x00 and 0xff.
143  uint8_t Byte = Rand.RandBool() ? Rand(256) : (Rand.RandBool() ? 0 : 255);
144  for (size_t i = 0; i < N; i++)
145  Data[Idx + i] = Byte;
146  return Size + N;
147 }
148 
149 size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
150  size_t MaxSize) {
151  if (Size > MaxSize) return 0;
152  size_t Idx = Rand(Size);
153  Data[Idx] = RandCh(Rand);
154  return Size;
155 }
156 
157 size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
158  size_t MaxSize) {
159  if (Size > MaxSize) return 0;
160  size_t Idx = Rand(Size);
161  Data[Idx] ^= 1 << Rand(8);
162  return Size;
163 }
164 
166  size_t Size,
167  size_t MaxSize) {
168  return AddWordFromDictionary(ManualDictionary, Data, Size, MaxSize);
169 }
170 
172  uint8_t *Data, size_t Size, size_t MaxSize) {
173  return AddWordFromDictionary(TempAutoDictionary, Data, Size, MaxSize);
174 }
175 
176 size_t MutationDispatcher::ApplyDictionaryEntry(uint8_t *Data, size_t Size,
177  size_t MaxSize,
178  DictionaryEntry &DE) {
179  const Word &W = DE.GetW();
180  bool UsePositionHint = DE.HasPositionHint() &&
181  DE.GetPositionHint() + W.size() < Size &&
182  Rand.RandBool();
183  if (Rand.RandBool()) { // Insert W.
184  if (Size + W.size() > MaxSize) return 0;
185  size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size + 1);
186  memmove(Data + Idx + W.size(), Data + Idx, Size - Idx);
187  memcpy(Data + Idx, W.data(), W.size());
188  Size += W.size();
189  } else { // Overwrite some bytes with W.
190  if (W.size() > Size) return 0;
191  size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size - W.size());
192  memcpy(Data + Idx, W.data(), W.size());
193  }
194  return Size;
195 }
196 
197 // Somewhere in the past we have observed a comparison instructions
198 // with arguments Arg1 Arg2. This function tries to guess a dictionary
199 // entry that will satisfy that comparison.
200 // It first tries to find one of the arguments (possibly swapped) in the
201 // input and if it succeeds it creates a DE with a position hint.
202 // Otherwise it creates a DE with one of the arguments w/o a position hint.
203 template <class T>
204 DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
205  T Arg1, T Arg2, const uint8_t *Data, size_t Size) {
206  ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;
207  bool HandleFirst = Rand.RandBool();
208  T ExistingBytes, DesiredBytes;
209  Word W;
210  const uint8_t *End = Data + Size;
211  for (int Arg = 0; Arg < 2; Arg++) {
212  ExistingBytes = HandleFirst ? Arg1 : Arg2;
213  DesiredBytes = HandleFirst ? Arg2 : Arg1;
214  DesiredBytes += Rand(-1, 1);
215  if (Rand.RandBool()) ExistingBytes = Bswap(ExistingBytes);
216  if (Rand.RandBool()) DesiredBytes = Bswap(DesiredBytes);
217  HandleFirst = !HandleFirst;
218  W.Set(reinterpret_cast<uint8_t*>(&DesiredBytes), sizeof(T));
219  const size_t kMaxNumPositions = 8;
220  size_t Positions[kMaxNumPositions];
221  size_t NumPositions = 0;
222  for (const uint8_t *Cur = Data;
223  Cur < End && NumPositions < kMaxNumPositions; Cur++) {
224  Cur = (uint8_t *)SearchMemory(Cur, End - Cur, &ExistingBytes, sizeof(T));
225  if (!Cur) break;
226  Positions[NumPositions++] = Cur - Data;
227  }
228  if (!NumPositions) break;
229  return DictionaryEntry(W, Positions[Rand(NumPositions)]);
230  }
231  DictionaryEntry DE(W);
232  return DE;
233 }
234 
236  uint8_t *Data, size_t Size, size_t MaxSize) {
237  Word W;
238  DictionaryEntry DE;
239  if (Rand.RandBool()) {
240  auto X = TPC.TORC8.Get(Rand.Rand());
241  DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
242  } else {
243  auto X = TPC.TORC4.Get(Rand.Rand());
244  if ((X.A >> 16) == 0 && (X.B >> 16) == 0 && Rand.RandBool())
245  DE = MakeDictionaryEntryFromCMP((uint16_t)X.A, (uint16_t)X.B, Data,
246  Size);
247  else
248  DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
249  }
250  Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
251  if (!Size) return 0;
252  DictionaryEntry &DERef =
253  CmpDictionaryEntriesDeque[CmpDictionaryEntriesDequeIdx++ %
254  kCmpDictionaryEntriesDequeSize];
255  DERef = DE;
256  CurrentDictionaryEntrySequence.push_back(&DERef);
257  return Size;
258 }
259 
261  uint8_t *Data, size_t Size, size_t MaxSize) {
262  return AddWordFromDictionary(PersistentAutoDictionary, Data, Size, MaxSize);
263 }
264 
265 size_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,
266  size_t Size, size_t MaxSize) {
267  if (Size > MaxSize) return 0;
268  if (D.empty()) return 0;
269  DictionaryEntry &DE = D[Rand(D.size())];
270  Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
271  if (!Size) return 0;
272  DE.IncUseCount();
273  CurrentDictionaryEntrySequence.push_back(&DE);
274  return Size;
275 }
276 
277 // Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
278 // Returns ToSize.
279 size_t MutationDispatcher::CopyPartOf(const uint8_t *From, size_t FromSize,
280  uint8_t *To, size_t ToSize) {
281  // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).
282  size_t ToBeg = Rand(ToSize);
283  size_t CopySize = Rand(ToSize - ToBeg) + 1;
284  assert(ToBeg + CopySize <= ToSize);
285  CopySize = std::min(CopySize, FromSize);
286  size_t FromBeg = Rand(FromSize - CopySize + 1);
287  assert(FromBeg + CopySize <= FromSize);
288  memmove(To + ToBeg, From + FromBeg, CopySize);
289  return ToSize;
290 }
291 
292 // Inserts part of From[0,ToSize) into To.
293 // Returns new size of To on success or 0 on failure.
294 size_t MutationDispatcher::InsertPartOf(const uint8_t *From, size_t FromSize,
295  uint8_t *To, size_t ToSize,
296  size_t MaxToSize) {
297  if (ToSize >= MaxToSize) return 0;
298  size_t AvailableSpace = MaxToSize - ToSize;
299  size_t MaxCopySize = std::min(AvailableSpace, FromSize);
300  size_t CopySize = Rand(MaxCopySize) + 1;
301  size_t FromBeg = Rand(FromSize - CopySize + 1);
302  assert(FromBeg + CopySize <= FromSize);
303  size_t ToInsertPos = Rand(ToSize + 1);
304  assert(ToInsertPos + CopySize <= MaxToSize);
305  size_t TailSize = ToSize - ToInsertPos;
306  if (To == From) {
307  MutateInPlaceHere.resize(MaxToSize);
308  memcpy(MutateInPlaceHere.data(), From + FromBeg, CopySize);
309  memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
310  memmove(To + ToInsertPos, MutateInPlaceHere.data(), CopySize);
311  } else {
312  memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
313  memmove(To + ToInsertPos, From + FromBeg, CopySize);
314  }
315  return ToSize + CopySize;
316 }
317 
318 size_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data, size_t Size,
319  size_t MaxSize) {
320  if (Size > MaxSize) return 0;
321  if (Rand.RandBool())
322  return CopyPartOf(Data, Size, Data, Size);
323  else
324  return InsertPartOf(Data, Size, Data, Size, MaxSize);
325 }
326 
327 size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
328  size_t MaxSize) {
329  if (Size > MaxSize) return 0;
330  size_t B = Rand(Size);
331  while (B < Size && !isdigit(Data[B])) B++;
332  if (B == Size) return 0;
333  size_t E = B;
334  while (E < Size && isdigit(Data[E])) E++;
335  assert(B < E);
336  // now we have digits in [B, E).
337  // strtol and friends don't accept non-zero-teminated data, parse it manually.
338  uint64_t Val = Data[B] - '0';
339  for (size_t i = B + 1; i < E; i++)
340  Val = Val * 10 + Data[i] - '0';
341 
342  // Mutate the integer value.
343  switch(Rand(5)) {
344  case 0: Val++; break;
345  case 1: Val--; break;
346  case 2: Val /= 2; break;
347  case 3: Val *= 2; break;
348  case 4: Val = Rand(Val * Val); break;
349  default: assert(0);
350  }
351  // Just replace the bytes with the new ones, don't bother moving bytes.
352  for (size_t i = B; i < E; i++) {
353  size_t Idx = E + B - i - 1;
354  assert(Idx >= B && Idx < E);
355  Data[Idx] = (Val % 10) + '0';
356  Val /= 10;
357  }
358  return Size;
359 }
360 
361 template<class T>
362 size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) {
363  if (Size < sizeof(T)) return 0;
364  size_t Off = Rand(Size - sizeof(T) + 1);
365  assert(Off + sizeof(T) <= Size);
366  T Val;
367  if (Off < 64 && !Rand(4)) {
368  Val = Size;
369  if (Rand.RandBool())
370  Val = Bswap(Val);
371  } else {
372  memcpy(&Val, Data + Off, sizeof(Val));
373  T Add = Rand(21);
374  Add -= 10;
375  if (Rand.RandBool())
376  Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes.
377  else
378  Val = Val + Add; // Add assuming current endiannes.
379  if (Add == 0 || Rand.RandBool()) // Maybe negate.
380  Val = -Val;
381  }
382  memcpy(Data + Off, &Val, sizeof(Val));
383  return Size;
384 }
385 
387  size_t Size,
388  size_t MaxSize) {
389  if (Size > MaxSize) return 0;
390  switch (Rand(4)) {
391  case 3: return ChangeBinaryInteger<uint64_t>(Data, Size, Rand);
392  case 2: return ChangeBinaryInteger<uint32_t>(Data, Size, Rand);
393  case 1: return ChangeBinaryInteger<uint16_t>(Data, Size, Rand);
394  case 0: return ChangeBinaryInteger<uint8_t>(Data, Size, Rand);
395  default: assert(0);
396  }
397  return 0;
398 }
399 
400 size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
401  size_t MaxSize) {
402  if (Size > MaxSize) return 0;
403  if (!Corpus || Corpus->size() < 2 || Size == 0) return 0;
404  size_t Idx = Rand(Corpus->size());
405  const Unit &O = (*Corpus)[Idx];
406  if (O.empty()) return 0;
407  MutateInPlaceHere.resize(MaxSize);
408  auto &U = MutateInPlaceHere;
409  size_t NewSize = 0;
410  switch(Rand(3)) {
411  case 0:
412  NewSize = CrossOver(Data, Size, O.data(), O.size(), U.data(), U.size());
413  break;
414  case 1:
415  NewSize = InsertPartOf(O.data(), O.size(), U.data(), U.size(), MaxSize);
416  if (NewSize)
417  break;
418  // LLVM_FALLTHROUGH;
419  case 2:
420  NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size());
421  break;
422  default: assert(0);
423  }
424  assert(NewSize > 0 && "CrossOver returned empty unit");
425  assert(NewSize <= MaxSize && "CrossOver returned overisized unit");
426  memcpy(Data, U.data(), NewSize);
427  return NewSize;
428 }
429 
431  CurrentMutatorSequence.clear();
432  CurrentDictionaryEntrySequence.clear();
433 }
434 
435 // Copy successful dictionary entries to PersistentAutoDictionary.
437  for (auto DE : CurrentDictionaryEntrySequence) {
438  // PersistentAutoDictionary.AddWithSuccessCountOne(DE);
439  DE->IncSuccessCount();
440  // Linear search is fine here as this happens seldom.
441  if (!PersistentAutoDictionary.ContainsWord(DE->GetW()))
442  PersistentAutoDictionary.push_back({DE->GetW(), 1});
443  }
444 }
445 
447  std::vector<DictionaryEntry> V;
448  for (auto &DE : PersistentAutoDictionary)
449  if (!ManualDictionary.ContainsWord(DE.GetW()))
450  V.push_back(DE);
451  if (V.empty()) return;
452  Printf("###### Recommended dictionary. ######\n");
453  for (auto &DE: V) {
454  Printf("\"");
455  PrintASCII(DE.GetW(), "\"");
456  Printf(" # Uses: %zd\n", DE.GetUseCount());
457  }
458  Printf("###### End of recommended dictionary. ######\n");
459 }
460 
462  Printf("MS: %zd ", CurrentMutatorSequence.size());
463  for (auto M : CurrentMutatorSequence)
464  Printf("%s-", M.Name);
465  if (!CurrentDictionaryEntrySequence.empty()) {
466  Printf(" DE: ");
467  for (auto DE : CurrentDictionaryEntrySequence) {
468  Printf("\"");
469  PrintASCII(DE->GetW(), "\"-");
470  }
471  }
472 }
473 
474 size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
475  return MutateImpl(Data, Size, MaxSize, Mutators);
476 }
477 
478 size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
479  size_t MaxSize) {
480  return MutateImpl(Data, Size, MaxSize, DefaultMutators);
481 }
482 
483 // Mutates Data in place, returns new size.
484 size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
485  size_t MaxSize,
486  const std::vector<Mutator> &Mutators) {
487  assert(MaxSize > 0);
488  if (Size == 0) {
489  for (size_t i = 0; i < Min(size_t(4), MaxSize); i++)
490  Data[i] = RandCh(Rand);
491  if (Options.OnlyASCII)
492  ToASCII(Data, MaxSize);
493  return MaxSize;
494  }
495  assert(Size > 0);
496  // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),
497  // in which case they will return 0.
498  // Try several times before returning un-mutated data.
499  for (int Iter = 0; Iter < 100; Iter++) {
500  auto M = Mutators[Rand(Mutators.size())];
501  size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
502  if (NewSize && NewSize <= MaxSize) {
503  if (Options.OnlyASCII)
504  ToASCII(Data, NewSize);
505  CurrentMutatorSequence.push_back(M);
506  return NewSize;
507  }
508  }
509  return std::min(Size, MaxSize);
510 }
511 
513  ManualDictionary.push_back(
514  {W, std::numeric_limits<size_t>::max()});
515 }
516 
518  static const size_t kMaxAutoDictSize = 1 << 14;
519  if (TempAutoDictionary.size() >= kMaxAutoDictSize) return;
520  TempAutoDictionary.push_back(DE);
521 }
522 
524  TempAutoDictionary.clear();
525 }
526 
527 } // namespace fuzzer
static char RandCh(Random &Rand)
size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by inserting a byte.
size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by invoking user-provided mutator.
const uint8_t * data() const
TableOfRecentCompares< uint32_t, kTORCSize > TORC4
Definition: FuzzerTracePC.h:84
size_t size() const
size_t i
void StartMutationSequence()
Indicate that we are about to start a new sequence of mutations.
size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize)
Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.
size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize)
CrossOver Data with some other element of the corpus.
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize)
Applies one of the configured mutations.
size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2, size_t Size2, uint8_t *Out, size_t MaxOutSize)
Creates a cross-over of two pieces of Data, returns its size.
ExternalFunctions * EF
size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize)
Applies one of the default mutations.
size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by adding a word from the manual dictionary.
uint8_t size() const
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
FixedWord< 27 > Word
void PrintMutationSequence()
Print the current sequence of mutations.
void RecordSuccessfulMutationSequence()
Indicate that the current sequence of mutations was successfull.
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:662
void AddWordToAutoDictionary(DictionaryEntry DE)
MutationDispatcher(Random &Rand, const FuzzingOptions &Options)
size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by chanding one bit.
#define T
size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by invoking user-provided crossover.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
uint8_t Bswap(uint8_t x)
Definition: FuzzerDefs.h:82
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
TracePC TPC
void Printf(const char *Fmt,...)
Definition: FuzzerIO.cpp:109
T Min(T a, T b)
Definition: FuzzerDefs.h:56
static PassOptionList PrintAfter("print-after", llvm::cl::desc("Print IR after specified passes"), cl::Hidden)
size_t Mutate_AddWordFromTemporaryAutoDictionary(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by adding a word from the temporary automatic dictionary.
bool HasPositionHint() const
size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by inserting several repeated bytes.
void AddWordToManualDictionary(const Word &W)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by adding a word from the persistent automatic dictionary.
static const unsigned End
void push_back(DictionaryEntry DE)
size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by copying/inserting a part of data into a different place.
size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize)
Tries to find an ASCII integer in Data, changes it to another ASCII int.
size_t size() const
Definition: FuzzerCorpus.h:50
size_t RandBool()
Definition: FuzzerRandom.h:22
bool ToASCII(uint8_t *Data, size_t Size)
Definition: FuzzerUtil.cpp:59
size_t Rand()
Definition: FuzzerRandom.h:21
bool ContainsWord(const Word &W) const
const void * SearchMemory(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
size_t GetUseCount() const
TableOfRecentCompares< uint64_t, kTORCSize > TORC8
Definition: FuzzerTracePC.h:85
size_t GetPositionHint() const
#define N
size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by chanding one byte.
uint64_t Arg2
static const size_t kMaxDictSize
std::vector< uint8_t > Unit
Definition: FuzzerDefs.h:71
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand)
const Word & GetW() const
size_t Mutate_AddWordFromTORC(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by adding a word from the TORC.
size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by erasing bytes.
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize)
Mutates data by shuffling bytes.
static void PrintASCII(const Word &W, const char *PrintAfter)