xref: /llvm-project/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp (revision ac40e81987bd07620d17cfbf7ad8287bb9bd973c)
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/DenseMap.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 Expected<bool> RawCoverageMappingDummyChecker::isDummy() {
298   // A dummy coverage mapping data consists of just one region with zero count.
299   uint64_t NumFileMappings;
300   if (Error Err = readSize(NumFileMappings))
301     return std::move(Err);
302   if (NumFileMappings != 1)
303     return false;
304   // We don't expect any specific value for the filename index, just skip it.
305   uint64_t FilenameIndex;
306   if (Error Err =
307           readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
308     return std::move(Err);
309   uint64_t NumExpressions;
310   if (Error Err = readSize(NumExpressions))
311     return std::move(Err);
312   if (NumExpressions != 0)
313     return false;
314   uint64_t NumRegions;
315   if (Error Err = readSize(NumRegions))
316     return std::move(Err);
317   if (NumRegions != 1)
318     return false;
319   uint64_t EncodedCounterAndRegion;
320   if (Error Err = readIntMax(EncodedCounterAndRegion,
321                              std::numeric_limits<unsigned>::max()))
322     return std::move(Err);
323   unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
324   return Tag == Counter::Zero;
325 }
326 
327 Error InstrProfSymtab::create(SectionRef &Section) {
328   if (auto EC = Section.getContents(Data))
329     return errorCodeToError(EC);
330   Address = Section.getAddress();
331   return Error::success();
332 }
333 
334 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
335   if (Pointer < Address)
336     return StringRef();
337   auto Offset = Pointer - Address;
338   if (Offset + Size > Data.size())
339     return StringRef();
340   return Data.substr(Pointer - Address, Size);
341 }
342 
343 // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
344 static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
345   // The hash value of dummy mapping records is always zero.
346   if (Hash)
347     return false;
348   return RawCoverageMappingDummyChecker(Mapping).isDummy();
349 }
350 
351 namespace {
352 struct CovMapFuncRecordReader {
353   // The interface to read coverage mapping function records for
354   // a module. \p Buf is a reference to the buffer pointer pointing
355   // to the \c CovHeader of coverage mapping data associated with
356   // the module.
357   virtual Error readFunctionRecords(const char *&Buf, const char *End) = 0;
358   virtual ~CovMapFuncRecordReader() {}
359   template <class IntPtrT, support::endianness Endian>
360   static Expected<std::unique_ptr<CovMapFuncRecordReader>>
361   get(coverage::CovMapVersion Version, InstrProfSymtab &P,
362       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
363       std::vector<StringRef> &F);
364 };
365 
366 // A class for reading coverage mapping function records for a module.
367 template <coverage::CovMapVersion Version, class IntPtrT,
368           support::endianness Endian>
369 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
370   typedef typename coverage::CovMapTraits<
371       Version, IntPtrT>::CovMapFuncRecordType FuncRecordType;
372   typedef typename coverage::CovMapTraits<Version, IntPtrT>::NameRefType
373       NameRefType;
374 
375   // Maps function's name references to the indexes of their records
376   // in \c Records.
377   llvm::DenseMap<NameRefType, size_t> FunctionRecords;
378   InstrProfSymtab &ProfileNames;
379   std::vector<StringRef> &Filenames;
380   std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
381 
382   // Add the record to the collection if we don't already have a record that
383   // points to the same function name. This is useful to ignore the redundant
384   // records for the functions with ODR linkage.
385   // In addition, prefer records with real coverage mapping data to dummy
386   // records, which were emitted for inline functions which were seen but
387   // not used in the corresponding translation unit.
388   Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
389                                      StringRef Mapping, size_t FilenamesBegin) {
390     uint64_t FuncHash = CFR->template getFuncHash<Endian>();
391     NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
392     auto InsertResult =
393         FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
394     if (InsertResult.second) {
395       StringRef FuncName;
396       if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
397         return Err;
398       Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
399                            Filenames.size() - FilenamesBegin);
400       return Error::success();
401     }
402     // Update the existing record if it's a dummy and the new record is real.
403     size_t OldRecordIndex = InsertResult.first->second;
404     BinaryCoverageReader::ProfileMappingRecord &OldRecord =
405         Records[OldRecordIndex];
406     Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
407         OldRecord.FunctionHash, OldRecord.CoverageMapping);
408     if (Error Err = OldIsDummyExpected.takeError())
409       return Err;
410     if (!*OldIsDummyExpected)
411       return Error::success();
412     Expected<bool> NewIsDummyExpected =
413         isCoverageMappingDummy(FuncHash, Mapping);
414     if (Error Err = NewIsDummyExpected.takeError())
415       return Err;
416     if (*NewIsDummyExpected)
417       return Error::success();
418     OldRecord.FunctionHash = FuncHash;
419     OldRecord.CoverageMapping = Mapping;
420     OldRecord.FilenamesBegin = FilenamesBegin;
421     OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin;
422     return Error::success();
423   }
424 
425 public:
426   VersionedCovMapFuncRecordReader(
427       InstrProfSymtab &P,
428       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
429       std::vector<StringRef> &F)
430       : ProfileNames(P), Filenames(F), Records(R) {}
431   ~VersionedCovMapFuncRecordReader() override {}
432 
433   Error readFunctionRecords(const char *&Buf, const char *End) override {
434     using namespace support;
435     if (Buf + sizeof(CovMapHeader) > End)
436       return make_error<CoverageMapError>(coveragemap_error::malformed);
437     auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
438     uint32_t NRecords = CovHeader->getNRecords<Endian>();
439     uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
440     uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
441     assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
442     Buf = reinterpret_cast<const char *>(CovHeader + 1);
443 
444     // Skip past the function records, saving the start and end for later.
445     const char *FunBuf = Buf;
446     Buf += NRecords * sizeof(FuncRecordType);
447     const char *FunEnd = Buf;
448 
449     // Get the filenames.
450     if (Buf + FilenamesSize > End)
451       return make_error<CoverageMapError>(coveragemap_error::malformed);
452     size_t FilenamesBegin = Filenames.size();
453     RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
454     if (auto Err = Reader.read())
455       return Err;
456     Buf += FilenamesSize;
457 
458     // We'll read the coverage mapping records in the loop below.
459     const char *CovBuf = Buf;
460     Buf += CoverageSize;
461     const char *CovEnd = Buf;
462 
463     if (Buf > End)
464       return make_error<CoverageMapError>(coveragemap_error::malformed);
465     // Each coverage map has an alignment of 8, so we need to adjust alignment
466     // before reading the next map.
467     Buf += alignmentAdjustment(Buf, 8);
468 
469     auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
470     while ((const char *)CFR < FunEnd) {
471       // Read the function information
472       uint32_t DataSize = CFR->template getDataSize<Endian>();
473 
474       // Now use that to read the coverage data.
475       if (CovBuf + DataSize > CovEnd)
476         return make_error<CoverageMapError>(coveragemap_error::malformed);
477       auto Mapping = StringRef(CovBuf, DataSize);
478       CovBuf += DataSize;
479 
480       if (Error Err =
481               insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
482         return Err;
483       CFR++;
484     }
485     return Error::success();
486   }
487 };
488 } // end anonymous namespace
489 
490 template <class IntPtrT, support::endianness Endian>
491 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
492     coverage::CovMapVersion Version, InstrProfSymtab &P,
493     std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
494     std::vector<StringRef> &F) {
495   using namespace coverage;
496   switch (Version) {
497   case CovMapVersion::Version1:
498     return llvm::make_unique<VersionedCovMapFuncRecordReader<
499         CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
500   case CovMapVersion::Version2:
501     // Decompress the name data.
502     if (Error E = P.create(P.getNameData()))
503       return std::move(E);
504     return llvm::make_unique<VersionedCovMapFuncRecordReader<
505         CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
506   }
507   llvm_unreachable("Unsupported version");
508 }
509 
510 template <typename T, support::endianness Endian>
511 static Error readCoverageMappingData(
512     InstrProfSymtab &ProfileNames, StringRef Data,
513     std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
514     std::vector<StringRef> &Filenames) {
515   using namespace coverage;
516   // Read the records in the coverage data section.
517   auto CovHeader =
518       reinterpret_cast<const coverage::CovMapHeader *>(Data.data());
519   CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
520   if (Version > coverage::CovMapVersion::CurrentVersion)
521     return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
522   Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
523       CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
524                                              Filenames);
525   if (Error E = ReaderExpected.takeError())
526     return E;
527   auto Reader = std::move(ReaderExpected.get());
528   for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
529     if (Error E = Reader->readFunctionRecords(Buf, End))
530       return E;
531   }
532   return Error::success();
533 }
534 static const char *TestingFormatMagic = "llvmcovmtestdata";
535 
536 static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames,
537                                StringRef &CoverageMapping,
538                                uint8_t &BytesInAddress,
539                                support::endianness &Endian) {
540   BytesInAddress = 8;
541   Endian = support::endianness::little;
542 
543   Data = Data.substr(StringRef(TestingFormatMagic).size());
544   if (Data.size() < 1)
545     return make_error<CoverageMapError>(coveragemap_error::truncated);
546   unsigned N = 0;
547   auto ProfileNamesSize =
548       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
549   if (N > Data.size())
550     return make_error<CoverageMapError>(coveragemap_error::malformed);
551   Data = Data.substr(N);
552   if (Data.size() < 1)
553     return make_error<CoverageMapError>(coveragemap_error::truncated);
554   N = 0;
555   uint64_t Address =
556       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
557   if (N > Data.size())
558     return make_error<CoverageMapError>(coveragemap_error::malformed);
559   Data = Data.substr(N);
560   if (Data.size() < ProfileNamesSize)
561     return make_error<CoverageMapError>(coveragemap_error::malformed);
562   if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
563     return E;
564   CoverageMapping = Data.substr(ProfileNamesSize);
565   // Skip the padding bytes because coverage map data has an alignment of 8.
566   if (CoverageMapping.size() < 1)
567     return make_error<CoverageMapError>(coveragemap_error::truncated);
568   size_t Pad = alignmentAdjustment(CoverageMapping.data(), 8);
569   if (CoverageMapping.size() < Pad)
570     return make_error<CoverageMapError>(coveragemap_error::malformed);
571   CoverageMapping = CoverageMapping.substr(Pad);
572   return Error::success();
573 }
574 
575 static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
576   StringRef FoundName;
577   for (const auto &Section : OF.sections()) {
578     if (auto EC = Section.getName(FoundName))
579       return errorCodeToError(EC);
580     if (FoundName == Name)
581       return Section;
582   }
583   return make_error<CoverageMapError>(coveragemap_error::no_data_found);
584 }
585 
586 static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
587                               InstrProfSymtab &ProfileNames,
588                               StringRef &CoverageMapping,
589                               uint8_t &BytesInAddress,
590                               support::endianness &Endian, StringRef Arch) {
591   auto BinOrErr = object::createBinary(ObjectBuffer);
592   if (!BinOrErr)
593     return BinOrErr.takeError();
594   auto Bin = std::move(BinOrErr.get());
595   std::unique_ptr<ObjectFile> OF;
596   if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
597     // If we have a universal binary, try to look up the object for the
598     // appropriate architecture.
599     auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
600     if (auto EC = ObjectFileOrErr.getError())
601       return errorCodeToError(EC);
602     OF = std::move(ObjectFileOrErr.get());
603   } else if (isa<object::ObjectFile>(Bin.get())) {
604     // For any other object file, upcast and take ownership.
605     OF.reset(cast<object::ObjectFile>(Bin.release()));
606     // If we've asked for a particular arch, make sure they match.
607     if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
608       return errorCodeToError(object_error::arch_not_found);
609   } else
610     // We can only handle object files.
611     return make_error<CoverageMapError>(coveragemap_error::malformed);
612 
613   // The coverage uses native pointer sizes for the object it's written in.
614   BytesInAddress = OF->getBytesInAddress();
615   Endian = OF->isLittleEndian() ? support::endianness::little
616                                 : support::endianness::big;
617 
618   // Look for the sections that we are interested in.
619   auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
620   if (auto E = NamesSection.takeError())
621     return E;
622   auto CoverageSection =
623       lookupSection(*OF, getInstrProfCoverageSectionName(false));
624   if (auto E = CoverageSection.takeError())
625     return E;
626 
627   // Get the contents of the given sections.
628   if (auto EC = CoverageSection->getContents(CoverageMapping))
629     return errorCodeToError(EC);
630   if (Error E = ProfileNames.create(*NamesSection))
631     return E;
632 
633   return Error::success();
634 }
635 
636 Expected<std::unique_ptr<BinaryCoverageReader>>
637 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
638                              StringRef Arch) {
639   std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
640 
641   StringRef Coverage;
642   uint8_t BytesInAddress;
643   support::endianness Endian;
644   Error E;
645   consumeError(std::move(E));
646   if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
647     // This is a special format used for testing.
648     E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
649                           Coverage, BytesInAddress, Endian);
650   else
651     E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
652                          Coverage, BytesInAddress, Endian, Arch);
653   if (E)
654     return std::move(E);
655 
656   if (BytesInAddress == 4 && Endian == support::endianness::little)
657     E = readCoverageMappingData<uint32_t, support::endianness::little>(
658         Reader->ProfileNames, Coverage, Reader->MappingRecords,
659         Reader->Filenames);
660   else if (BytesInAddress == 4 && Endian == support::endianness::big)
661     E = readCoverageMappingData<uint32_t, support::endianness::big>(
662         Reader->ProfileNames, Coverage, Reader->MappingRecords,
663         Reader->Filenames);
664   else if (BytesInAddress == 8 && Endian == support::endianness::little)
665     E = readCoverageMappingData<uint64_t, support::endianness::little>(
666         Reader->ProfileNames, Coverage, Reader->MappingRecords,
667         Reader->Filenames);
668   else if (BytesInAddress == 8 && Endian == support::endianness::big)
669     E = readCoverageMappingData<uint64_t, support::endianness::big>(
670         Reader->ProfileNames, Coverage, Reader->MappingRecords,
671         Reader->Filenames);
672   else
673     return make_error<CoverageMapError>(coveragemap_error::malformed);
674   if (E)
675     return std::move(E);
676   return std::move(Reader);
677 }
678 
679 Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
680   if (CurrentRecord >= MappingRecords.size())
681     return make_error<CoverageMapError>(coveragemap_error::eof);
682 
683   FunctionsFilenames.clear();
684   Expressions.clear();
685   MappingRegions.clear();
686   auto &R = MappingRecords[CurrentRecord];
687   RawCoverageMappingReader Reader(
688       R.CoverageMapping,
689       makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
690       FunctionsFilenames, Expressions, MappingRegions);
691   if (auto Err = Reader.read())
692     return Err;
693 
694   Record.FunctionName = R.FunctionName;
695   Record.FunctionHash = R.FunctionHash;
696   Record.Filenames = FunctionsFilenames;
697   Record.Expressions = Expressions;
698   Record.MappingRegions = MappingRegions;
699 
700   ++CurrentRecord;
701   return Error::success();
702 }
703