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