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