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 CoverageMappingReader *Reader; 46 CoverageMappingRecord Record; 47 coveragemap_error ReadErr; 48 49 void increment(); 50 51 public: 52 using iterator_category = std::input_iterator_tag; 53 using value_type = CoverageMappingRecord; 54 using difference_type = std::ptrdiff_t; 55 using pointer = value_type *; 56 using reference = value_type &; 57 58 CoverageMappingIterator() 59 : Reader(nullptr), ReadErr(coveragemap_error::success) {} 60 61 CoverageMappingIterator(CoverageMappingReader *Reader) 62 : Reader(Reader), ReadErr(coveragemap_error::success) { 63 increment(); 64 } 65 66 ~CoverageMappingIterator() { 67 if (ReadErr != coveragemap_error::success) 68 llvm_unreachable("Unexpected error in coverage mapping iterator"); 69 } 70 71 CoverageMappingIterator &operator++() { 72 increment(); 73 return *this; 74 } 75 bool operator==(const CoverageMappingIterator &RHS) const { 76 return Reader == RHS.Reader; 77 } 78 bool operator!=(const CoverageMappingIterator &RHS) const { 79 return Reader != RHS.Reader; 80 } 81 Expected<CoverageMappingRecord &> operator*() { 82 if (ReadErr != coveragemap_error::success) { 83 auto E = make_error<CoverageMapError>(ReadErr); 84 ReadErr = coveragemap_error::success; 85 return std::move(E); 86 } 87 return Record; 88 } 89 Expected<CoverageMappingRecord *> operator->() { 90 if (ReadErr != coveragemap_error::success) { 91 auto E = make_error<CoverageMapError>(ReadErr); 92 ReadErr = coveragemap_error::success; 93 return std::move(E); 94 } 95 return &Record; 96 } 97 }; 98 99 class CoverageMappingReader { 100 public: 101 virtual ~CoverageMappingReader() = default; 102 103 virtual Error readNextRecord(CoverageMappingRecord &Record) = 0; 104 CoverageMappingIterator begin() { return CoverageMappingIterator(this); } 105 CoverageMappingIterator end() { return CoverageMappingIterator(); } 106 }; 107 108 /// Base class for the raw coverage mapping and filenames data readers. 109 class RawCoverageReader { 110 protected: 111 StringRef Data; 112 113 RawCoverageReader(StringRef Data) : Data(Data) {} 114 115 Error readULEB128(uint64_t &Result); 116 Error readIntMax(uint64_t &Result, uint64_t MaxPlus1); 117 Error readSize(uint64_t &Result); 118 Error readString(StringRef &Result); 119 }; 120 121 /// Checks if the given coverage mapping data is exported for 122 /// an unused function. 123 class RawCoverageMappingDummyChecker : public RawCoverageReader { 124 public: 125 RawCoverageMappingDummyChecker(StringRef MappingData) 126 : RawCoverageReader(MappingData) {} 127 128 Expected<bool> isDummy(); 129 }; 130 131 /// Reader for the raw coverage mapping data. 132 class RawCoverageMappingReader : public RawCoverageReader { 133 ArrayRef<std::string> &TranslationUnitFilenames; 134 std::vector<StringRef> &Filenames; 135 std::vector<CounterExpression> &Expressions; 136 std::vector<CounterMappingRegion> &MappingRegions; 137 138 public: 139 RawCoverageMappingReader(StringRef MappingData, 140 ArrayRef<std::string> &TranslationUnitFilenames, 141 std::vector<StringRef> &Filenames, 142 std::vector<CounterExpression> &Expressions, 143 std::vector<CounterMappingRegion> &MappingRegions) 144 : RawCoverageReader(MappingData), 145 TranslationUnitFilenames(TranslationUnitFilenames), 146 Filenames(Filenames), Expressions(Expressions), 147 MappingRegions(MappingRegions) {} 148 RawCoverageMappingReader(const RawCoverageMappingReader &) = delete; 149 RawCoverageMappingReader & 150 operator=(const RawCoverageMappingReader &) = delete; 151 152 Error read(); 153 154 private: 155 Error decodeCounter(unsigned Value, Counter &C); 156 Error readCounter(Counter &C); 157 Error 158 readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions, 159 unsigned InferredFileID, size_t NumFileIDs); 160 }; 161 162 /// Reader for the coverage mapping data that is emitted by the 163 /// frontend and stored in an object file. 164 class BinaryCoverageReader : public CoverageMappingReader { 165 public: 166 struct ProfileMappingRecord { 167 CovMapVersion Version; 168 StringRef FunctionName; 169 uint64_t FunctionHash; 170 StringRef CoverageMapping; 171 size_t FilenamesBegin; 172 size_t FilenamesSize; 173 174 ProfileMappingRecord(CovMapVersion Version, StringRef FunctionName, 175 uint64_t FunctionHash, StringRef CoverageMapping, 176 size_t FilenamesBegin, size_t FilenamesSize) 177 : Version(Version), FunctionName(FunctionName), 178 FunctionHash(FunctionHash), CoverageMapping(CoverageMapping), 179 FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {} 180 }; 181 182 using FuncRecordsStorage = std::unique_ptr<MemoryBuffer>; 183 184 private: 185 std::vector<std::string> Filenames; 186 std::vector<ProfileMappingRecord> MappingRecords; 187 InstrProfSymtab ProfileNames; 188 size_t CurrentRecord = 0; 189 std::vector<StringRef> FunctionsFilenames; 190 std::vector<CounterExpression> Expressions; 191 std::vector<CounterMappingRegion> MappingRegions; 192 193 // Used to tie the lifetimes of coverage function records to the lifetime of 194 // this BinaryCoverageReader instance. Needed to support the format change in 195 // D69471, which can split up function records into multiple sections on ELF. 196 FuncRecordsStorage FuncRecords; 197 198 BinaryCoverageReader(FuncRecordsStorage &&FuncRecords) 199 : FuncRecords(std::move(FuncRecords)) {} 200 201 public: 202 BinaryCoverageReader(const BinaryCoverageReader &) = delete; 203 BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete; 204 205 static Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>> 206 create(MemoryBufferRef ObjectBuffer, StringRef Arch, 207 SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers, 208 StringRef CompilationDir = "", 209 SmallVectorImpl<object::BuildIDRef> *BinaryIDs = nullptr); 210 211 static Expected<std::unique_ptr<BinaryCoverageReader>> 212 createCoverageReaderFromBuffer(StringRef Coverage, 213 FuncRecordsStorage &&FuncRecords, 214 InstrProfSymtab &&ProfileNames, 215 uint8_t BytesInAddress, 216 support::endianness Endian, 217 StringRef CompilationDir = ""); 218 219 Error readNextRecord(CoverageMappingRecord &Record) override; 220 }; 221 222 /// Reader for the raw coverage filenames. 223 class RawCoverageFilenamesReader : public RawCoverageReader { 224 std::vector<std::string> &Filenames; 225 StringRef CompilationDir; 226 227 // Read an uncompressed sequence of filenames. 228 Error readUncompressed(CovMapVersion Version, uint64_t NumFilenames); 229 230 public: 231 RawCoverageFilenamesReader(StringRef Data, 232 std::vector<std::string> &Filenames, 233 StringRef CompilationDir = "") 234 : RawCoverageReader(Data), Filenames(Filenames), 235 CompilationDir(CompilationDir) {} 236 RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete; 237 RawCoverageFilenamesReader & 238 operator=(const RawCoverageFilenamesReader &) = delete; 239 240 Error read(CovMapVersion Version); 241 }; 242 243 } // end namespace coverage 244 } // end namespace llvm 245 246 #endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H 247