xref: /openbsd-src/gnu/llvm/compiler-rt/lib/fuzzer/FuzzerDictionary.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===- FuzzerDictionary.h - Internal header for the Fuzzer ------*- C++ -* ===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick // fuzzer::Dictionary
93cab2bb3Spatrick //===----------------------------------------------------------------------===//
103cab2bb3Spatrick 
113cab2bb3Spatrick #ifndef LLVM_FUZZER_DICTIONARY_H
123cab2bb3Spatrick #define LLVM_FUZZER_DICTIONARY_H
133cab2bb3Spatrick 
143cab2bb3Spatrick #include "FuzzerDefs.h"
153cab2bb3Spatrick #include "FuzzerIO.h"
163cab2bb3Spatrick #include "FuzzerUtil.h"
173cab2bb3Spatrick #include <algorithm>
183cab2bb3Spatrick #include <limits>
193cab2bb3Spatrick 
203cab2bb3Spatrick namespace fuzzer {
213cab2bb3Spatrick // A simple POD sized array of bytes.
223cab2bb3Spatrick template <size_t kMaxSizeT> class FixedWord {
233cab2bb3Spatrick public:
243cab2bb3Spatrick   static const size_t kMaxSize = kMaxSizeT;
FixedWord()253cab2bb3Spatrick   FixedWord() {}
FixedWord(const uint8_t * B,size_t S)26d89ec533Spatrick   FixedWord(const uint8_t *B, size_t S) { Set(B, S); }
273cab2bb3Spatrick 
Set(const uint8_t * B,size_t S)28d89ec533Spatrick   void Set(const uint8_t *B, size_t S) {
29d89ec533Spatrick     static_assert(kMaxSizeT <= std::numeric_limits<uint8_t>::max(),
30d89ec533Spatrick                   "FixedWord::kMaxSizeT cannot fit in a uint8_t.");
313cab2bb3Spatrick     assert(S <= kMaxSize);
323cab2bb3Spatrick     memcpy(Data, B, S);
33d89ec533Spatrick     Size = static_cast<uint8_t>(S);
343cab2bb3Spatrick   }
353cab2bb3Spatrick 
363cab2bb3Spatrick   bool operator==(const FixedWord<kMaxSize> &w) const {
373cab2bb3Spatrick     return Size == w.Size && 0 == memcmp(Data, w.Data, Size);
383cab2bb3Spatrick   }
393cab2bb3Spatrick 
GetMaxSize()403cab2bb3Spatrick   static size_t GetMaxSize() { return kMaxSize; }
data()413cab2bb3Spatrick   const uint8_t *data() const { return Data; }
size()423cab2bb3Spatrick   uint8_t size() const { return Size; }
433cab2bb3Spatrick 
443cab2bb3Spatrick private:
453cab2bb3Spatrick   uint8_t Size = 0;
463cab2bb3Spatrick   uint8_t Data[kMaxSize];
473cab2bb3Spatrick };
483cab2bb3Spatrick 
493cab2bb3Spatrick typedef FixedWord<64> Word;
503cab2bb3Spatrick 
513cab2bb3Spatrick class DictionaryEntry {
523cab2bb3Spatrick  public:
DictionaryEntry()533cab2bb3Spatrick   DictionaryEntry() {}
DictionaryEntry(Word W)543cab2bb3Spatrick   DictionaryEntry(Word W) : W(W) {}
DictionaryEntry(Word W,size_t PositionHint)55*810390e3Srobert   DictionaryEntry(Word W, size_t PositionHint)
56*810390e3Srobert       : W(W), PositionHint(PositionHint) {}
GetW()573cab2bb3Spatrick   const Word &GetW() const { return W; }
583cab2bb3Spatrick 
HasPositionHint()59*810390e3Srobert   bool HasPositionHint() const {
60*810390e3Srobert     return PositionHint != std::numeric_limits<size_t>::max();
61*810390e3Srobert   }
GetPositionHint()623cab2bb3Spatrick   size_t GetPositionHint() const {
633cab2bb3Spatrick     assert(HasPositionHint());
643cab2bb3Spatrick     return PositionHint;
653cab2bb3Spatrick   }
IncUseCount()663cab2bb3Spatrick   void IncUseCount() { UseCount++; }
IncSuccessCount()673cab2bb3Spatrick   void IncSuccessCount() { SuccessCount++; }
GetUseCount()683cab2bb3Spatrick   size_t GetUseCount() const { return UseCount; }
GetSuccessCount()693cab2bb3Spatrick   size_t GetSuccessCount() const {return SuccessCount; }
703cab2bb3Spatrick 
713cab2bb3Spatrick   void Print(const char *PrintAfter = "\n") {
723cab2bb3Spatrick     PrintASCII(W.data(), W.size());
733cab2bb3Spatrick     if (HasPositionHint())
743cab2bb3Spatrick       Printf("@%zd", GetPositionHint());
753cab2bb3Spatrick     Printf("%s", PrintAfter);
763cab2bb3Spatrick   }
773cab2bb3Spatrick 
783cab2bb3Spatrick private:
793cab2bb3Spatrick   Word W;
803cab2bb3Spatrick   size_t PositionHint = std::numeric_limits<size_t>::max();
813cab2bb3Spatrick   size_t UseCount = 0;
823cab2bb3Spatrick   size_t SuccessCount = 0;
833cab2bb3Spatrick };
843cab2bb3Spatrick 
853cab2bb3Spatrick class Dictionary {
863cab2bb3Spatrick  public:
873cab2bb3Spatrick   static const size_t kMaxDictSize = 1 << 14;
883cab2bb3Spatrick 
ContainsWord(const Word & W)893cab2bb3Spatrick   bool ContainsWord(const Word &W) const {
903cab2bb3Spatrick     return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {
913cab2bb3Spatrick       return DE.GetW() == W;
923cab2bb3Spatrick     });
933cab2bb3Spatrick   }
begin()943cab2bb3Spatrick   const DictionaryEntry *begin() const { return &DE[0]; }
end()953cab2bb3Spatrick   const DictionaryEntry *end() const { return begin() + Size; }
963cab2bb3Spatrick   DictionaryEntry & operator[] (size_t Idx) {
973cab2bb3Spatrick     assert(Idx < Size);
983cab2bb3Spatrick     return DE[Idx];
993cab2bb3Spatrick   }
push_back(DictionaryEntry DE)1003cab2bb3Spatrick   void push_back(DictionaryEntry DE) {
1013cab2bb3Spatrick     if (Size < kMaxDictSize)
1023cab2bb3Spatrick       this->DE[Size++] = DE;
1033cab2bb3Spatrick   }
clear()1043cab2bb3Spatrick   void clear() { Size = 0; }
empty()1053cab2bb3Spatrick   bool empty() const { return Size == 0; }
size()1063cab2bb3Spatrick   size_t size() const { return Size; }
1073cab2bb3Spatrick 
1083cab2bb3Spatrick private:
1093cab2bb3Spatrick   DictionaryEntry DE[kMaxDictSize];
1103cab2bb3Spatrick   size_t Size = 0;
1113cab2bb3Spatrick };
1123cab2bb3Spatrick 
1133cab2bb3Spatrick // Parses one dictionary entry.
114*810390e3Srobert // If successful, writes the entry to Unit and returns true,
1153cab2bb3Spatrick // otherwise returns false.
1163cab2bb3Spatrick bool ParseOneDictionaryEntry(const std::string &Str, Unit *U);
1173cab2bb3Spatrick // Parses the dictionary file, fills Units, returns true iff all lines
1183cab2bb3Spatrick // were parsed successfully.
119*810390e3Srobert bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units);
1203cab2bb3Spatrick 
1213cab2bb3Spatrick }  // namespace fuzzer
1223cab2bb3Spatrick 
1233cab2bb3Spatrick #endif  // LLVM_FUZZER_DICTIONARY_H
124