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