LCOV - code coverage report
Current view: top level - lib/ProfileData/Coverage - CoverageMappingReader.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 433 759 57.0 %
Date: 2018-10-20 13:21:21 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         714 : void CoverageMappingIterator::increment() {
      44         714 :   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        1428 :   if (auto E = Reader->readNextRecord(Record))
      50         645 :     handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
      51         215 :       if (CME.get() == coveragemap_error::eof)
      52         214 :         *this = CoverageMappingIterator();
      53             :       else
      54           1 :         ReadErr = CME.get();
      55             :     });
      56             : }
      57             : 
      58       21227 : Error RawCoverageReader::readULEB128(uint64_t &Result) {
      59       21227 :   if (Data.empty())
      60             :     return make_error<CoverageMapError>(coveragemap_error::truncated);
      61       21227 :   unsigned N = 0;
      62       21227 :   Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
      63       42454 :   if (N > Data.size())
      64             :     return make_error<CoverageMapError>(coveragemap_error::malformed);
      65       21227 :   Data = Data.substr(N);
      66             :   return Error::success();
      67             : }
      68             : 
      69       15268 : Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
      70       30536 :   if (auto Err = readULEB128(Result))
      71             :     return Err;
      72       15268 :   if (Result >= MaxPlus1)
      73             :     return make_error<CoverageMapError>(coveragemap_error::malformed);
      74             :   return Error::success();
      75             : }
      76             : 
      77        2645 : Error RawCoverageReader::readSize(uint64_t &Result) {
      78        5290 :   if (auto Err = readULEB128(Result))
      79             :     return Err;
      80             :   // Sanity check the number.
      81        5290 :   if (Result > Data.size())
      82             :     return make_error<CoverageMapError>(coveragemap_error::malformed);
      83             :   return Error::success();
      84             : }
      85             : 
      86         288 : Error RawCoverageReader::readString(StringRef &Result) {
      87             :   uint64_t Length;
      88         576 :   if (auto Err = readSize(Length))
      89             :     return Err;
      90         288 :   Result = Data.substr(0, Length);
      91         288 :   Data = Data.substr(Length);
      92             :   return Error::success();
      93             : }
      94             : 
      95         152 : Error RawCoverageFilenamesReader::read() {
      96             :   uint64_t NumFilenames;
      97         304 :   if (auto Err = readSize(NumFilenames))
      98             :     return Err;
      99         440 :   for (size_t I = 0; I < NumFilenames; ++I) {
     100         288 :     StringRef Filename;
     101         576 :     if (auto Err = readString(Filename))
     102             :       return Err;
     103         288 :     Filenames.push_back(Filename);
     104             :   }
     105             :   return Error::success();
     106             : }
     107             : 
     108        4104 : Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
     109        4104 :   auto Tag = Value & Counter::EncodingTagMask;
     110        4104 :   switch (Tag) {
     111             :   case Counter::Zero:
     112           0 :     C = Counter::getZero();
     113             :     return Error::success();
     114        3309 :   case Counter::CounterValueReference:
     115        3309 :     C = Counter::getCounter(Value >> Counter::EncodingTagBits);
     116             :     return Error::success();
     117             :   default:
     118             :     break;
     119             :   }
     120         795 :   Tag -= Counter::Expression;
     121         795 :   switch (Tag) {
     122         795 :   case CounterExpression::Subtract:
     123             :   case CounterExpression::Add: {
     124         795 :     auto ID = Value >> Counter::EncodingTagBits;
     125        1590 :     if (ID >= Expressions.size())
     126             :       return make_error<CoverageMapError>(coveragemap_error::malformed);
     127         795 :     Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
     128         795 :     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        1128 : Error RawCoverageMappingReader::readCounter(Counter &C) {
     138             :   uint64_t EncodedCounter;
     139        1128 :   if (auto Err =
     140        1128 :           readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
     141             :     return Err;
     142        2256 :   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         882 : Error RawCoverageMappingReader::readMappingRegionsSubArray(
     154             :     std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
     155             :     size_t NumFileIDs) {
     156             :   uint64_t NumRegions;
     157        1764 :   if (auto Err = readSize(NumRegions))
     158             :     return Err;
     159             :   unsigned LineStart = 0;
     160        4195 :   for (size_t I = 0; I < NumRegions; ++I) {
     161        3314 :     Counter C;
     162             :     CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
     163             : 
     164             :     // Read the combined counter + region kind.
     165             :     uint64_t EncodedCounterAndRegion;
     166        3314 :     if (auto Err = readIntMax(EncodedCounterAndRegion,
     167        3314 :                               std::numeric_limits<unsigned>::max()))
     168             :       return Err;
     169        3314 :     unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
     170             :     uint64_t ExpandedFileID = 0;
     171        3314 :     if (Tag != Counter::Zero) {
     172        5952 :       if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
     173             :         return Err;
     174             :     } else {
     175             :       // Is it an expansion region?
     176         338 :       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         148 :         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        3314 :     if (auto Err =
     200        3314 :             readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
     201             :       return Err;
     202        6628 :     if (auto Err = readULEB128(ColumnStart))
     203             :       return Err;
     204        3314 :     if (ColumnStart > std::numeric_limits<unsigned>::max())
     205             :       return make_error<CoverageMapError>(coveragemap_error::malformed);
     206        6628 :     if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
     207             :       return Err;
     208        6628 :     if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
     209             :       return Err;
     210        3314 :     LineStart += LineStartDelta;
     211             : 
     212             :     // If the high bit of ColumnEnd is set, this is a gap region.
     213        3314 :     if (ColumnEnd & (1U << 31)) {
     214             :       Kind = CounterMappingRegion::GapRegion;
     215         592 :       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        3314 :     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        3314 :                                     LineStart + NumLines, ColumnEnd, Kind);
     245             :     if (CMR.startLoc() > CMR.endLoc())
     246             :       return make_error<CoverageMapError>(coveragemap_error::malformed);
     247        3313 :     MappingRegions.push_back(CMR);
     248             :   }
     249             :   return Error::success();
     250             : }
     251             : 
     252         660 : Error RawCoverageMappingReader::read() {
     253             :   // Read the virtual file mapping.
     254             :   SmallVector<unsigned, 8> VirtualFileMapping;
     255             :   uint64_t NumFileMappings;
     256        1320 :   if (auto Err = readSize(NumFileMappings))
     257             :     return Err;
     258        1542 :   for (size_t I = 0; I < NumFileMappings; ++I) {
     259             :     uint64_t FilenameIndex;
     260        1764 :     if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
     261             :       return Err;
     262         882 :     VirtualFileMapping.push_back(FilenameIndex);
     263             :   }
     264             : 
     265             :   // Construct the files using unique filenames and virtual file mapping.
     266        1542 :   for (auto I : VirtualFileMapping) {
     267        1764 :     Filenames.push_back(TranslationUnitFilenames[I]);
     268             :   }
     269             : 
     270             :   // Read the expressions.
     271             :   uint64_t NumExpressions;
     272        1320 :   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        1320 :   Expressions.resize(
     278             :       NumExpressions,
     279         660 :       CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
     280        1224 :   for (size_t I = 0; I < NumExpressions; ++I) {
     281        1692 :     if (auto Err = readCounter(Expressions[I].LHS))
     282             :       return Err;
     283        1692 :     if (auto Err = readCounter(Expressions[I].RHS))
     284             :       return Err;
     285             :   }
     286             : 
     287             :   // Read the mapping regions sub-arrays.
     288        1541 :   for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
     289        1541 :        InferredFileID < S; ++InferredFileID) {
     290         882 :     if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
     291        1764 :                                               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        1318 :   FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
     302         881 :   for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
     303        5726 :     for (auto &R : MappingRegions) {
     304        5504 :       if (R.Kind != CounterMappingRegion::ExpansionRegion)
     305             :         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           9 : Error InstrProfSymtab::create(SectionRef &Section) {
     351           9 :   if (auto EC = Section.getContents(Data))
     352           0 :     return errorCodeToError(EC);
     353           9 :   Address = Section.getAddress();
     354             :   return Error::success();
     355             : }
     356             : 
     357          44 : StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
     358          44 :   if (Pointer < Address)
     359           0 :     return StringRef();
     360          44 :   auto Offset = Pointer - Address;
     361          88 :   if (Offset + Size > Data.size())
     362           0 :     return StringRef();
     363          44 :   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         414 :   Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
     417             :                                      StringRef Mapping, size_t FilenamesBegin) {
     418         414 :     uint64_t FuncHash = CFR->template getFuncHash<Endian>();
     419             :     NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
     420             :     auto InsertResult =
     421         828 :         FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
     422         414 :     if (InsertResult.second) {
     423         376 :       StringRef FuncName;
     424         420 :       if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
     425             :         return Err;
     426         376 :       if (FuncName.empty())
     427             :         return make_error<InstrProfError>(instrprof_error::malformed);
     428        1128 :       Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
     429         752 :                            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           1 : 
     455             : public:
     456           1 :   VersionedCovMapFuncRecordReader(
     457             :       InstrProfSymtab &P,
     458             :       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
     459           2 :       std::vector<StringRef> &F)
     460           1 :       : ProfileNames(P), Filenames(F), Records(R) {}
     461           1 : 
     462           2 :   ~VersionedCovMapFuncRecordReader() override = default;
     463             : 
     464           1 :   Expected<const char *> readFunctionRecords(const char *Buf,
     465             :                                              const char *End) override {
     466           3 :     using namespace support;
     467           2 : 
     468             :     if (Buf + sizeof(CovMapHeader) > End)
     469             :       return make_error<CoverageMapError>(coveragemap_error::malformed);
     470             :     auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);
     471           0 :     uint32_t NRecords = CovHeader->getNRecords<Endian>();
     472           0 :     uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
     473           0 :     uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
     474           0 :     assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
     475             :     Buf = reinterpret_cast<const char *>(CovHeader + 1);
     476           0 : 
     477             :     // Skip past the function records, saving the start and end for later.
     478           0 :     const char *FunBuf = Buf;
     479             :     Buf += NRecords * sizeof(FuncRecordType);
     480           0 :     const char *FunEnd = Buf;
     481             : 
     482           0 :     // Get the filenames.
     483             :     if (Buf + FilenamesSize > End)
     484           0 :       return make_error<CoverageMapError>(coveragemap_error::malformed);
     485             :     size_t FilenamesBegin = Filenames.size();
     486           0 :     RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
     487           0 :     if (auto Err = Reader.read())
     488           0 :       return std::move(Err);
     489           0 :     Buf += FilenamesSize;
     490             : 
     491             :     // We'll read the coverage mapping records in the loop below.
     492           3 :     const char *CovBuf = Buf;
     493             :     Buf += CoverageSize;
     494           3 :     const char *CovEnd = Buf;
     495             : 
     496             :     if (Buf > End)
     497           6 :       return make_error<CoverageMapError>(coveragemap_error::malformed);
     498           3 :     // Each coverage map has an alignment of 8, so we need to adjust alignment
     499           3 :     // before reading the next map.
     500           3 :     Buf += alignmentAdjustment(Buf, 8);
     501             : 
     502           3 :     auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
     503             :     while ((const char *)CFR < FunEnd) {
     504           9 :       // Read the function information
     505           6 :       uint32_t DataSize = CFR->template getDataSize<Endian>();
     506             : 
     507             :       // Now use that to read the coverage data.
     508             :       if (CovBuf + DataSize > CovEnd)
     509           0 :         return make_error<CoverageMapError>(coveragemap_error::malformed);
     510           0 :       auto Mapping = StringRef(CovBuf, DataSize);
     511           0 :       CovBuf += DataSize;
     512           0 : 
     513             :       if (Error Err =
     514           0 :               insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
     515             :         return std::move(Err);
     516           0 :       CFR++;
     517             :     }
     518           0 :     return Buf;
     519             :   }
     520           0 : };
     521             : 
     522           0 : } // end anonymous namespace
     523             : 
     524           0 : template <class IntPtrT, support::endianness Endian>
     525           0 : Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
     526           0 :     CovMapVersion Version, InstrProfSymtab &P,
     527           0 :     std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
     528             :     std::vector<StringRef> &F) {
     529             :   using namespace coverage;
     530           0 : 
     531             :   switch (Version) {
     532           0 :   case CovMapVersion::Version1:
     533             :     return llvm::make_unique<VersionedCovMapFuncRecordReader<
     534             :         CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
     535           0 :   case CovMapVersion::Version2:
     536           0 :   case CovMapVersion::Version3:
     537           0 :     // Decompress the name data.
     538           0 :     if (Error E = P.create(P.getNameData()))
     539             :       return std::move(E);
     540           0 :     if (Version == CovMapVersion::Version2)
     541             :       return llvm::make_unique<VersionedCovMapFuncRecordReader<
     542           0 :           CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
     543           0 :     else
     544             :       return llvm::make_unique<VersionedCovMapFuncRecordReader<
     545             :           CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
     546             :   }
     547           0 :   llvm_unreachable("Unsupported version");
     548           0 : }
     549           0 : 
     550           0 : template <typename T, support::endianness Endian>
     551             : static Error readCoverageMappingData(
     552           0 :     InstrProfSymtab &ProfileNames, StringRef Data,
     553             :     std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
     554           0 :     std::vector<StringRef> &Filenames) {
     555             :   using namespace coverage;
     556           0 : 
     557             :   // Read the records in the coverage data section.
     558           0 :   auto CovHeader =
     559             :       reinterpret_cast<const CovMapHeader *>(Data.data());
     560           0 :   CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
     561             :   if (Version > CovMapVersion::CurrentVersion)
     562           0 :     return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
     563           0 :   Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
     564           0 :       CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
     565           0 :                                              Filenames);
     566             :   if (Error E = ReaderExpected.takeError())
     567             :     return E;
     568           1 :   auto Reader = std::move(ReaderExpected.get());
     569             :   for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
     570           1 :     auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End);
     571             :     if (auto E = NextHeaderOrErr.takeError())
     572             :       return E;
     573           2 :     Buf = NextHeaderOrErr.get();
     574           1 :   }
     575           1 :   return Error::success();
     576           2 : }
     577             : 
     578           1 : static const char *TestingFormatMagic = "llvmcovmtestdata";
     579             : 
     580           3 : static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames,
     581           2 :                                StringRef &CoverageMapping,
     582             :                                uint8_t &BytesInAddress,
     583             :                                support::endianness &Endian) {
     584             :   BytesInAddress = 8;
     585           0 :   Endian = support::endianness::little;
     586           0 : 
     587           0 :   Data = Data.substr(StringRef(TestingFormatMagic).size());
     588           0 :   if (Data.empty())
     589             :     return make_error<CoverageMapError>(coveragemap_error::truncated);
     590           0 :   unsigned N = 0;
     591             :   auto ProfileNamesSize =
     592           0 :       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
     593             :   if (N > Data.size())
     594           0 :     return make_error<CoverageMapError>(coveragemap_error::malformed);
     595             :   Data = Data.substr(N);
     596           0 :   if (Data.empty())
     597             :     return make_error<CoverageMapError>(coveragemap_error::truncated);
     598           0 :   N = 0;
     599             :   uint64_t Address =
     600           0 :       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
     601           0 :   if (N > Data.size())
     602           0 :     return make_error<CoverageMapError>(coveragemap_error::malformed);
     603           0 :   Data = Data.substr(N);
     604             :   if (Data.size() < ProfileNamesSize)
     605             :     return make_error<CoverageMapError>(coveragemap_error::malformed);
     606           0 :   if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
     607             :     return E;
     608           0 :   CoverageMapping = Data.substr(ProfileNamesSize);
     609             :   // Skip the padding bytes because coverage map data has an alignment of 8.
     610             :   if (CoverageMapping.empty())
     611           0 :     return make_error<CoverageMapError>(coveragemap_error::truncated);
     612           0 :   size_t Pad = alignmentAdjustment(CoverageMapping.data(), 8);
     613           0 :   if (CoverageMapping.size() < Pad)
     614           0 :     return make_error<CoverageMapError>(coveragemap_error::malformed);
     615             :   CoverageMapping = CoverageMapping.substr(Pad);
     616           0 :   return Error::success();
     617             : }
     618           0 : 
     619           0 : static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
     620             :   StringRef FoundName;
     621             :   for (const auto &Section : OF.sections()) {
     622             :     if (auto EC = Section.getName(FoundName))
     623           0 :       return errorCodeToError(EC);
     624           0 :     if (FoundName == Name)
     625           0 :       return Section;
     626           0 :   }
     627             :   return make_error<CoverageMapError>(coveragemap_error::no_data_found);
     628           0 : }
     629             : 
     630           0 : static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
     631             :                               InstrProfSymtab &ProfileNames,
     632           0 :                               StringRef &CoverageMapping,
     633             :                               uint8_t &BytesInAddress,
     634           0 :                               support::endianness &Endian, StringRef Arch) {
     635             :   auto BinOrErr = createBinary(ObjectBuffer);
     636           0 :   if (!BinOrErr)
     637             :     return BinOrErr.takeError();
     638           0 :   auto Bin = std::move(BinOrErr.get());
     639           0 :   std::unique_ptr<ObjectFile> OF;
     640           0 :   if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
     641           0 :     // If we have a universal binary, try to look up the object for the
     642             :     // appropriate architecture.
     643             :     auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
     644           0 :     if (!ObjectFileOrErr)
     645             :       return ObjectFileOrErr.takeError();
     646           0 :     OF = std::move(ObjectFileOrErr.get());
     647             :   } else if (isa<ObjectFile>(Bin.get())) {
     648             :     // For any other object file, upcast and take ownership.
     649           0 :     OF.reset(cast<ObjectFile>(Bin.release()));
     650           0 :     // If we've asked for a particular arch, make sure they match.
     651           0 :     if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
     652           0 :       return errorCodeToError(object_error::arch_not_found);
     653             :   } else
     654           0 :     // We can only handle object files.
     655             :     return make_error<CoverageMapError>(coveragemap_error::malformed);
     656           0 : 
     657           0 :   // The coverage uses native pointer sizes for the object it's written in.
     658             :   BytesInAddress = OF->getBytesInAddress();
     659             :   Endian = OF->isLittleEndian() ? support::endianness::little
     660             :                                 : support::endianness::big;
     661           0 : 
     662           0 :   // Look for the sections that we are interested in.
     663           0 :   auto ObjFormat = OF->getTripleObjectFormat();
     664           0 :   auto NamesSection =
     665             :       lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
     666           0 :                                                  /*AddSegmentInfo=*/false));
     667             :   if (auto E = NamesSection.takeError())
     668           0 :     return E;
     669             :   auto CoverageSection =
     670           0 :       lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
     671             :                                                  /*AddSegmentInfo=*/false));
     672           0 :   if (auto E = CoverageSection.takeError())
     673             :     return E;
     674           0 : 
     675             :   // Get the contents of the given sections.
     676           0 :   if (auto EC = CoverageSection->getContents(CoverageMapping))
     677           0 :     return errorCodeToError(EC);
     678           0 :   if (Error E = ProfileNames.create(*NamesSection))
     679           0 :     return E;
     680             : 
     681             :   return Error::success();
     682          44 : }
     683             : 
     684          44 : Expected<std::unique_ptr<BinaryCoverageReader>>
     685             : BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
     686             :                              StringRef Arch) {
     687          88 :   std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
     688          44 : 
     689          42 :   StringRef Coverage;
     690          84 :   uint8_t BytesInAddress;
     691             :   support::endianness Endian;
     692          42 :   Error E = Error::success();
     693             :   consumeError(std::move(E));
     694         126 :   if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
     695          84 :     // This is a special format used for testing.
     696             :     E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
     697             :                           Coverage, BytesInAddress, Endian);
     698             :   else
     699           2 :     E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
     700           2 :                          Coverage, BytesInAddress, Endian, Arch);
     701           2 :   if (E)
     702           2 :     return std::move(E);
     703             : 
     704           2 :   if (BytesInAddress == 4 && Endian == support::endianness::little)
     705             :     E = readCoverageMappingData<uint32_t, support::endianness::little>(
     706           2 :         Reader->ProfileNames, Coverage, Reader->MappingRecords,
     707             :         Reader->Filenames);
     708           0 :   else if (BytesInAddress == 4 && Endian == support::endianness::big)
     709             :     E = readCoverageMappingData<uint32_t, support::endianness::big>(
     710           0 :         Reader->ProfileNames, Coverage, Reader->MappingRecords,
     711             :         Reader->Filenames);
     712           0 :   else if (BytesInAddress == 8 && Endian == support::endianness::little)
     713             :     E = readCoverageMappingData<uint64_t, support::endianness::little>(
     714           0 :         Reader->ProfileNames, Coverage, Reader->MappingRecords,
     715           0 :         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          54 :   else
     721             :     return make_error<CoverageMapError>(coveragemap_error::malformed);
     722          54 :   if (E)
     723             :     return std::move(E);
     724             :   return std::move(Reader);
     725         108 : }
     726          54 : 
     727          54 : Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
     728          54 :   if (CurrentRecord >= MappingRecords.size())
     729             :     return make_error<CoverageMapError>(coveragemap_error::eof);
     730          54 : 
     731             :   FunctionsFilenames.clear();
     732         162 :   Expressions.clear();
     733         108 :   MappingRegions.clear();
     734             :   auto &R = MappingRecords[CurrentRecord];
     735             :   RawCoverageMappingReader Reader(
     736             :       R.CoverageMapping,
     737           0 :       makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
     738           0 :       FunctionsFilenames, Expressions, MappingRegions);
     739           0 :   if (auto Err = Reader.read())
     740           0 :     return Err;
     741             : 
     742           0 :   Record.FunctionName = R.FunctionName;
     743             :   Record.FunctionHash = R.FunctionHash;
     744           0 :   Record.Filenames = FunctionsFilenames;
     745             :   Record.Expressions = Expressions;
     746           0 :   Record.MappingRegions = MappingRegions;
     747             : 
     748           0 :   ++CurrentRecord;
     749             :   return Error::success();
     750           0 : }

Generated by: LCOV version 1.13