xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerDictionary.h (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
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