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 Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin, 423 Filenames.size() - FilenamesBegin); 424 return Error::success(); 425 } 426 // Update the existing record if it's a dummy and the new record is real. 427 size_t OldRecordIndex = InsertResult.first->second; 428 BinaryCoverageReader::ProfileMappingRecord &OldRecord = 429 Records[OldRecordIndex]; 430 Expected<bool> OldIsDummyExpected = isCoverageMappingDummy( 431 OldRecord.FunctionHash, OldRecord.CoverageMapping); 432 if (Error Err = OldIsDummyExpected.takeError()) 433 return Err; 434 if (!*OldIsDummyExpected) 435 return Error::success(); 436 Expected<bool> NewIsDummyExpected = 437 isCoverageMappingDummy(FuncHash, Mapping); 438 if (Error Err = NewIsDummyExpected.takeError()) 439 return Err; 440 if (*NewIsDummyExpected) 441 return Error::success(); 442 OldRecord.FunctionHash = FuncHash; 443 OldRecord.CoverageMapping = Mapping; 444 OldRecord.FilenamesBegin = FilenamesBegin; 445 OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin; 446 return Error::success(); 447 } 448 449 public: 450 VersionedCovMapFuncRecordReader( 451 InstrProfSymtab &P, 452 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, 453 std::vector<StringRef> &F) 454 : ProfileNames(P), Filenames(F), Records(R) {} 455 456 ~VersionedCovMapFuncRecordReader() override = default; 457 458 Expected<const char *> readFunctionRecords(const char *Buf, 459 const char *End) override { 460 using namespace support; 461 462 if (Buf + sizeof(CovMapHeader) > End) 463 return make_error<CoverageMapError>(coveragemap_error::malformed); 464 auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf); 465 uint32_t NRecords = CovHeader->getNRecords<Endian>(); 466 uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>(); 467 uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>(); 468 assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version); 469 Buf = reinterpret_cast<const char *>(CovHeader + 1); 470 471 // Skip past the function records, saving the start and end for later. 472 const char *FunBuf = Buf; 473 Buf += NRecords * sizeof(FuncRecordType); 474 const char *FunEnd = Buf; 475 476 // Get the filenames. 477 if (Buf + FilenamesSize > End) 478 return make_error<CoverageMapError>(coveragemap_error::malformed); 479 size_t FilenamesBegin = Filenames.size(); 480 RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames); 481 if (auto Err = Reader.read()) 482 return std::move(Err); 483 Buf += FilenamesSize; 484 485 // We'll read the coverage mapping records in the loop below. 486 const char *CovBuf = Buf; 487 Buf += CoverageSize; 488 const char *CovEnd = Buf; 489 490 if (Buf > End) 491 return make_error<CoverageMapError>(coveragemap_error::malformed); 492 // Each coverage map has an alignment of 8, so we need to adjust alignment 493 // before reading the next map. 494 Buf += alignmentAdjustment(Buf, 8); 495 496 auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf); 497 while ((const char *)CFR < FunEnd) { 498 // Read the function information 499 uint32_t DataSize = CFR->template getDataSize<Endian>(); 500 501 // Now use that to read the coverage data. 502 if (CovBuf + DataSize > CovEnd) 503 return make_error<CoverageMapError>(coveragemap_error::malformed); 504 auto Mapping = StringRef(CovBuf, DataSize); 505 CovBuf += DataSize; 506 507 if (Error Err = 508 insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin)) 509 return std::move(Err); 510 CFR++; 511 } 512 return Buf; 513 } 514 }; 515 516 } // end anonymous namespace 517 518 template <class IntPtrT, support::endianness Endian> 519 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( 520 CovMapVersion Version, InstrProfSymtab &P, 521 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, 522 std::vector<StringRef> &F) { 523 using namespace coverage; 524 525 switch (Version) { 526 case CovMapVersion::Version1: 527 return llvm::make_unique<VersionedCovMapFuncRecordReader< 528 CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F); 529 case CovMapVersion::Version2: 530 // Decompress the name data. 531 if (Error E = P.create(P.getNameData())) 532 return std::move(E); 533 return llvm::make_unique<VersionedCovMapFuncRecordReader< 534 CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F); 535 } 536 llvm_unreachable("Unsupported version"); 537 } 538 539 template <typename T, support::endianness Endian> 540 static Error readCoverageMappingData( 541 InstrProfSymtab &ProfileNames, StringRef Data, 542 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records, 543 std::vector<StringRef> &Filenames) { 544 using namespace coverage; 545 546 // Read the records in the coverage data section. 547 auto CovHeader = 548 reinterpret_cast<const CovMapHeader *>(Data.data()); 549 CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>(); 550 if (Version > CovMapVersion::CurrentVersion) 551 return make_error<CoverageMapError>(coveragemap_error::unsupported_version); 552 Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected = 553 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records, 554 Filenames); 555 if (Error E = ReaderExpected.takeError()) 556 return E; 557 auto Reader = std::move(ReaderExpected.get()); 558 for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) { 559 auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End); 560 if (auto E = NextHeaderOrErr.takeError()) 561 return E; 562 Buf = NextHeaderOrErr.get(); 563 } 564 return Error::success(); 565 } 566 567 static const char *TestingFormatMagic = "llvmcovmtestdata"; 568 569 static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames, 570 StringRef &CoverageMapping, 571 uint8_t &BytesInAddress, 572 support::endianness &Endian) { 573 BytesInAddress = 8; 574 Endian = support::endianness::little; 575 576 Data = Data.substr(StringRef(TestingFormatMagic).size()); 577 if (Data.size() < 1) 578 return make_error<CoverageMapError>(coveragemap_error::truncated); 579 unsigned N = 0; 580 auto ProfileNamesSize = 581 decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N); 582 if (N > Data.size()) 583 return make_error<CoverageMapError>(coveragemap_error::malformed); 584 Data = Data.substr(N); 585 if (Data.size() < 1) 586 return make_error<CoverageMapError>(coveragemap_error::truncated); 587 N = 0; 588 uint64_t Address = 589 decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N); 590 if (N > Data.size()) 591 return make_error<CoverageMapError>(coveragemap_error::malformed); 592 Data = Data.substr(N); 593 if (Data.size() < ProfileNamesSize) 594 return make_error<CoverageMapError>(coveragemap_error::malformed); 595 if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address)) 596 return E; 597 CoverageMapping = Data.substr(ProfileNamesSize); 598 // Skip the padding bytes because coverage map data has an alignment of 8. 599 if (CoverageMapping.size() < 1) 600 return make_error<CoverageMapError>(coveragemap_error::truncated); 601 size_t Pad = alignmentAdjustment(CoverageMapping.data(), 8); 602 if (CoverageMapping.size() < Pad) 603 return make_error<CoverageMapError>(coveragemap_error::malformed); 604 CoverageMapping = CoverageMapping.substr(Pad); 605 return Error::success(); 606 } 607 608 static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) { 609 StringRef FoundName; 610 for (const auto &Section : OF.sections()) { 611 if (auto EC = Section.getName(FoundName)) 612 return errorCodeToError(EC); 613 if (FoundName == Name) 614 return Section; 615 } 616 return make_error<CoverageMapError>(coveragemap_error::no_data_found); 617 } 618 619 static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer, 620 InstrProfSymtab &ProfileNames, 621 StringRef &CoverageMapping, 622 uint8_t &BytesInAddress, 623 support::endianness &Endian, StringRef Arch) { 624 auto BinOrErr = createBinary(ObjectBuffer); 625 if (!BinOrErr) 626 return BinOrErr.takeError(); 627 auto Bin = std::move(BinOrErr.get()); 628 std::unique_ptr<ObjectFile> OF; 629 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) { 630 // If we have a universal binary, try to look up the object for the 631 // appropriate architecture. 632 auto ObjectFileOrErr = Universal->getObjectForArch(Arch); 633 if (!ObjectFileOrErr) 634 return ObjectFileOrErr.takeError(); 635 OF = std::move(ObjectFileOrErr.get()); 636 } else if (isa<ObjectFile>(Bin.get())) { 637 // For any other object file, upcast and take ownership. 638 OF.reset(cast<ObjectFile>(Bin.release())); 639 // If we've asked for a particular arch, make sure they match. 640 if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch()) 641 return errorCodeToError(object_error::arch_not_found); 642 } else 643 // We can only handle object files. 644 return make_error<CoverageMapError>(coveragemap_error::malformed); 645 646 // The coverage uses native pointer sizes for the object it's written in. 647 BytesInAddress = OF->getBytesInAddress(); 648 Endian = OF->isLittleEndian() ? support::endianness::little 649 : support::endianness::big; 650 651 // Look for the sections that we are interested in. 652 bool IsCoff = (dyn_cast<COFFObjectFile>(OF.get()) != nullptr); 653 auto NamesSection = 654 lookupSection(*OF, getInstrProfNameSectionNameInObject(IsCoff)); 655 if (auto E = NamesSection.takeError()) 656 return E; 657 auto CoverageSection = 658 lookupSection(*OF, getInstrProfCoverageSectionNameInObject(IsCoff)); 659 if (auto E = CoverageSection.takeError()) 660 return E; 661 662 // Get the contents of the given sections. 663 if (auto EC = CoverageSection->getContents(CoverageMapping)) 664 return errorCodeToError(EC); 665 if (Error E = ProfileNames.create(*NamesSection)) 666 return E; 667 668 return Error::success(); 669 } 670 671 Expected<std::unique_ptr<BinaryCoverageReader>> 672 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer, 673 StringRef Arch) { 674 std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader()); 675 676 StringRef Coverage; 677 uint8_t BytesInAddress; 678 support::endianness Endian; 679 Error E = Error::success(); 680 consumeError(std::move(E)); 681 if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic)) 682 // This is a special format used for testing. 683 E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames, 684 Coverage, BytesInAddress, Endian); 685 else 686 E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames, 687 Coverage, BytesInAddress, Endian, Arch); 688 if (E) 689 return std::move(E); 690 691 if (BytesInAddress == 4 && Endian == support::endianness::little) 692 E = readCoverageMappingData<uint32_t, support::endianness::little>( 693 Reader->ProfileNames, Coverage, Reader->MappingRecords, 694 Reader->Filenames); 695 else if (BytesInAddress == 4 && Endian == support::endianness::big) 696 E = readCoverageMappingData<uint32_t, support::endianness::big>( 697 Reader->ProfileNames, Coverage, Reader->MappingRecords, 698 Reader->Filenames); 699 else if (BytesInAddress == 8 && Endian == support::endianness::little) 700 E = readCoverageMappingData<uint64_t, support::endianness::little>( 701 Reader->ProfileNames, Coverage, Reader->MappingRecords, 702 Reader->Filenames); 703 else if (BytesInAddress == 8 && Endian == support::endianness::big) 704 E = readCoverageMappingData<uint64_t, support::endianness::big>( 705 Reader->ProfileNames, Coverage, Reader->MappingRecords, 706 Reader->Filenames); 707 else 708 return make_error<CoverageMapError>(coveragemap_error::malformed); 709 if (E) 710 return std::move(E); 711 return std::move(Reader); 712 } 713 714 Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) { 715 if (CurrentRecord >= MappingRecords.size()) 716 return make_error<CoverageMapError>(coveragemap_error::eof); 717 718 FunctionsFilenames.clear(); 719 Expressions.clear(); 720 MappingRegions.clear(); 721 auto &R = MappingRecords[CurrentRecord]; 722 RawCoverageMappingReader Reader( 723 R.CoverageMapping, 724 makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize), 725 FunctionsFilenames, Expressions, MappingRegions); 726 if (auto Err = Reader.read()) 727 return Err; 728 729 Record.FunctionName = R.FunctionName; 730 Record.FunctionHash = R.FunctionHash; 731 Record.Filenames = FunctionsFilenames; 732 Record.Expressions = Expressions; 733 Record.MappingRegions = MappingRegions; 734 735 ++CurrentRecord; 736 return Error::success(); 737 } 738