brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 054dce1 Raw
138 lines · c
1//===- FuzzerDataFlowTrace.h - Internal header for the Fuzzer ---*- C++ -* ===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// fuzzer::DataFlowTrace; reads and handles a data-flow trace.9//10// A data flow trace is generated by e.g. dataflow/DataFlow.cpp11// and is stored on disk in a separate directory.12//13// The trace dir contains a file 'functions.txt' which lists function names,14// oner per line, e.g.15// ==> functions.txt <==16// Func217// LLVMFuzzerTestOneInput18// Func119//20// All other files in the dir are the traces, see dataflow/DataFlow.cpp.21// The name of the file is sha1 of the input used to generate the trace.22//23// Current status:24//   the data is parsed and the summary is printed, but the data is not yet25//   used in any other way.26//===----------------------------------------------------------------------===//27 28#ifndef LLVM_FUZZER_DATA_FLOW_TRACE29#define LLVM_FUZZER_DATA_FLOW_TRACE30 31#include "FuzzerDefs.h"32#include "FuzzerIO.h"33 34#include <unordered_map>35#include <unordered_set>36#include <vector>37#include <string>38 39namespace fuzzer {40 41int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,42                    const std::vector<SizedFile> &CorporaFiles);43 44class BlockCoverage {45public:46  // These functions guarantee no CoverageVector is longer than UINT32_MAX.47  bool AppendCoverage(std::istream &IN);48  bool AppendCoverage(const std::string &S);49 50  size_t NumCoveredFunctions() const { return Functions.size(); }51 52  uint32_t GetCounter(size_t FunctionId, size_t BasicBlockId) {53    auto It = Functions.find(FunctionId);54    if (It == Functions.end())55      return 0;56    const auto &Counters = It->second;57    if (BasicBlockId < Counters.size())58      return Counters[BasicBlockId];59    return 0;60  }61 62  uint32_t GetNumberOfBlocks(size_t FunctionId) {63    auto It = Functions.find(FunctionId);64    if (It == Functions.end()) return 0;65    const auto &Counters = It->second;66    return static_cast<uint32_t>(Counters.size());67  }68 69  uint32_t GetNumberOfCoveredBlocks(size_t FunctionId) {70    auto It = Functions.find(FunctionId);71    if (It == Functions.end()) return 0;72    const auto &Counters = It->second;73    uint32_t Result = 0;74    for (auto Cnt: Counters)75      if (Cnt)76        Result++;77    return Result;78  }79 80  std::vector<double> FunctionWeights(size_t NumFunctions) const;81  void clear() { Functions.clear(); }82 83private:84  typedef std::vector<uint32_t> CoverageVector;85 86  uint32_t NumberOfCoveredBlocks(const CoverageVector &Counters) const {87    uint32_t Res = 0;88    for (auto Cnt : Counters)89      if (Cnt)90        Res++;91    return Res;92  }93 94  uint32_t NumberOfUncoveredBlocks(const CoverageVector &Counters) const {95    return static_cast<uint32_t>(Counters.size()) -96           NumberOfCoveredBlocks(Counters);97  }98 99  uint32_t SmallestNonZeroCounter(const CoverageVector &Counters) const {100    assert(!Counters.empty());101    uint32_t Res = Counters[0];102    for (auto Cnt : Counters)103      if (Cnt)104        Res = Min(Res, Cnt);105    assert(Res);106    return Res;107  }108 109  // Function ID => vector of counters.110  // Each counter represents how many input files trigger the given basic block.111  std::unordered_map<size_t, CoverageVector> Functions;112  // Functions that have DFT entry.113  std::unordered_set<size_t> FunctionsWithDFT;114};115 116class DataFlowTrace {117 public:118  void ReadCoverage(const std::string &DirPath);119  bool Init(const std::string &DirPath, std::string *FocusFunction,120            std::vector<SizedFile> &CorporaFiles, Random &Rand);121  void Clear() { Traces.clear(); }122  const std::vector<uint8_t> *Get(const std::string &InputSha1) const {123    auto It = Traces.find(InputSha1);124    if (It != Traces.end())125      return &It->second;126    return nullptr;127  }128 129 private:130  // Input's sha1 => DFT for the FocusFunction.131   std::unordered_map<std::string, std::vector<uint8_t>> Traces;132   BlockCoverage Coverage;133   std::unordered_set<std::string> CorporaHashes;134};135}  // namespace fuzzer136 137#endif // LLVM_FUZZER_DATA_FLOW_TRACE138