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