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