xref: /llvm-project/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp (revision df41bd89a56d03aa88cdfc2f8b1255f8ed3fbeca)
1 //=-- CoverageMappingReader.cpp - 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 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
16 #include "llvm/ADT/DenseSet.h"
17 #include "llvm/Object/MachOUniversal.h"
18 #include "llvm/Object/ObjectFile.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/Endian.h"
21 #include "llvm/Support/LEB128.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/raw_ostream.h"
24 
25 using namespace llvm;
26 using namespace coverage;
27 using namespace object;
28 
29 #define DEBUG_TYPE "coverage-mapping"
30 
31 void CoverageMappingIterator::increment() {
32   // Check if all the records were read or if an error occurred while reading
33   // the next record.
34   if (auto E = Reader->readNextRecord(Record)) {
35     handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
36       if (CME.get() == coveragemap_error::eof)
37         *this = CoverageMappingIterator();
38       else
39         llvm_unreachable("Unexpected error in coverage mapping iterator");
40     });
41   }
42 }
43 
44 Error RawCoverageReader::readULEB128(uint64_t &Result) {
45   if (Data.size() < 1)
46     return make_error<CoverageMapError>(coveragemap_error::truncated);
47   unsigned N = 0;
48   Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
49   if (N > Data.size())
50     return make_error<CoverageMapError>(coveragemap_error::malformed);
51   Data = Data.substr(N);
52   return Error::success();
53 }
54 
55 Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
56   if (auto Err = readULEB128(Result))
57     return Err;
58   if (Result >= MaxPlus1)
59     return make_error<CoverageMapError>(coveragemap_error::malformed);
60   return Error::success();
61 }
62 
63 Error RawCoverageReader::readSize(uint64_t &Result) {
64   if (auto Err = readULEB128(Result))
65     return Err;
66   // Sanity check the number.
67   if (Result > Data.size())
68     return make_error<CoverageMapError>(coveragemap_error::malformed);
69   return Error::success();
70 }
71 
72 Error RawCoverageReader::readString(StringRef &Result) {
73   uint64_t Length;
74   if (auto Err = readSize(Length))
75     return Err;
76   Result = Data.substr(0, Length);
77   Data = Data.substr(Length);
78   return Error::success();
79 }
80 
81 Error RawCoverageFilenamesReader::read() {
82   uint64_t NumFilenames;
83   if (auto Err = readSize(NumFilenames))
84     return Err;
85   for (size_t I = 0; I < NumFilenames; ++I) {
86     StringRef Filename;
87     if (auto Err = readString(Filename))
88       return Err;
89     Filenames.push_back(Filename);
90   }
91   return Error::success();
92 }
93 
94 Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
95   auto Tag = Value & Counter::EncodingTagMask;
96   switch (Tag) {
97   case Counter::Zero:
98     C = Counter::getZero();
99     return Error::success();
100   case Counter::CounterValueReference:
101     C = Counter::getCounter(Value >> Counter::EncodingTagBits);
102     return Error::success();
103   default:
104     break;
105   }
106   Tag -= Counter::Expression;
107   switch (Tag) {
108   case CounterExpression::Subtract:
109   case CounterExpression::Add: {
110     auto ID = Value >> Counter::EncodingTagBits;
111     if (ID >= Expressions.size())
112       return make_error<CoverageMapError>(coveragemap_error::malformed);
113     Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
114     C = Counter::getExpression(ID);
115     break;
116   }
117   default:
118     return make_error<CoverageMapError>(coveragemap_error::malformed);
119   }
120   return Error::success();
121 }
122 
123 Error RawCoverageMappingReader::readCounter(Counter &C) {
124   uint64_t EncodedCounter;
125   if (auto Err =
126           readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
127     return Err;
128   if (auto Err = decodeCounter(EncodedCounter, C))
129     return Err;
130   return Error::success();
131 }
132 
133 static const unsigned EncodingExpansionRegionBit = 1
134                                                    << Counter::EncodingTagBits;
135 
136 /// \brief Read the sub-array of regions for the given inferred file id.
137 /// \param NumFileIDs the number of file ids that are defined for this
138 /// function.
139 Error RawCoverageMappingReader::readMappingRegionsSubArray(
140     std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
141     size_t NumFileIDs) {
142   uint64_t NumRegions;
143   if (auto Err = readSize(NumRegions))
144     return Err;
145   unsigned LineStart = 0;
146   for (size_t I = 0; I < NumRegions; ++I) {
147     Counter C;
148     CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
149 
150     // Read the combined counter + region kind.
151     uint64_t EncodedCounterAndRegion;
152     if (auto Err = readIntMax(EncodedCounterAndRegion,
153                               std::numeric_limits<unsigned>::max()))
154       return Err;
155     unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
156     uint64_t ExpandedFileID = 0;
157     if (Tag != Counter::Zero) {
158       if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
159         return Err;
160     } else {
161       // Is it an expansion region?
162       if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
163         Kind = CounterMappingRegion::ExpansionRegion;
164         ExpandedFileID = EncodedCounterAndRegion >>
165                          Counter::EncodingCounterTagAndExpansionRegionTagBits;
166         if (ExpandedFileID >= NumFileIDs)
167           return make_error<CoverageMapError>(coveragemap_error::malformed);
168       } else {
169         switch (EncodedCounterAndRegion >>
170                 Counter::EncodingCounterTagAndExpansionRegionTagBits) {
171         case CounterMappingRegion::CodeRegion:
172           // Don't do anything when we have a code region with a zero counter.
173           break;
174         case CounterMappingRegion::SkippedRegion:
175           Kind = CounterMappingRegion::SkippedRegion;
176           break;
177         default:
178           return make_error<CoverageMapError>(coveragemap_error::malformed);
179         }
180       }
181     }
182 
183     // Read the source range.
184     uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
185     if (auto Err =
186             readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
187       return Err;
188     if (auto Err = readULEB128(ColumnStart))
189       return Err;
190     if (ColumnStart > std::numeric_limits<unsigned>::max())
191       return make_error<CoverageMapError>(coveragemap_error::malformed);
192     if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
193       return Err;
194     if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
195       return Err;
196     LineStart += LineStartDelta;
197     // Adjust the column locations for the empty regions that are supposed to
198     // cover whole lines. Those regions should be encoded with the
199     // column range (1 -> std::numeric_limits<unsigned>::max()), but because
200     // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
201     // we set the column range to (0 -> 0) to ensure that the column start and
202     // column end take up one byte each.
203     // The std::numeric_limits<unsigned>::max() is used to represent a column
204     // position at the end of the line without knowing the length of that line.
205     if (ColumnStart == 0 && ColumnEnd == 0) {
206       ColumnStart = 1;
207       ColumnEnd = std::numeric_limits<unsigned>::max();
208     }
209 
210     DEBUG({
211       dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
212              << ColumnStart << " -> " << (LineStart + NumLines) << ":"
213              << ColumnEnd << ", ";
214       if (Kind == CounterMappingRegion::ExpansionRegion)
215         dbgs() << "Expands to file " << ExpandedFileID;
216       else
217         CounterMappingContext(Expressions).dump(C, dbgs());
218       dbgs() << "\n";
219     });
220 
221     MappingRegions.push_back(CounterMappingRegion(
222         C, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
223         LineStart + NumLines, ColumnEnd, Kind));
224   }
225   return Error::success();
226 }
227 
228 Error RawCoverageMappingReader::read() {
229 
230   // Read the virtual file mapping.
231   llvm::SmallVector<unsigned, 8> VirtualFileMapping;
232   uint64_t NumFileMappings;
233   if (auto Err = readSize(NumFileMappings))
234     return Err;
235   for (size_t I = 0; I < NumFileMappings; ++I) {
236     uint64_t FilenameIndex;
237     if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
238       return Err;
239     VirtualFileMapping.push_back(FilenameIndex);
240   }
241 
242   // Construct the files using unique filenames and virtual file mapping.
243   for (auto I : VirtualFileMapping) {
244     Filenames.push_back(TranslationUnitFilenames[I]);
245   }
246 
247   // Read the expressions.
248   uint64_t NumExpressions;
249   if (auto Err = readSize(NumExpressions))
250     return Err;
251   // Create an array of dummy expressions that get the proper counters
252   // when the expressions are read, and the proper kinds when the counters
253   // are decoded.
254   Expressions.resize(
255       NumExpressions,
256       CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
257   for (size_t I = 0; I < NumExpressions; ++I) {
258     if (auto Err = readCounter(Expressions[I].LHS))
259       return Err;
260     if (auto Err = readCounter(Expressions[I].RHS))
261       return Err;
262   }
263 
264   // Read the mapping regions sub-arrays.
265   for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
266        InferredFileID < S; ++InferredFileID) {
267     if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
268                                               VirtualFileMapping.size()))
269       return Err;
270   }
271 
272   // Set the counters for the expansion regions.
273   // i.e. Counter of expansion region = counter of the first region
274   // from the expanded file.
275   // Perform multiple passes to correctly propagate the counters through
276   // all the nested expansion regions.
277   SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
278   FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
279   for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
280     for (auto &R : MappingRegions) {
281       if (R.Kind != CounterMappingRegion::ExpansionRegion)
282         continue;
283       assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
284       FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
285     }
286     for (auto &R : MappingRegions) {
287       if (FileIDExpansionRegionMapping[R.FileID]) {
288         FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
289         FileIDExpansionRegionMapping[R.FileID] = nullptr;
290       }
291     }
292   }
293 
294   return Error::success();
295 }
296 
297 Error InstrProfSymtab::create(SectionRef &Section) {
298   if (auto EC = Section.getContents(Data))
299     return errorCodeToError(EC);
300   Address = Section.getAddress();
301   return Error::success();
302 }
303 
304 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
305   if (Pointer < Address)
306     return StringRef();
307   auto Offset = Pointer - Address;
308   if (Offset + Size > Data.size())
309     return StringRef();
310   return Data.substr(Pointer - Address, Size);
311 }
312 
313 namespace {
314 struct CovMapFuncRecordReader {
315   // The interface to read coverage mapping function records for
316   // a module. \p Buf is a reference to the buffer pointer pointing
317   // to the \c CovHeader of coverage mapping data associated with
318   // the module.
319   virtual Error readFunctionRecords(const char *&Buf, const char *End) = 0;
320   virtual ~CovMapFuncRecordReader() {}
321   template <class IntPtrT, support::endianness Endian>
322   static Expected<std::unique_ptr<CovMapFuncRecordReader>>
323   get(coverage::CovMapVersion Version, InstrProfSymtab &P,
324       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
325       std::vector<StringRef> &F);
326 };
327 
328 // A class for reading coverage mapping function records for a module.
329 template <coverage::CovMapVersion Version, class IntPtrT,
330           support::endianness Endian>
331 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
332   typedef typename coverage::CovMapTraits<
333       Version, IntPtrT>::CovMapFuncRecordType FuncRecordType;
334   typedef typename coverage::CovMapTraits<Version, IntPtrT>::NameRefType
335       NameRefType;
336 
337   llvm::DenseSet<NameRefType> UniqueFunctionMappingData;
338   InstrProfSymtab &ProfileNames;
339   std::vector<StringRef> &Filenames;
340   std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
341 
342 public:
343   VersionedCovMapFuncRecordReader(
344       InstrProfSymtab &P,
345       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
346       std::vector<StringRef> &F)
347       : ProfileNames(P), Filenames(F), Records(R) {}
348   ~VersionedCovMapFuncRecordReader() override {}
349 
350   Error readFunctionRecords(const char *&Buf, const char *End) override {
351     using namespace support;
352     if (Buf + sizeof(CovMapHeader) > End)
353       return make_error<CoverageMapError>(coveragemap_error::malformed);
354     auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
355     uint32_t NRecords = CovHeader->getNRecords<Endian>();
356     uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
357     uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
358     assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
359     Buf = reinterpret_cast<const char *>(CovHeader + 1);
360 
361     // Skip past the function records, saving the start and end for later.
362     const char *FunBuf = Buf;
363     Buf += NRecords * sizeof(FuncRecordType);
364     const char *FunEnd = Buf;
365 
366     // Get the filenames.
367     if (Buf + FilenamesSize > End)
368       return make_error<CoverageMapError>(coveragemap_error::malformed);
369     size_t FilenamesBegin = Filenames.size();
370     RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
371     if (auto Err = Reader.read())
372       return Err;
373     Buf += FilenamesSize;
374 
375     // We'll read the coverage mapping records in the loop below.
376     const char *CovBuf = Buf;
377     Buf += CoverageSize;
378     const char *CovEnd = Buf;
379 
380     if (Buf > End)
381       return make_error<CoverageMapError>(coveragemap_error::malformed);
382     // Each coverage map has an alignment of 8, so we need to adjust alignment
383     // before reading the next map.
384     Buf += alignmentAdjustment(Buf, 8);
385 
386     auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
387     while ((const char *)CFR < FunEnd) {
388       // Read the function information
389       uint32_t DataSize = CFR->template getDataSize<Endian>();
390       uint64_t FuncHash = CFR->template getFuncHash<Endian>();
391 
392       // Now use that to read the coverage data.
393       if (CovBuf + DataSize > CovEnd)
394         return make_error<CoverageMapError>(coveragemap_error::malformed);
395       auto Mapping = StringRef(CovBuf, DataSize);
396       CovBuf += DataSize;
397 
398       // Ignore this record if we already have a record that points to the same
399       // function name. This is useful to ignore the redundant records for the
400       // functions with ODR linkage.
401       NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
402       if (!UniqueFunctionMappingData.insert(NameRef).second) {
403         CFR++;
404         continue;
405       }
406 
407       StringRef FuncName;
408       if (Error E = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
409         return E;
410       Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
411           Version, FuncName, FuncHash, Mapping, FilenamesBegin,
412           Filenames.size() - FilenamesBegin));
413       CFR++;
414     }
415     return Error::success();
416   }
417 };
418 } // end anonymous namespace
419 
420 template <class IntPtrT, support::endianness Endian>
421 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
422     coverage::CovMapVersion Version, InstrProfSymtab &P,
423     std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
424     std::vector<StringRef> &F) {
425   using namespace coverage;
426   switch (Version) {
427   case CovMapVersion::Version1:
428     return llvm::make_unique<VersionedCovMapFuncRecordReader<
429         CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
430   case CovMapVersion::Version2:
431     // Decompress the name data.
432     if (Error E = P.create(P.getNameData()))
433       return std::move(E);
434     return llvm::make_unique<VersionedCovMapFuncRecordReader<
435         CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
436   }
437   llvm_unreachable("Unsupported version");
438 }
439 
440 template <typename T, support::endianness Endian>
441 static Error readCoverageMappingData(
442     InstrProfSymtab &ProfileNames, StringRef Data,
443     std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
444     std::vector<StringRef> &Filenames) {
445   using namespace coverage;
446   // Read the records in the coverage data section.
447   auto CovHeader =
448       reinterpret_cast<const coverage::CovMapHeader *>(Data.data());
449   CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
450   if (Version > coverage::CovMapVersion::CurrentVersion)
451     return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
452   Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
453       CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
454                                              Filenames);
455   if (Error E = ReaderExpected.takeError())
456     return E;
457   auto Reader = std::move(ReaderExpected.get());
458   for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
459     if (Error E = Reader->readFunctionRecords(Buf, End))
460       return E;
461   }
462   return Error::success();
463 }
464 static const char *TestingFormatMagic = "llvmcovmtestdata";
465 
466 static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames,
467                                StringRef &CoverageMapping,
468                                uint8_t &BytesInAddress,
469                                support::endianness &Endian) {
470   BytesInAddress = 8;
471   Endian = support::endianness::little;
472 
473   Data = Data.substr(StringRef(TestingFormatMagic).size());
474   if (Data.size() < 1)
475     return make_error<CoverageMapError>(coveragemap_error::truncated);
476   unsigned N = 0;
477   auto ProfileNamesSize =
478       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
479   if (N > Data.size())
480     return make_error<CoverageMapError>(coveragemap_error::malformed);
481   Data = Data.substr(N);
482   if (Data.size() < 1)
483     return make_error<CoverageMapError>(coveragemap_error::truncated);
484   N = 0;
485   uint64_t Address =
486       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
487   if (N > Data.size())
488     return make_error<CoverageMapError>(coveragemap_error::malformed);
489   Data = Data.substr(N);
490   if (Data.size() < ProfileNamesSize)
491     return make_error<CoverageMapError>(coveragemap_error::malformed);
492   if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
493     return E;
494   CoverageMapping = Data.substr(ProfileNamesSize);
495   return Error::success();
496 }
497 
498 static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
499   StringRef FoundName;
500   for (const auto &Section : OF.sections()) {
501     if (auto EC = Section.getName(FoundName))
502       return errorCodeToError(EC);
503     if (FoundName == Name)
504       return Section;
505   }
506   return make_error<CoverageMapError>(coveragemap_error::no_data_found);
507 }
508 
509 static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
510                               InstrProfSymtab &ProfileNames,
511                               StringRef &CoverageMapping,
512                               uint8_t &BytesInAddress,
513                               support::endianness &Endian, StringRef Arch) {
514   auto BinOrErr = object::createBinary(ObjectBuffer);
515   if (!BinOrErr)
516     return BinOrErr.takeError();
517   auto Bin = std::move(BinOrErr.get());
518   std::unique_ptr<ObjectFile> OF;
519   if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
520     // If we have a universal binary, try to look up the object for the
521     // appropriate architecture.
522     auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
523     if (auto EC = ObjectFileOrErr.getError())
524       return errorCodeToError(EC);
525     OF = std::move(ObjectFileOrErr.get());
526   } else if (isa<object::ObjectFile>(Bin.get())) {
527     // For any other object file, upcast and take ownership.
528     OF.reset(cast<object::ObjectFile>(Bin.release()));
529     // If we've asked for a particular arch, make sure they match.
530     if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
531       return errorCodeToError(object_error::arch_not_found);
532   } else
533     // We can only handle object files.
534     return make_error<CoverageMapError>(coveragemap_error::malformed);
535 
536   // The coverage uses native pointer sizes for the object it's written in.
537   BytesInAddress = OF->getBytesInAddress();
538   Endian = OF->isLittleEndian() ? support::endianness::little
539                                 : support::endianness::big;
540 
541   // Look for the sections that we are interested in.
542   auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
543   if (auto E = NamesSection.takeError())
544     return E;
545   auto CoverageSection =
546       lookupSection(*OF, getInstrProfCoverageSectionName(false));
547   if (auto E = CoverageSection.takeError())
548     return E;
549 
550   // Get the contents of the given sections.
551   if (auto EC = CoverageSection->getContents(CoverageMapping))
552     return errorCodeToError(EC);
553   if (Error E = ProfileNames.create(*NamesSection))
554     return E;
555 
556   return Error::success();
557 }
558 
559 Expected<std::unique_ptr<BinaryCoverageReader>>
560 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
561                              StringRef Arch) {
562   std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
563 
564   StringRef Coverage;
565   uint8_t BytesInAddress;
566   support::endianness Endian;
567   Error E;
568   consumeError(std::move(E));
569   if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
570     // This is a special format used for testing.
571     E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
572                           Coverage, BytesInAddress, Endian);
573   else
574     E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
575                          Coverage, BytesInAddress, Endian, Arch);
576   if (E)
577     return std::move(E);
578 
579   if (BytesInAddress == 4 && Endian == support::endianness::little)
580     E = readCoverageMappingData<uint32_t, support::endianness::little>(
581         Reader->ProfileNames, Coverage, Reader->MappingRecords,
582         Reader->Filenames);
583   else if (BytesInAddress == 4 && Endian == support::endianness::big)
584     E = readCoverageMappingData<uint32_t, support::endianness::big>(
585         Reader->ProfileNames, Coverage, Reader->MappingRecords,
586         Reader->Filenames);
587   else if (BytesInAddress == 8 && Endian == support::endianness::little)
588     E = readCoverageMappingData<uint64_t, support::endianness::little>(
589         Reader->ProfileNames, Coverage, Reader->MappingRecords,
590         Reader->Filenames);
591   else if (BytesInAddress == 8 && Endian == support::endianness::big)
592     E = readCoverageMappingData<uint64_t, support::endianness::big>(
593         Reader->ProfileNames, Coverage, Reader->MappingRecords,
594         Reader->Filenames);
595   else
596     return make_error<CoverageMapError>(coveragemap_error::malformed);
597   if (E)
598     return std::move(E);
599   return std::move(Reader);
600 }
601 
602 Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
603   if (CurrentRecord >= MappingRecords.size())
604     return make_error<CoverageMapError>(coveragemap_error::eof);
605 
606   FunctionsFilenames.clear();
607   Expressions.clear();
608   MappingRegions.clear();
609   auto &R = MappingRecords[CurrentRecord];
610   RawCoverageMappingReader Reader(
611       R.CoverageMapping,
612       makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
613       FunctionsFilenames, Expressions, MappingRegions);
614   if (auto Err = Reader.read())
615     return Err;
616 
617   Record.FunctionName = R.FunctionName;
618   Record.FunctionHash = R.FunctionHash;
619   Record.Filenames = FunctionsFilenames;
620   Record.Expressions = Expressions;
621   Record.MappingRegions = MappingRegions;
622 
623   ++CurrentRecord;
624   return Error::success();
625 }
626