xref: /freebsd/contrib/llvm-project/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp (revision 8bcb0991864975618c09697b1aca10683346d9f0)
10b57cec5SDimitry Andric //===- CoverageMappingReader.cpp - Code coverage mapping reader -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains support for reading coverage mapping data for
100b57cec5SDimitry Andric // instrumentation based coverage.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
150b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
160b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
170b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
200b57cec5SDimitry Andric #include "llvm/ADT/Triple.h"
210b57cec5SDimitry Andric #include "llvm/Object/Binary.h"
220b57cec5SDimitry Andric #include "llvm/Object/Error.h"
230b57cec5SDimitry Andric #include "llvm/Object/MachOUniversal.h"
240b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
250b57cec5SDimitry Andric #include "llvm/Object/COFF.h"
260b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h"
270b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
280b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
290b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
300b57cec5SDimitry Andric #include "llvm/Support/Error.h"
310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
320b57cec5SDimitry Andric #include "llvm/Support/LEB128.h"
330b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
340b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
350b57cec5SDimitry Andric #include <vector>
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric using namespace llvm;
380b57cec5SDimitry Andric using namespace coverage;
390b57cec5SDimitry Andric using namespace object;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric #define DEBUG_TYPE "coverage-mapping"
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric void CoverageMappingIterator::increment() {
440b57cec5SDimitry Andric   if (ReadErr != coveragemap_error::success)
450b57cec5SDimitry Andric     return;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric   // Check if all the records were read or if an error occurred while reading
480b57cec5SDimitry Andric   // the next record.
490b57cec5SDimitry Andric   if (auto E = Reader->readNextRecord(Record))
500b57cec5SDimitry Andric     handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
510b57cec5SDimitry Andric       if (CME.get() == coveragemap_error::eof)
520b57cec5SDimitry Andric         *this = CoverageMappingIterator();
530b57cec5SDimitry Andric       else
540b57cec5SDimitry Andric         ReadErr = CME.get();
550b57cec5SDimitry Andric     });
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric Error RawCoverageReader::readULEB128(uint64_t &Result) {
590b57cec5SDimitry Andric   if (Data.empty())
600b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::truncated);
610b57cec5SDimitry Andric   unsigned N = 0;
620b57cec5SDimitry Andric   Result = decodeULEB128(Data.bytes_begin(), &N);
630b57cec5SDimitry Andric   if (N > Data.size())
640b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
650b57cec5SDimitry Andric   Data = Data.substr(N);
660b57cec5SDimitry Andric   return Error::success();
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
700b57cec5SDimitry Andric   if (auto Err = readULEB128(Result))
710b57cec5SDimitry Andric     return Err;
720b57cec5SDimitry Andric   if (Result >= MaxPlus1)
730b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
740b57cec5SDimitry Andric   return Error::success();
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric Error RawCoverageReader::readSize(uint64_t &Result) {
780b57cec5SDimitry Andric   if (auto Err = readULEB128(Result))
790b57cec5SDimitry Andric     return Err;
800b57cec5SDimitry Andric   // Sanity check the number.
810b57cec5SDimitry Andric   if (Result > Data.size())
820b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
830b57cec5SDimitry Andric   return Error::success();
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric Error RawCoverageReader::readString(StringRef &Result) {
870b57cec5SDimitry Andric   uint64_t Length;
880b57cec5SDimitry Andric   if (auto Err = readSize(Length))
890b57cec5SDimitry Andric     return Err;
900b57cec5SDimitry Andric   Result = Data.substr(0, Length);
910b57cec5SDimitry Andric   Data = Data.substr(Length);
920b57cec5SDimitry Andric   return Error::success();
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric Error RawCoverageFilenamesReader::read() {
960b57cec5SDimitry Andric   uint64_t NumFilenames;
970b57cec5SDimitry Andric   if (auto Err = readSize(NumFilenames))
980b57cec5SDimitry Andric     return Err;
990b57cec5SDimitry Andric   for (size_t I = 0; I < NumFilenames; ++I) {
1000b57cec5SDimitry Andric     StringRef Filename;
1010b57cec5SDimitry Andric     if (auto Err = readString(Filename))
1020b57cec5SDimitry Andric       return Err;
1030b57cec5SDimitry Andric     Filenames.push_back(Filename);
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric   return Error::success();
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
1090b57cec5SDimitry Andric   auto Tag = Value & Counter::EncodingTagMask;
1100b57cec5SDimitry Andric   switch (Tag) {
1110b57cec5SDimitry Andric   case Counter::Zero:
1120b57cec5SDimitry Andric     C = Counter::getZero();
1130b57cec5SDimitry Andric     return Error::success();
1140b57cec5SDimitry Andric   case Counter::CounterValueReference:
1150b57cec5SDimitry Andric     C = Counter::getCounter(Value >> Counter::EncodingTagBits);
1160b57cec5SDimitry Andric     return Error::success();
1170b57cec5SDimitry Andric   default:
1180b57cec5SDimitry Andric     break;
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric   Tag -= Counter::Expression;
1210b57cec5SDimitry Andric   switch (Tag) {
1220b57cec5SDimitry Andric   case CounterExpression::Subtract:
1230b57cec5SDimitry Andric   case CounterExpression::Add: {
1240b57cec5SDimitry Andric     auto ID = Value >> Counter::EncodingTagBits;
1250b57cec5SDimitry Andric     if (ID >= Expressions.size())
1260b57cec5SDimitry Andric       return make_error<CoverageMapError>(coveragemap_error::malformed);
1270b57cec5SDimitry Andric     Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
1280b57cec5SDimitry Andric     C = Counter::getExpression(ID);
1290b57cec5SDimitry Andric     break;
1300b57cec5SDimitry Andric   }
1310b57cec5SDimitry Andric   default:
1320b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
1330b57cec5SDimitry Andric   }
1340b57cec5SDimitry Andric   return Error::success();
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric Error RawCoverageMappingReader::readCounter(Counter &C) {
1380b57cec5SDimitry Andric   uint64_t EncodedCounter;
1390b57cec5SDimitry Andric   if (auto Err =
1400b57cec5SDimitry Andric           readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
1410b57cec5SDimitry Andric     return Err;
1420b57cec5SDimitry Andric   if (auto Err = decodeCounter(EncodedCounter, C))
1430b57cec5SDimitry Andric     return Err;
1440b57cec5SDimitry Andric   return Error::success();
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric static const unsigned EncodingExpansionRegionBit = 1
1480b57cec5SDimitry Andric                                                    << Counter::EncodingTagBits;
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric /// Read the sub-array of regions for the given inferred file id.
1510b57cec5SDimitry Andric /// \param NumFileIDs the number of file ids that are defined for this
1520b57cec5SDimitry Andric /// function.
1530b57cec5SDimitry Andric Error RawCoverageMappingReader::readMappingRegionsSubArray(
1540b57cec5SDimitry Andric     std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
1550b57cec5SDimitry Andric     size_t NumFileIDs) {
1560b57cec5SDimitry Andric   uint64_t NumRegions;
1570b57cec5SDimitry Andric   if (auto Err = readSize(NumRegions))
1580b57cec5SDimitry Andric     return Err;
1590b57cec5SDimitry Andric   unsigned LineStart = 0;
1600b57cec5SDimitry Andric   for (size_t I = 0; I < NumRegions; ++I) {
1610b57cec5SDimitry Andric     Counter C;
1620b57cec5SDimitry Andric     CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric     // Read the combined counter + region kind.
1650b57cec5SDimitry Andric     uint64_t EncodedCounterAndRegion;
1660b57cec5SDimitry Andric     if (auto Err = readIntMax(EncodedCounterAndRegion,
1670b57cec5SDimitry Andric                               std::numeric_limits<unsigned>::max()))
1680b57cec5SDimitry Andric       return Err;
1690b57cec5SDimitry Andric     unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
1700b57cec5SDimitry Andric     uint64_t ExpandedFileID = 0;
1710b57cec5SDimitry Andric     if (Tag != Counter::Zero) {
1720b57cec5SDimitry Andric       if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
1730b57cec5SDimitry Andric         return Err;
1740b57cec5SDimitry Andric     } else {
1750b57cec5SDimitry Andric       // Is it an expansion region?
1760b57cec5SDimitry Andric       if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
1770b57cec5SDimitry Andric         Kind = CounterMappingRegion::ExpansionRegion;
1780b57cec5SDimitry Andric         ExpandedFileID = EncodedCounterAndRegion >>
1790b57cec5SDimitry Andric                          Counter::EncodingCounterTagAndExpansionRegionTagBits;
1800b57cec5SDimitry Andric         if (ExpandedFileID >= NumFileIDs)
1810b57cec5SDimitry Andric           return make_error<CoverageMapError>(coveragemap_error::malformed);
1820b57cec5SDimitry Andric       } else {
1830b57cec5SDimitry Andric         switch (EncodedCounterAndRegion >>
1840b57cec5SDimitry Andric                 Counter::EncodingCounterTagAndExpansionRegionTagBits) {
1850b57cec5SDimitry Andric         case CounterMappingRegion::CodeRegion:
1860b57cec5SDimitry Andric           // Don't do anything when we have a code region with a zero counter.
1870b57cec5SDimitry Andric           break;
1880b57cec5SDimitry Andric         case CounterMappingRegion::SkippedRegion:
1890b57cec5SDimitry Andric           Kind = CounterMappingRegion::SkippedRegion;
1900b57cec5SDimitry Andric           break;
1910b57cec5SDimitry Andric         default:
1920b57cec5SDimitry Andric           return make_error<CoverageMapError>(coveragemap_error::malformed);
1930b57cec5SDimitry Andric         }
1940b57cec5SDimitry Andric       }
1950b57cec5SDimitry Andric     }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric     // Read the source range.
1980b57cec5SDimitry Andric     uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
1990b57cec5SDimitry Andric     if (auto Err =
2000b57cec5SDimitry Andric             readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
2010b57cec5SDimitry Andric       return Err;
2020b57cec5SDimitry Andric     if (auto Err = readULEB128(ColumnStart))
2030b57cec5SDimitry Andric       return Err;
2040b57cec5SDimitry Andric     if (ColumnStart > std::numeric_limits<unsigned>::max())
2050b57cec5SDimitry Andric       return make_error<CoverageMapError>(coveragemap_error::malformed);
2060b57cec5SDimitry Andric     if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
2070b57cec5SDimitry Andric       return Err;
2080b57cec5SDimitry Andric     if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
2090b57cec5SDimitry Andric       return Err;
2100b57cec5SDimitry Andric     LineStart += LineStartDelta;
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric     // If the high bit of ColumnEnd is set, this is a gap region.
2130b57cec5SDimitry Andric     if (ColumnEnd & (1U << 31)) {
2140b57cec5SDimitry Andric       Kind = CounterMappingRegion::GapRegion;
2150b57cec5SDimitry Andric       ColumnEnd &= ~(1U << 31);
2160b57cec5SDimitry Andric     }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric     // Adjust the column locations for the empty regions that are supposed to
2190b57cec5SDimitry Andric     // cover whole lines. Those regions should be encoded with the
2200b57cec5SDimitry Andric     // column range (1 -> std::numeric_limits<unsigned>::max()), but because
2210b57cec5SDimitry Andric     // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
2220b57cec5SDimitry Andric     // we set the column range to (0 -> 0) to ensure that the column start and
2230b57cec5SDimitry Andric     // column end take up one byte each.
2240b57cec5SDimitry Andric     // The std::numeric_limits<unsigned>::max() is used to represent a column
2250b57cec5SDimitry Andric     // position at the end of the line without knowing the length of that line.
2260b57cec5SDimitry Andric     if (ColumnStart == 0 && ColumnEnd == 0) {
2270b57cec5SDimitry Andric       ColumnStart = 1;
2280b57cec5SDimitry Andric       ColumnEnd = std::numeric_limits<unsigned>::max();
2290b57cec5SDimitry Andric     }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric     LLVM_DEBUG({
2320b57cec5SDimitry Andric       dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
2330b57cec5SDimitry Andric              << ColumnStart << " -> " << (LineStart + NumLines) << ":"
2340b57cec5SDimitry Andric              << ColumnEnd << ", ";
2350b57cec5SDimitry Andric       if (Kind == CounterMappingRegion::ExpansionRegion)
2360b57cec5SDimitry Andric         dbgs() << "Expands to file " << ExpandedFileID;
2370b57cec5SDimitry Andric       else
2380b57cec5SDimitry Andric         CounterMappingContext(Expressions).dump(C, dbgs());
2390b57cec5SDimitry Andric       dbgs() << "\n";
2400b57cec5SDimitry Andric     });
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric     auto CMR = CounterMappingRegion(C, InferredFileID, ExpandedFileID,
2430b57cec5SDimitry Andric                                     LineStart, ColumnStart,
2440b57cec5SDimitry Andric                                     LineStart + NumLines, ColumnEnd, Kind);
2450b57cec5SDimitry Andric     if (CMR.startLoc() > CMR.endLoc())
2460b57cec5SDimitry Andric       return make_error<CoverageMapError>(coveragemap_error::malformed);
2470b57cec5SDimitry Andric     MappingRegions.push_back(CMR);
2480b57cec5SDimitry Andric   }
2490b57cec5SDimitry Andric   return Error::success();
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric Error RawCoverageMappingReader::read() {
2530b57cec5SDimitry Andric   // Read the virtual file mapping.
2540b57cec5SDimitry Andric   SmallVector<unsigned, 8> VirtualFileMapping;
2550b57cec5SDimitry Andric   uint64_t NumFileMappings;
2560b57cec5SDimitry Andric   if (auto Err = readSize(NumFileMappings))
2570b57cec5SDimitry Andric     return Err;
2580b57cec5SDimitry Andric   for (size_t I = 0; I < NumFileMappings; ++I) {
2590b57cec5SDimitry Andric     uint64_t FilenameIndex;
2600b57cec5SDimitry Andric     if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
2610b57cec5SDimitry Andric       return Err;
2620b57cec5SDimitry Andric     VirtualFileMapping.push_back(FilenameIndex);
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   // Construct the files using unique filenames and virtual file mapping.
2660b57cec5SDimitry Andric   for (auto I : VirtualFileMapping) {
2670b57cec5SDimitry Andric     Filenames.push_back(TranslationUnitFilenames[I]);
2680b57cec5SDimitry Andric   }
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   // Read the expressions.
2710b57cec5SDimitry Andric   uint64_t NumExpressions;
2720b57cec5SDimitry Andric   if (auto Err = readSize(NumExpressions))
2730b57cec5SDimitry Andric     return Err;
2740b57cec5SDimitry Andric   // Create an array of dummy expressions that get the proper counters
2750b57cec5SDimitry Andric   // when the expressions are read, and the proper kinds when the counters
2760b57cec5SDimitry Andric   // are decoded.
2770b57cec5SDimitry Andric   Expressions.resize(
2780b57cec5SDimitry Andric       NumExpressions,
2790b57cec5SDimitry Andric       CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
2800b57cec5SDimitry Andric   for (size_t I = 0; I < NumExpressions; ++I) {
2810b57cec5SDimitry Andric     if (auto Err = readCounter(Expressions[I].LHS))
2820b57cec5SDimitry Andric       return Err;
2830b57cec5SDimitry Andric     if (auto Err = readCounter(Expressions[I].RHS))
2840b57cec5SDimitry Andric       return Err;
2850b57cec5SDimitry Andric   }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   // Read the mapping regions sub-arrays.
2880b57cec5SDimitry Andric   for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
2890b57cec5SDimitry Andric        InferredFileID < S; ++InferredFileID) {
2900b57cec5SDimitry Andric     if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
2910b57cec5SDimitry Andric                                               VirtualFileMapping.size()))
2920b57cec5SDimitry Andric       return Err;
2930b57cec5SDimitry Andric   }
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   // Set the counters for the expansion regions.
2960b57cec5SDimitry Andric   // i.e. Counter of expansion region = counter of the first region
2970b57cec5SDimitry Andric   // from the expanded file.
2980b57cec5SDimitry Andric   // Perform multiple passes to correctly propagate the counters through
2990b57cec5SDimitry Andric   // all the nested expansion regions.
3000b57cec5SDimitry Andric   SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
3010b57cec5SDimitry Andric   FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
3020b57cec5SDimitry Andric   for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
3030b57cec5SDimitry Andric     for (auto &R : MappingRegions) {
3040b57cec5SDimitry Andric       if (R.Kind != CounterMappingRegion::ExpansionRegion)
3050b57cec5SDimitry Andric         continue;
3060b57cec5SDimitry Andric       assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
3070b57cec5SDimitry Andric       FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
3080b57cec5SDimitry Andric     }
3090b57cec5SDimitry Andric     for (auto &R : MappingRegions) {
3100b57cec5SDimitry Andric       if (FileIDExpansionRegionMapping[R.FileID]) {
3110b57cec5SDimitry Andric         FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
3120b57cec5SDimitry Andric         FileIDExpansionRegionMapping[R.FileID] = nullptr;
3130b57cec5SDimitry Andric       }
3140b57cec5SDimitry Andric     }
3150b57cec5SDimitry Andric   }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric   return Error::success();
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric Expected<bool> RawCoverageMappingDummyChecker::isDummy() {
3210b57cec5SDimitry Andric   // A dummy coverage mapping data consists of just one region with zero count.
3220b57cec5SDimitry Andric   uint64_t NumFileMappings;
3230b57cec5SDimitry Andric   if (Error Err = readSize(NumFileMappings))
3240b57cec5SDimitry Andric     return std::move(Err);
3250b57cec5SDimitry Andric   if (NumFileMappings != 1)
3260b57cec5SDimitry Andric     return false;
3270b57cec5SDimitry Andric   // We don't expect any specific value for the filename index, just skip it.
3280b57cec5SDimitry Andric   uint64_t FilenameIndex;
3290b57cec5SDimitry Andric   if (Error Err =
3300b57cec5SDimitry Andric           readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
3310b57cec5SDimitry Andric     return std::move(Err);
3320b57cec5SDimitry Andric   uint64_t NumExpressions;
3330b57cec5SDimitry Andric   if (Error Err = readSize(NumExpressions))
3340b57cec5SDimitry Andric     return std::move(Err);
3350b57cec5SDimitry Andric   if (NumExpressions != 0)
3360b57cec5SDimitry Andric     return false;
3370b57cec5SDimitry Andric   uint64_t NumRegions;
3380b57cec5SDimitry Andric   if (Error Err = readSize(NumRegions))
3390b57cec5SDimitry Andric     return std::move(Err);
3400b57cec5SDimitry Andric   if (NumRegions != 1)
3410b57cec5SDimitry Andric     return false;
3420b57cec5SDimitry Andric   uint64_t EncodedCounterAndRegion;
3430b57cec5SDimitry Andric   if (Error Err = readIntMax(EncodedCounterAndRegion,
3440b57cec5SDimitry Andric                              std::numeric_limits<unsigned>::max()))
3450b57cec5SDimitry Andric     return std::move(Err);
3460b57cec5SDimitry Andric   unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
3470b57cec5SDimitry Andric   return Tag == Counter::Zero;
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric Error InstrProfSymtab::create(SectionRef &Section) {
3510b57cec5SDimitry Andric   Expected<StringRef> DataOrErr = Section.getContents();
3520b57cec5SDimitry Andric   if (!DataOrErr)
3530b57cec5SDimitry Andric     return DataOrErr.takeError();
3540b57cec5SDimitry Andric   Data = *DataOrErr;
3550b57cec5SDimitry Andric   Address = Section.getAddress();
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric   // If this is a linked PE/COFF file, then we have to skip over the null byte
3580b57cec5SDimitry Andric   // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
3590b57cec5SDimitry Andric   const ObjectFile *Obj = Section.getObject();
3600b57cec5SDimitry Andric   if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
3610b57cec5SDimitry Andric     Data = Data.drop_front(1);
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric   return Error::success();
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
3670b57cec5SDimitry Andric   if (Pointer < Address)
3680b57cec5SDimitry Andric     return StringRef();
3690b57cec5SDimitry Andric   auto Offset = Pointer - Address;
3700b57cec5SDimitry Andric   if (Offset + Size > Data.size())
3710b57cec5SDimitry Andric     return StringRef();
3720b57cec5SDimitry Andric   return Data.substr(Pointer - Address, Size);
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
3760b57cec5SDimitry Andric static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
3770b57cec5SDimitry Andric   // The hash value of dummy mapping records is always zero.
3780b57cec5SDimitry Andric   if (Hash)
3790b57cec5SDimitry Andric     return false;
3800b57cec5SDimitry Andric   return RawCoverageMappingDummyChecker(Mapping).isDummy();
3810b57cec5SDimitry Andric }
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric namespace {
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric struct CovMapFuncRecordReader {
3860b57cec5SDimitry Andric   virtual ~CovMapFuncRecordReader() = default;
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   // The interface to read coverage mapping function records for a module.
3890b57cec5SDimitry Andric   //
3900b57cec5SDimitry Andric   // \p Buf points to the buffer containing the \c CovHeader of the coverage
3910b57cec5SDimitry Andric   // mapping data associated with the module.
3920b57cec5SDimitry Andric   //
3930b57cec5SDimitry Andric   // Returns a pointer to the next \c CovHeader if it exists, or a pointer
3940b57cec5SDimitry Andric   // greater than \p End if not.
3950b57cec5SDimitry Andric   virtual Expected<const char *> readFunctionRecords(const char *Buf,
3960b57cec5SDimitry Andric                                                      const char *End) = 0;
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   template <class IntPtrT, support::endianness Endian>
3990b57cec5SDimitry Andric   static Expected<std::unique_ptr<CovMapFuncRecordReader>>
4000b57cec5SDimitry Andric   get(CovMapVersion Version, InstrProfSymtab &P,
4010b57cec5SDimitry Andric       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
4020b57cec5SDimitry Andric       std::vector<StringRef> &F);
4030b57cec5SDimitry Andric };
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric // A class for reading coverage mapping function records for a module.
4060b57cec5SDimitry Andric template <CovMapVersion Version, class IntPtrT, support::endianness Endian>
4070b57cec5SDimitry Andric class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
4080b57cec5SDimitry Andric   using FuncRecordType =
4090b57cec5SDimitry Andric       typename CovMapTraits<Version, IntPtrT>::CovMapFuncRecordType;
4100b57cec5SDimitry Andric   using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   // Maps function's name references to the indexes of their records
4130b57cec5SDimitry Andric   // in \c Records.
4140b57cec5SDimitry Andric   DenseMap<NameRefType, size_t> FunctionRecords;
4150b57cec5SDimitry Andric   InstrProfSymtab &ProfileNames;
4160b57cec5SDimitry Andric   std::vector<StringRef> &Filenames;
4170b57cec5SDimitry Andric   std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   // Add the record to the collection if we don't already have a record that
4200b57cec5SDimitry Andric   // points to the same function name. This is useful to ignore the redundant
4210b57cec5SDimitry Andric   // records for the functions with ODR linkage.
4220b57cec5SDimitry Andric   // In addition, prefer records with real coverage mapping data to dummy
4230b57cec5SDimitry Andric   // records, which were emitted for inline functions which were seen but
4240b57cec5SDimitry Andric   // not used in the corresponding translation unit.
4250b57cec5SDimitry Andric   Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
4260b57cec5SDimitry Andric                                      StringRef Mapping, size_t FilenamesBegin) {
4270b57cec5SDimitry Andric     uint64_t FuncHash = CFR->template getFuncHash<Endian>();
4280b57cec5SDimitry Andric     NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
4290b57cec5SDimitry Andric     auto InsertResult =
4300b57cec5SDimitry Andric         FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
4310b57cec5SDimitry Andric     if (InsertResult.second) {
4320b57cec5SDimitry Andric       StringRef FuncName;
4330b57cec5SDimitry Andric       if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
4340b57cec5SDimitry Andric         return Err;
4350b57cec5SDimitry Andric       if (FuncName.empty())
4360b57cec5SDimitry Andric         return make_error<InstrProfError>(instrprof_error::malformed);
4370b57cec5SDimitry Andric       Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
4380b57cec5SDimitry Andric                            Filenames.size() - FilenamesBegin);
4390b57cec5SDimitry Andric       return Error::success();
4400b57cec5SDimitry Andric     }
4410b57cec5SDimitry Andric     // Update the existing record if it's a dummy and the new record is real.
4420b57cec5SDimitry Andric     size_t OldRecordIndex = InsertResult.first->second;
4430b57cec5SDimitry Andric     BinaryCoverageReader::ProfileMappingRecord &OldRecord =
4440b57cec5SDimitry Andric         Records[OldRecordIndex];
4450b57cec5SDimitry Andric     Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
4460b57cec5SDimitry Andric         OldRecord.FunctionHash, OldRecord.CoverageMapping);
4470b57cec5SDimitry Andric     if (Error Err = OldIsDummyExpected.takeError())
4480b57cec5SDimitry Andric       return Err;
4490b57cec5SDimitry Andric     if (!*OldIsDummyExpected)
4500b57cec5SDimitry Andric       return Error::success();
4510b57cec5SDimitry Andric     Expected<bool> NewIsDummyExpected =
4520b57cec5SDimitry Andric         isCoverageMappingDummy(FuncHash, Mapping);
4530b57cec5SDimitry Andric     if (Error Err = NewIsDummyExpected.takeError())
4540b57cec5SDimitry Andric       return Err;
4550b57cec5SDimitry Andric     if (*NewIsDummyExpected)
4560b57cec5SDimitry Andric       return Error::success();
4570b57cec5SDimitry Andric     OldRecord.FunctionHash = FuncHash;
4580b57cec5SDimitry Andric     OldRecord.CoverageMapping = Mapping;
4590b57cec5SDimitry Andric     OldRecord.FilenamesBegin = FilenamesBegin;
4600b57cec5SDimitry Andric     OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin;
4610b57cec5SDimitry Andric     return Error::success();
4620b57cec5SDimitry Andric   }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric public:
4650b57cec5SDimitry Andric   VersionedCovMapFuncRecordReader(
4660b57cec5SDimitry Andric       InstrProfSymtab &P,
4670b57cec5SDimitry Andric       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
4680b57cec5SDimitry Andric       std::vector<StringRef> &F)
4690b57cec5SDimitry Andric       : ProfileNames(P), Filenames(F), Records(R) {}
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric   ~VersionedCovMapFuncRecordReader() override = default;
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric   Expected<const char *> readFunctionRecords(const char *Buf,
4740b57cec5SDimitry Andric                                              const char *End) override {
4750b57cec5SDimitry Andric     using namespace support;
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric     if (Buf + sizeof(CovMapHeader) > End)
4780b57cec5SDimitry Andric       return make_error<CoverageMapError>(coveragemap_error::malformed);
4790b57cec5SDimitry Andric     auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);
4800b57cec5SDimitry Andric     uint32_t NRecords = CovHeader->getNRecords<Endian>();
4810b57cec5SDimitry Andric     uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
4820b57cec5SDimitry Andric     uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
4830b57cec5SDimitry Andric     assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
4840b57cec5SDimitry Andric     Buf = reinterpret_cast<const char *>(CovHeader + 1);
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric     // Skip past the function records, saving the start and end for later.
4870b57cec5SDimitry Andric     const char *FunBuf = Buf;
4880b57cec5SDimitry Andric     Buf += NRecords * sizeof(FuncRecordType);
4890b57cec5SDimitry Andric     const char *FunEnd = Buf;
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric     // Get the filenames.
4920b57cec5SDimitry Andric     if (Buf + FilenamesSize > End)
4930b57cec5SDimitry Andric       return make_error<CoverageMapError>(coveragemap_error::malformed);
4940b57cec5SDimitry Andric     size_t FilenamesBegin = Filenames.size();
4950b57cec5SDimitry Andric     RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
4960b57cec5SDimitry Andric     if (auto Err = Reader.read())
4970b57cec5SDimitry Andric       return std::move(Err);
4980b57cec5SDimitry Andric     Buf += FilenamesSize;
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric     // We'll read the coverage mapping records in the loop below.
5010b57cec5SDimitry Andric     const char *CovBuf = Buf;
5020b57cec5SDimitry Andric     Buf += CoverageSize;
5030b57cec5SDimitry Andric     const char *CovEnd = Buf;
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric     if (Buf > End)
5060b57cec5SDimitry Andric       return make_error<CoverageMapError>(coveragemap_error::malformed);
5070b57cec5SDimitry Andric     // Each coverage map has an alignment of 8, so we need to adjust alignment
5080b57cec5SDimitry Andric     // before reading the next map.
509*8bcb0991SDimitry Andric     Buf += offsetToAlignedAddr(Buf, Align(8));
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric     auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
5120b57cec5SDimitry Andric     while ((const char *)CFR < FunEnd) {
5130b57cec5SDimitry Andric       // Read the function information
5140b57cec5SDimitry Andric       uint32_t DataSize = CFR->template getDataSize<Endian>();
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric       // Now use that to read the coverage data.
5170b57cec5SDimitry Andric       if (CovBuf + DataSize > CovEnd)
5180b57cec5SDimitry Andric         return make_error<CoverageMapError>(coveragemap_error::malformed);
5190b57cec5SDimitry Andric       auto Mapping = StringRef(CovBuf, DataSize);
5200b57cec5SDimitry Andric       CovBuf += DataSize;
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric       if (Error Err =
5230b57cec5SDimitry Andric               insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
5240b57cec5SDimitry Andric         return std::move(Err);
5250b57cec5SDimitry Andric       CFR++;
5260b57cec5SDimitry Andric     }
5270b57cec5SDimitry Andric     return Buf;
5280b57cec5SDimitry Andric   }
5290b57cec5SDimitry Andric };
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric } // end anonymous namespace
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric template <class IntPtrT, support::endianness Endian>
5340b57cec5SDimitry Andric Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
5350b57cec5SDimitry Andric     CovMapVersion Version, InstrProfSymtab &P,
5360b57cec5SDimitry Andric     std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
5370b57cec5SDimitry Andric     std::vector<StringRef> &F) {
5380b57cec5SDimitry Andric   using namespace coverage;
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric   switch (Version) {
5410b57cec5SDimitry Andric   case CovMapVersion::Version1:
542*8bcb0991SDimitry Andric     return std::make_unique<VersionedCovMapFuncRecordReader<
5430b57cec5SDimitry Andric         CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
5440b57cec5SDimitry Andric   case CovMapVersion::Version2:
5450b57cec5SDimitry Andric   case CovMapVersion::Version3:
5460b57cec5SDimitry Andric     // Decompress the name data.
5470b57cec5SDimitry Andric     if (Error E = P.create(P.getNameData()))
5480b57cec5SDimitry Andric       return std::move(E);
5490b57cec5SDimitry Andric     if (Version == CovMapVersion::Version2)
550*8bcb0991SDimitry Andric       return std::make_unique<VersionedCovMapFuncRecordReader<
5510b57cec5SDimitry Andric           CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
5520b57cec5SDimitry Andric     else
553*8bcb0991SDimitry Andric       return std::make_unique<VersionedCovMapFuncRecordReader<
5540b57cec5SDimitry Andric           CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
5550b57cec5SDimitry Andric   }
5560b57cec5SDimitry Andric   llvm_unreachable("Unsupported version");
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric template <typename T, support::endianness Endian>
5600b57cec5SDimitry Andric static Error readCoverageMappingData(
5610b57cec5SDimitry Andric     InstrProfSymtab &ProfileNames, StringRef Data,
5620b57cec5SDimitry Andric     std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
5630b57cec5SDimitry Andric     std::vector<StringRef> &Filenames) {
5640b57cec5SDimitry Andric   using namespace coverage;
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric   // Read the records in the coverage data section.
5670b57cec5SDimitry Andric   auto CovHeader =
5680b57cec5SDimitry Andric       reinterpret_cast<const CovMapHeader *>(Data.data());
5690b57cec5SDimitry Andric   CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
5700b57cec5SDimitry Andric   if (Version > CovMapVersion::CurrentVersion)
5710b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
5720b57cec5SDimitry Andric   Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
5730b57cec5SDimitry Andric       CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
5740b57cec5SDimitry Andric                                              Filenames);
5750b57cec5SDimitry Andric   if (Error E = ReaderExpected.takeError())
5760b57cec5SDimitry Andric     return E;
5770b57cec5SDimitry Andric   auto Reader = std::move(ReaderExpected.get());
5780b57cec5SDimitry Andric   for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
5790b57cec5SDimitry Andric     auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End);
5800b57cec5SDimitry Andric     if (auto E = NextHeaderOrErr.takeError())
5810b57cec5SDimitry Andric       return E;
5820b57cec5SDimitry Andric     Buf = NextHeaderOrErr.get();
5830b57cec5SDimitry Andric   }
5840b57cec5SDimitry Andric   return Error::success();
5850b57cec5SDimitry Andric }
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric static const char *TestingFormatMagic = "llvmcovmtestdata";
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric Expected<std::unique_ptr<BinaryCoverageReader>>
5900b57cec5SDimitry Andric BinaryCoverageReader::createCoverageReaderFromBuffer(
5910b57cec5SDimitry Andric     StringRef Coverage, InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress,
5920b57cec5SDimitry Andric     support::endianness Endian) {
5930b57cec5SDimitry Andric   std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
5940b57cec5SDimitry Andric   Reader->ProfileNames = std::move(ProfileNames);
5950b57cec5SDimitry Andric   if (BytesInAddress == 4 && Endian == support::endianness::little) {
5960b57cec5SDimitry Andric     if (Error E =
5970b57cec5SDimitry Andric             readCoverageMappingData<uint32_t, support::endianness::little>(
5980b57cec5SDimitry Andric                 Reader->ProfileNames, Coverage, Reader->MappingRecords,
5990b57cec5SDimitry Andric                 Reader->Filenames))
6000b57cec5SDimitry Andric       return std::move(E);
6010b57cec5SDimitry Andric   } else if (BytesInAddress == 4 && Endian == support::endianness::big) {
6020b57cec5SDimitry Andric     if (Error E = readCoverageMappingData<uint32_t, support::endianness::big>(
6030b57cec5SDimitry Andric             Reader->ProfileNames, Coverage, Reader->MappingRecords,
6040b57cec5SDimitry Andric             Reader->Filenames))
6050b57cec5SDimitry Andric       return std::move(E);
6060b57cec5SDimitry Andric   } else if (BytesInAddress == 8 && Endian == support::endianness::little) {
6070b57cec5SDimitry Andric     if (Error E =
6080b57cec5SDimitry Andric             readCoverageMappingData<uint64_t, support::endianness::little>(
6090b57cec5SDimitry Andric                 Reader->ProfileNames, Coverage, Reader->MappingRecords,
6100b57cec5SDimitry Andric                 Reader->Filenames))
6110b57cec5SDimitry Andric       return std::move(E);
6120b57cec5SDimitry Andric   } else if (BytesInAddress == 8 && Endian == support::endianness::big) {
6130b57cec5SDimitry Andric     if (Error E = readCoverageMappingData<uint64_t, support::endianness::big>(
6140b57cec5SDimitry Andric             Reader->ProfileNames, Coverage, Reader->MappingRecords,
6150b57cec5SDimitry Andric             Reader->Filenames))
6160b57cec5SDimitry Andric       return std::move(E);
6170b57cec5SDimitry Andric   } else
6180b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
6190b57cec5SDimitry Andric   return std::move(Reader);
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric static Expected<std::unique_ptr<BinaryCoverageReader>>
6230b57cec5SDimitry Andric loadTestingFormat(StringRef Data) {
6240b57cec5SDimitry Andric   uint8_t BytesInAddress = 8;
6250b57cec5SDimitry Andric   support::endianness Endian = support::endianness::little;
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric   Data = Data.substr(StringRef(TestingFormatMagic).size());
6280b57cec5SDimitry Andric   if (Data.empty())
6290b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::truncated);
6300b57cec5SDimitry Andric   unsigned N = 0;
6310b57cec5SDimitry Andric   uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
6320b57cec5SDimitry Andric   if (N > Data.size())
6330b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
6340b57cec5SDimitry Andric   Data = Data.substr(N);
6350b57cec5SDimitry Andric   if (Data.empty())
6360b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::truncated);
6370b57cec5SDimitry Andric   N = 0;
6380b57cec5SDimitry Andric   uint64_t Address = decodeULEB128(Data.bytes_begin(), &N);
6390b57cec5SDimitry Andric   if (N > Data.size())
6400b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
6410b57cec5SDimitry Andric   Data = Data.substr(N);
6420b57cec5SDimitry Andric   if (Data.size() < ProfileNamesSize)
6430b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
6440b57cec5SDimitry Andric   InstrProfSymtab ProfileNames;
6450b57cec5SDimitry Andric   if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
6460b57cec5SDimitry Andric     return std::move(E);
6470b57cec5SDimitry Andric   StringRef CoverageMapping = Data.substr(ProfileNamesSize);
6480b57cec5SDimitry Andric   // Skip the padding bytes because coverage map data has an alignment of 8.
6490b57cec5SDimitry Andric   if (CoverageMapping.empty())
6500b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::truncated);
651*8bcb0991SDimitry Andric   size_t Pad = offsetToAlignedAddr(CoverageMapping.data(), Align(8));
6520b57cec5SDimitry Andric   if (CoverageMapping.size() < Pad)
6530b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
6540b57cec5SDimitry Andric   CoverageMapping = CoverageMapping.substr(Pad);
6550b57cec5SDimitry Andric   return BinaryCoverageReader::createCoverageReaderFromBuffer(
6560b57cec5SDimitry Andric       CoverageMapping, std::move(ProfileNames), BytesInAddress, Endian);
6570b57cec5SDimitry Andric }
6580b57cec5SDimitry Andric 
6590b57cec5SDimitry Andric static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
6600b57cec5SDimitry Andric   // On COFF, the object file section name may end in "$M". This tells the
6610b57cec5SDimitry Andric   // linker to sort these sections between "$A" and "$Z". The linker removes the
6620b57cec5SDimitry Andric   // dollar and everything after it in the final binary. Do the same to match.
6630b57cec5SDimitry Andric   bool IsCOFF = isa<COFFObjectFile>(OF);
6640b57cec5SDimitry Andric   auto stripSuffix = [IsCOFF](StringRef N) {
6650b57cec5SDimitry Andric     return IsCOFF ? N.split('$').first : N;
6660b57cec5SDimitry Andric   };
6670b57cec5SDimitry Andric   Name = stripSuffix(Name);
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric   for (const auto &Section : OF.sections()) {
670*8bcb0991SDimitry Andric     Expected<StringRef> NameOrErr = Section.getName();
671*8bcb0991SDimitry Andric     if (!NameOrErr)
672*8bcb0991SDimitry Andric       return NameOrErr.takeError();
673*8bcb0991SDimitry Andric     if (stripSuffix(*NameOrErr) == Name)
6740b57cec5SDimitry Andric       return Section;
6750b57cec5SDimitry Andric   }
6760b57cec5SDimitry Andric   return make_error<CoverageMapError>(coveragemap_error::no_data_found);
6770b57cec5SDimitry Andric }
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric static Expected<std::unique_ptr<BinaryCoverageReader>>
6800b57cec5SDimitry Andric loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch) {
6810b57cec5SDimitry Andric   std::unique_ptr<ObjectFile> OF;
6820b57cec5SDimitry Andric   if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
6830b57cec5SDimitry Andric     // If we have a universal binary, try to look up the object for the
6840b57cec5SDimitry Andric     // appropriate architecture.
685*8bcb0991SDimitry Andric     auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
6860b57cec5SDimitry Andric     if (!ObjectFileOrErr)
6870b57cec5SDimitry Andric       return ObjectFileOrErr.takeError();
6880b57cec5SDimitry Andric     OF = std::move(ObjectFileOrErr.get());
6890b57cec5SDimitry Andric   } else if (isa<ObjectFile>(Bin.get())) {
6900b57cec5SDimitry Andric     // For any other object file, upcast and take ownership.
6910b57cec5SDimitry Andric     OF.reset(cast<ObjectFile>(Bin.release()));
6920b57cec5SDimitry Andric     // If we've asked for a particular arch, make sure they match.
6930b57cec5SDimitry Andric     if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
6940b57cec5SDimitry Andric       return errorCodeToError(object_error::arch_not_found);
6950b57cec5SDimitry Andric   } else
6960b57cec5SDimitry Andric     // We can only handle object files.
6970b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::malformed);
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric   // The coverage uses native pointer sizes for the object it's written in.
7000b57cec5SDimitry Andric   uint8_t BytesInAddress = OF->getBytesInAddress();
7010b57cec5SDimitry Andric   support::endianness Endian = OF->isLittleEndian()
7020b57cec5SDimitry Andric                                    ? support::endianness::little
7030b57cec5SDimitry Andric                                    : support::endianness::big;
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric   // Look for the sections that we are interested in.
7060b57cec5SDimitry Andric   auto ObjFormat = OF->getTripleObjectFormat();
7070b57cec5SDimitry Andric   auto NamesSection =
7080b57cec5SDimitry Andric       lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
7090b57cec5SDimitry Andric                                                  /*AddSegmentInfo=*/false));
7100b57cec5SDimitry Andric   if (auto E = NamesSection.takeError())
7110b57cec5SDimitry Andric     return std::move(E);
7120b57cec5SDimitry Andric   auto CoverageSection =
7130b57cec5SDimitry Andric       lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
7140b57cec5SDimitry Andric                                                  /*AddSegmentInfo=*/false));
7150b57cec5SDimitry Andric   if (auto E = CoverageSection.takeError())
7160b57cec5SDimitry Andric     return std::move(E);
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric   // Get the contents of the given sections.
7190b57cec5SDimitry Andric   auto CoverageMappingOrErr = CoverageSection->getContents();
7200b57cec5SDimitry Andric   if (!CoverageMappingOrErr)
7210b57cec5SDimitry Andric     return CoverageMappingOrErr.takeError();
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric   InstrProfSymtab ProfileNames;
7240b57cec5SDimitry Andric   if (Error E = ProfileNames.create(*NamesSection))
7250b57cec5SDimitry Andric     return std::move(E);
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric   return BinaryCoverageReader::createCoverageReaderFromBuffer(
7280b57cec5SDimitry Andric       CoverageMappingOrErr.get(), std::move(ProfileNames), BytesInAddress,
7290b57cec5SDimitry Andric       Endian);
7300b57cec5SDimitry Andric }
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
7330b57cec5SDimitry Andric BinaryCoverageReader::create(
7340b57cec5SDimitry Andric     MemoryBufferRef ObjectBuffer, StringRef Arch,
7350b57cec5SDimitry Andric     SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers) {
7360b57cec5SDimitry Andric   std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric   if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) {
7390b57cec5SDimitry Andric     // This is a special format used for testing.
7400b57cec5SDimitry Andric     auto ReaderOrErr = loadTestingFormat(ObjectBuffer.getBuffer());
7410b57cec5SDimitry Andric     if (!ReaderOrErr)
7420b57cec5SDimitry Andric       return ReaderOrErr.takeError();
7430b57cec5SDimitry Andric     Readers.push_back(std::move(ReaderOrErr.get()));
7440b57cec5SDimitry Andric     return std::move(Readers);
7450b57cec5SDimitry Andric   }
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric   auto BinOrErr = createBinary(ObjectBuffer);
7480b57cec5SDimitry Andric   if (!BinOrErr)
7490b57cec5SDimitry Andric     return BinOrErr.takeError();
7500b57cec5SDimitry Andric   std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric   // MachO universal binaries which contain archives need to be treated as
7530b57cec5SDimitry Andric   // archives, not as regular binaries.
7540b57cec5SDimitry Andric   if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
7550b57cec5SDimitry Andric     for (auto &ObjForArch : Universal->objects()) {
7560b57cec5SDimitry Andric       // Skip slices within the universal binary which target the wrong arch.
7570b57cec5SDimitry Andric       std::string ObjArch = ObjForArch.getArchFlagName();
7580b57cec5SDimitry Andric       if (Arch != ObjArch)
7590b57cec5SDimitry Andric         continue;
7600b57cec5SDimitry Andric 
7610b57cec5SDimitry Andric       auto ArchiveOrErr = ObjForArch.getAsArchive();
7620b57cec5SDimitry Andric       if (!ArchiveOrErr) {
7630b57cec5SDimitry Andric         // If this is not an archive, try treating it as a regular object.
7640b57cec5SDimitry Andric         consumeError(ArchiveOrErr.takeError());
7650b57cec5SDimitry Andric         break;
7660b57cec5SDimitry Andric       }
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric       return BinaryCoverageReader::create(
7690b57cec5SDimitry Andric           ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers);
7700b57cec5SDimitry Andric     }
7710b57cec5SDimitry Andric   }
7720b57cec5SDimitry Andric 
7730b57cec5SDimitry Andric   // Load coverage out of archive members.
7740b57cec5SDimitry Andric   if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
7750b57cec5SDimitry Andric     Error Err = Error::success();
7760b57cec5SDimitry Andric     for (auto &Child : Ar->children(Err)) {
7770b57cec5SDimitry Andric       Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
7780b57cec5SDimitry Andric       if (!ChildBufOrErr)
7790b57cec5SDimitry Andric         return ChildBufOrErr.takeError();
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric       auto ChildReadersOrErr = BinaryCoverageReader::create(
7820b57cec5SDimitry Andric           ChildBufOrErr.get(), Arch, ObjectFileBuffers);
7830b57cec5SDimitry Andric       if (!ChildReadersOrErr)
7840b57cec5SDimitry Andric         return ChildReadersOrErr.takeError();
7850b57cec5SDimitry Andric       for (auto &Reader : ChildReadersOrErr.get())
7860b57cec5SDimitry Andric         Readers.push_back(std::move(Reader));
7870b57cec5SDimitry Andric     }
7880b57cec5SDimitry Andric     if (Err)
7890b57cec5SDimitry Andric       return std::move(Err);
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric     // Thin archives reference object files outside of the archive file, i.e.
7920b57cec5SDimitry Andric     // files which reside in memory not owned by the caller. Transfer ownership
7930b57cec5SDimitry Andric     // to the caller.
7940b57cec5SDimitry Andric     if (Ar->isThin())
7950b57cec5SDimitry Andric       for (auto &Buffer : Ar->takeThinBuffers())
7960b57cec5SDimitry Andric         ObjectFileBuffers.push_back(std::move(Buffer));
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric     return std::move(Readers);
7990b57cec5SDimitry Andric   }
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch);
8020b57cec5SDimitry Andric   if (!ReaderOrErr)
8030b57cec5SDimitry Andric     return ReaderOrErr.takeError();
8040b57cec5SDimitry Andric   Readers.push_back(std::move(ReaderOrErr.get()));
8050b57cec5SDimitry Andric   return std::move(Readers);
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
8090b57cec5SDimitry Andric   if (CurrentRecord >= MappingRecords.size())
8100b57cec5SDimitry Andric     return make_error<CoverageMapError>(coveragemap_error::eof);
8110b57cec5SDimitry Andric 
8120b57cec5SDimitry Andric   FunctionsFilenames.clear();
8130b57cec5SDimitry Andric   Expressions.clear();
8140b57cec5SDimitry Andric   MappingRegions.clear();
8150b57cec5SDimitry Andric   auto &R = MappingRecords[CurrentRecord];
8160b57cec5SDimitry Andric   RawCoverageMappingReader Reader(
8170b57cec5SDimitry Andric       R.CoverageMapping,
8180b57cec5SDimitry Andric       makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
8190b57cec5SDimitry Andric       FunctionsFilenames, Expressions, MappingRegions);
8200b57cec5SDimitry Andric   if (auto Err = Reader.read())
8210b57cec5SDimitry Andric     return Err;
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   Record.FunctionName = R.FunctionName;
8240b57cec5SDimitry Andric   Record.FunctionHash = R.FunctionHash;
8250b57cec5SDimitry Andric   Record.Filenames = FunctionsFilenames;
8260b57cec5SDimitry Andric   Record.Expressions = Expressions;
8270b57cec5SDimitry Andric   Record.MappingRegions = MappingRegions;
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric   ++CurrentRecord;
8300b57cec5SDimitry Andric   return Error::success();
8310b57cec5SDimitry Andric }
832