Path: blob/main/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerDictionary.h
35262 views
//===- FuzzerDictionary.h - Internal header for the Fuzzer ------*- C++ -* ===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7// fuzzer::Dictionary8//===----------------------------------------------------------------------===//910#ifndef LLVM_FUZZER_DICTIONARY_H11#define LLVM_FUZZER_DICTIONARY_H1213#include "FuzzerDefs.h"14#include "FuzzerIO.h"15#include "FuzzerUtil.h"16#include <algorithm>17#include <limits>1819namespace fuzzer {20// A simple POD sized array of bytes.21template <size_t kMaxSizeT> class FixedWord {22public:23static const size_t kMaxSize = kMaxSizeT;24FixedWord() {}25FixedWord(const uint8_t *B, size_t S) { Set(B, S); }2627void Set(const uint8_t *B, size_t S) {28static_assert(kMaxSizeT <= std::numeric_limits<uint8_t>::max(),29"FixedWord::kMaxSizeT cannot fit in a uint8_t.");30assert(S <= kMaxSize);31memcpy(Data, B, S);32Size = static_cast<uint8_t>(S);33}3435bool operator==(const FixedWord<kMaxSize> &w) const {36return Size == w.Size && 0 == memcmp(Data, w.Data, Size);37}3839static size_t GetMaxSize() { return kMaxSize; }40const uint8_t *data() const { return Data; }41uint8_t size() const { return Size; }4243private:44uint8_t Size = 0;45uint8_t Data[kMaxSize];46};4748typedef FixedWord<64> Word;4950class DictionaryEntry {51public:52DictionaryEntry() {}53DictionaryEntry(Word W) : W(W) {}54DictionaryEntry(Word W, size_t PositionHint)55: W(W), PositionHint(PositionHint) {}56const Word &GetW() const { return W; }5758bool HasPositionHint() const {59return PositionHint != std::numeric_limits<size_t>::max();60}61size_t GetPositionHint() const {62assert(HasPositionHint());63return PositionHint;64}65void IncUseCount() { UseCount++; }66void IncSuccessCount() { SuccessCount++; }67size_t GetUseCount() const { return UseCount; }68size_t GetSuccessCount() const {return SuccessCount; }6970void Print(const char *PrintAfter = "\n") {71PrintASCII(W.data(), W.size());72if (HasPositionHint())73Printf("@%zd", GetPositionHint());74Printf("%s", PrintAfter);75}7677private:78Word W;79size_t PositionHint = std::numeric_limits<size_t>::max();80size_t UseCount = 0;81size_t SuccessCount = 0;82};8384class Dictionary {85public:86static const size_t kMaxDictSize = 1 << 14;8788bool ContainsWord(const Word &W) const {89return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {90return DE.GetW() == W;91});92}93const DictionaryEntry *begin() const { return &DE[0]; }94const DictionaryEntry *end() const { return begin() + Size; }95DictionaryEntry & operator[] (size_t Idx) {96assert(Idx < Size);97return DE[Idx];98}99void push_back(DictionaryEntry DE) {100if (Size < kMaxDictSize)101this->DE[Size++] = DE;102}103void clear() { Size = 0; }104bool empty() const { return Size == 0; }105size_t size() const { return Size; }106107private:108DictionaryEntry DE[kMaxDictSize];109size_t Size = 0;110};111112// Parses one dictionary entry.113// If successful, writes the entry to Unit and returns true,114// otherwise returns false.115bool ParseOneDictionaryEntry(const std::string &Str, Unit *U);116// Parses the dictionary file, fills Units, returns true iff all lines117// were parsed successfully.118bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units);119120} // namespace fuzzer121122#endif // LLVM_FUZZER_DICTIONARY_H123124125