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/Statistic.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/Compression.h" 30 #include "llvm/Support/Debug.h" 31 #include "llvm/Support/Endian.h" 32 #include "llvm/Support/Error.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/LEB128.h" 35 #include "llvm/Support/MathExtras.h" 36 #include "llvm/Support/Path.h" 37 #include "llvm/Support/raw_ostream.h" 38 #include <vector> 39 40 using namespace llvm; 41 using namespace coverage; 42 using namespace object; 43 44 #define DEBUG_TYPE "coverage-mapping" 45 46 STATISTIC(CovMapNumRecords, "The # of coverage function records"); 47 STATISTIC(CovMapNumUsedRecords, "The # of used coverage function records"); 48 49 void CoverageMappingIterator::increment() { 50 if (ReadErr != coveragemap_error::success) 51 return; 52 53 // Check if all the records were read or if an error occurred while reading 54 // the next record. 55 if (auto E = Reader->readNextRecord(Record)) 56 handleAllErrors(std::move(E), [&](const CoverageMapError &CME) { 57 if (CME.get() == coveragemap_error::eof) 58 *this = CoverageMappingIterator(); 59 else 60 ReadErr = CME.get(); 61 }); 62 } 63 64 Error RawCoverageReader::readULEB128(uint64_t &Result) { 65 if (Data.empty()) 66 return make_error<CoverageMapError>(coveragemap_error::truncated); 67 unsigned N = 0; 68 Result = decodeULEB128(Data.bytes_begin(), &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(CovMapVersion Version) { 102 uint64_t NumFilenames; 103 if (auto Err = readSize(NumFilenames)) 104 return Err; 105 if (!NumFilenames) 106 return make_error<CoverageMapError>(coveragemap_error::malformed); 107 108 if (Version < CovMapVersion::Version4) 109 return readUncompressed(Version, NumFilenames); 110 111 // The uncompressed length may exceed the size of the encoded filenames. 112 // Skip size validation. 113 uint64_t UncompressedLen; 114 if (auto Err = readULEB128(UncompressedLen)) 115 return Err; 116 117 uint64_t CompressedLen; 118 if (auto Err = readSize(CompressedLen)) 119 return Err; 120 121 if (CompressedLen > 0) { 122 if (!zlib::isAvailable()) 123 return make_error<CoverageMapError>( 124 coveragemap_error::decompression_failed); 125 126 // Allocate memory for the decompressed filenames. 127 SmallVector<char, 0> StorageBuf; 128 129 // Read compressed filenames. 130 StringRef CompressedFilenames = Data.substr(0, CompressedLen); 131 Data = Data.substr(CompressedLen); 132 auto Err = 133 zlib::uncompress(CompressedFilenames, StorageBuf, UncompressedLen); 134 if (Err) { 135 consumeError(std::move(Err)); 136 return make_error<CoverageMapError>( 137 coveragemap_error::decompression_failed); 138 } 139 140 StringRef UncompressedFilenames(StorageBuf.data(), StorageBuf.size()); 141 RawCoverageFilenamesReader Delegate(UncompressedFilenames, Filenames, 142 CompilationDir); 143 return Delegate.readUncompressed(Version, NumFilenames); 144 } 145 146 return readUncompressed(Version, NumFilenames); 147 } 148 149 Error RawCoverageFilenamesReader::readUncompressed(CovMapVersion Version, 150 uint64_t NumFilenames) { 151 // Read uncompressed filenames. 152 if (Version < CovMapVersion::Version6) { 153 for (size_t I = 0; I < NumFilenames; ++I) { 154 StringRef Filename; 155 if (auto Err = readString(Filename)) 156 return Err; 157 Filenames.push_back(Filename.str()); 158 } 159 } else { 160 StringRef CWD; 161 if (auto Err = readString(CWD)) 162 return Err; 163 Filenames.push_back(CWD.str()); 164 165 for (size_t I = 1; I < NumFilenames; ++I) { 166 StringRef Filename; 167 if (auto Err = readString(Filename)) 168 return Err; 169 if (sys::path::is_absolute(Filename)) { 170 Filenames.push_back(Filename.str()); 171 } else { 172 SmallString<256> P; 173 if (!CompilationDir.empty()) 174 P.assign(CompilationDir); 175 else 176 P.assign(CWD); 177 llvm::sys::path::append(P, Filename); 178 Filenames.push_back(static_cast<std::string>(P)); 179 } 180 } 181 } 182 return Error::success(); 183 } 184 185 Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) { 186 auto Tag = Value & Counter::EncodingTagMask; 187 switch (Tag) { 188 case Counter::Zero: 189 C = Counter::getZero(); 190 return Error::success(); 191 case Counter::CounterValueReference: 192 C = Counter::getCounter(Value >> Counter::EncodingTagBits); 193 return Error::success(); 194 default: 195 break; 196 } 197 Tag -= Counter::Expression; 198 switch (Tag) { 199 case CounterExpression::Subtract: 200 case CounterExpression::Add: { 201 auto ID = Value >> Counter::EncodingTagBits; 202 if (ID >= Expressions.size()) 203 return make_error<CoverageMapError>(coveragemap_error::malformed); 204 Expressions[ID].Kind = CounterExpression::ExprKind(Tag); 205 C = Counter::getExpression(ID); 206 break; 207 } 208 default: 209 return make_error<CoverageMapError>(coveragemap_error::malformed); 210 } 211 return Error::success(); 212 } 213 214 Error RawCoverageMappingReader::readCounter(Counter &C) { 215 uint64_t EncodedCounter; 216 if (auto Err = 217 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max())) 218 return Err; 219 if (auto Err = decodeCounter(EncodedCounter, C)) 220 return Err; 221 return Error::success(); 222 } 223 224 static const unsigned EncodingExpansionRegionBit = 1 225 << Counter::EncodingTagBits; 226 227 /// Read the sub-array of regions for the given inferred file id. 228 /// \param NumFileIDs the number of file ids that are defined for this 229 /// function. 230 Error RawCoverageMappingReader::readMappingRegionsSubArray( 231 std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID, 232 size_t NumFileIDs) { 233 uint64_t NumRegions; 234 if (auto Err = readSize(NumRegions)) 235 return Err; 236 unsigned LineStart = 0; 237 for (size_t I = 0; I < NumRegions; ++I) { 238 Counter C, C2; 239 CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion; 240 241 // Read the combined counter + region kind. 242 uint64_t EncodedCounterAndRegion; 243 if (auto Err = readIntMax(EncodedCounterAndRegion, 244 std::numeric_limits<unsigned>::max())) 245 return Err; 246 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask; 247 uint64_t ExpandedFileID = 0; 248 249 // If Tag does not represent a ZeroCounter, then it is understood to refer 250 // to a counter or counter expression with region kind assumed to be 251 // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the 252 // referenced counter or counter expression (and nothing else). 253 // 254 // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set, 255 // then EncodedCounterAndRegion is interpreted to represent an 256 // ExpansionRegion. In all other cases, EncodedCounterAndRegion is 257 // interpreted to refer to a specific region kind, after which additional 258 // fields may be read (e.g. BranchRegions have two encoded counters that 259 // follow an encoded region kind value). 260 if (Tag != Counter::Zero) { 261 if (auto Err = decodeCounter(EncodedCounterAndRegion, C)) 262 return Err; 263 } else { 264 // Is it an expansion region? 265 if (EncodedCounterAndRegion & EncodingExpansionRegionBit) { 266 Kind = CounterMappingRegion::ExpansionRegion; 267 ExpandedFileID = EncodedCounterAndRegion >> 268 Counter::EncodingCounterTagAndExpansionRegionTagBits; 269 if (ExpandedFileID >= NumFileIDs) 270 return make_error<CoverageMapError>(coveragemap_error::malformed); 271 } else { 272 switch (EncodedCounterAndRegion >> 273 Counter::EncodingCounterTagAndExpansionRegionTagBits) { 274 case CounterMappingRegion::CodeRegion: 275 // Don't do anything when we have a code region with a zero counter. 276 break; 277 case CounterMappingRegion::SkippedRegion: 278 Kind = CounterMappingRegion::SkippedRegion; 279 break; 280 case CounterMappingRegion::BranchRegion: 281 // For a Branch Region, read two successive counters. 282 Kind = CounterMappingRegion::BranchRegion; 283 if (auto Err = readCounter(C)) 284 return Err; 285 if (auto Err = readCounter(C2)) 286 return Err; 287 break; 288 default: 289 return make_error<CoverageMapError>(coveragemap_error::malformed); 290 } 291 } 292 } 293 294 // Read the source range. 295 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd; 296 if (auto Err = 297 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max())) 298 return Err; 299 if (auto Err = readULEB128(ColumnStart)) 300 return Err; 301 if (ColumnStart > std::numeric_limits<unsigned>::max()) 302 return make_error<CoverageMapError>(coveragemap_error::malformed); 303 if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max())) 304 return Err; 305 if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max())) 306 return Err; 307 LineStart += LineStartDelta; 308 309 // If the high bit of ColumnEnd is set, this is a gap region. 310 if (ColumnEnd & (1U << 31)) { 311 Kind = CounterMappingRegion::GapRegion; 312 ColumnEnd &= ~(1U << 31); 313 } 314 315 // Adjust the column locations for the empty regions that are supposed to 316 // cover whole lines. Those regions should be encoded with the 317 // column range (1 -> std::numeric_limits<unsigned>::max()), but because 318 // the encoded std::numeric_limits<unsigned>::max() is several bytes long, 319 // we set the column range to (0 -> 0) to ensure that the column start and 320 // column end take up one byte each. 321 // The std::numeric_limits<unsigned>::max() is used to represent a column 322 // position at the end of the line without knowing the length of that line. 323 if (ColumnStart == 0 && ColumnEnd == 0) { 324 ColumnStart = 1; 325 ColumnEnd = std::numeric_limits<unsigned>::max(); 326 } 327 328 LLVM_DEBUG({ 329 dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":" 330 << ColumnStart << " -> " << (LineStart + NumLines) << ":" 331 << ColumnEnd << ", "; 332 if (Kind == CounterMappingRegion::ExpansionRegion) 333 dbgs() << "Expands to file " << ExpandedFileID; 334 else 335 CounterMappingContext(Expressions).dump(C, dbgs()); 336 dbgs() << "\n"; 337 }); 338 339 auto CMR = CounterMappingRegion(C, C2, InferredFileID, ExpandedFileID, 340 LineStart, ColumnStart, 341 LineStart + NumLines, ColumnEnd, Kind); 342 if (CMR.startLoc() > CMR.endLoc()) 343 return make_error<CoverageMapError>(coveragemap_error::malformed); 344 MappingRegions.push_back(CMR); 345 } 346 return Error::success(); 347 } 348 349 Error RawCoverageMappingReader::read() { 350 // Read the virtual file mapping. 351 SmallVector<unsigned, 8> VirtualFileMapping; 352 uint64_t NumFileMappings; 353 if (auto Err = readSize(NumFileMappings)) 354 return Err; 355 for (size_t I = 0; I < NumFileMappings; ++I) { 356 uint64_t FilenameIndex; 357 if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size())) 358 return Err; 359 VirtualFileMapping.push_back(FilenameIndex); 360 } 361 362 // Construct the files using unique filenames and virtual file mapping. 363 for (auto I : VirtualFileMapping) { 364 Filenames.push_back(TranslationUnitFilenames[I]); 365 } 366 367 // Read the expressions. 368 uint64_t NumExpressions; 369 if (auto Err = readSize(NumExpressions)) 370 return Err; 371 // Create an array of dummy expressions that get the proper counters 372 // when the expressions are read, and the proper kinds when the counters 373 // are decoded. 374 Expressions.resize( 375 NumExpressions, 376 CounterExpression(CounterExpression::Subtract, Counter(), Counter())); 377 for (size_t I = 0; I < NumExpressions; ++I) { 378 if (auto Err = readCounter(Expressions[I].LHS)) 379 return Err; 380 if (auto Err = readCounter(Expressions[I].RHS)) 381 return Err; 382 } 383 384 // Read the mapping regions sub-arrays. 385 for (unsigned InferredFileID = 0, S = VirtualFileMapping.size(); 386 InferredFileID < S; ++InferredFileID) { 387 if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID, 388 VirtualFileMapping.size())) 389 return Err; 390 } 391 392 // Set the counters for the expansion regions. 393 // i.e. Counter of expansion region = counter of the first region 394 // from the expanded file. 395 // Perform multiple passes to correctly propagate the counters through 396 // all the nested expansion regions. 397 SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping; 398 FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr); 399 for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) { 400 for (auto &R : MappingRegions) { 401 if (R.Kind != CounterMappingRegion::ExpansionRegion) 402 continue; 403 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]); 404 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R; 405 } 406 for (auto &R : MappingRegions) { 407 if (FileIDExpansionRegionMapping[R.FileID]) { 408 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count; 409 FileIDExpansionRegionMapping[R.FileID] = nullptr; 410 } 411 } 412 } 413 414 return Error::success(); 415 } 416 417 Expected<bool> RawCoverageMappingDummyChecker::isDummy() { 418 // A dummy coverage mapping data consists of just one region with zero count. 419 uint64_t NumFileMappings; 420 if (Error Err = readSize(NumFileMappings)) 421 return std::move(Err); 422 if (NumFileMappings != 1) 423 return false; 424 // We don't expect any specific value for the filename index, just skip it. 425 uint64_t FilenameIndex; 426 if (Error Err = 427 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max())) 428 return std::move(Err); 429 uint64_t NumExpressions; 430 if (Error Err = readSize(NumExpressions)) 431 return std::move(Err); 432 if (NumExpressions != 0) 433 return false; 434 uint64_t NumRegions; 435 if (Error Err = readSize(NumRegions)) 436 return std::move(Err); 437 if (NumRegions != 1) 438 return false; 439 uint64_t EncodedCounterAndRegion; 440 if (Error Err = readIntMax(EncodedCounterAndRegion, 441 std::numeric_limits<unsigned>::max())) 442 return std::move(Err); 443 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask; 444 return Tag == Counter::Zero; 445 } 446 447 Error InstrProfSymtab::create(SectionRef &Section) { 448 Expected<StringRef> DataOrErr = Section.getContents(); 449 if (!DataOrErr) 450 return DataOrErr.takeError(); 451 Data = *DataOrErr; 452 Address = Section.getAddress(); 453 454 // If this is a linked PE/COFF file, then we have to skip over the null byte 455 // that is allocated in the .lprfn$A section in the LLVM profiling runtime. 456 const ObjectFile *Obj = Section.getObject(); 457 if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject()) 458 Data = Data.drop_front(1); 459 460 return Error::success(); 461 } 462 463 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) { 464 if (Pointer < Address) 465 return StringRef(); 466 auto Offset = Pointer - Address; 467 if (Offset + Size > Data.size()) 468 return StringRef(); 469 return Data.substr(Pointer - Address, Size); 470 } 471 472 // Check if the mapping data is a dummy, i.e. is emitted for an unused function. 473 static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) { 474 // The hash value of dummy mapping records is always zero. 475 if (Hash) 476 return false; 477 return RawCoverageMappingDummyChecker(Mapping).isDummy(); 478 } 479 480 /// A range of filename indices. Used to specify the location of a batch of 481 /// filenames in a vector-like container. 482 struct FilenameRange { 483 unsigned StartingIndex; 484 unsigned Length; 485 486 FilenameRange(unsigned StartingIndex, unsigned Length) 487 : StartingIndex(StartingIndex), Length(Length) {} 488 489 void markInvalid() { Length = 0; } 490 bool isInvalid() const { return Length == 0; } 491 }; 492 493 namespace { 494 495 /// The interface to read coverage mapping function records for a module. 496 struct CovMapFuncRecordReader { 497 virtual ~CovMapFuncRecordReader() = default; 498 499 // Read a coverage header. 500 // 501 // \p CovBuf points to the buffer containing the \c CovHeader of the coverage 502 // mapping data associated with the module. 503 // 504 // Returns a pointer to the next \c CovHeader if it exists, or to an address 505 // greater than \p CovEnd if not. 506 virtual Expected<const char *> readCoverageHeader(const char *CovBuf, 507 const char *CovBufEnd) = 0; 508 509 // Read function records. 510 // 511 // \p FuncRecBuf points to the buffer containing a batch of function records. 512 // \p FuncRecBufEnd points past the end of the batch of records. 513 // 514 // Prior to Version4, \p OutOfLineFileRange points to a sequence of filenames 515 // associated with the function records. It is unused in Version4. 516 // 517 // Prior to Version4, \p OutOfLineMappingBuf points to a sequence of coverage 518 // mappings associated with the function records. It is unused in Version4. 519 virtual Error readFunctionRecords(const char *FuncRecBuf, 520 const char *FuncRecBufEnd, 521 Optional<FilenameRange> OutOfLineFileRange, 522 const char *OutOfLineMappingBuf, 523 const char *OutOfLineMappingBufEnd) = 0; 524 525 template <class IntPtrT, support::endianness Endian> 526 static Expected<std::unique_ptr<CovMapFuncRecordReader>> 527 get(CovMapVersion Version, InstrProfSymtab &P, 528 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D, 529 std::vector<std::string> &F); 530 }; 531 532 // A class for reading coverage mapping function records for a module. 533 template <CovMapVersion Version, class IntPtrT, support::endianness Endian> 534 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader { 535 using FuncRecordType = 536 typename CovMapTraits<Version, IntPtrT>::CovMapFuncRecordType; 537 using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType; 538 539 // Maps function's name references to the indexes of their records 540 // in \c Records. 541 DenseMap<NameRefType, size_t> FunctionRecords; 542 InstrProfSymtab &ProfileNames; 543 StringRef CompilationDir; 544 std::vector<std::string> &Filenames; 545 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records; 546 547 // Maps a hash of the filenames in a TU to a \c FileRange. The range 548 // specifies the location of the hashed filenames in \c Filenames. 549 DenseMap<uint64_t, FilenameRange> FileRangeMap; 550 551 // Add the record to the collection if we don't already have a record that 552 // points to the same function name. This is useful to ignore the redundant 553 // records for the functions with ODR linkage. 554 // In addition, prefer records with real coverage mapping data to dummy 555 // records, which were emitted for inline functions which were seen but 556 // not used in the corresponding translation unit. 557 Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR, 558 StringRef Mapping, 559 FilenameRange FileRange) { 560 ++CovMapNumRecords; 561 uint64_t FuncHash = CFR->template getFuncHash<Endian>(); 562 NameRefType NameRef = CFR->template getFuncNameRef<Endian>(); 563 auto InsertResult = 564 FunctionRecords.insert(std::make_pair(NameRef, Records.size())); 565 if (InsertResult.second) { 566 StringRef FuncName; 567 if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName)) 568 return Err; 569 if (FuncName.empty()) 570 return make_error<InstrProfError>(instrprof_error::malformed, 571 "function name is empty"); 572 ++CovMapNumUsedRecords; 573 Records.emplace_back(Version, FuncName, FuncHash, Mapping, 574 FileRange.StartingIndex, FileRange.Length); 575 return Error::success(); 576 } 577 // Update the existing record if it's a dummy and the new record is real. 578 size_t OldRecordIndex = InsertResult.first->second; 579 BinaryCoverageReader::ProfileMappingRecord &OldRecord = 580 Records[OldRecordIndex]; 581 Expected<bool> OldIsDummyExpected = isCoverageMappingDummy( 582 OldRecord.FunctionHash, OldRecord.CoverageMapping); 583 if (Error Err = OldIsDummyExpected.takeError()) 584 return Err; 585 if (!*OldIsDummyExpected) 586 return Error::success(); 587 Expected<bool> NewIsDummyExpected = 588 isCoverageMappingDummy(FuncHash, Mapping); 589 if (Error Err = NewIsDummyExpected.takeError()) 590 return Err; 591 if (*NewIsDummyExpected) 592 return Error::success(); 593 ++CovMapNumUsedRecords; 594 OldRecord.FunctionHash = FuncHash; 595 OldRecord.CoverageMapping = Mapping; 596 OldRecord.FilenamesBegin = FileRange.StartingIndex; 597 OldRecord.FilenamesSize = FileRange.Length; 598 return Error::success(); 599 } 600 601 public: 602 VersionedCovMapFuncRecordReader( 603 InstrProfSymtab &P, 604 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D, 605 std::vector<std::string> &F) 606 : ProfileNames(P), CompilationDir(D), Filenames(F), Records(R) {} 607 608 ~VersionedCovMapFuncRecordReader() override = default; 609 610 Expected<const char *> readCoverageHeader(const char *CovBuf, 611 const char *CovBufEnd) override { 612 using namespace support; 613 614 if (CovBuf + sizeof(CovMapHeader) > CovBufEnd) 615 return make_error<CoverageMapError>(coveragemap_error::malformed); 616 auto CovHeader = reinterpret_cast<const CovMapHeader *>(CovBuf); 617 uint32_t NRecords = CovHeader->getNRecords<Endian>(); 618 uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>(); 619 uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>(); 620 assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version); 621 CovBuf = reinterpret_cast<const char *>(CovHeader + 1); 622 623 // Skip past the function records, saving the start and end for later. 624 // This is a no-op in Version4 (function records are read after all headers 625 // are read). 626 const char *FuncRecBuf = nullptr; 627 const char *FuncRecBufEnd = nullptr; 628 if (Version < CovMapVersion::Version4) 629 FuncRecBuf = CovBuf; 630 CovBuf += NRecords * sizeof(FuncRecordType); 631 if (Version < CovMapVersion::Version4) 632 FuncRecBufEnd = CovBuf; 633 634 // Get the filenames. 635 if (CovBuf + FilenamesSize > CovBufEnd) 636 return make_error<CoverageMapError>(coveragemap_error::malformed); 637 size_t FilenamesBegin = Filenames.size(); 638 StringRef FilenameRegion(CovBuf, FilenamesSize); 639 RawCoverageFilenamesReader Reader(FilenameRegion, Filenames, 640 CompilationDir); 641 if (auto Err = Reader.read(Version)) 642 return std::move(Err); 643 CovBuf += FilenamesSize; 644 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin); 645 646 if (Version >= CovMapVersion::Version4) { 647 // Map a hash of the filenames region to the filename range associated 648 // with this coverage header. 649 int64_t FilenamesRef = 650 llvm::IndexedInstrProf::ComputeHash(FilenameRegion); 651 auto Insert = 652 FileRangeMap.insert(std::make_pair(FilenamesRef, FileRange)); 653 if (!Insert.second) { 654 // The same filenames ref was encountered twice. It's possible that 655 // the associated filenames are the same. 656 auto It = Filenames.begin(); 657 FilenameRange &OrigRange = Insert.first->getSecond(); 658 if (std::equal(It + OrigRange.StartingIndex, 659 It + OrigRange.StartingIndex + OrigRange.Length, 660 It + FileRange.StartingIndex, 661 It + FileRange.StartingIndex + FileRange.Length)) 662 // Map the new range to the original one. 663 FileRange = OrigRange; 664 else 665 // This is a hash collision. Mark the filenames ref invalid. 666 OrigRange.markInvalid(); 667 } 668 } 669 670 // We'll read the coverage mapping records in the loop below. 671 // This is a no-op in Version4 (coverage mappings are not affixed to the 672 // coverage header). 673 const char *MappingBuf = CovBuf; 674 if (Version >= CovMapVersion::Version4 && CoverageSize != 0) 675 return make_error<CoverageMapError>(coveragemap_error::malformed); 676 CovBuf += CoverageSize; 677 const char *MappingEnd = CovBuf; 678 679 if (CovBuf > CovBufEnd) 680 return make_error<CoverageMapError>(coveragemap_error::malformed); 681 682 if (Version < CovMapVersion::Version4) { 683 // Read each function record. 684 if (Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange, 685 MappingBuf, MappingEnd)) 686 return std::move(E); 687 } 688 689 // Each coverage map has an alignment of 8, so we need to adjust alignment 690 // before reading the next map. 691 CovBuf += offsetToAlignedAddr(CovBuf, Align(8)); 692 693 return CovBuf; 694 } 695 696 Error readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd, 697 Optional<FilenameRange> OutOfLineFileRange, 698 const char *OutOfLineMappingBuf, 699 const char *OutOfLineMappingBufEnd) override { 700 auto CFR = reinterpret_cast<const FuncRecordType *>(FuncRecBuf); 701 while ((const char *)CFR < FuncRecBufEnd) { 702 // Validate the length of the coverage mapping for this function. 703 const char *NextMappingBuf; 704 const FuncRecordType *NextCFR; 705 std::tie(NextMappingBuf, NextCFR) = 706 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf); 707 if (Version < CovMapVersion::Version4) 708 if (NextMappingBuf > OutOfLineMappingBufEnd) 709 return make_error<CoverageMapError>(coveragemap_error::malformed); 710 711 // Look up the set of filenames associated with this function record. 712 Optional<FilenameRange> FileRange; 713 if (Version < CovMapVersion::Version4) { 714 FileRange = OutOfLineFileRange; 715 } else { 716 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>(); 717 auto It = FileRangeMap.find(FilenamesRef); 718 if (It == FileRangeMap.end()) 719 return make_error<CoverageMapError>(coveragemap_error::malformed); 720 else 721 FileRange = It->getSecond(); 722 } 723 724 // Now, read the coverage data. 725 if (FileRange && !FileRange->isInvalid()) { 726 StringRef Mapping = 727 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf); 728 if (Version >= CovMapVersion::Version4 && 729 Mapping.data() + Mapping.size() > FuncRecBufEnd) 730 return make_error<CoverageMapError>(coveragemap_error::malformed); 731 if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange)) 732 return Err; 733 } 734 735 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR); 736 } 737 return Error::success(); 738 } 739 }; 740 741 } // end anonymous namespace 742 743 template <class IntPtrT, support::endianness Endian> 744 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( 745 CovMapVersion Version, InstrProfSymtab &P, 746 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D, 747 std::vector<std::string> &F) { 748 using namespace coverage; 749 750 switch (Version) { 751 case CovMapVersion::Version1: 752 return std::make_unique<VersionedCovMapFuncRecordReader< 753 CovMapVersion::Version1, IntPtrT, Endian>>(P, R, D, F); 754 case CovMapVersion::Version2: 755 case CovMapVersion::Version3: 756 case CovMapVersion::Version4: 757 case CovMapVersion::Version5: 758 case CovMapVersion::Version6: 759 // Decompress the name data. 760 if (Error E = P.create(P.getNameData())) 761 return std::move(E); 762 if (Version == CovMapVersion::Version2) 763 return std::make_unique<VersionedCovMapFuncRecordReader< 764 CovMapVersion::Version2, IntPtrT, Endian>>(P, R, D, F); 765 else if (Version == CovMapVersion::Version3) 766 return std::make_unique<VersionedCovMapFuncRecordReader< 767 CovMapVersion::Version3, IntPtrT, Endian>>(P, R, D, F); 768 else if (Version == CovMapVersion::Version4) 769 return std::make_unique<VersionedCovMapFuncRecordReader< 770 CovMapVersion::Version4, IntPtrT, Endian>>(P, R, D, F); 771 else if (Version == CovMapVersion::Version5) 772 return std::make_unique<VersionedCovMapFuncRecordReader< 773 CovMapVersion::Version5, IntPtrT, Endian>>(P, R, D, F); 774 else if (Version == CovMapVersion::Version6) 775 return std::make_unique<VersionedCovMapFuncRecordReader< 776 CovMapVersion::Version6, IntPtrT, Endian>>(P, R, D, F); 777 } 778 llvm_unreachable("Unsupported version"); 779 } 780 781 template <typename T, support::endianness Endian> 782 static Error readCoverageMappingData( 783 InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, 784 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records, 785 StringRef CompilationDir, std::vector<std::string> &Filenames) { 786 using namespace coverage; 787 788 // Read the records in the coverage data section. 789 auto CovHeader = 790 reinterpret_cast<const CovMapHeader *>(CovMap.data()); 791 CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>(); 792 if (Version > CovMapVersion::CurrentVersion) 793 return make_error<CoverageMapError>(coveragemap_error::unsupported_version); 794 Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected = 795 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records, 796 CompilationDir, Filenames); 797 if (Error E = ReaderExpected.takeError()) 798 return E; 799 auto Reader = std::move(ReaderExpected.get()); 800 const char *CovBuf = CovMap.data(); 801 const char *CovBufEnd = CovBuf + CovMap.size(); 802 const char *FuncRecBuf = FuncRecords.data(); 803 const char *FuncRecBufEnd = FuncRecords.data() + FuncRecords.size(); 804 while (CovBuf < CovBufEnd) { 805 // Read the current coverage header & filename data. 806 // 807 // Prior to Version4, this also reads all function records affixed to the 808 // header. 809 // 810 // Return a pointer to the next coverage header. 811 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd); 812 if (auto E = NextOrErr.takeError()) 813 return E; 814 CovBuf = NextOrErr.get(); 815 } 816 // In Version4, function records are not affixed to coverage headers. Read 817 // the records from their dedicated section. 818 if (Version >= CovMapVersion::Version4) 819 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, None, nullptr, 820 nullptr); 821 return Error::success(); 822 } 823 824 static const char *TestingFormatMagic = "llvmcovmtestdata"; 825 826 Expected<std::unique_ptr<BinaryCoverageReader>> 827 BinaryCoverageReader::createCoverageReaderFromBuffer( 828 StringRef Coverage, FuncRecordsStorage &&FuncRecords, 829 InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress, 830 support::endianness Endian, StringRef CompilationDir) { 831 std::unique_ptr<BinaryCoverageReader> Reader( 832 new BinaryCoverageReader(std::move(FuncRecords))); 833 Reader->ProfileNames = std::move(ProfileNames); 834 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer(); 835 if (BytesInAddress == 4 && Endian == support::endianness::little) { 836 if (Error E = 837 readCoverageMappingData<uint32_t, support::endianness::little>( 838 Reader->ProfileNames, Coverage, FuncRecordsRef, 839 Reader->MappingRecords, CompilationDir, Reader->Filenames)) 840 return std::move(E); 841 } else if (BytesInAddress == 4 && Endian == support::endianness::big) { 842 if (Error E = readCoverageMappingData<uint32_t, support::endianness::big>( 843 Reader->ProfileNames, Coverage, FuncRecordsRef, 844 Reader->MappingRecords, CompilationDir, Reader->Filenames)) 845 return std::move(E); 846 } else if (BytesInAddress == 8 && Endian == support::endianness::little) { 847 if (Error E = 848 readCoverageMappingData<uint64_t, support::endianness::little>( 849 Reader->ProfileNames, Coverage, FuncRecordsRef, 850 Reader->MappingRecords, CompilationDir, Reader->Filenames)) 851 return std::move(E); 852 } else if (BytesInAddress == 8 && Endian == support::endianness::big) { 853 if (Error E = readCoverageMappingData<uint64_t, support::endianness::big>( 854 Reader->ProfileNames, Coverage, FuncRecordsRef, 855 Reader->MappingRecords, CompilationDir, Reader->Filenames)) 856 return std::move(E); 857 } else 858 return make_error<CoverageMapError>(coveragemap_error::malformed); 859 return std::move(Reader); 860 } 861 862 static Expected<std::unique_ptr<BinaryCoverageReader>> 863 loadTestingFormat(StringRef Data, StringRef CompilationDir) { 864 uint8_t BytesInAddress = 8; 865 support::endianness Endian = support::endianness::little; 866 867 Data = Data.substr(StringRef(TestingFormatMagic).size()); 868 if (Data.empty()) 869 return make_error<CoverageMapError>(coveragemap_error::truncated); 870 unsigned N = 0; 871 uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N); 872 if (N > Data.size()) 873 return make_error<CoverageMapError>(coveragemap_error::malformed); 874 Data = Data.substr(N); 875 if (Data.empty()) 876 return make_error<CoverageMapError>(coveragemap_error::truncated); 877 N = 0; 878 uint64_t Address = decodeULEB128(Data.bytes_begin(), &N); 879 if (N > Data.size()) 880 return make_error<CoverageMapError>(coveragemap_error::malformed); 881 Data = Data.substr(N); 882 if (Data.size() < ProfileNamesSize) 883 return make_error<CoverageMapError>(coveragemap_error::malformed); 884 InstrProfSymtab ProfileNames; 885 if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address)) 886 return std::move(E); 887 Data = Data.substr(ProfileNamesSize); 888 // Skip the padding bytes because coverage map data has an alignment of 8. 889 size_t Pad = offsetToAlignedAddr(Data.data(), Align(8)); 890 if (Data.size() < Pad) 891 return make_error<CoverageMapError>(coveragemap_error::malformed); 892 Data = Data.substr(Pad); 893 if (Data.size() < sizeof(CovMapHeader)) 894 return make_error<CoverageMapError>(coveragemap_error::malformed); 895 auto const *CovHeader = reinterpret_cast<const CovMapHeader *>( 896 Data.substr(0, sizeof(CovMapHeader)).data()); 897 CovMapVersion Version = 898 (CovMapVersion)CovHeader->getVersion<support::endianness::little>(); 899 StringRef CoverageMapping; 900 BinaryCoverageReader::FuncRecordsStorage CoverageRecords; 901 if (Version < CovMapVersion::Version4) { 902 CoverageMapping = Data; 903 if (CoverageMapping.empty()) 904 return make_error<CoverageMapError>(coveragemap_error::truncated); 905 CoverageRecords = MemoryBuffer::getMemBuffer(""); 906 } else { 907 uint32_t FilenamesSize = 908 CovHeader->getFilenamesSize<support::endianness::little>(); 909 uint32_t CoverageMappingSize = sizeof(CovMapHeader) + FilenamesSize; 910 CoverageMapping = Data.substr(0, CoverageMappingSize); 911 if (CoverageMapping.empty()) 912 return make_error<CoverageMapError>(coveragemap_error::truncated); 913 Data = Data.substr(CoverageMappingSize); 914 // Skip the padding bytes because coverage records data has an alignment 915 // of 8. 916 Pad = offsetToAlignedAddr(Data.data(), Align(8)); 917 if (Data.size() < Pad) 918 return make_error<CoverageMapError>(coveragemap_error::malformed); 919 CoverageRecords = MemoryBuffer::getMemBuffer(Data.substr(Pad)); 920 if (CoverageRecords->getBufferSize() == 0) 921 return make_error<CoverageMapError>(coveragemap_error::truncated); 922 } 923 return BinaryCoverageReader::createCoverageReaderFromBuffer( 924 CoverageMapping, std::move(CoverageRecords), std::move(ProfileNames), 925 BytesInAddress, Endian, CompilationDir); 926 } 927 928 /// Find all sections that match \p Name. There may be more than one if comdats 929 /// are in use, e.g. for the __llvm_covfun section on ELF. 930 static Expected<std::vector<SectionRef>> lookupSections(ObjectFile &OF, 931 StringRef Name) { 932 // On COFF, the object file section name may end in "$M". This tells the 933 // linker to sort these sections between "$A" and "$Z". The linker removes the 934 // dollar and everything after it in the final binary. Do the same to match. 935 bool IsCOFF = isa<COFFObjectFile>(OF); 936 auto stripSuffix = [IsCOFF](StringRef N) { 937 return IsCOFF ? N.split('$').first : N; 938 }; 939 Name = stripSuffix(Name); 940 941 std::vector<SectionRef> Sections; 942 for (const auto &Section : OF.sections()) { 943 Expected<StringRef> NameOrErr = Section.getName(); 944 if (!NameOrErr) 945 return NameOrErr.takeError(); 946 if (stripSuffix(*NameOrErr) == Name) 947 Sections.push_back(Section); 948 } 949 if (Sections.empty()) 950 return make_error<CoverageMapError>(coveragemap_error::no_data_found); 951 return Sections; 952 } 953 954 static Expected<std::unique_ptr<BinaryCoverageReader>> 955 loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch, 956 StringRef CompilationDir = "") { 957 std::unique_ptr<ObjectFile> OF; 958 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) { 959 // If we have a universal binary, try to look up the object for the 960 // appropriate architecture. 961 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch); 962 if (!ObjectFileOrErr) 963 return ObjectFileOrErr.takeError(); 964 OF = std::move(ObjectFileOrErr.get()); 965 } else if (isa<ObjectFile>(Bin.get())) { 966 // For any other object file, upcast and take ownership. 967 OF.reset(cast<ObjectFile>(Bin.release())); 968 // If we've asked for a particular arch, make sure they match. 969 if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch()) 970 return errorCodeToError(object_error::arch_not_found); 971 } else 972 // We can only handle object files. 973 return make_error<CoverageMapError>(coveragemap_error::malformed); 974 975 // The coverage uses native pointer sizes for the object it's written in. 976 uint8_t BytesInAddress = OF->getBytesInAddress(); 977 support::endianness Endian = OF->isLittleEndian() 978 ? support::endianness::little 979 : support::endianness::big; 980 981 // Look for the sections that we are interested in. 982 auto ObjFormat = OF->getTripleObjectFormat(); 983 auto NamesSection = 984 lookupSections(*OF, getInstrProfSectionName(IPSK_name, ObjFormat, 985 /*AddSegmentInfo=*/false)); 986 if (auto E = NamesSection.takeError()) 987 return std::move(E); 988 auto CoverageSection = 989 lookupSections(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat, 990 /*AddSegmentInfo=*/false)); 991 if (auto E = CoverageSection.takeError()) 992 return std::move(E); 993 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection; 994 if (CoverageSectionRefs.size() != 1) 995 return make_error<CoverageMapError>(coveragemap_error::malformed); 996 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents(); 997 if (!CoverageMappingOrErr) 998 return CoverageMappingOrErr.takeError(); 999 StringRef CoverageMapping = CoverageMappingOrErr.get(); 1000 1001 InstrProfSymtab ProfileNames; 1002 std::vector<SectionRef> NamesSectionRefs = *NamesSection; 1003 if (NamesSectionRefs.size() != 1) 1004 return make_error<CoverageMapError>(coveragemap_error::malformed); 1005 if (Error E = ProfileNames.create(NamesSectionRefs.back())) 1006 return std::move(E); 1007 1008 // Look for the coverage records section (Version4 only). 1009 auto CoverageRecordsSections = 1010 lookupSections(*OF, getInstrProfSectionName(IPSK_covfun, ObjFormat, 1011 /*AddSegmentInfo=*/false)); 1012 1013 BinaryCoverageReader::FuncRecordsStorage FuncRecords; 1014 if (auto E = CoverageRecordsSections.takeError()) { 1015 consumeError(std::move(E)); 1016 FuncRecords = MemoryBuffer::getMemBuffer(""); 1017 } else { 1018 // Compute the FuncRecordsBuffer of the buffer, taking into account the 1019 // padding between each record, and making sure the first block is aligned 1020 // in memory to maintain consistency between buffer address and size 1021 // alignment. 1022 const Align RecordAlignment(8); 1023 uint64_t FuncRecordsSize = 0; 1024 for (SectionRef Section : *CoverageRecordsSections) { 1025 auto CoverageRecordsOrErr = Section.getContents(); 1026 if (!CoverageRecordsOrErr) 1027 return CoverageRecordsOrErr.takeError(); 1028 FuncRecordsSize += alignTo(CoverageRecordsOrErr->size(), RecordAlignment); 1029 } 1030 auto WritableBuffer = 1031 WritableMemoryBuffer::getNewUninitMemBuffer(FuncRecordsSize); 1032 char *FuncRecordsBuffer = WritableBuffer->getBufferStart(); 1033 assert(isAddrAligned(RecordAlignment, FuncRecordsBuffer) && 1034 "Allocated memory is correctly aligned"); 1035 1036 for (SectionRef Section : *CoverageRecordsSections) { 1037 auto CoverageRecordsOrErr = Section.getContents(); 1038 if (!CoverageRecordsOrErr) 1039 return CoverageRecordsOrErr.takeError(); 1040 const auto &CoverageRecords = CoverageRecordsOrErr.get(); 1041 FuncRecordsBuffer = std::copy(CoverageRecords.begin(), 1042 CoverageRecords.end(), FuncRecordsBuffer); 1043 FuncRecordsBuffer = 1044 std::fill_n(FuncRecordsBuffer, 1045 alignAddr(FuncRecordsBuffer, RecordAlignment) - 1046 (uintptr_t)FuncRecordsBuffer, 1047 '\0'); 1048 } 1049 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() && 1050 "consistent init"); 1051 FuncRecords = std::move(WritableBuffer); 1052 } 1053 1054 return BinaryCoverageReader::createCoverageReaderFromBuffer( 1055 CoverageMapping, std::move(FuncRecords), std::move(ProfileNames), 1056 BytesInAddress, Endian, CompilationDir); 1057 } 1058 1059 /// Determine whether \p Arch is invalid or empty, given \p Bin. 1060 static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) { 1061 // If we have a universal binary and Arch doesn't identify any of its slices, 1062 // it's user error. 1063 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) { 1064 for (auto &ObjForArch : Universal->objects()) 1065 if (Arch == ObjForArch.getArchFlagName()) 1066 return false; 1067 return true; 1068 } 1069 return false; 1070 } 1071 1072 Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>> 1073 BinaryCoverageReader::create( 1074 MemoryBufferRef ObjectBuffer, StringRef Arch, 1075 SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers, 1076 StringRef CompilationDir) { 1077 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers; 1078 1079 if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) { 1080 // This is a special format used for testing. 1081 auto ReaderOrErr = 1082 loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir); 1083 if (!ReaderOrErr) 1084 return ReaderOrErr.takeError(); 1085 Readers.push_back(std::move(ReaderOrErr.get())); 1086 return std::move(Readers); 1087 } 1088 1089 auto BinOrErr = createBinary(ObjectBuffer); 1090 if (!BinOrErr) 1091 return BinOrErr.takeError(); 1092 std::unique_ptr<Binary> Bin = std::move(BinOrErr.get()); 1093 1094 if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch)) 1095 return make_error<CoverageMapError>( 1096 coveragemap_error::invalid_or_missing_arch_specifier); 1097 1098 // MachO universal binaries which contain archives need to be treated as 1099 // archives, not as regular binaries. 1100 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) { 1101 for (auto &ObjForArch : Universal->objects()) { 1102 // Skip slices within the universal binary which target the wrong arch. 1103 std::string ObjArch = ObjForArch.getArchFlagName(); 1104 if (Arch != ObjArch) 1105 continue; 1106 1107 auto ArchiveOrErr = ObjForArch.getAsArchive(); 1108 if (!ArchiveOrErr) { 1109 // If this is not an archive, try treating it as a regular object. 1110 consumeError(ArchiveOrErr.takeError()); 1111 break; 1112 } 1113 1114 return BinaryCoverageReader::create( 1115 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers, 1116 CompilationDir); 1117 } 1118 } 1119 1120 // Load coverage out of archive members. 1121 if (auto *Ar = dyn_cast<Archive>(Bin.get())) { 1122 Error Err = Error::success(); 1123 for (auto &Child : Ar->children(Err)) { 1124 Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef(); 1125 if (!ChildBufOrErr) 1126 return ChildBufOrErr.takeError(); 1127 1128 auto ChildReadersOrErr = BinaryCoverageReader::create( 1129 ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir); 1130 if (!ChildReadersOrErr) 1131 return ChildReadersOrErr.takeError(); 1132 for (auto &Reader : ChildReadersOrErr.get()) 1133 Readers.push_back(std::move(Reader)); 1134 } 1135 if (Err) 1136 return std::move(Err); 1137 1138 // Thin archives reference object files outside of the archive file, i.e. 1139 // files which reside in memory not owned by the caller. Transfer ownership 1140 // to the caller. 1141 if (Ar->isThin()) 1142 for (auto &Buffer : Ar->takeThinBuffers()) 1143 ObjectFileBuffers.push_back(std::move(Buffer)); 1144 1145 return std::move(Readers); 1146 } 1147 1148 auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir); 1149 if (!ReaderOrErr) 1150 return ReaderOrErr.takeError(); 1151 Readers.push_back(std::move(ReaderOrErr.get())); 1152 return std::move(Readers); 1153 } 1154 1155 Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) { 1156 if (CurrentRecord >= MappingRecords.size()) 1157 return make_error<CoverageMapError>(coveragemap_error::eof); 1158 1159 FunctionsFilenames.clear(); 1160 Expressions.clear(); 1161 MappingRegions.clear(); 1162 auto &R = MappingRecords[CurrentRecord]; 1163 auto F = makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize); 1164 RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames, 1165 Expressions, MappingRegions); 1166 if (auto Err = Reader.read()) 1167 return Err; 1168 1169 Record.FunctionName = R.FunctionName; 1170 Record.FunctionHash = R.FunctionHash; 1171 Record.Filenames = FunctionsFilenames; 1172 Record.Expressions = Expressions; 1173 Record.MappingRegions = MappingRegions; 1174 1175 ++CurrentRecord; 1176 return Error::success(); 1177 } 1178