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