10b57cec5SDimitry Andric //===- FuzzerDictionary.h - Internal header for the Fuzzer ------*- C++ -* ===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // fuzzer::Dictionary 90b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #ifndef LLVM_FUZZER_DICTIONARY_H 120b57cec5SDimitry Andric #define LLVM_FUZZER_DICTIONARY_H 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "FuzzerDefs.h" 150b57cec5SDimitry Andric #include "FuzzerIO.h" 160b57cec5SDimitry Andric #include "FuzzerUtil.h" 170b57cec5SDimitry Andric #include <algorithm> 180b57cec5SDimitry Andric #include <limits> 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace fuzzer { 210b57cec5SDimitry Andric // A simple POD sized array of bytes. 220b57cec5SDimitry Andric template <size_t kMaxSizeT> class FixedWord { 230b57cec5SDimitry Andric public: 240b57cec5SDimitry Andric static const size_t kMaxSize = kMaxSizeT; FixedWord()250b57cec5SDimitry Andric FixedWord() {} FixedWord(const uint8_t * B,size_t S)26fe6060f1SDimitry Andric FixedWord(const uint8_t *B, size_t S) { Set(B, S); } 270b57cec5SDimitry Andric Set(const uint8_t * B,size_t S)28fe6060f1SDimitry Andric void Set(const uint8_t *B, size_t S) { 29fe6060f1SDimitry Andric static_assert(kMaxSizeT <= std::numeric_limits<uint8_t>::max(), 30fe6060f1SDimitry Andric "FixedWord::kMaxSizeT cannot fit in a uint8_t."); 310b57cec5SDimitry Andric assert(S <= kMaxSize); 320b57cec5SDimitry Andric memcpy(Data, B, S); 33fe6060f1SDimitry Andric Size = static_cast<uint8_t>(S); 340b57cec5SDimitry Andric } 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric bool operator==(const FixedWord<kMaxSize> &w) const { 370b57cec5SDimitry Andric return Size == w.Size && 0 == memcmp(Data, w.Data, Size); 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric GetMaxSize()400b57cec5SDimitry Andric static size_t GetMaxSize() { return kMaxSize; } data()410b57cec5SDimitry Andric const uint8_t *data() const { return Data; } size()420b57cec5SDimitry Andric uint8_t size() const { return Size; } 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric private: 450b57cec5SDimitry Andric uint8_t Size = 0; 460b57cec5SDimitry Andric uint8_t Data[kMaxSize]; 470b57cec5SDimitry Andric }; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric typedef FixedWord<64> Word; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric class DictionaryEntry { 520b57cec5SDimitry Andric public: DictionaryEntry()530b57cec5SDimitry Andric DictionaryEntry() {} DictionaryEntry(Word W)540b57cec5SDimitry Andric DictionaryEntry(Word W) : W(W) {} DictionaryEntry(Word W,size_t PositionHint)55*349cc55cSDimitry Andric DictionaryEntry(Word W, size_t PositionHint) 56*349cc55cSDimitry Andric : W(W), PositionHint(PositionHint) {} GetW()570b57cec5SDimitry Andric const Word &GetW() const { return W; } 580b57cec5SDimitry Andric HasPositionHint()59*349cc55cSDimitry Andric bool HasPositionHint() const { 60*349cc55cSDimitry Andric return PositionHint != std::numeric_limits<size_t>::max(); 61*349cc55cSDimitry Andric } GetPositionHint()620b57cec5SDimitry Andric size_t GetPositionHint() const { 630b57cec5SDimitry Andric assert(HasPositionHint()); 640b57cec5SDimitry Andric return PositionHint; 650b57cec5SDimitry Andric } IncUseCount()660b57cec5SDimitry Andric void IncUseCount() { UseCount++; } IncSuccessCount()670b57cec5SDimitry Andric void IncSuccessCount() { SuccessCount++; } GetUseCount()680b57cec5SDimitry Andric size_t GetUseCount() const { return UseCount; } GetSuccessCount()690b57cec5SDimitry Andric size_t GetSuccessCount() const {return SuccessCount; } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric void Print(const char *PrintAfter = "\n") { 720b57cec5SDimitry Andric PrintASCII(W.data(), W.size()); 730b57cec5SDimitry Andric if (HasPositionHint()) 740b57cec5SDimitry Andric Printf("@%zd", GetPositionHint()); 750b57cec5SDimitry Andric Printf("%s", PrintAfter); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric private: 790b57cec5SDimitry Andric Word W; 800b57cec5SDimitry Andric size_t PositionHint = std::numeric_limits<size_t>::max(); 810b57cec5SDimitry Andric size_t UseCount = 0; 820b57cec5SDimitry Andric size_t SuccessCount = 0; 830b57cec5SDimitry Andric }; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric class Dictionary { 860b57cec5SDimitry Andric public: 870b57cec5SDimitry Andric static const size_t kMaxDictSize = 1 << 14; 880b57cec5SDimitry Andric ContainsWord(const Word & W)890b57cec5SDimitry Andric bool ContainsWord(const Word &W) const { 900b57cec5SDimitry Andric return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) { 910b57cec5SDimitry Andric return DE.GetW() == W; 920b57cec5SDimitry Andric }); 930b57cec5SDimitry Andric } begin()940b57cec5SDimitry Andric const DictionaryEntry *begin() const { return &DE[0]; } end()950b57cec5SDimitry Andric const DictionaryEntry *end() const { return begin() + Size; } 960b57cec5SDimitry Andric DictionaryEntry & operator[] (size_t Idx) { 970b57cec5SDimitry Andric assert(Idx < Size); 980b57cec5SDimitry Andric return DE[Idx]; 990b57cec5SDimitry Andric } push_back(DictionaryEntry DE)1000b57cec5SDimitry Andric void push_back(DictionaryEntry DE) { 1010b57cec5SDimitry Andric if (Size < kMaxDictSize) 1020b57cec5SDimitry Andric this->DE[Size++] = DE; 1030b57cec5SDimitry Andric } clear()1040b57cec5SDimitry Andric void clear() { Size = 0; } empty()1050b57cec5SDimitry Andric bool empty() const { return Size == 0; } size()1060b57cec5SDimitry Andric size_t size() const { return Size; } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric private: 1090b57cec5SDimitry Andric DictionaryEntry DE[kMaxDictSize]; 1100b57cec5SDimitry Andric size_t Size = 0; 1110b57cec5SDimitry Andric }; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric // Parses one dictionary entry. 114*349cc55cSDimitry Andric // If successful, writes the entry to Unit and returns true, 1150b57cec5SDimitry Andric // otherwise returns false. 1160b57cec5SDimitry Andric bool ParseOneDictionaryEntry(const std::string &Str, Unit *U); 1170b57cec5SDimitry Andric // Parses the dictionary file, fills Units, returns true iff all lines 1180b57cec5SDimitry Andric // were parsed successfully. 119*349cc55cSDimitry Andric bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric } // namespace fuzzer 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric #endif // LLVM_FUZZER_DICTIONARY_H 124