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