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

Generated by: LCOV version 1.13