Path: blob/main/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.h
35262 views
//===- FuzzerDataFlowTrace.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::DataFlowTrace; reads and handles a data-flow trace.8//9// A data flow trace is generated by e.g. dataflow/DataFlow.cpp10// and is stored on disk in a separate directory.11//12// The trace dir contains a file 'functions.txt' which lists function names,13// oner per line, e.g.14// ==> functions.txt <==15// Func216// LLVMFuzzerTestOneInput17// Func118//19// All other files in the dir are the traces, see dataflow/DataFlow.cpp.20// The name of the file is sha1 of the input used to generate the trace.21//22// Current status:23// the data is parsed and the summary is printed, but the data is not yet24// used in any other way.25//===----------------------------------------------------------------------===//2627#ifndef LLVM_FUZZER_DATA_FLOW_TRACE28#define LLVM_FUZZER_DATA_FLOW_TRACE2930#include "FuzzerDefs.h"31#include "FuzzerIO.h"3233#include <unordered_map>34#include <unordered_set>35#include <vector>36#include <string>3738namespace fuzzer {3940int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,41const std::vector<SizedFile> &CorporaFiles);4243class BlockCoverage {44public:45// These functions guarantee no CoverageVector is longer than UINT32_MAX.46bool AppendCoverage(std::istream &IN);47bool AppendCoverage(const std::string &S);4849size_t NumCoveredFunctions() const { return Functions.size(); }5051uint32_t GetCounter(size_t FunctionId, size_t BasicBlockId) {52auto It = Functions.find(FunctionId);53if (It == Functions.end())54return 0;55const auto &Counters = It->second;56if (BasicBlockId < Counters.size())57return Counters[BasicBlockId];58return 0;59}6061uint32_t GetNumberOfBlocks(size_t FunctionId) {62auto It = Functions.find(FunctionId);63if (It == Functions.end()) return 0;64const auto &Counters = It->second;65return static_cast<uint32_t>(Counters.size());66}6768uint32_t GetNumberOfCoveredBlocks(size_t FunctionId) {69auto It = Functions.find(FunctionId);70if (It == Functions.end()) return 0;71const auto &Counters = It->second;72uint32_t Result = 0;73for (auto Cnt: Counters)74if (Cnt)75Result++;76return Result;77}7879std::vector<double> FunctionWeights(size_t NumFunctions) const;80void clear() { Functions.clear(); }8182private:83typedef std::vector<uint32_t> CoverageVector;8485uint32_t NumberOfCoveredBlocks(const CoverageVector &Counters) const {86uint32_t Res = 0;87for (auto Cnt : Counters)88if (Cnt)89Res++;90return Res;91}9293uint32_t NumberOfUncoveredBlocks(const CoverageVector &Counters) const {94return static_cast<uint32_t>(Counters.size()) -95NumberOfCoveredBlocks(Counters);96}9798uint32_t SmallestNonZeroCounter(const CoverageVector &Counters) const {99assert(!Counters.empty());100uint32_t Res = Counters[0];101for (auto Cnt : Counters)102if (Cnt)103Res = Min(Res, Cnt);104assert(Res);105return Res;106}107108// Function ID => vector of counters.109// Each counter represents how many input files trigger the given basic block.110std::unordered_map<size_t, CoverageVector> Functions;111// Functions that have DFT entry.112std::unordered_set<size_t> FunctionsWithDFT;113};114115class DataFlowTrace {116public:117void ReadCoverage(const std::string &DirPath);118bool Init(const std::string &DirPath, std::string *FocusFunction,119std::vector<SizedFile> &CorporaFiles, Random &Rand);120void Clear() { Traces.clear(); }121const std::vector<uint8_t> *Get(const std::string &InputSha1) const {122auto It = Traces.find(InputSha1);123if (It != Traces.end())124return &It->second;125return nullptr;126}127128private:129// Input's sha1 => DFT for the FocusFunction.130std::unordered_map<std::string, std::vector<uint8_t>> Traces;131BlockCoverage Coverage;132std::unordered_set<std::string> CorporaHashes;133};134} // namespace fuzzer135136#endif // LLVM_FUZZER_DATA_FLOW_TRACE137138139