1*0a6a1f1dSLionel Sambuc //=-- CoverageMappingReader.h - Code coverage mapping reader ------*- C++ -*-=// 2*0a6a1f1dSLionel Sambuc // 3*0a6a1f1dSLionel Sambuc // The LLVM Compiler Infrastructure 4*0a6a1f1dSLionel Sambuc // 5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details. 7*0a6a1f1dSLionel Sambuc // 8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===// 9*0a6a1f1dSLionel Sambuc // 10*0a6a1f1dSLionel Sambuc // This file contains support for reading coverage mapping data for 11*0a6a1f1dSLionel Sambuc // instrumentation based coverage. 12*0a6a1f1dSLionel Sambuc // 13*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===// 14*0a6a1f1dSLionel Sambuc 15*0a6a1f1dSLionel Sambuc #ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H 16*0a6a1f1dSLionel Sambuc #define LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H 17*0a6a1f1dSLionel Sambuc 18*0a6a1f1dSLionel Sambuc #include "llvm/ADT/ArrayRef.h" 19*0a6a1f1dSLionel Sambuc #include "llvm/ADT/StringRef.h" 20*0a6a1f1dSLionel Sambuc #include "llvm/Object/ObjectFile.h" 21*0a6a1f1dSLionel Sambuc #include "llvm/ProfileData/CoverageMapping.h" 22*0a6a1f1dSLionel Sambuc #include "llvm/ProfileData/InstrProf.h" 23*0a6a1f1dSLionel Sambuc #include "llvm/Support/FileSystem.h" 24*0a6a1f1dSLionel Sambuc #include "llvm/Support/MemoryBuffer.h" 25*0a6a1f1dSLionel Sambuc #include <iterator> 26*0a6a1f1dSLionel Sambuc 27*0a6a1f1dSLionel Sambuc namespace llvm { 28*0a6a1f1dSLionel Sambuc namespace coverage { 29*0a6a1f1dSLionel Sambuc 30*0a6a1f1dSLionel Sambuc class ObjectFileCoverageMappingReader; 31*0a6a1f1dSLionel Sambuc 32*0a6a1f1dSLionel Sambuc /// \brief Coverage mapping information for a single function. 33*0a6a1f1dSLionel Sambuc struct CoverageMappingRecord { 34*0a6a1f1dSLionel Sambuc StringRef FunctionName; 35*0a6a1f1dSLionel Sambuc uint64_t FunctionHash; 36*0a6a1f1dSLionel Sambuc ArrayRef<StringRef> Filenames; 37*0a6a1f1dSLionel Sambuc ArrayRef<CounterExpression> Expressions; 38*0a6a1f1dSLionel Sambuc ArrayRef<CounterMappingRegion> MappingRegions; 39*0a6a1f1dSLionel Sambuc }; 40*0a6a1f1dSLionel Sambuc 41*0a6a1f1dSLionel Sambuc /// \brief A file format agnostic iterator over coverage mapping data. 42*0a6a1f1dSLionel Sambuc class CoverageMappingIterator 43*0a6a1f1dSLionel Sambuc : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> { 44*0a6a1f1dSLionel Sambuc ObjectFileCoverageMappingReader *Reader; 45*0a6a1f1dSLionel Sambuc CoverageMappingRecord Record; 46*0a6a1f1dSLionel Sambuc 47*0a6a1f1dSLionel Sambuc void increment(); 48*0a6a1f1dSLionel Sambuc 49*0a6a1f1dSLionel Sambuc public: CoverageMappingIterator()50*0a6a1f1dSLionel Sambuc CoverageMappingIterator() : Reader(nullptr) {} CoverageMappingIterator(ObjectFileCoverageMappingReader * Reader)51*0a6a1f1dSLionel Sambuc CoverageMappingIterator(ObjectFileCoverageMappingReader *Reader) 52*0a6a1f1dSLionel Sambuc : Reader(Reader) { 53*0a6a1f1dSLionel Sambuc increment(); 54*0a6a1f1dSLionel Sambuc } 55*0a6a1f1dSLionel Sambuc 56*0a6a1f1dSLionel Sambuc CoverageMappingIterator &operator++() { 57*0a6a1f1dSLionel Sambuc increment(); 58*0a6a1f1dSLionel Sambuc return *this; 59*0a6a1f1dSLionel Sambuc } 60*0a6a1f1dSLionel Sambuc bool operator==(const CoverageMappingIterator &RHS) { 61*0a6a1f1dSLionel Sambuc return Reader == RHS.Reader; 62*0a6a1f1dSLionel Sambuc } 63*0a6a1f1dSLionel Sambuc bool operator!=(const CoverageMappingIterator &RHS) { 64*0a6a1f1dSLionel Sambuc return Reader != RHS.Reader; 65*0a6a1f1dSLionel Sambuc } 66*0a6a1f1dSLionel Sambuc CoverageMappingRecord &operator*() { return Record; } 67*0a6a1f1dSLionel Sambuc CoverageMappingRecord *operator->() { return &Record; } 68*0a6a1f1dSLionel Sambuc }; 69*0a6a1f1dSLionel Sambuc 70*0a6a1f1dSLionel Sambuc /// \brief Base class for the raw coverage mapping and filenames data readers. 71*0a6a1f1dSLionel Sambuc class RawCoverageReader { 72*0a6a1f1dSLionel Sambuc protected: 73*0a6a1f1dSLionel Sambuc StringRef Data; 74*0a6a1f1dSLionel Sambuc 75*0a6a1f1dSLionel Sambuc /// \brief Return the error code. error(std::error_code EC)76*0a6a1f1dSLionel Sambuc std::error_code error(std::error_code EC) { return EC; } 77*0a6a1f1dSLionel Sambuc 78*0a6a1f1dSLionel Sambuc /// \brief Clear the current error code and return a successful one. success()79*0a6a1f1dSLionel Sambuc std::error_code success() { return error(instrprof_error::success); } 80*0a6a1f1dSLionel Sambuc RawCoverageReader(StringRef Data)81*0a6a1f1dSLionel Sambuc RawCoverageReader(StringRef Data) : Data(Data) {} 82*0a6a1f1dSLionel Sambuc 83*0a6a1f1dSLionel Sambuc std::error_code readULEB128(uint64_t &Result); 84*0a6a1f1dSLionel Sambuc std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1); 85*0a6a1f1dSLionel Sambuc std::error_code readSize(uint64_t &Result); 86*0a6a1f1dSLionel Sambuc std::error_code readString(StringRef &Result); 87*0a6a1f1dSLionel Sambuc }; 88*0a6a1f1dSLionel Sambuc 89*0a6a1f1dSLionel Sambuc /// \brief Reader for the raw coverage filenames. 90*0a6a1f1dSLionel Sambuc class RawCoverageFilenamesReader : public RawCoverageReader { 91*0a6a1f1dSLionel Sambuc std::vector<StringRef> &Filenames; 92*0a6a1f1dSLionel Sambuc 93*0a6a1f1dSLionel Sambuc RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) 94*0a6a1f1dSLionel Sambuc LLVM_DELETED_FUNCTION; 95*0a6a1f1dSLionel Sambuc RawCoverageFilenamesReader & 96*0a6a1f1dSLionel Sambuc operator=(const RawCoverageFilenamesReader &) LLVM_DELETED_FUNCTION; 97*0a6a1f1dSLionel Sambuc 98*0a6a1f1dSLionel Sambuc public: RawCoverageFilenamesReader(StringRef Data,std::vector<StringRef> & Filenames)99*0a6a1f1dSLionel Sambuc RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames) 100*0a6a1f1dSLionel Sambuc : RawCoverageReader(Data), Filenames(Filenames) {} 101*0a6a1f1dSLionel Sambuc 102*0a6a1f1dSLionel Sambuc std::error_code read(); 103*0a6a1f1dSLionel Sambuc }; 104*0a6a1f1dSLionel Sambuc 105*0a6a1f1dSLionel Sambuc /// \brief Reader for the raw coverage mapping data. 106*0a6a1f1dSLionel Sambuc class RawCoverageMappingReader : public RawCoverageReader { 107*0a6a1f1dSLionel Sambuc StringRef FunctionName; 108*0a6a1f1dSLionel Sambuc ArrayRef<StringRef> TranslationUnitFilenames; 109*0a6a1f1dSLionel Sambuc std::vector<StringRef> &Filenames; 110*0a6a1f1dSLionel Sambuc std::vector<CounterExpression> &Expressions; 111*0a6a1f1dSLionel Sambuc std::vector<CounterMappingRegion> &MappingRegions; 112*0a6a1f1dSLionel Sambuc 113*0a6a1f1dSLionel Sambuc RawCoverageMappingReader(const RawCoverageMappingReader &) 114*0a6a1f1dSLionel Sambuc LLVM_DELETED_FUNCTION; 115*0a6a1f1dSLionel Sambuc RawCoverageMappingReader & 116*0a6a1f1dSLionel Sambuc operator=(const RawCoverageMappingReader &) LLVM_DELETED_FUNCTION; 117*0a6a1f1dSLionel Sambuc 118*0a6a1f1dSLionel Sambuc public: RawCoverageMappingReader(StringRef FunctionName,StringRef MappingData,ArrayRef<StringRef> TranslationUnitFilenames,std::vector<StringRef> & Filenames,std::vector<CounterExpression> & Expressions,std::vector<CounterMappingRegion> & MappingRegions)119*0a6a1f1dSLionel Sambuc RawCoverageMappingReader(StringRef FunctionName, StringRef MappingData, 120*0a6a1f1dSLionel Sambuc ArrayRef<StringRef> TranslationUnitFilenames, 121*0a6a1f1dSLionel Sambuc std::vector<StringRef> &Filenames, 122*0a6a1f1dSLionel Sambuc std::vector<CounterExpression> &Expressions, 123*0a6a1f1dSLionel Sambuc std::vector<CounterMappingRegion> &MappingRegions) 124*0a6a1f1dSLionel Sambuc : RawCoverageReader(MappingData), FunctionName(FunctionName), 125*0a6a1f1dSLionel Sambuc TranslationUnitFilenames(TranslationUnitFilenames), 126*0a6a1f1dSLionel Sambuc Filenames(Filenames), Expressions(Expressions), 127*0a6a1f1dSLionel Sambuc MappingRegions(MappingRegions) {} 128*0a6a1f1dSLionel Sambuc 129*0a6a1f1dSLionel Sambuc std::error_code read(CoverageMappingRecord &Record); 130*0a6a1f1dSLionel Sambuc 131*0a6a1f1dSLionel Sambuc private: 132*0a6a1f1dSLionel Sambuc std::error_code decodeCounter(unsigned Value, Counter &C); 133*0a6a1f1dSLionel Sambuc std::error_code readCounter(Counter &C); 134*0a6a1f1dSLionel Sambuc std::error_code 135*0a6a1f1dSLionel Sambuc readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions, 136*0a6a1f1dSLionel Sambuc unsigned InferredFileID, size_t NumFileIDs); 137*0a6a1f1dSLionel Sambuc }; 138*0a6a1f1dSLionel Sambuc 139*0a6a1f1dSLionel Sambuc /// \brief Reader for the coverage mapping data that is emitted by the 140*0a6a1f1dSLionel Sambuc /// frontend and stored in an object file. 141*0a6a1f1dSLionel Sambuc class ObjectFileCoverageMappingReader { 142*0a6a1f1dSLionel Sambuc public: 143*0a6a1f1dSLionel Sambuc struct ProfileMappingRecord { 144*0a6a1f1dSLionel Sambuc CoverageMappingVersion Version; 145*0a6a1f1dSLionel Sambuc StringRef FunctionName; 146*0a6a1f1dSLionel Sambuc uint64_t FunctionHash; 147*0a6a1f1dSLionel Sambuc StringRef CoverageMapping; 148*0a6a1f1dSLionel Sambuc size_t FilenamesBegin; 149*0a6a1f1dSLionel Sambuc size_t FilenamesSize; 150*0a6a1f1dSLionel Sambuc ProfileMappingRecordProfileMappingRecord151*0a6a1f1dSLionel Sambuc ProfileMappingRecord(CoverageMappingVersion Version, StringRef FunctionName, 152*0a6a1f1dSLionel Sambuc uint64_t FunctionHash, StringRef CoverageMapping, 153*0a6a1f1dSLionel Sambuc size_t FilenamesBegin, size_t FilenamesSize) 154*0a6a1f1dSLionel Sambuc : Version(Version), FunctionName(FunctionName), 155*0a6a1f1dSLionel Sambuc FunctionHash(FunctionHash), CoverageMapping(CoverageMapping), 156*0a6a1f1dSLionel Sambuc FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {} 157*0a6a1f1dSLionel Sambuc }; 158*0a6a1f1dSLionel Sambuc 159*0a6a1f1dSLionel Sambuc private: 160*0a6a1f1dSLionel Sambuc std::error_code LastError; 161*0a6a1f1dSLionel Sambuc object::OwningBinary<object::ObjectFile> Object; 162*0a6a1f1dSLionel Sambuc std::vector<StringRef> Filenames; 163*0a6a1f1dSLionel Sambuc std::vector<ProfileMappingRecord> MappingRecords; 164*0a6a1f1dSLionel Sambuc size_t CurrentRecord; 165*0a6a1f1dSLionel Sambuc std::vector<StringRef> FunctionsFilenames; 166*0a6a1f1dSLionel Sambuc std::vector<CounterExpression> Expressions; 167*0a6a1f1dSLionel Sambuc std::vector<CounterMappingRegion> MappingRegions; 168*0a6a1f1dSLionel Sambuc 169*0a6a1f1dSLionel Sambuc ObjectFileCoverageMappingReader(const ObjectFileCoverageMappingReader &) 170*0a6a1f1dSLionel Sambuc LLVM_DELETED_FUNCTION; 171*0a6a1f1dSLionel Sambuc ObjectFileCoverageMappingReader & 172*0a6a1f1dSLionel Sambuc operator=(const ObjectFileCoverageMappingReader &) LLVM_DELETED_FUNCTION; 173*0a6a1f1dSLionel Sambuc 174*0a6a1f1dSLionel Sambuc /// \brief Set the current error_code and return same. error(std::error_code EC)175*0a6a1f1dSLionel Sambuc std::error_code error(std::error_code EC) { 176*0a6a1f1dSLionel Sambuc LastError = EC; 177*0a6a1f1dSLionel Sambuc return EC; 178*0a6a1f1dSLionel Sambuc } 179*0a6a1f1dSLionel Sambuc 180*0a6a1f1dSLionel Sambuc /// \brief Clear the current error code and return a successful one. success()181*0a6a1f1dSLionel Sambuc std::error_code success() { return error(instrprof_error::success); } 182*0a6a1f1dSLionel Sambuc 183*0a6a1f1dSLionel Sambuc public: 184*0a6a1f1dSLionel Sambuc ObjectFileCoverageMappingReader(StringRef FileName); 185*0a6a1f1dSLionel Sambuc ObjectFileCoverageMappingReader( 186*0a6a1f1dSLionel Sambuc std::unique_ptr<MemoryBuffer> &ObjectBuffer, 187*0a6a1f1dSLionel Sambuc sys::fs::file_magic Type = sys::fs::file_magic::unknown); 188*0a6a1f1dSLionel Sambuc 189*0a6a1f1dSLionel Sambuc std::error_code readHeader(); 190*0a6a1f1dSLionel Sambuc std::error_code readNextRecord(CoverageMappingRecord &Record); 191*0a6a1f1dSLionel Sambuc 192*0a6a1f1dSLionel Sambuc /// Iterator over profile data. begin()193*0a6a1f1dSLionel Sambuc CoverageMappingIterator begin() { return CoverageMappingIterator(this); } end()194*0a6a1f1dSLionel Sambuc CoverageMappingIterator end() { return CoverageMappingIterator(); } 195*0a6a1f1dSLionel Sambuc 196*0a6a1f1dSLionel Sambuc /// \brief Return true if the reader has finished reading the profile data. isEOF()197*0a6a1f1dSLionel Sambuc bool isEOF() { return LastError == instrprof_error::eof; } 198*0a6a1f1dSLionel Sambuc /// \brief Return true if the reader encountered an error reading profiling 199*0a6a1f1dSLionel Sambuc /// data. hasError()200*0a6a1f1dSLionel Sambuc bool hasError() { return LastError && !isEOF(); } 201*0a6a1f1dSLionel Sambuc /// \brief Get the current error code. getError()202*0a6a1f1dSLionel Sambuc std::error_code getError() { return LastError; } 203*0a6a1f1dSLionel Sambuc }; 204*0a6a1f1dSLionel Sambuc 205*0a6a1f1dSLionel Sambuc } // end namespace coverage 206*0a6a1f1dSLionel Sambuc } // end namespace llvm 207*0a6a1f1dSLionel Sambuc 208*0a6a1f1dSLionel Sambuc #endif 209