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