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