1 //=-- CoverageMappingReader.h - Code coverage mapping reader ------*- 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 // 10 // This file contains support for reading coverage mapping data for 11 // instrumentation based coverage. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H 16 #define LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H 17 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/Triple.h" 21 #include "llvm/Object/ObjectFile.h" 22 #include "llvm/ProfileData/Coverage/CoverageMapping.h" 23 #include "llvm/ProfileData/InstrProf.h" 24 #include "llvm/Support/FileSystem.h" 25 #include "llvm/Support/MemoryBuffer.h" 26 #include <iterator> 27 28 namespace llvm { 29 namespace coverage { 30 31 class CoverageMappingReader; 32 33 /// \brief Coverage mapping information for a single function. 34 struct CoverageMappingRecord { 35 StringRef FunctionName; 36 uint64_t FunctionHash; 37 ArrayRef<StringRef> Filenames; 38 ArrayRef<CounterExpression> Expressions; 39 ArrayRef<CounterMappingRegion> MappingRegions; 40 }; 41 42 /// \brief A file format agnostic iterator over coverage mapping data. 43 class CoverageMappingIterator 44 : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> { 45 CoverageMappingReader *Reader; 46 CoverageMappingRecord Record; 47 48 void increment(); 49 50 public: CoverageMappingIterator()51 CoverageMappingIterator() : Reader(nullptr) {} CoverageMappingIterator(CoverageMappingReader * Reader)52 CoverageMappingIterator(CoverageMappingReader *Reader) : Reader(Reader) { 53 increment(); 54 } 55 56 CoverageMappingIterator &operator++() { 57 increment(); 58 return *this; 59 } 60 bool operator==(const CoverageMappingIterator &RHS) { 61 return Reader == RHS.Reader; 62 } 63 bool operator!=(const CoverageMappingIterator &RHS) { 64 return Reader != RHS.Reader; 65 } 66 CoverageMappingRecord &operator*() { return Record; } 67 CoverageMappingRecord *operator->() { return &Record; } 68 }; 69 70 class CoverageMappingReader { 71 public: 72 virtual Error readNextRecord(CoverageMappingRecord &Record) = 0; begin()73 CoverageMappingIterator begin() { return CoverageMappingIterator(this); } end()74 CoverageMappingIterator end() { return CoverageMappingIterator(); } ~CoverageMappingReader()75 virtual ~CoverageMappingReader() {} 76 }; 77 78 /// \brief Base class for the raw coverage mapping and filenames data readers. 79 class RawCoverageReader { 80 protected: 81 StringRef Data; 82 RawCoverageReader(StringRef Data)83 RawCoverageReader(StringRef Data) : Data(Data) {} 84 85 Error readULEB128(uint64_t &Result); 86 Error readIntMax(uint64_t &Result, uint64_t MaxPlus1); 87 Error readSize(uint64_t &Result); 88 Error readString(StringRef &Result); 89 }; 90 91 /// \brief Reader for the raw coverage filenames. 92 class RawCoverageFilenamesReader : public RawCoverageReader { 93 std::vector<StringRef> &Filenames; 94 95 RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete; 96 RawCoverageFilenamesReader & 97 operator=(const RawCoverageFilenamesReader &) = delete; 98 99 public: RawCoverageFilenamesReader(StringRef Data,std::vector<StringRef> & Filenames)100 RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames) 101 : RawCoverageReader(Data), Filenames(Filenames) {} 102 103 Error read(); 104 }; 105 106 /// \brief Checks if the given coverage mapping data is exported for 107 /// an unused function. 108 class RawCoverageMappingDummyChecker : public RawCoverageReader { 109 public: RawCoverageMappingDummyChecker(StringRef MappingData)110 RawCoverageMappingDummyChecker(StringRef MappingData) 111 : RawCoverageReader(MappingData) {} 112 113 Expected<bool> isDummy(); 114 }; 115 116 /// \brief Reader for the raw coverage mapping data. 117 class RawCoverageMappingReader : public RawCoverageReader { 118 ArrayRef<StringRef> TranslationUnitFilenames; 119 std::vector<StringRef> &Filenames; 120 std::vector<CounterExpression> &Expressions; 121 std::vector<CounterMappingRegion> &MappingRegions; 122 123 RawCoverageMappingReader(const RawCoverageMappingReader &) = delete; 124 RawCoverageMappingReader & 125 operator=(const RawCoverageMappingReader &) = delete; 126 127 public: RawCoverageMappingReader(StringRef MappingData,ArrayRef<StringRef> TranslationUnitFilenames,std::vector<StringRef> & Filenames,std::vector<CounterExpression> & Expressions,std::vector<CounterMappingRegion> & MappingRegions)128 RawCoverageMappingReader(StringRef MappingData, 129 ArrayRef<StringRef> TranslationUnitFilenames, 130 std::vector<StringRef> &Filenames, 131 std::vector<CounterExpression> &Expressions, 132 std::vector<CounterMappingRegion> &MappingRegions) 133 : RawCoverageReader(MappingData), 134 TranslationUnitFilenames(TranslationUnitFilenames), 135 Filenames(Filenames), Expressions(Expressions), 136 MappingRegions(MappingRegions) {} 137 138 Error read(); 139 140 private: 141 Error decodeCounter(unsigned Value, Counter &C); 142 Error readCounter(Counter &C); 143 Error 144 readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions, 145 unsigned InferredFileID, size_t NumFileIDs); 146 }; 147 148 /// \brief Reader for the coverage mapping data that is emitted by the 149 /// frontend and stored in an object file. 150 class BinaryCoverageReader : public CoverageMappingReader { 151 public: 152 struct ProfileMappingRecord { 153 CovMapVersion Version; 154 StringRef FunctionName; 155 uint64_t FunctionHash; 156 StringRef CoverageMapping; 157 size_t FilenamesBegin; 158 size_t FilenamesSize; 159 ProfileMappingRecordProfileMappingRecord160 ProfileMappingRecord(CovMapVersion Version, StringRef FunctionName, 161 uint64_t FunctionHash, StringRef CoverageMapping, 162 size_t FilenamesBegin, size_t FilenamesSize) 163 : Version(Version), FunctionName(FunctionName), 164 FunctionHash(FunctionHash), CoverageMapping(CoverageMapping), 165 FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {} 166 }; 167 168 private: 169 std::vector<StringRef> Filenames; 170 std::vector<ProfileMappingRecord> MappingRecords; 171 InstrProfSymtab ProfileNames; 172 size_t CurrentRecord; 173 std::vector<StringRef> FunctionsFilenames; 174 std::vector<CounterExpression> Expressions; 175 std::vector<CounterMappingRegion> MappingRegions; 176 177 BinaryCoverageReader(const BinaryCoverageReader &) = delete; 178 BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete; 179 BinaryCoverageReader()180 BinaryCoverageReader() : CurrentRecord(0) {} 181 182 public: 183 static Expected<std::unique_ptr<BinaryCoverageReader>> 184 create(std::unique_ptr<MemoryBuffer> &ObjectBuffer, 185 StringRef Arch); 186 187 Error readNextRecord(CoverageMappingRecord &Record) override; 188 }; 189 190 } // end namespace coverage 191 } // end namespace llvm 192 193 #endif 194