1 //===- FuzzerDictionary.h - Internal header for the Fuzzer ------*- C++ -* ===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // fuzzer::Dictionary 9 //===----------------------------------------------------------------------===// 10 11 #ifndef LLVM_FUZZER_DICTIONARY_H 12 #define LLVM_FUZZER_DICTIONARY_H 13 14 #include "FuzzerDefs.h" 15 #include "FuzzerIO.h" 16 #include "FuzzerUtil.h" 17 #include <algorithm> 18 #include <limits> 19 20 namespace fuzzer { 21 // A simple POD sized array of bytes. 22 template <size_t kMaxSizeT> class FixedWord { 23 public: 24 static const size_t kMaxSize = kMaxSizeT; FixedWord()25 FixedWord() {} FixedWord(const uint8_t * B,uint8_t S)26 FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); } 27 Set(const uint8_t * B,uint8_t S)28 void Set(const uint8_t *B, uint8_t S) { 29 assert(S <= kMaxSize); 30 memcpy(Data, B, S); 31 Size = S; 32 } 33 34 bool operator==(const FixedWord<kMaxSize> &w) const { 35 return Size == w.Size && 0 == memcmp(Data, w.Data, Size); 36 } 37 GetMaxSize()38 static size_t GetMaxSize() { return kMaxSize; } data()39 const uint8_t *data() const { return Data; } size()40 uint8_t size() const { return Size; } 41 42 private: 43 uint8_t Size = 0; 44 uint8_t Data[kMaxSize]; 45 }; 46 47 typedef FixedWord<64> Word; 48 49 class DictionaryEntry { 50 public: DictionaryEntry()51 DictionaryEntry() {} DictionaryEntry(Word W)52 DictionaryEntry(Word W) : W(W) {} DictionaryEntry(Word W,size_t PositionHint)53 DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {} GetW()54 const Word &GetW() const { return W; } 55 HasPositionHint()56 bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); } GetPositionHint()57 size_t GetPositionHint() const { 58 assert(HasPositionHint()); 59 return PositionHint; 60 } IncUseCount()61 void IncUseCount() { UseCount++; } IncSuccessCount()62 void IncSuccessCount() { SuccessCount++; } GetUseCount()63 size_t GetUseCount() const { return UseCount; } GetSuccessCount()64 size_t GetSuccessCount() const {return SuccessCount; } 65 66 void Print(const char *PrintAfter = "\n") { 67 PrintASCII(W.data(), W.size()); 68 if (HasPositionHint()) 69 Printf("@%zd", GetPositionHint()); 70 Printf("%s", PrintAfter); 71 } 72 73 private: 74 Word W; 75 size_t PositionHint = std::numeric_limits<size_t>::max(); 76 size_t UseCount = 0; 77 size_t SuccessCount = 0; 78 }; 79 80 class Dictionary { 81 public: 82 static const size_t kMaxDictSize = 1 << 14; 83 ContainsWord(const Word & W)84 bool ContainsWord(const Word &W) const { 85 return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) { 86 return DE.GetW() == W; 87 }); 88 } begin()89 const DictionaryEntry *begin() const { return &DE[0]; } end()90 const DictionaryEntry *end() const { return begin() + Size; } 91 DictionaryEntry & operator[] (size_t Idx) { 92 assert(Idx < Size); 93 return DE[Idx]; 94 } push_back(DictionaryEntry DE)95 void push_back(DictionaryEntry DE) { 96 if (Size < kMaxDictSize) 97 this->DE[Size++] = DE; 98 } clear()99 void clear() { Size = 0; } empty()100 bool empty() const { return Size == 0; } size()101 size_t size() const { return Size; } 102 103 private: 104 DictionaryEntry DE[kMaxDictSize]; 105 size_t Size = 0; 106 }; 107 108 // Parses one dictionary entry. 109 // If successful, write the enty to Unit and returns true, 110 // otherwise returns false. 111 bool ParseOneDictionaryEntry(const std::string &Str, Unit *U); 112 // Parses the dictionary file, fills Units, returns true iff all lines 113 // were parsed successfully. 114 bool ParseDictionaryFile(const std::string &Text, Vector<Unit> *Units); 115 116 } // namespace fuzzer 117 118 #endif // LLVM_FUZZER_DICTIONARY_H 119