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