LCOV - code coverage report
Current view: top level - lib/ProfileData/Coverage - CoverageMappingReader.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 239 260 91.9 %
Date: 2018-06-17 00:07:59 Functions: 42 74 56.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13