xref: /freebsd/contrib/llvm-project/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp (revision 2d7bb03adb43dd605464db3a9634ff33bf74ca5f)
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/Statistic.h"
20  #include "llvm/ADT/StringRef.h"
21  #include "llvm/ADT/Triple.h"
22  #include "llvm/Object/Archive.h"
23  #include "llvm/Object/Binary.h"
24  #include "llvm/Object/COFF.h"
25  #include "llvm/Object/Error.h"
26  #include "llvm/Object/MachOUniversal.h"
27  #include "llvm/Object/ObjectFile.h"
28  #include "llvm/ProfileData/InstrProf.h"
29  #include "llvm/Support/Casting.h"
30  #include "llvm/Support/Compression.h"
31  #include "llvm/Support/Debug.h"
32  #include "llvm/Support/Endian.h"
33  #include "llvm/Support/Error.h"
34  #include "llvm/Support/ErrorHandling.h"
35  #include "llvm/Support/LEB128.h"
36  #include "llvm/Support/MathExtras.h"
37  #include "llvm/Support/Path.h"
38  #include "llvm/Support/raw_ostream.h"
39  #include <vector>
40  
41  using namespace llvm;
42  using namespace coverage;
43  using namespace object;
44  
45  #define DEBUG_TYPE "coverage-mapping"
46  
47  STATISTIC(CovMapNumRecords, "The # of coverage function records");
48  STATISTIC(CovMapNumUsedRecords, "The # of used coverage function records");
49  
50  void CoverageMappingIterator::increment() {
51    if (ReadErr != coveragemap_error::success)
52      return;
53  
54    // Check if all the records were read or if an error occurred while reading
55    // the next record.
56    if (auto E = Reader->readNextRecord(Record))
57      handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
58        if (CME.get() == coveragemap_error::eof)
59          *this = CoverageMappingIterator();
60        else
61          ReadErr = CME.get();
62      });
63  }
64  
65  Error RawCoverageReader::readULEB128(uint64_t &Result) {
66    if (Data.empty())
67      return make_error<CoverageMapError>(coveragemap_error::truncated);
68    unsigned N = 0;
69    Result = decodeULEB128(Data.bytes_begin(), &N);
70    if (N > Data.size())
71      return make_error<CoverageMapError>(coveragemap_error::malformed);
72    Data = Data.substr(N);
73    return Error::success();
74  }
75  
76  Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
77    if (auto Err = readULEB128(Result))
78      return Err;
79    if (Result >= MaxPlus1)
80      return make_error<CoverageMapError>(coveragemap_error::malformed);
81    return Error::success();
82  }
83  
84  Error RawCoverageReader::readSize(uint64_t &Result) {
85    if (auto Err = readULEB128(Result))
86      return Err;
87    if (Result > Data.size())
88      return make_error<CoverageMapError>(coveragemap_error::malformed);
89    return Error::success();
90  }
91  
92  Error RawCoverageReader::readString(StringRef &Result) {
93    uint64_t Length;
94    if (auto Err = readSize(Length))
95      return Err;
96    Result = Data.substr(0, Length);
97    Data = Data.substr(Length);
98    return Error::success();
99  }
100  
101  Error RawCoverageFilenamesReader::read(CovMapVersion Version) {
102    uint64_t NumFilenames;
103    if (auto Err = readSize(NumFilenames))
104      return Err;
105    if (!NumFilenames)
106      return make_error<CoverageMapError>(coveragemap_error::malformed);
107  
108    if (Version < CovMapVersion::Version4)
109      return readUncompressed(Version, NumFilenames);
110  
111    // The uncompressed length may exceed the size of the encoded filenames.
112    // Skip size validation.
113    uint64_t UncompressedLen;
114    if (auto Err = readULEB128(UncompressedLen))
115      return Err;
116  
117    uint64_t CompressedLen;
118    if (auto Err = readSize(CompressedLen))
119      return Err;
120  
121    if (CompressedLen > 0) {
122      if (!compression::zlib::isAvailable())
123        return make_error<CoverageMapError>(
124            coveragemap_error::decompression_failed);
125  
126      // Allocate memory for the decompressed filenames.
127      SmallVector<uint8_t, 0> StorageBuf;
128  
129      // Read compressed filenames.
130      StringRef CompressedFilenames = Data.substr(0, CompressedLen);
131      Data = Data.substr(CompressedLen);
132      auto Err = compression::zlib::decompress(
133          arrayRefFromStringRef(CompressedFilenames), StorageBuf,
134          UncompressedLen);
135      if (Err) {
136        consumeError(std::move(Err));
137        return make_error<CoverageMapError>(
138            coveragemap_error::decompression_failed);
139      }
140  
141      RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
142                                          CompilationDir);
143      return Delegate.readUncompressed(Version, NumFilenames);
144    }
145  
146    return readUncompressed(Version, NumFilenames);
147  }
148  
149  Error RawCoverageFilenamesReader::readUncompressed(CovMapVersion Version,
150                                                     uint64_t NumFilenames) {
151    // Read uncompressed filenames.
152    if (Version < CovMapVersion::Version6) {
153      for (size_t I = 0; I < NumFilenames; ++I) {
154        StringRef Filename;
155        if (auto Err = readString(Filename))
156          return Err;
157        Filenames.push_back(Filename.str());
158      }
159    } else {
160      StringRef CWD;
161      if (auto Err = readString(CWD))
162        return Err;
163      Filenames.push_back(CWD.str());
164  
165      for (size_t I = 1; I < NumFilenames; ++I) {
166        StringRef Filename;
167        if (auto Err = readString(Filename))
168          return Err;
169        if (sys::path::is_absolute(Filename)) {
170          Filenames.push_back(Filename.str());
171        } else {
172          SmallString<256> P;
173          if (!CompilationDir.empty())
174            P.assign(CompilationDir);
175          else
176            P.assign(CWD);
177          llvm::sys::path::append(P, Filename);
178          sys::path::remove_dots(P, /*remove_dot_dot=*/true);
179          Filenames.push_back(static_cast<std::string>(P.str()));
180        }
181      }
182    }
183    return Error::success();
184  }
185  
186  Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
187    auto Tag = Value & Counter::EncodingTagMask;
188    switch (Tag) {
189    case Counter::Zero:
190      C = Counter::getZero();
191      return Error::success();
192    case Counter::CounterValueReference:
193      C = Counter::getCounter(Value >> Counter::EncodingTagBits);
194      return Error::success();
195    default:
196      break;
197    }
198    Tag -= Counter::Expression;
199    switch (Tag) {
200    case CounterExpression::Subtract:
201    case CounterExpression::Add: {
202      auto ID = Value >> Counter::EncodingTagBits;
203      if (ID >= Expressions.size())
204        return make_error<CoverageMapError>(coveragemap_error::malformed);
205      Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
206      C = Counter::getExpression(ID);
207      break;
208    }
209    default:
210      return make_error<CoverageMapError>(coveragemap_error::malformed);
211    }
212    return Error::success();
213  }
214  
215  Error RawCoverageMappingReader::readCounter(Counter &C) {
216    uint64_t EncodedCounter;
217    if (auto Err =
218            readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
219      return Err;
220    if (auto Err = decodeCounter(EncodedCounter, C))
221      return Err;
222    return Error::success();
223  }
224  
225  static const unsigned EncodingExpansionRegionBit = 1
226                                                     << Counter::EncodingTagBits;
227  
228  /// Read the sub-array of regions for the given inferred file id.
229  /// \param NumFileIDs the number of file ids that are defined for this
230  /// function.
231  Error RawCoverageMappingReader::readMappingRegionsSubArray(
232      std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
233      size_t NumFileIDs) {
234    uint64_t NumRegions;
235    if (auto Err = readSize(NumRegions))
236      return Err;
237    unsigned LineStart = 0;
238    for (size_t I = 0; I < NumRegions; ++I) {
239      Counter C, C2;
240      CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
241  
242      // Read the combined counter + region kind.
243      uint64_t EncodedCounterAndRegion;
244      if (auto Err = readIntMax(EncodedCounterAndRegion,
245                                std::numeric_limits<unsigned>::max()))
246        return Err;
247      unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
248      uint64_t ExpandedFileID = 0;
249  
250      // If Tag does not represent a ZeroCounter, then it is understood to refer
251      // to a counter or counter expression with region kind assumed to be
252      // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the
253      // referenced counter or counter expression (and nothing else).
254      //
255      // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set,
256      // then EncodedCounterAndRegion is interpreted to represent an
257      // ExpansionRegion. In all other cases, EncodedCounterAndRegion is
258      // interpreted to refer to a specific region kind, after which additional
259      // fields may be read (e.g. BranchRegions have two encoded counters that
260      // follow an encoded region kind value).
261      if (Tag != Counter::Zero) {
262        if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
263          return Err;
264      } else {
265        // Is it an expansion region?
266        if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
267          Kind = CounterMappingRegion::ExpansionRegion;
268          ExpandedFileID = EncodedCounterAndRegion >>
269                           Counter::EncodingCounterTagAndExpansionRegionTagBits;
270          if (ExpandedFileID >= NumFileIDs)
271            return make_error<CoverageMapError>(coveragemap_error::malformed);
272        } else {
273          switch (EncodedCounterAndRegion >>
274                  Counter::EncodingCounterTagAndExpansionRegionTagBits) {
275          case CounterMappingRegion::CodeRegion:
276            // Don't do anything when we have a code region with a zero counter.
277            break;
278          case CounterMappingRegion::SkippedRegion:
279            Kind = CounterMappingRegion::SkippedRegion;
280            break;
281          case CounterMappingRegion::BranchRegion:
282            // For a Branch Region, read two successive counters.
283            Kind = CounterMappingRegion::BranchRegion;
284            if (auto Err = readCounter(C))
285              return Err;
286            if (auto Err = readCounter(C2))
287              return Err;
288            break;
289          default:
290            return make_error<CoverageMapError>(coveragemap_error::malformed);
291          }
292        }
293      }
294  
295      // Read the source range.
296      uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
297      if (auto Err =
298              readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
299        return Err;
300      if (auto Err = readULEB128(ColumnStart))
301        return Err;
302      if (ColumnStart > std::numeric_limits<unsigned>::max())
303        return make_error<CoverageMapError>(coveragemap_error::malformed);
304      if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
305        return Err;
306      if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
307        return Err;
308      LineStart += LineStartDelta;
309  
310      // If the high bit of ColumnEnd is set, this is a gap region.
311      if (ColumnEnd & (1U << 31)) {
312        Kind = CounterMappingRegion::GapRegion;
313        ColumnEnd &= ~(1U << 31);
314      }
315  
316      // Adjust the column locations for the empty regions that are supposed to
317      // cover whole lines. Those regions should be encoded with the
318      // column range (1 -> std::numeric_limits<unsigned>::max()), but because
319      // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
320      // we set the column range to (0 -> 0) to ensure that the column start and
321      // column end take up one byte each.
322      // The std::numeric_limits<unsigned>::max() is used to represent a column
323      // position at the end of the line without knowing the length of that line.
324      if (ColumnStart == 0 && ColumnEnd == 0) {
325        ColumnStart = 1;
326        ColumnEnd = std::numeric_limits<unsigned>::max();
327      }
328  
329      LLVM_DEBUG({
330        dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
331               << ColumnStart << " -> " << (LineStart + NumLines) << ":"
332               << ColumnEnd << ", ";
333        if (Kind == CounterMappingRegion::ExpansionRegion)
334          dbgs() << "Expands to file " << ExpandedFileID;
335        else
336          CounterMappingContext(Expressions).dump(C, dbgs());
337        dbgs() << "\n";
338      });
339  
340      auto CMR = CounterMappingRegion(C, C2, InferredFileID, ExpandedFileID,
341                                      LineStart, ColumnStart,
342                                      LineStart + NumLines, ColumnEnd, Kind);
343      if (CMR.startLoc() > CMR.endLoc())
344        return make_error<CoverageMapError>(coveragemap_error::malformed);
345      MappingRegions.push_back(CMR);
346    }
347    return Error::success();
348  }
349  
350  Error RawCoverageMappingReader::read() {
351    // Read the virtual file mapping.
352    SmallVector<unsigned, 8> VirtualFileMapping;
353    uint64_t NumFileMappings;
354    if (auto Err = readSize(NumFileMappings))
355      return Err;
356    for (size_t I = 0; I < NumFileMappings; ++I) {
357      uint64_t FilenameIndex;
358      if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
359        return Err;
360      VirtualFileMapping.push_back(FilenameIndex);
361    }
362  
363    // Construct the files using unique filenames and virtual file mapping.
364    for (auto I : VirtualFileMapping) {
365      Filenames.push_back(TranslationUnitFilenames[I]);
366    }
367  
368    // Read the expressions.
369    uint64_t NumExpressions;
370    if (auto Err = readSize(NumExpressions))
371      return Err;
372    // Create an array of dummy expressions that get the proper counters
373    // when the expressions are read, and the proper kinds when the counters
374    // are decoded.
375    Expressions.resize(
376        NumExpressions,
377        CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
378    for (size_t I = 0; I < NumExpressions; ++I) {
379      if (auto Err = readCounter(Expressions[I].LHS))
380        return Err;
381      if (auto Err = readCounter(Expressions[I].RHS))
382        return Err;
383    }
384  
385    // Read the mapping regions sub-arrays.
386    for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
387         InferredFileID < S; ++InferredFileID) {
388      if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
389                                                VirtualFileMapping.size()))
390        return Err;
391    }
392  
393    // Set the counters for the expansion regions.
394    // i.e. Counter of expansion region = counter of the first region
395    // from the expanded file.
396    // Perform multiple passes to correctly propagate the counters through
397    // all the nested expansion regions.
398    SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
399    FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
400    for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
401      for (auto &R : MappingRegions) {
402        if (R.Kind != CounterMappingRegion::ExpansionRegion)
403          continue;
404        assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
405        FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
406      }
407      for (auto &R : MappingRegions) {
408        if (FileIDExpansionRegionMapping[R.FileID]) {
409          FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
410          FileIDExpansionRegionMapping[R.FileID] = nullptr;
411        }
412      }
413    }
414  
415    return Error::success();
416  }
417  
418  Expected<bool> RawCoverageMappingDummyChecker::isDummy() {
419    // A dummy coverage mapping data consists of just one region with zero count.
420    uint64_t NumFileMappings;
421    if (Error Err = readSize(NumFileMappings))
422      return std::move(Err);
423    if (NumFileMappings != 1)
424      return false;
425    // We don't expect any specific value for the filename index, just skip it.
426    uint64_t FilenameIndex;
427    if (Error Err =
428            readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
429      return std::move(Err);
430    uint64_t NumExpressions;
431    if (Error Err = readSize(NumExpressions))
432      return std::move(Err);
433    if (NumExpressions != 0)
434      return false;
435    uint64_t NumRegions;
436    if (Error Err = readSize(NumRegions))
437      return std::move(Err);
438    if (NumRegions != 1)
439      return false;
440    uint64_t EncodedCounterAndRegion;
441    if (Error Err = readIntMax(EncodedCounterAndRegion,
442                               std::numeric_limits<unsigned>::max()))
443      return std::move(Err);
444    unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
445    return Tag == Counter::Zero;
446  }
447  
448  Error InstrProfSymtab::create(SectionRef &Section) {
449    Expected<StringRef> DataOrErr = Section.getContents();
450    if (!DataOrErr)
451      return DataOrErr.takeError();
452    Data = *DataOrErr;
453    Address = Section.getAddress();
454  
455    // If this is a linked PE/COFF file, then we have to skip over the null byte
456    // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
457    const ObjectFile *Obj = Section.getObject();
458    if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
459      Data = Data.drop_front(1);
460  
461    return Error::success();
462  }
463  
464  StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
465    if (Pointer < Address)
466      return StringRef();
467    auto Offset = Pointer - Address;
468    if (Offset + Size > Data.size())
469      return StringRef();
470    return Data.substr(Pointer - Address, Size);
471  }
472  
473  // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
474  static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
475    // The hash value of dummy mapping records is always zero.
476    if (Hash)
477      return false;
478    return RawCoverageMappingDummyChecker(Mapping).isDummy();
479  }
480  
481  /// A range of filename indices. Used to specify the location of a batch of
482  /// filenames in a vector-like container.
483  struct FilenameRange {
484    unsigned StartingIndex;
485    unsigned Length;
486  
487    FilenameRange(unsigned StartingIndex, unsigned Length)
488        : StartingIndex(StartingIndex), Length(Length) {}
489  
490    void markInvalid() { Length = 0; }
491    bool isInvalid() const { return Length == 0; }
492  };
493  
494  namespace {
495  
496  /// The interface to read coverage mapping function records for a module.
497  struct CovMapFuncRecordReader {
498    virtual ~CovMapFuncRecordReader() = default;
499  
500    // Read a coverage header.
501    //
502    // \p CovBuf points to the buffer containing the \c CovHeader of the coverage
503    // mapping data associated with the module.
504    //
505    // Returns a pointer to the next \c CovHeader if it exists, or to an address
506    // greater than \p CovEnd if not.
507    virtual Expected<const char *> readCoverageHeader(const char *CovBuf,
508                                                      const char *CovBufEnd) = 0;
509  
510    // Read function records.
511    //
512    // \p FuncRecBuf points to the buffer containing a batch of function records.
513    // \p FuncRecBufEnd points past the end of the batch of records.
514    //
515    // Prior to Version4, \p OutOfLineFileRange points to a sequence of filenames
516    // associated with the function records. It is unused in Version4.
517    //
518    // Prior to Version4, \p OutOfLineMappingBuf points to a sequence of coverage
519    // mappings associated with the function records. It is unused in Version4.
520    virtual Error
521    readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
522                        std::optional<FilenameRange> OutOfLineFileRange,
523                        const char *OutOfLineMappingBuf,
524                        const char *OutOfLineMappingBufEnd) = 0;
525  
526    template <class IntPtrT, support::endianness Endian>
527    static Expected<std::unique_ptr<CovMapFuncRecordReader>>
528    get(CovMapVersion Version, InstrProfSymtab &P,
529        std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
530        std::vector<std::string> &F);
531  };
532  
533  // A class for reading coverage mapping function records for a module.
534  template <CovMapVersion Version, class IntPtrT, support::endianness Endian>
535  class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
536    using FuncRecordType =
537        typename CovMapTraits<Version, IntPtrT>::CovMapFuncRecordType;
538    using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
539  
540    // Maps function's name references to the indexes of their records
541    // in \c Records.
542    DenseMap<NameRefType, size_t> FunctionRecords;
543    InstrProfSymtab &ProfileNames;
544    StringRef CompilationDir;
545    std::vector<std::string> &Filenames;
546    std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
547  
548    // Maps a hash of the filenames in a TU to a \c FileRange. The range
549    // specifies the location of the hashed filenames in \c Filenames.
550    DenseMap<uint64_t, FilenameRange> FileRangeMap;
551  
552    // Add the record to the collection if we don't already have a record that
553    // points to the same function name. This is useful to ignore the redundant
554    // records for the functions with ODR linkage.
555    // In addition, prefer records with real coverage mapping data to dummy
556    // records, which were emitted for inline functions which were seen but
557    // not used in the corresponding translation unit.
558    Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
559                                       StringRef Mapping,
560                                       FilenameRange FileRange) {
561      ++CovMapNumRecords;
562      uint64_t FuncHash = CFR->template getFuncHash<Endian>();
563      NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
564      auto InsertResult =
565          FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
566      if (InsertResult.second) {
567        StringRef FuncName;
568        if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
569          return Err;
570        if (FuncName.empty())
571          return make_error<InstrProfError>(instrprof_error::malformed,
572                                            "function name is empty");
573        ++CovMapNumUsedRecords;
574        Records.emplace_back(Version, FuncName, FuncHash, Mapping,
575                             FileRange.StartingIndex, FileRange.Length);
576        return Error::success();
577      }
578      // Update the existing record if it's a dummy and the new record is real.
579      size_t OldRecordIndex = InsertResult.first->second;
580      BinaryCoverageReader::ProfileMappingRecord &OldRecord =
581          Records[OldRecordIndex];
582      Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
583          OldRecord.FunctionHash, OldRecord.CoverageMapping);
584      if (Error Err = OldIsDummyExpected.takeError())
585        return Err;
586      if (!*OldIsDummyExpected)
587        return Error::success();
588      Expected<bool> NewIsDummyExpected =
589          isCoverageMappingDummy(FuncHash, Mapping);
590      if (Error Err = NewIsDummyExpected.takeError())
591        return Err;
592      if (*NewIsDummyExpected)
593        return Error::success();
594      ++CovMapNumUsedRecords;
595      OldRecord.FunctionHash = FuncHash;
596      OldRecord.CoverageMapping = Mapping;
597      OldRecord.FilenamesBegin = FileRange.StartingIndex;
598      OldRecord.FilenamesSize = FileRange.Length;
599      return Error::success();
600    }
601  
602  public:
603    VersionedCovMapFuncRecordReader(
604        InstrProfSymtab &P,
605        std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
606        std::vector<std::string> &F)
607        : ProfileNames(P), CompilationDir(D), Filenames(F), Records(R) {}
608  
609    ~VersionedCovMapFuncRecordReader() override = default;
610  
611    Expected<const char *> readCoverageHeader(const char *CovBuf,
612                                              const char *CovBufEnd) override {
613      using namespace support;
614  
615      if (CovBuf + sizeof(CovMapHeader) > CovBufEnd)
616        return make_error<CoverageMapError>(coveragemap_error::malformed);
617      auto CovHeader = reinterpret_cast<const CovMapHeader *>(CovBuf);
618      uint32_t NRecords = CovHeader->getNRecords<Endian>();
619      uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
620      uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
621      assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
622      CovBuf = reinterpret_cast<const char *>(CovHeader + 1);
623  
624      // Skip past the function records, saving the start and end for later.
625      // This is a no-op in Version4 (function records are read after all headers
626      // are read).
627      const char *FuncRecBuf = nullptr;
628      const char *FuncRecBufEnd = nullptr;
629      if (Version < CovMapVersion::Version4)
630        FuncRecBuf = CovBuf;
631      CovBuf += NRecords * sizeof(FuncRecordType);
632      if (Version < CovMapVersion::Version4)
633        FuncRecBufEnd = CovBuf;
634  
635      // Get the filenames.
636      if (CovBuf + FilenamesSize > CovBufEnd)
637        return make_error<CoverageMapError>(coveragemap_error::malformed);
638      size_t FilenamesBegin = Filenames.size();
639      StringRef FilenameRegion(CovBuf, FilenamesSize);
640      RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
641                                        CompilationDir);
642      if (auto Err = Reader.read(Version))
643        return std::move(Err);
644      CovBuf += FilenamesSize;
645      FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
646  
647      if (Version >= CovMapVersion::Version4) {
648        // Map a hash of the filenames region to the filename range associated
649        // with this coverage header.
650        int64_t FilenamesRef =
651            llvm::IndexedInstrProf::ComputeHash(FilenameRegion);
652        auto Insert =
653            FileRangeMap.insert(std::make_pair(FilenamesRef, FileRange));
654        if (!Insert.second) {
655          // The same filenames ref was encountered twice. It's possible that
656          // the associated filenames are the same.
657          auto It = Filenames.begin();
658          FilenameRange &OrigRange = Insert.first->getSecond();
659          if (std::equal(It + OrigRange.StartingIndex,
660                         It + OrigRange.StartingIndex + OrigRange.Length,
661                         It + FileRange.StartingIndex,
662                         It + FileRange.StartingIndex + FileRange.Length))
663            // Map the new range to the original one.
664            FileRange = OrigRange;
665          else
666            // This is a hash collision. Mark the filenames ref invalid.
667            OrigRange.markInvalid();
668        }
669      }
670  
671      // We'll read the coverage mapping records in the loop below.
672      // This is a no-op in Version4 (coverage mappings are not affixed to the
673      // coverage header).
674      const char *MappingBuf = CovBuf;
675      if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
676        return make_error<CoverageMapError>(coveragemap_error::malformed);
677      CovBuf += CoverageSize;
678      const char *MappingEnd = CovBuf;
679  
680      if (CovBuf > CovBufEnd)
681        return make_error<CoverageMapError>(coveragemap_error::malformed);
682  
683      if (Version < CovMapVersion::Version4) {
684        // Read each function record.
685        if (Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
686                                          MappingBuf, MappingEnd))
687          return std::move(E);
688      }
689  
690      // Each coverage map has an alignment of 8, so we need to adjust alignment
691      // before reading the next map.
692      CovBuf += offsetToAlignedAddr(CovBuf, Align(8));
693  
694      return CovBuf;
695    }
696  
697    Error readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
698                              std::optional<FilenameRange> OutOfLineFileRange,
699                              const char *OutOfLineMappingBuf,
700                              const char *OutOfLineMappingBufEnd) override {
701      auto CFR = reinterpret_cast<const FuncRecordType *>(FuncRecBuf);
702      while ((const char *)CFR < FuncRecBufEnd) {
703        // Validate the length of the coverage mapping for this function.
704        const char *NextMappingBuf;
705        const FuncRecordType *NextCFR;
706        std::tie(NextMappingBuf, NextCFR) =
707            CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
708        if (Version < CovMapVersion::Version4)
709          if (NextMappingBuf > OutOfLineMappingBufEnd)
710            return make_error<CoverageMapError>(coveragemap_error::malformed);
711  
712        // Look up the set of filenames associated with this function record.
713        std::optional<FilenameRange> FileRange;
714        if (Version < CovMapVersion::Version4) {
715          FileRange = OutOfLineFileRange;
716        } else {
717          uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
718          auto It = FileRangeMap.find(FilenamesRef);
719          if (It == FileRangeMap.end())
720            return make_error<CoverageMapError>(coveragemap_error::malformed);
721          else
722            FileRange = It->getSecond();
723        }
724  
725        // Now, read the coverage data.
726        if (FileRange && !FileRange->isInvalid()) {
727          StringRef Mapping =
728              CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
729          if (Version >= CovMapVersion::Version4 &&
730              Mapping.data() + Mapping.size() > FuncRecBufEnd)
731            return make_error<CoverageMapError>(coveragemap_error::malformed);
732          if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
733            return Err;
734        }
735  
736        std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
737      }
738      return Error::success();
739    }
740  };
741  
742  } // end anonymous namespace
743  
744  template <class IntPtrT, support::endianness Endian>
745  Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
746      CovMapVersion Version, InstrProfSymtab &P,
747      std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
748      std::vector<std::string> &F) {
749    using namespace coverage;
750  
751    switch (Version) {
752    case CovMapVersion::Version1:
753      return std::make_unique<VersionedCovMapFuncRecordReader<
754          CovMapVersion::Version1, IntPtrT, Endian>>(P, R, D, F);
755    case CovMapVersion::Version2:
756    case CovMapVersion::Version3:
757    case CovMapVersion::Version4:
758    case CovMapVersion::Version5:
759    case CovMapVersion::Version6:
760      // Decompress the name data.
761      if (Error E = P.create(P.getNameData()))
762        return std::move(E);
763      if (Version == CovMapVersion::Version2)
764        return std::make_unique<VersionedCovMapFuncRecordReader<
765            CovMapVersion::Version2, IntPtrT, Endian>>(P, R, D, F);
766      else if (Version == CovMapVersion::Version3)
767        return std::make_unique<VersionedCovMapFuncRecordReader<
768            CovMapVersion::Version3, IntPtrT, Endian>>(P, R, D, F);
769      else if (Version == CovMapVersion::Version4)
770        return std::make_unique<VersionedCovMapFuncRecordReader<
771            CovMapVersion::Version4, IntPtrT, Endian>>(P, R, D, F);
772      else if (Version == CovMapVersion::Version5)
773        return std::make_unique<VersionedCovMapFuncRecordReader<
774            CovMapVersion::Version5, IntPtrT, Endian>>(P, R, D, F);
775      else if (Version == CovMapVersion::Version6)
776        return std::make_unique<VersionedCovMapFuncRecordReader<
777            CovMapVersion::Version6, IntPtrT, Endian>>(P, R, D, F);
778    }
779    llvm_unreachable("Unsupported version");
780  }
781  
782  template <typename T, support::endianness Endian>
783  static Error readCoverageMappingData(
784      InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords,
785      std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
786      StringRef CompilationDir, std::vector<std::string> &Filenames) {
787    using namespace coverage;
788  
789    // Read the records in the coverage data section.
790    auto CovHeader =
791        reinterpret_cast<const CovMapHeader *>(CovMap.data());
792    CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
793    if (Version > CovMapVersion::CurrentVersion)
794      return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
795    Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
796        CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
797                                               CompilationDir, Filenames);
798    if (Error E = ReaderExpected.takeError())
799      return E;
800    auto Reader = std::move(ReaderExpected.get());
801    const char *CovBuf = CovMap.data();
802    const char *CovBufEnd = CovBuf + CovMap.size();
803    const char *FuncRecBuf = FuncRecords.data();
804    const char *FuncRecBufEnd = FuncRecords.data() + FuncRecords.size();
805    while (CovBuf < CovBufEnd) {
806      // Read the current coverage header & filename data.
807      //
808      // Prior to Version4, this also reads all function records affixed to the
809      // header.
810      //
811      // Return a pointer to the next coverage header.
812      auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
813      if (auto E = NextOrErr.takeError())
814        return E;
815      CovBuf = NextOrErr.get();
816    }
817    // In Version4, function records are not affixed to coverage headers. Read
818    // the records from their dedicated section.
819    if (Version >= CovMapVersion::Version4)
820      return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
821                                         nullptr, nullptr);
822    return Error::success();
823  }
824  
825  static const char *TestingFormatMagic = "llvmcovmtestdata";
826  
827  Expected<std::unique_ptr<BinaryCoverageReader>>
828  BinaryCoverageReader::createCoverageReaderFromBuffer(
829      StringRef Coverage, FuncRecordsStorage &&FuncRecords,
830      InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress,
831      support::endianness Endian, StringRef CompilationDir) {
832    std::unique_ptr<BinaryCoverageReader> Reader(
833        new BinaryCoverageReader(std::move(FuncRecords)));
834    Reader->ProfileNames = std::move(ProfileNames);
835    StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
836    if (BytesInAddress == 4 && Endian == support::endianness::little) {
837      if (Error E =
838              readCoverageMappingData<uint32_t, support::endianness::little>(
839                  Reader->ProfileNames, Coverage, FuncRecordsRef,
840                  Reader->MappingRecords, CompilationDir, Reader->Filenames))
841        return std::move(E);
842    } else if (BytesInAddress == 4 && Endian == support::endianness::big) {
843      if (Error E = readCoverageMappingData<uint32_t, support::endianness::big>(
844              Reader->ProfileNames, Coverage, FuncRecordsRef,
845              Reader->MappingRecords, CompilationDir, Reader->Filenames))
846        return std::move(E);
847    } else if (BytesInAddress == 8 && Endian == support::endianness::little) {
848      if (Error E =
849              readCoverageMappingData<uint64_t, support::endianness::little>(
850                  Reader->ProfileNames, Coverage, FuncRecordsRef,
851                  Reader->MappingRecords, CompilationDir, Reader->Filenames))
852        return std::move(E);
853    } else if (BytesInAddress == 8 && Endian == support::endianness::big) {
854      if (Error E = readCoverageMappingData<uint64_t, support::endianness::big>(
855              Reader->ProfileNames, Coverage, FuncRecordsRef,
856              Reader->MappingRecords, CompilationDir, Reader->Filenames))
857        return std::move(E);
858    } else
859      return make_error<CoverageMapError>(coveragemap_error::malformed);
860    return std::move(Reader);
861  }
862  
863  static Expected<std::unique_ptr<BinaryCoverageReader>>
864  loadTestingFormat(StringRef Data, StringRef CompilationDir) {
865    uint8_t BytesInAddress = 8;
866    support::endianness Endian = support::endianness::little;
867  
868    Data = Data.substr(StringRef(TestingFormatMagic).size());
869    if (Data.empty())
870      return make_error<CoverageMapError>(coveragemap_error::truncated);
871    unsigned N = 0;
872    uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
873    if (N > Data.size())
874      return make_error<CoverageMapError>(coveragemap_error::malformed);
875    Data = Data.substr(N);
876    if (Data.empty())
877      return make_error<CoverageMapError>(coveragemap_error::truncated);
878    N = 0;
879    uint64_t Address = decodeULEB128(Data.bytes_begin(), &N);
880    if (N > Data.size())
881      return make_error<CoverageMapError>(coveragemap_error::malformed);
882    Data = Data.substr(N);
883    if (Data.size() < ProfileNamesSize)
884      return make_error<CoverageMapError>(coveragemap_error::malformed);
885    InstrProfSymtab ProfileNames;
886    if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
887      return std::move(E);
888    Data = Data.substr(ProfileNamesSize);
889    // Skip the padding bytes because coverage map data has an alignment of 8.
890    size_t Pad = offsetToAlignedAddr(Data.data(), Align(8));
891    if (Data.size() < Pad)
892      return make_error<CoverageMapError>(coveragemap_error::malformed);
893    Data = Data.substr(Pad);
894    if (Data.size() < sizeof(CovMapHeader))
895      return make_error<CoverageMapError>(coveragemap_error::malformed);
896    auto const *CovHeader = reinterpret_cast<const CovMapHeader *>(
897        Data.substr(0, sizeof(CovMapHeader)).data());
898    CovMapVersion Version =
899        (CovMapVersion)CovHeader->getVersion<support::endianness::little>();
900    StringRef CoverageMapping;
901    BinaryCoverageReader::FuncRecordsStorage CoverageRecords;
902    if (Version < CovMapVersion::Version4) {
903      CoverageMapping = Data;
904      if (CoverageMapping.empty())
905        return make_error<CoverageMapError>(coveragemap_error::truncated);
906      CoverageRecords = MemoryBuffer::getMemBuffer("");
907    } else {
908      uint32_t FilenamesSize =
909          CovHeader->getFilenamesSize<support::endianness::little>();
910      uint32_t CoverageMappingSize = sizeof(CovMapHeader) + FilenamesSize;
911      CoverageMapping = Data.substr(0, CoverageMappingSize);
912      if (CoverageMapping.empty())
913        return make_error<CoverageMapError>(coveragemap_error::truncated);
914      Data = Data.substr(CoverageMappingSize);
915      // Skip the padding bytes because coverage records data has an alignment
916      // of 8.
917      Pad = offsetToAlignedAddr(Data.data(), Align(8));
918      if (Data.size() < Pad)
919        return make_error<CoverageMapError>(coveragemap_error::malformed);
920      CoverageRecords = MemoryBuffer::getMemBuffer(Data.substr(Pad));
921      if (CoverageRecords->getBufferSize() == 0)
922        return make_error<CoverageMapError>(coveragemap_error::truncated);
923    }
924    return BinaryCoverageReader::createCoverageReaderFromBuffer(
925        CoverageMapping, std::move(CoverageRecords), std::move(ProfileNames),
926        BytesInAddress, Endian, CompilationDir);
927  }
928  
929  /// Find all sections that match \p Name. There may be more than one if comdats
930  /// are in use, e.g. for the __llvm_covfun section on ELF.
931  static Expected<std::vector<SectionRef>> lookupSections(ObjectFile &OF,
932                                                          StringRef Name) {
933    // On COFF, the object file section name may end in "$M". This tells the
934    // linker to sort these sections between "$A" and "$Z". The linker removes the
935    // dollar and everything after it in the final binary. Do the same to match.
936    bool IsCOFF = isa<COFFObjectFile>(OF);
937    auto stripSuffix = [IsCOFF](StringRef N) {
938      return IsCOFF ? N.split('$').first : N;
939    };
940    Name = stripSuffix(Name);
941  
942    std::vector<SectionRef> Sections;
943    for (const auto &Section : OF.sections()) {
944      Expected<StringRef> NameOrErr = Section.getName();
945      if (!NameOrErr)
946        return NameOrErr.takeError();
947      if (stripSuffix(*NameOrErr) == Name)
948        Sections.push_back(Section);
949    }
950    if (Sections.empty())
951      return make_error<CoverageMapError>(coveragemap_error::no_data_found);
952    return Sections;
953  }
954  
955  static Expected<std::unique_ptr<BinaryCoverageReader>>
956  loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
957                   StringRef CompilationDir = "",
958                   std::optional<object::BuildIDRef> *BinaryID = nullptr) {
959    std::unique_ptr<ObjectFile> OF;
960    if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
961      // If we have a universal binary, try to look up the object for the
962      // appropriate architecture.
963      auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
964      if (!ObjectFileOrErr)
965        return ObjectFileOrErr.takeError();
966      OF = std::move(ObjectFileOrErr.get());
967    } else if (isa<ObjectFile>(Bin.get())) {
968      // For any other object file, upcast and take ownership.
969      OF.reset(cast<ObjectFile>(Bin.release()));
970      // If we've asked for a particular arch, make sure they match.
971      if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
972        return errorCodeToError(object_error::arch_not_found);
973    } else
974      // We can only handle object files.
975      return make_error<CoverageMapError>(coveragemap_error::malformed);
976  
977    // The coverage uses native pointer sizes for the object it's written in.
978    uint8_t BytesInAddress = OF->getBytesInAddress();
979    support::endianness Endian = OF->isLittleEndian()
980                                     ? support::endianness::little
981                                     : support::endianness::big;
982  
983    // Look for the sections that we are interested in.
984    auto ObjFormat = OF->getTripleObjectFormat();
985    auto NamesSection =
986        lookupSections(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
987                                                   /*AddSegmentInfo=*/false));
988    if (auto E = NamesSection.takeError())
989      return std::move(E);
990    auto CoverageSection =
991        lookupSections(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
992                                                    /*AddSegmentInfo=*/false));
993    if (auto E = CoverageSection.takeError())
994      return std::move(E);
995    std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
996    if (CoverageSectionRefs.size() != 1)
997      return make_error<CoverageMapError>(coveragemap_error::malformed);
998    auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
999    if (!CoverageMappingOrErr)
1000      return CoverageMappingOrErr.takeError();
1001    StringRef CoverageMapping = CoverageMappingOrErr.get();
1002  
1003    InstrProfSymtab ProfileNames;
1004    std::vector<SectionRef> NamesSectionRefs = *NamesSection;
1005    if (NamesSectionRefs.size() != 1)
1006      return make_error<CoverageMapError>(coveragemap_error::malformed);
1007    if (Error E = ProfileNames.create(NamesSectionRefs.back()))
1008      return std::move(E);
1009  
1010    // Look for the coverage records section (Version4 only).
1011    auto CoverageRecordsSections =
1012        lookupSections(*OF, getInstrProfSectionName(IPSK_covfun, ObjFormat,
1013                                                    /*AddSegmentInfo=*/false));
1014  
1015    BinaryCoverageReader::FuncRecordsStorage FuncRecords;
1016    if (auto E = CoverageRecordsSections.takeError()) {
1017      consumeError(std::move(E));
1018      FuncRecords = MemoryBuffer::getMemBuffer("");
1019    } else {
1020      // Compute the FuncRecordsBuffer of the buffer, taking into account the
1021      // padding between each record, and making sure the first block is aligned
1022      // in memory to maintain consistency between buffer address and size
1023      // alignment.
1024      const Align RecordAlignment(8);
1025      uint64_t FuncRecordsSize = 0;
1026      for (SectionRef Section : *CoverageRecordsSections) {
1027        auto CoverageRecordsOrErr = Section.getContents();
1028        if (!CoverageRecordsOrErr)
1029          return CoverageRecordsOrErr.takeError();
1030        FuncRecordsSize += alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1031      }
1032      auto WritableBuffer =
1033          WritableMemoryBuffer::getNewUninitMemBuffer(FuncRecordsSize);
1034      char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1035      assert(isAddrAligned(RecordAlignment, FuncRecordsBuffer) &&
1036             "Allocated memory is correctly aligned");
1037  
1038      for (SectionRef Section : *CoverageRecordsSections) {
1039        auto CoverageRecordsOrErr = Section.getContents();
1040        if (!CoverageRecordsOrErr)
1041          return CoverageRecordsOrErr.takeError();
1042        const auto &CoverageRecords = CoverageRecordsOrErr.get();
1043        FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1044                                      CoverageRecords.end(), FuncRecordsBuffer);
1045        FuncRecordsBuffer =
1046            std::fill_n(FuncRecordsBuffer,
1047                        alignAddr(FuncRecordsBuffer, RecordAlignment) -
1048                            (uintptr_t)FuncRecordsBuffer,
1049                        '\0');
1050      }
1051      assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1052             "consistent init");
1053      FuncRecords = std::move(WritableBuffer);
1054    }
1055  
1056    if (BinaryID)
1057      *BinaryID = getBuildID(OF.get());
1058  
1059    return BinaryCoverageReader::createCoverageReaderFromBuffer(
1060        CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
1061        BytesInAddress, Endian, CompilationDir);
1062  }
1063  
1064  /// Determine whether \p Arch is invalid or empty, given \p Bin.
1065  static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) {
1066    // If we have a universal binary and Arch doesn't identify any of its slices,
1067    // it's user error.
1068    if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
1069      for (auto &ObjForArch : Universal->objects())
1070        if (Arch == ObjForArch.getArchFlagName())
1071          return false;
1072      return true;
1073    }
1074    return false;
1075  }
1076  
1077  Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
1078  BinaryCoverageReader::create(
1079      MemoryBufferRef ObjectBuffer, StringRef Arch,
1080      SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
1081      StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
1082    std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1083  
1084    if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) {
1085      // This is a special format used for testing.
1086      auto ReaderOrErr =
1087          loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir);
1088      if (!ReaderOrErr)
1089        return ReaderOrErr.takeError();
1090      Readers.push_back(std::move(ReaderOrErr.get()));
1091      return std::move(Readers);
1092    }
1093  
1094    auto BinOrErr = createBinary(ObjectBuffer);
1095    if (!BinOrErr)
1096      return BinOrErr.takeError();
1097    std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
1098  
1099    if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
1100      return make_error<CoverageMapError>(
1101          coveragemap_error::invalid_or_missing_arch_specifier);
1102  
1103    // MachO universal binaries which contain archives need to be treated as
1104    // archives, not as regular binaries.
1105    if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1106      for (auto &ObjForArch : Universal->objects()) {
1107        // Skip slices within the universal binary which target the wrong arch.
1108        std::string ObjArch = ObjForArch.getArchFlagName();
1109        if (Arch != ObjArch)
1110          continue;
1111  
1112        auto ArchiveOrErr = ObjForArch.getAsArchive();
1113        if (!ArchiveOrErr) {
1114          // If this is not an archive, try treating it as a regular object.
1115          consumeError(ArchiveOrErr.takeError());
1116          break;
1117        }
1118  
1119        return BinaryCoverageReader::create(
1120            ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1121            CompilationDir, BinaryIDs);
1122      }
1123    }
1124  
1125    // Load coverage out of archive members.
1126    if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
1127      Error Err = Error::success();
1128      for (auto &Child : Ar->children(Err)) {
1129        Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
1130        if (!ChildBufOrErr)
1131          return ChildBufOrErr.takeError();
1132  
1133        auto ChildReadersOrErr = BinaryCoverageReader::create(
1134            ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
1135            BinaryIDs);
1136        if (!ChildReadersOrErr)
1137          return ChildReadersOrErr.takeError();
1138        for (auto &Reader : ChildReadersOrErr.get())
1139          Readers.push_back(std::move(Reader));
1140      }
1141      if (Err)
1142        return std::move(Err);
1143  
1144      // Thin archives reference object files outside of the archive file, i.e.
1145      // files which reside in memory not owned by the caller. Transfer ownership
1146      // to the caller.
1147      if (Ar->isThin())
1148        for (auto &Buffer : Ar->takeThinBuffers())
1149          ObjectFileBuffers.push_back(std::move(Buffer));
1150  
1151      return std::move(Readers);
1152    }
1153  
1154    std::optional<object::BuildIDRef> BinaryID;
1155    auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
1156                                        BinaryIDs ? &BinaryID : nullptr);
1157    if (!ReaderOrErr)
1158      return ReaderOrErr.takeError();
1159    Readers.push_back(std::move(ReaderOrErr.get()));
1160    if (BinaryID)
1161      BinaryIDs->push_back(*BinaryID);
1162    return std::move(Readers);
1163  }
1164  
1165  Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
1166    if (CurrentRecord >= MappingRecords.size())
1167      return make_error<CoverageMapError>(coveragemap_error::eof);
1168  
1169    FunctionsFilenames.clear();
1170    Expressions.clear();
1171    MappingRegions.clear();
1172    auto &R = MappingRecords[CurrentRecord];
1173    auto F = ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1174    RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames,
1175                                    Expressions, MappingRegions);
1176    if (auto Err = Reader.read())
1177      return Err;
1178  
1179    Record.FunctionName = R.FunctionName;
1180    Record.FunctionHash = R.FunctionHash;
1181    Record.Filenames = FunctionsFilenames;
1182    Record.Expressions = Expressions;
1183    Record.MappingRegions = MappingRegions;
1184  
1185    ++CurrentRecord;
1186    return Error::success();
1187  }
1188