blob: 3b5457bb8fe69547139f73da49c8ed75494f275e [file] [log] [blame]
Kostya Serebryany6f5a8042016-09-21 01:50: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
17namespace fuzzer {
18// A simple POD sized array of bytes.
19template <size_t kMaxSize> class FixedWord {
20public:
21 FixedWord() {}
22 FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); }
23
24 void Set(const uint8_t *B, uint8_t S) {
25 assert(S <= kMaxSize);
26 memcpy(Data, B, S);
27 Size = S;
28 }
29
30 bool operator==(const FixedWord<kMaxSize> &w) const {
31 return Size == w.Size && 0 == memcmp(Data, w.Data, Size);
32 }
33
34 bool operator<(const FixedWord<kMaxSize> &w) const {
35 if (Size != w.Size)
36 return Size < w.Size;
37 return memcmp(Data, w.Data, Size) < 0;
38 }
39
40 static size_t GetMaxSize() { return kMaxSize; }
41 const uint8_t *data() const { return Data; }
42 uint8_t size() const { return Size; }
43
44private:
45 uint8_t Size = 0;
46 uint8_t Data[kMaxSize];
47};
48
49typedef FixedWord<27> Word; // 28 bytes.
50
51class DictionaryEntry {
52 public:
53 DictionaryEntry() {}
54 DictionaryEntry(Word W) : W(W) {}
55 DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
56 const Word &GetW() const { return W; }
57
58 bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); }
59 size_t GetPositionHint() const {
60 assert(HasPositionHint());
61 return PositionHint;
62 }
63 void IncUseCount() { UseCount++; }
64 void IncSuccessCount() { SuccessCount++; }
65 size_t GetUseCount() const { return UseCount; }
66 size_t GetSuccessCount() const {return SuccessCount; }
67
68private:
69 Word W;
70 size_t PositionHint = std::numeric_limits<size_t>::max();
71 size_t UseCount = 0;
72 size_t SuccessCount = 0;
73};
74
75class Dictionary {
76 public:
77 static const size_t kMaxDictSize = 1 << 14;
78
79 bool ContainsWord(const Word &W) const {
80 return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {
81 return DE.GetW() == W;
82 });
83 }
84 const DictionaryEntry *begin() const { return &DE[0]; }
85 const DictionaryEntry *end() const { return begin() + Size; }
86 DictionaryEntry & operator[] (size_t Idx) {
87 assert(Idx < Size);
88 return DE[Idx];
89 }
90 void push_back(DictionaryEntry DE) {
91 if (Size < kMaxDictSize)
92 this->DE[Size++] = DE;
93 }
94 void clear() { Size = 0; }
95 bool empty() const { return Size == 0; }
96 size_t size() const { return Size; }
97
98private:
99 DictionaryEntry DE[kMaxDictSize];
100 size_t Size = 0;
101};
102
103// Parses one dictionary entry.
104// If successfull, write the enty to Unit and returns true,
105// otherwise returns false.
106bool ParseOneDictionaryEntry(const std::string &Str, Unit *U);
107// Parses the dictionary file, fills Units, returns true iff all lines
108// were parsed succesfully.
109bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units);
110
111} // namespace fuzzer
112
113#endif // LLVM_FUZZER_DICTIONARY_H
114