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