blob: 0d9d91bcd2f15b3a112be8645a2d4a6c13860db3 [file] [log] [blame]
George Karpenkov10ab2ac2017-08-21 23:25:50 +00001//===- FuzzerDictionary.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::Dictionary
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_FUZZER_DICTIONARY_H
13#define LLVM_FUZZER_DICTIONARY_H
14
15#include "FuzzerDefs.h"
16#include "FuzzerIO.h"
17#include "FuzzerUtil.h"
18#include <algorithm>
19#include <limits>
20
21namespace fuzzer {
22// A simple POD sized array of bytes.
23template <size_t kMaxSizeT> class FixedWord {
24public:
25 static const size_t kMaxSize = kMaxSizeT;
26 FixedWord() {}
27 FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); }
28
29 void Set(const uint8_t *B, uint8_t S) {
30 assert(S <= kMaxSize);
31 memcpy(Data, B, S);
32 Size = S;
33 }
34
35 bool operator==(const FixedWord<kMaxSize> &w) const {
George Karpenkov10ab2ac2017-08-21 23:25:50 +000036 return Size == w.Size && 0 == memcmp(Data, w.Data, Size);
37 }
38
George Karpenkov10ab2ac2017-08-21 23:25:50 +000039 static size_t GetMaxSize() { return kMaxSize; }
40 const uint8_t *data() const { return Data; }
41 uint8_t size() const { return Size; }
42
43private:
44 uint8_t Size = 0;
45 uint8_t Data[kMaxSize];
46};
47
48typedef FixedWord<64> Word;
49
50class DictionaryEntry {
51 public:
52 DictionaryEntry() {}
53 DictionaryEntry(Word W) : W(W) {}
54 DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
55 const Word &GetW() const { return W; }
56
57 bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); }
58 size_t GetPositionHint() const {
59 assert(HasPositionHint());
60 return PositionHint;
61 }
62 void IncUseCount() { UseCount++; }
63 void IncSuccessCount() { SuccessCount++; }
64 size_t GetUseCount() const { return UseCount; }
65 size_t GetSuccessCount() const {return SuccessCount; }
66
67 void Print(const char *PrintAfter = "\n") {
68 PrintASCII(W.data(), W.size());
69 if (HasPositionHint())
70 Printf("@%zd", GetPositionHint());
71 Printf("%s", PrintAfter);
72 }
73
74private:
75 Word W;
76 size_t PositionHint = std::numeric_limits<size_t>::max();
77 size_t UseCount = 0;
78 size_t SuccessCount = 0;
79};
80
81class Dictionary {
82 public:
83 static const size_t kMaxDictSize = 1 << 14;
84
85 bool ContainsWord(const Word &W) const {
86 return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {
87 return DE.GetW() == W;
88 });
89 }
90 const DictionaryEntry *begin() const { return &DE[0]; }
91 const DictionaryEntry *end() const { return begin() + Size; }
92 DictionaryEntry & operator[] (size_t Idx) {
93 assert(Idx < Size);
94 return DE[Idx];
95 }
96 void push_back(DictionaryEntry DE) {
97 if (Size < kMaxDictSize)
98 this->DE[Size++] = DE;
99 }
100 void clear() { Size = 0; }
101 bool empty() const { return Size == 0; }
102 size_t size() const { return Size; }
103
104private:
105 DictionaryEntry DE[kMaxDictSize];
106 size_t Size = 0;
107};
108
109// Parses one dictionary entry.
Sylvestre Ledrud9a8b6a2018-03-13 14:35:10 +0000110// If successful, write the enty to Unit and returns true,
George Karpenkov10ab2ac2017-08-21 23:25:50 +0000111// otherwise returns false.
112bool ParseOneDictionaryEntry(const std::string &Str, Unit *U);
113// Parses the dictionary file, fills Units, returns true iff all lines
Sylvestre Ledrud9a8b6a2018-03-13 14:35:10 +0000114// were parsed successfully.
George Karpenkovbebcbfb2017-08-27 23:20:09 +0000115bool ParseDictionaryFile(const std::string &Text, Vector<Unit> *Units);
George Karpenkov10ab2ac2017-08-21 23:25:50 +0000116
117} // namespace fuzzer
118
119#endif // LLVM_FUZZER_DICTIONARY_H