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