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