LLVM 19.0.0git
CoverageMappingReader.cpp
Go to the documentation of this file.
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
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/Statistic.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/Object/Archive.h"
22#include "llvm/Object/Binary.h"
23#include "llvm/Object/COFF.h"
24#include "llvm/Object/Error.h"
30#include "llvm/Support/Debug.h"
31#include "llvm/Support/Endian.h"
32#include "llvm/Support/Error.h"
34#include "llvm/Support/LEB128.h"
36#include "llvm/Support/Path.h"
39#include <vector>
40
41using namespace llvm;
42using namespace coverage;
43using namespace object;
44
45#define DEBUG_TYPE "coverage-mapping"
46
47STATISTIC(CovMapNumRecords, "The # of coverage function records");
48STATISTIC(CovMapNumUsedRecords, "The # of used coverage function records");
49
50void CoverageMappingIterator::increment() {
51 if (ReadErr != coveragemap_error::success)
52 return;
53
54 // Check if all the records were read or if an error occurred while reading
55 // the next record.
56 if (auto E = Reader->readNextRecord(Record))
57 handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
58 if (CME.get() == coveragemap_error::eof)
60 else
61 ReadErr = CME.get();
62 });
63}
64
66 if (Data.empty())
67 return make_error<CoverageMapError>(coveragemap_error::truncated);
68 unsigned N = 0;
69 Result = decodeULEB128(Data.bytes_begin(), &N);
70 if (N > Data.size())
71 return make_error<CoverageMapError>(coveragemap_error::malformed,
72 "the size of ULEB128 is too big");
73 Data = Data.substr(N);
74 return Error::success();
75}
76
78 if (auto Err = readULEB128(Result))
79 return Err;
80 if (Result >= MaxPlus1)
81 return make_error<CoverageMapError>(
83 "the value of ULEB128 is greater than or equal to MaxPlus1");
84 return Error::success();
85}
86
88 if (auto Err = readULEB128(Result))
89 return Err;
90 if (Result > Data.size())
91 return make_error<CoverageMapError>(coveragemap_error::malformed,
92 "the value of ULEB128 is too big");
93 return Error::success();
94}
95
98 if (auto Err = readSize(Length))
99 return Err;
100 Result = Data.substr(0, Length);
102 return Error::success();
103}
104
106 uint64_t NumFilenames;
107 if (auto Err = readSize(NumFilenames))
108 return Err;
109 if (!NumFilenames)
110 return make_error<CoverageMapError>(coveragemap_error::malformed,
111 "number of filenames is zero");
112
113 if (Version < CovMapVersion::Version4)
114 return readUncompressed(Version, NumFilenames);
115
116 // The uncompressed length may exceed the size of the encoded filenames.
117 // Skip size validation.
118 uint64_t UncompressedLen;
119 if (auto Err = readULEB128(UncompressedLen))
120 return Err;
121
122 uint64_t CompressedLen;
123 if (auto Err = readSize(CompressedLen))
124 return Err;
125
126 if (CompressedLen > 0) {
128 return make_error<CoverageMapError>(
130
131 // Allocate memory for the decompressed filenames.
132 SmallVector<uint8_t, 0> StorageBuf;
133
134 // Read compressed filenames.
135 StringRef CompressedFilenames = Data.substr(0, CompressedLen);
136 Data = Data.substr(CompressedLen);
138 arrayRefFromStringRef(CompressedFilenames), StorageBuf,
139 UncompressedLen);
140 if (Err) {
141 consumeError(std::move(Err));
142 return make_error<CoverageMapError>(
144 }
145
146 RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
147 CompilationDir);
148 return Delegate.readUncompressed(Version, NumFilenames);
149 }
150
151 return readUncompressed(Version, NumFilenames);
152}
153
154Error RawCoverageFilenamesReader::readUncompressed(CovMapVersion Version,
155 uint64_t NumFilenames) {
156 // Read uncompressed filenames.
157 if (Version < CovMapVersion::Version6) {
158 for (size_t I = 0; I < NumFilenames; ++I) {
159 StringRef Filename;
160 if (auto Err = readString(Filename))
161 return Err;
162 Filenames.push_back(Filename.str());
163 }
164 } else {
165 StringRef CWD;
166 if (auto Err = readString(CWD))
167 return Err;
168 Filenames.push_back(CWD.str());
169
170 for (size_t I = 1; I < NumFilenames; ++I) {
171 StringRef Filename;
172 if (auto Err = readString(Filename))
173 return Err;
174 if (sys::path::is_absolute(Filename)) {
175 Filenames.push_back(Filename.str());
176 } else {
178 if (!CompilationDir.empty())
179 P.assign(CompilationDir);
180 else
181 P.assign(CWD);
182 llvm::sys::path::append(P, Filename);
183 sys::path::remove_dots(P, /*remove_dot_dot=*/true);
184 Filenames.push_back(static_cast<std::string>(P.str()));
185 }
186 }
187 }
188 return Error::success();
189}
190
191Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
193 switch (Tag) {
194 case Counter::Zero:
196 return Error::success();
199 return Error::success();
200 default:
201 break;
202 }
204 switch (Tag) {
208 if (ID >= Expressions.size())
209 return make_error<CoverageMapError>(coveragemap_error::malformed,
210 "counter expression is invalid");
211 Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
213 break;
214 }
215 default:
216 return make_error<CoverageMapError>(coveragemap_error::malformed,
217 "counter expression kind is invalid");
218 }
219 return Error::success();
220}
221
222Error RawCoverageMappingReader::readCounter(Counter &C) {
223 uint64_t EncodedCounter;
224 if (auto Err =
225 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
226 return Err;
227 if (auto Err = decodeCounter(EncodedCounter, C))
228 return Err;
229 return Error::success();
230}
231
232static const unsigned EncodingExpansionRegionBit = 1
234
235/// Read the sub-array of regions for the given inferred file id.
236/// \param NumFileIDs the number of file ids that are defined for this
237/// function.
238Error RawCoverageMappingReader::readMappingRegionsSubArray(
239 std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
240 size_t NumFileIDs) {
241 uint64_t NumRegions;
242 if (auto Err = readSize(NumRegions))
243 return Err;
244 unsigned LineStart = 0;
245 for (size_t I = 0; I < NumRegions; ++I) {
246 Counter C, C2;
247 uint64_t BIDX, NC;
248 // They are stored as internal values plus 1 (min is -1)
249 uint64_t ID1, TID1, FID1;
250 mcdc::Parameters Params;
252
253 // Read the combined counter + region kind.
254 uint64_t EncodedCounterAndRegion;
255 if (auto Err = readIntMax(EncodedCounterAndRegion,
256 std::numeric_limits<unsigned>::max()))
257 return Err;
258 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
259 uint64_t ExpandedFileID = 0;
260
261 // If Tag does not represent a ZeroCounter, then it is understood to refer
262 // to a counter or counter expression with region kind assumed to be
263 // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the
264 // referenced counter or counter expression (and nothing else).
265 //
266 // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set,
267 // then EncodedCounterAndRegion is interpreted to represent an
268 // ExpansionRegion. In all other cases, EncodedCounterAndRegion is
269 // interpreted to refer to a specific region kind, after which additional
270 // fields may be read (e.g. BranchRegions have two encoded counters that
271 // follow an encoded region kind value).
272 if (Tag != Counter::Zero) {
273 if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
274 return Err;
275 } else {
276 // Is it an expansion region?
277 if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
279 ExpandedFileID = EncodedCounterAndRegion >>
281 if (ExpandedFileID >= NumFileIDs)
282 return make_error<CoverageMapError>(coveragemap_error::malformed,
283 "ExpandedFileID is invalid");
284 } else {
285 switch (EncodedCounterAndRegion >>
288 // Don't do anything when we have a code region with a zero counter.
289 break;
292 break;
294 // For a Branch Region, read two successive counters.
296 if (auto Err = readCounter(C))
297 return Err;
298 if (auto Err = readCounter(C2))
299 return Err;
300 break;
302 // For a MCDC Branch Region, read two successive counters and 3 IDs.
304 if (auto Err = readCounter(C))
305 return Err;
306 if (auto Err = readCounter(C2))
307 return Err;
308 if (auto Err = readIntMax(ID1, std::numeric_limits<int16_t>::max()))
309 return Err;
310 if (auto Err = readIntMax(TID1, std::numeric_limits<int16_t>::max()))
311 return Err;
312 if (auto Err = readIntMax(FID1, std::numeric_limits<int16_t>::max()))
313 return Err;
314 if (ID1 == 0)
315 return make_error<CoverageMapError>(
317 "MCDCConditionID shouldn't be zero");
318 Params = mcdc::BranchParameters{
319 static_cast<int16_t>(static_cast<int16_t>(ID1) - 1),
320 {static_cast<int16_t>(static_cast<int16_t>(FID1) - 1),
321 static_cast<int16_t>(static_cast<int16_t>(TID1) - 1)}};
322 break;
325 if (auto Err = readIntMax(BIDX, std::numeric_limits<unsigned>::max()))
326 return Err;
327 if (auto Err = readIntMax(NC, std::numeric_limits<int16_t>::max()))
328 return Err;
329 Params = mcdc::DecisionParameters{static_cast<unsigned>(BIDX),
330 static_cast<uint16_t>(NC)};
331 break;
332 default:
333 return make_error<CoverageMapError>(coveragemap_error::malformed,
334 "region kind is incorrect");
335 }
336 }
337 }
338
339 // Read the source range.
340 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
341 if (auto Err =
342 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
343 return Err;
344 if (auto Err = readULEB128(ColumnStart))
345 return Err;
346 if (ColumnStart > std::numeric_limits<unsigned>::max())
347 return make_error<CoverageMapError>(coveragemap_error::malformed,
348 "start column is too big");
349 if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
350 return Err;
351 if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
352 return Err;
353 LineStart += LineStartDelta;
354
355 // If the high bit of ColumnEnd is set, this is a gap region.
356 if (ColumnEnd & (1U << 31)) {
358 ColumnEnd &= ~(1U << 31);
359 }
360
361 // Adjust the column locations for the empty regions that are supposed to
362 // cover whole lines. Those regions should be encoded with the
363 // column range (1 -> std::numeric_limits<unsigned>::max()), but because
364 // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
365 // we set the column range to (0 -> 0) to ensure that the column start and
366 // column end take up one byte each.
367 // The std::numeric_limits<unsigned>::max() is used to represent a column
368 // position at the end of the line without knowing the length of that line.
369 if (ColumnStart == 0 && ColumnEnd == 0) {
370 ColumnStart = 1;
371 ColumnEnd = std::numeric_limits<unsigned>::max();
372 }
373
374 LLVM_DEBUG({
375 dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
376 << ColumnStart << " -> " << (LineStart + NumLines) << ":"
377 << ColumnEnd << ", ";
379 dbgs() << "Expands to file " << ExpandedFileID;
380 else
381 CounterMappingContext(Expressions).dump(C, dbgs());
382 dbgs() << "\n";
383 });
384
385 auto CMR = CounterMappingRegion(
386 C, C2, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
387 LineStart + NumLines, ColumnEnd, Kind, Params);
388 if (CMR.startLoc() > CMR.endLoc())
389 return make_error<CoverageMapError>(
391 "counter mapping region locations are incorrect");
392 MappingRegions.push_back(CMR);
393 }
394 return Error::success();
395}
396
398 // Read the virtual file mapping.
399 SmallVector<unsigned, 8> VirtualFileMapping;
400 uint64_t NumFileMappings;
401 if (auto Err = readSize(NumFileMappings))
402 return Err;
403 for (size_t I = 0; I < NumFileMappings; ++I) {
404 uint64_t FilenameIndex;
405 if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
406 return Err;
407 VirtualFileMapping.push_back(FilenameIndex);
408 }
409
410 // Construct the files using unique filenames and virtual file mapping.
411 for (auto I : VirtualFileMapping) {
412 Filenames.push_back(TranslationUnitFilenames[I]);
413 }
414
415 // Read the expressions.
416 uint64_t NumExpressions;
417 if (auto Err = readSize(NumExpressions))
418 return Err;
419 // Create an array of dummy expressions that get the proper counters
420 // when the expressions are read, and the proper kinds when the counters
421 // are decoded.
422 Expressions.resize(
423 NumExpressions,
425 for (size_t I = 0; I < NumExpressions; ++I) {
426 if (auto Err = readCounter(Expressions[I].LHS))
427 return Err;
428 if (auto Err = readCounter(Expressions[I].RHS))
429 return Err;
430 }
431
432 // Read the mapping regions sub-arrays.
433 for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
434 InferredFileID < S; ++InferredFileID) {
435 if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
436 VirtualFileMapping.size()))
437 return Err;
438 }
439
440 // Set the counters for the expansion regions.
441 // i.e. Counter of expansion region = counter of the first region
442 // from the expanded file.
443 // Perform multiple passes to correctly propagate the counters through
444 // all the nested expansion regions.
445 SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
446 FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
447 for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
448 for (auto &R : MappingRegions) {
450 continue;
451 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
452 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
453 }
454 for (auto &R : MappingRegions) {
455 if (FileIDExpansionRegionMapping[R.FileID]) {
456 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
457 FileIDExpansionRegionMapping[R.FileID] = nullptr;
458 }
459 }
460 }
461
462 return Error::success();
463}
464
466 // A dummy coverage mapping data consists of just one region with zero count.
467 uint64_t NumFileMappings;
468 if (Error Err = readSize(NumFileMappings))
469 return std::move(Err);
470 if (NumFileMappings != 1)
471 return false;
472 // We don't expect any specific value for the filename index, just skip it.
473 uint64_t FilenameIndex;
474 if (Error Err =
475 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
476 return std::move(Err);
477 uint64_t NumExpressions;
478 if (Error Err = readSize(NumExpressions))
479 return std::move(Err);
480 if (NumExpressions != 0)
481 return false;
482 uint64_t NumRegions;
483 if (Error Err = readSize(NumRegions))
484 return std::move(Err);
485 if (NumRegions != 1)
486 return false;
487 uint64_t EncodedCounterAndRegion;
488 if (Error Err = readIntMax(EncodedCounterAndRegion,
489 std::numeric_limits<unsigned>::max()))
490 return std::move(Err);
491 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
492 return Tag == Counter::Zero;
493}
494
496 Expected<StringRef> DataOrErr = Section.getContents();
497 if (!DataOrErr)
498 return DataOrErr.takeError();
499 Data = *DataOrErr;
500 Address = Section.getAddress();
501
502 // If this is a linked PE/COFF file, then we have to skip over the null byte
503 // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
504 // If the name section is .lprfcovnames, it doesn't have the null byte at the
505 // beginning.
506 const ObjectFile *Obj = Section.getObject();
507 if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
508 if (Expected<StringRef> NameOrErr = Section.getName())
509 if (*NameOrErr != getInstrProfSectionName(IPSK_covname, Triple::COFF))
510 Data = Data.drop_front(1);
511
512 return Error::success();
513}
514
516 if (Pointer < Address)
517 return StringRef();
518 auto Offset = Pointer - Address;
519 if (Offset + Size > Data.size())
520 return StringRef();
521 return Data.substr(Pointer - Address, Size);
522}
523
524// Check if the mapping data is a dummy, i.e. is emitted for an unused function.
526 // The hash value of dummy mapping records is always zero.
527 if (Hash)
528 return false;
529 return RawCoverageMappingDummyChecker(Mapping).isDummy();
530}
531
532/// A range of filename indices. Used to specify the location of a batch of
533/// filenames in a vector-like container.
536 unsigned Length;
537
538 FilenameRange(unsigned StartingIndex, unsigned Length)
539 : StartingIndex(StartingIndex), Length(Length) {}
540
541 void markInvalid() { Length = 0; }
542 bool isInvalid() const { return Length == 0; }
543};
544
545namespace {
546
547/// The interface to read coverage mapping function records for a module.
548struct CovMapFuncRecordReader {
549 virtual ~CovMapFuncRecordReader() = default;
550
551 // Read a coverage header.
552 //
553 // \p CovBuf points to the buffer containing the \c CovHeader of the coverage
554 // mapping data associated with the module.
555 //
556 // Returns a pointer to the next \c CovHeader if it exists, or to an address
557 // greater than \p CovEnd if not.
558 virtual Expected<const char *> readCoverageHeader(const char *CovBuf,
559 const char *CovBufEnd) = 0;
560
561 // Read function records.
562 //
563 // \p FuncRecBuf points to the buffer containing a batch of function records.
564 // \p FuncRecBufEnd points past the end of the batch of records.
565 //
566 // Prior to Version4, \p OutOfLineFileRange points to a sequence of filenames
567 // associated with the function records. It is unused in Version4.
568 //
569 // Prior to Version4, \p OutOfLineMappingBuf points to a sequence of coverage
570 // mappings associated with the function records. It is unused in Version4.
571 virtual Error
572 readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
573 std::optional<FilenameRange> OutOfLineFileRange,
574 const char *OutOfLineMappingBuf,
575 const char *OutOfLineMappingBufEnd) = 0;
576
577 template <class IntPtrT, llvm::endianness Endian>
580 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
581 std::vector<std::string> &F);
582};
583
584// A class for reading coverage mapping function records for a module.
585template <CovMapVersion Version, class IntPtrT, llvm::endianness Endian>
586class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
587 using FuncRecordType =
589 using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
590
591 // Maps function's name references to the indexes of their records
592 // in \c Records.
593 DenseMap<NameRefType, size_t> FunctionRecords;
594 InstrProfSymtab &ProfileNames;
595 StringRef CompilationDir;
596 std::vector<std::string> &Filenames;
597 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
598
599 // Maps a hash of the filenames in a TU to a \c FileRange. The range
600 // specifies the location of the hashed filenames in \c Filenames.
602
603 // Add the record to the collection if we don't already have a record that
604 // points to the same function name. This is useful to ignore the redundant
605 // records for the functions with ODR linkage.
606 // In addition, prefer records with real coverage mapping data to dummy
607 // records, which were emitted for inline functions which were seen but
608 // not used in the corresponding translation unit.
609 Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
610 StringRef Mapping,
611 FilenameRange FileRange) {
612 ++CovMapNumRecords;
613 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
614 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
615 auto InsertResult =
616 FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
617 if (InsertResult.second) {
618 StringRef FuncName;
619 if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
620 return Err;
621 if (FuncName.empty())
622 return make_error<InstrProfError>(instrprof_error::malformed,
623 "function name is empty");
624 ++CovMapNumUsedRecords;
625 Records.emplace_back(Version, FuncName, FuncHash, Mapping,
626 FileRange.StartingIndex, FileRange.Length);
627 return Error::success();
628 }
629 // Update the existing record if it's a dummy and the new record is real.
630 size_t OldRecordIndex = InsertResult.first->second;
632 Records[OldRecordIndex];
633 Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
634 OldRecord.FunctionHash, OldRecord.CoverageMapping);
635 if (Error Err = OldIsDummyExpected.takeError())
636 return Err;
637 if (!*OldIsDummyExpected)
638 return Error::success();
639 Expected<bool> NewIsDummyExpected =
640 isCoverageMappingDummy(FuncHash, Mapping);
641 if (Error Err = NewIsDummyExpected.takeError())
642 return Err;
643 if (*NewIsDummyExpected)
644 return Error::success();
645 ++CovMapNumUsedRecords;
646 OldRecord.FunctionHash = FuncHash;
647 OldRecord.CoverageMapping = Mapping;
648 OldRecord.FilenamesBegin = FileRange.StartingIndex;
649 OldRecord.FilenamesSize = FileRange.Length;
650 return Error::success();
651 }
652
653public:
654 VersionedCovMapFuncRecordReader(
656 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
657 std::vector<std::string> &F)
658 : ProfileNames(P), CompilationDir(D), Filenames(F), Records(R) {}
659
660 ~VersionedCovMapFuncRecordReader() override = default;
661
662 Expected<const char *> readCoverageHeader(const char *CovBuf,
663 const char *CovBufEnd) override {
664 using namespace support;
665
666 if (CovBuf + sizeof(CovMapHeader) > CovBufEnd)
667 return make_error<CoverageMapError>(
668 coveragemap_error::malformed,
669 "coverage mapping header section is larger than buffer size");
670 auto CovHeader = reinterpret_cast<const CovMapHeader *>(CovBuf);
671 uint32_t NRecords = CovHeader->getNRecords<Endian>();
672 uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
673 uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
674 assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
675 CovBuf = reinterpret_cast<const char *>(CovHeader + 1);
676
677 // Skip past the function records, saving the start and end for later.
678 // This is a no-op in Version4 (function records are read after all headers
679 // are read).
680 const char *FuncRecBuf = nullptr;
681 const char *FuncRecBufEnd = nullptr;
682 if (Version < CovMapVersion::Version4)
683 FuncRecBuf = CovBuf;
684 CovBuf += NRecords * sizeof(FuncRecordType);
685 if (Version < CovMapVersion::Version4)
686 FuncRecBufEnd = CovBuf;
687
688 // Get the filenames.
689 if (CovBuf + FilenamesSize > CovBufEnd)
690 return make_error<CoverageMapError>(
691 coveragemap_error::malformed,
692 "filenames section is larger than buffer size");
693 size_t FilenamesBegin = Filenames.size();
694 StringRef FilenameRegion(CovBuf, FilenamesSize);
695 RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
696 CompilationDir);
697 if (auto Err = Reader.read(Version))
698 return std::move(Err);
699 CovBuf += FilenamesSize;
700 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
701
702 if (Version >= CovMapVersion::Version4) {
703 // Map a hash of the filenames region to the filename range associated
704 // with this coverage header.
705 int64_t FilenamesRef =
707 auto Insert =
708 FileRangeMap.insert(std::make_pair(FilenamesRef, FileRange));
709 if (!Insert.second) {
710 // The same filenames ref was encountered twice. It's possible that
711 // the associated filenames are the same.
712 auto It = Filenames.begin();
713 FilenameRange &OrigRange = Insert.first->getSecond();
714 if (std::equal(It + OrigRange.StartingIndex,
715 It + OrigRange.StartingIndex + OrigRange.Length,
716 It + FileRange.StartingIndex,
717 It + FileRange.StartingIndex + FileRange.Length))
718 // Map the new range to the original one.
719 FileRange = OrigRange;
720 else
721 // This is a hash collision. Mark the filenames ref invalid.
722 OrigRange.markInvalid();
723 }
724 }
725
726 // We'll read the coverage mapping records in the loop below.
727 // This is a no-op in Version4 (coverage mappings are not affixed to the
728 // coverage header).
729 const char *MappingBuf = CovBuf;
730 if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
731 return make_error<CoverageMapError>(coveragemap_error::malformed,
732 "coverage mapping size is not zero");
733 CovBuf += CoverageSize;
734 const char *MappingEnd = CovBuf;
735
736 if (CovBuf > CovBufEnd)
737 return make_error<CoverageMapError>(
738 coveragemap_error::malformed,
739 "function records section is larger than buffer size");
740
741 if (Version < CovMapVersion::Version4) {
742 // Read each function record.
743 if (Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
744 MappingBuf, MappingEnd))
745 return std::move(E);
746 }
747
748 // Each coverage map has an alignment of 8, so we need to adjust alignment
749 // before reading the next map.
750 CovBuf += offsetToAlignedAddr(CovBuf, Align(8));
751
752 return CovBuf;
753 }
754
755 Error readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
756 std::optional<FilenameRange> OutOfLineFileRange,
757 const char *OutOfLineMappingBuf,
758 const char *OutOfLineMappingBufEnd) override {
759 auto CFR = reinterpret_cast<const FuncRecordType *>(FuncRecBuf);
760 while ((const char *)CFR < FuncRecBufEnd) {
761 // Validate the length of the coverage mapping for this function.
762 const char *NextMappingBuf;
763 const FuncRecordType *NextCFR;
764 std::tie(NextMappingBuf, NextCFR) =
765 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
766 if (Version < CovMapVersion::Version4)
767 if (NextMappingBuf > OutOfLineMappingBufEnd)
768 return make_error<CoverageMapError>(
769 coveragemap_error::malformed,
770 "next mapping buffer is larger than buffer size");
771
772 // Look up the set of filenames associated with this function record.
773 std::optional<FilenameRange> FileRange;
774 if (Version < CovMapVersion::Version4) {
775 FileRange = OutOfLineFileRange;
776 } else {
777 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
778 auto It = FileRangeMap.find(FilenamesRef);
779 if (It == FileRangeMap.end())
780 return make_error<CoverageMapError>(
781 coveragemap_error::malformed,
782 "no filename found for function with hash=0x" +
783 Twine::utohexstr(FilenamesRef));
784 else
785 FileRange = It->getSecond();
786 }
787
788 // Now, read the coverage data.
789 if (FileRange && !FileRange->isInvalid()) {
790 StringRef Mapping =
791 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
792 if (Version >= CovMapVersion::Version4 &&
793 Mapping.data() + Mapping.size() > FuncRecBufEnd)
794 return make_error<CoverageMapError>(
795 coveragemap_error::malformed,
796 "coverage mapping data is larger than buffer size");
797 if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
798 return Err;
799 }
800
801 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
802 }
803 return Error::success();
804 }
805};
806
807} // end anonymous namespace
808
809template <class IntPtrT, llvm::endianness Endian>
810Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
812 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
813 std::vector<std::string> &F) {
814 using namespace coverage;
815
816 switch (Version) {
818 return std::make_unique<VersionedCovMapFuncRecordReader<
826 // Decompress the name data.
827 if (Error E = P.create(P.getNameData()))
828 return std::move(E);
829 if (Version == CovMapVersion::Version2)
830 return std::make_unique<VersionedCovMapFuncRecordReader<
832 else if (Version == CovMapVersion::Version3)
833 return std::make_unique<VersionedCovMapFuncRecordReader<
835 else if (Version == CovMapVersion::Version4)
836 return std::make_unique<VersionedCovMapFuncRecordReader<
838 else if (Version == CovMapVersion::Version5)
839 return std::make_unique<VersionedCovMapFuncRecordReader<
841 else if (Version == CovMapVersion::Version6)
842 return std::make_unique<VersionedCovMapFuncRecordReader<
844 else if (Version == CovMapVersion::Version7)
845 return std::make_unique<VersionedCovMapFuncRecordReader<
847 }
848 llvm_unreachable("Unsupported version");
849}
850
851template <typename T, llvm::endianness Endian>
853 InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords,
854 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
855 StringRef CompilationDir, std::vector<std::string> &Filenames) {
856 using namespace coverage;
857
858 // Read the records in the coverage data section.
859 auto CovHeader =
860 reinterpret_cast<const CovMapHeader *>(CovMap.data());
861 CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
862 if (Version > CovMapVersion::CurrentVersion)
863 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
865 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
866 CompilationDir, Filenames);
867 if (Error E = ReaderExpected.takeError())
868 return E;
869 auto Reader = std::move(ReaderExpected.get());
870 const char *CovBuf = CovMap.data();
871 const char *CovBufEnd = CovBuf + CovMap.size();
872 const char *FuncRecBuf = FuncRecords.data();
873 const char *FuncRecBufEnd = FuncRecords.data() + FuncRecords.size();
874 while (CovBuf < CovBufEnd) {
875 // Read the current coverage header & filename data.
876 //
877 // Prior to Version4, this also reads all function records affixed to the
878 // header.
879 //
880 // Return a pointer to the next coverage header.
881 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
882 if (auto E = NextOrErr.takeError())
883 return E;
884 CovBuf = NextOrErr.get();
885 }
886 // In Version4, function records are not affixed to coverage headers. Read
887 // the records from their dedicated section.
888 if (Version >= CovMapVersion::Version4)
889 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
890 nullptr, nullptr);
891 return Error::success();
892}
893
896 StringRef Coverage, FuncRecordsStorage &&FuncRecords,
897 InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress,
898 llvm::endianness Endian, StringRef CompilationDir) {
899 std::unique_ptr<BinaryCoverageReader> Reader(
900 new BinaryCoverageReader(std::move(FuncRecords)));
901 Reader->ProfileNames = std::move(ProfileNames);
902 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
903 if (BytesInAddress == 4 && Endian == llvm::endianness::little) {
904 if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>(
905 Reader->ProfileNames, Coverage, FuncRecordsRef,
906 Reader->MappingRecords, CompilationDir, Reader->Filenames))
907 return std::move(E);
908 } else if (BytesInAddress == 4 && Endian == llvm::endianness::big) {
909 if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>(
910 Reader->ProfileNames, Coverage, FuncRecordsRef,
911 Reader->MappingRecords, CompilationDir, Reader->Filenames))
912 return std::move(E);
913 } else if (BytesInAddress == 8 && Endian == llvm::endianness::little) {
914 if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>(
915 Reader->ProfileNames, Coverage, FuncRecordsRef,
916 Reader->MappingRecords, CompilationDir, Reader->Filenames))
917 return std::move(E);
918 } else if (BytesInAddress == 8 && Endian == llvm::endianness::big) {
919 if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>(
920 Reader->ProfileNames, Coverage, FuncRecordsRef,
921 Reader->MappingRecords, CompilationDir, Reader->Filenames))
922 return std::move(E);
923 } else
924 return make_error<CoverageMapError>(
926 "not supported endianness or bytes in address");
927 return std::move(Reader);
928}
929
932 uint8_t BytesInAddress = 8;
934
935 // Read the magic and version.
936 Data = Data.substr(sizeof(TestingFormatMagic));
937 if (Data.size() < sizeof(uint64_t))
938 return make_error<CoverageMapError>(coveragemap_error::malformed,
939 "the size of data is too small");
940 auto TestingVersion =
941 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
942 *reinterpret_cast<const uint64_t *>(Data.data()));
943 Data = Data.substr(sizeof(uint64_t));
944
945 // Read the ProfileNames data.
946 if (Data.empty())
947 return make_error<CoverageMapError>(coveragemap_error::truncated);
948 unsigned N = 0;
949 uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
950 if (N > Data.size())
951 return make_error<CoverageMapError>(
953 "the size of TestingFormatMagic is too big");
954 Data = Data.substr(N);
955 if (Data.empty())
956 return make_error<CoverageMapError>(coveragemap_error::truncated);
957 N = 0;
958 uint64_t Address = decodeULEB128(Data.bytes_begin(), &N);
959 if (N > Data.size())
960 return make_error<CoverageMapError>(coveragemap_error::malformed,
961 "the size of ULEB128 is too big");
962 Data = Data.substr(N);
963 if (Data.size() < ProfileNamesSize)
964 return make_error<CoverageMapError>(coveragemap_error::malformed,
965 "the size of ProfileNames is too big");
966 InstrProfSymtab ProfileNames;
967 if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
968 return std::move(E);
969 Data = Data.substr(ProfileNamesSize);
970
971 // In Version2, the size of CoverageMapping is stored directly.
972 uint64_t CoverageMappingSize;
973 if (TestingVersion == uint64_t(TestingFormatVersion::Version2)) {
974 N = 0;
975 CoverageMappingSize = decodeULEB128(Data.bytes_begin(), &N);
976 if (N > Data.size())
977 return make_error<CoverageMapError>(coveragemap_error::malformed,
978 "the size of ULEB128 is too big");
979 Data = Data.substr(N);
980 if (CoverageMappingSize < sizeof(CovMapHeader))
981 return make_error<CoverageMapError>(
983 "the size of CoverageMapping is teoo small");
984 } else if (TestingVersion != uint64_t(TestingFormatVersion::Version1)) {
985 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
986 }
987
988 // Skip the padding bytes because coverage map data has an alignment of 8.
989 auto Pad = offsetToAlignedAddr(Data.data(), Align(8));
990 if (Data.size() < Pad)
991 return make_error<CoverageMapError>(coveragemap_error::malformed,
992 "insufficient padding");
993 Data = Data.substr(Pad);
994 if (Data.size() < sizeof(CovMapHeader))
995 return make_error<CoverageMapError>(
997 "coverage mapping header section is larger than data size");
998 auto const *CovHeader = reinterpret_cast<const CovMapHeader *>(
999 Data.substr(0, sizeof(CovMapHeader)).data());
1000 auto Version =
1001 CovMapVersion(CovHeader->getVersion<llvm::endianness::little>());
1002
1003 // In Version1, the size of CoverageMapping is calculated.
1004 if (TestingVersion == uint64_t(TestingFormatVersion::Version1)) {
1005 if (Version < CovMapVersion::Version4) {
1006 CoverageMappingSize = Data.size();
1007 } else {
1008 auto FilenamesSize =
1009 CovHeader->getFilenamesSize<llvm::endianness::little>();
1010 CoverageMappingSize = sizeof(CovMapHeader) + FilenamesSize;
1011 }
1012 }
1013
1014 auto CoverageMapping = Data.substr(0, CoverageMappingSize);
1015 Data = Data.substr(CoverageMappingSize);
1016
1017 // Read the CoverageRecords data.
1018 if (Version < CovMapVersion::Version4) {
1019 if (!Data.empty())
1020 return make_error<CoverageMapError>(coveragemap_error::malformed,
1021 "data is not empty");
1022 } else {
1023 // Skip the padding bytes because coverage records data has an alignment
1024 // of 8.
1025 Pad = offsetToAlignedAddr(Data.data(), Align(8));
1026 if (Data.size() < Pad)
1027 return make_error<CoverageMapError>(coveragemap_error::malformed,
1028 "insufficient padding");
1029 Data = Data.substr(Pad);
1030 }
1033
1035 CoverageMapping, std::move(CoverageRecords), std::move(ProfileNames),
1036 BytesInAddress, Endian, CompilationDir);
1037}
1038
1039/// Find all sections that match \p IPSK name. There may be more than one if
1040/// comdats are in use, e.g. for the __llvm_covfun section on ELF.
1043 auto ObjFormat = OF.getTripleObjectFormat();
1044 auto Name =
1045 getInstrProfSectionName(IPSK, ObjFormat, /*AddSegmentInfo=*/false);
1046 // On COFF, the object file section name may end in "$M". This tells the
1047 // linker to sort these sections between "$A" and "$Z". The linker removes the
1048 // dollar and everything after it in the final binary. Do the same to match.
1049 bool IsCOFF = isa<COFFObjectFile>(OF);
1050 auto stripSuffix = [IsCOFF](StringRef N) {
1051 return IsCOFF ? N.split('$').first : N;
1052 };
1053 Name = stripSuffix(Name);
1054
1055 std::vector<SectionRef> Sections;
1056 for (const auto &Section : OF.sections()) {
1057 Expected<StringRef> NameOrErr = Section.getName();
1058 if (!NameOrErr)
1059 return NameOrErr.takeError();
1060 if (stripSuffix(*NameOrErr) == Name) {
1061 // COFF profile name section contains two null bytes indicating the
1062 // start/end of the section. If its size is 2 bytes, it's empty.
1063 if (IsCOFF && IPSK == IPSK_name && Section.getSize() == 2)
1064 continue;
1065 Sections.push_back(Section);
1066 }
1067 }
1068 if (Sections.empty())
1069 return make_error<CoverageMapError>(coveragemap_error::no_data_found);
1070 return Sections;
1071}
1072
1074loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
1075 StringRef CompilationDir = "",
1076 object::BuildIDRef *BinaryID = nullptr) {
1077 std::unique_ptr<ObjectFile> OF;
1078 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1079 // If we have a universal binary, try to look up the object for the
1080 // appropriate architecture.
1081 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1082 if (!ObjectFileOrErr)
1083 return ObjectFileOrErr.takeError();
1084 OF = std::move(ObjectFileOrErr.get());
1085 } else if (isa<ObjectFile>(Bin.get())) {
1086 // For any other object file, upcast and take ownership.
1087 OF.reset(cast<ObjectFile>(Bin.release()));
1088 // If we've asked for a particular arch, make sure they match.
1089 if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
1090 return errorCodeToError(object_error::arch_not_found);
1091 } else
1092 // We can only handle object files.
1093 return make_error<CoverageMapError>(coveragemap_error::malformed,
1094 "binary is not an object file");
1095
1096 // The coverage uses native pointer sizes for the object it's written in.
1097 uint8_t BytesInAddress = OF->getBytesInAddress();
1099 OF->isLittleEndian() ? llvm::endianness::little : llvm::endianness::big;
1100
1101 // Look for the sections that we are interested in.
1102 InstrProfSymtab ProfileNames;
1103 std::vector<SectionRef> NamesSectionRefs;
1104 // If IPSK_name is not found, fallback to search for IPK_covname, which is
1105 // used when binary correlation is enabled.
1106 auto NamesSection = lookupSections(*OF, IPSK_name);
1107 if (auto E = NamesSection.takeError()) {
1108 consumeError(std::move(E));
1109 NamesSection = lookupSections(*OF, IPSK_covname);
1110 if (auto E = NamesSection.takeError())
1111 return std::move(E);
1112 }
1113 NamesSectionRefs = *NamesSection;
1114
1115 if (NamesSectionRefs.size() != 1)
1116 return make_error<CoverageMapError>(
1118 "the size of coverage mapping section is not one");
1119 if (Error E = ProfileNames.create(NamesSectionRefs.back()))
1120 return std::move(E);
1121
1122 auto CoverageSection = lookupSections(*OF, IPSK_covmap);
1123 if (auto E = CoverageSection.takeError())
1124 return std::move(E);
1125 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1126 if (CoverageSectionRefs.size() != 1)
1127 return make_error<CoverageMapError>(coveragemap_error::malformed,
1128 "the size of name section is not one");
1129 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1130 if (!CoverageMappingOrErr)
1131 return CoverageMappingOrErr.takeError();
1132 StringRef CoverageMapping = CoverageMappingOrErr.get();
1133
1134 // Look for the coverage records section (Version4 only).
1135 auto CoverageRecordsSections = lookupSections(*OF, IPSK_covfun);
1136
1138 if (auto E = CoverageRecordsSections.takeError()) {
1139 consumeError(std::move(E));
1140 FuncRecords = MemoryBuffer::getMemBuffer("");
1141 } else {
1142 // Compute the FuncRecordsBuffer of the buffer, taking into account the
1143 // padding between each record, and making sure the first block is aligned
1144 // in memory to maintain consistency between buffer address and size
1145 // alignment.
1146 const Align RecordAlignment(8);
1147 uint64_t FuncRecordsSize = 0;
1148 for (SectionRef Section : *CoverageRecordsSections) {
1149 auto CoverageRecordsOrErr = Section.getContents();
1150 if (!CoverageRecordsOrErr)
1151 return CoverageRecordsOrErr.takeError();
1152 FuncRecordsSize += alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1153 }
1154 auto WritableBuffer =
1156 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1157 assert(isAddrAligned(RecordAlignment, FuncRecordsBuffer) &&
1158 "Allocated memory is correctly aligned");
1159
1160 for (SectionRef Section : *CoverageRecordsSections) {
1161 auto CoverageRecordsOrErr = Section.getContents();
1162 if (!CoverageRecordsOrErr)
1163 return CoverageRecordsOrErr.takeError();
1164 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1165 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1166 CoverageRecords.end(), FuncRecordsBuffer);
1167 FuncRecordsBuffer =
1168 std::fill_n(FuncRecordsBuffer,
1169 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1170 (uintptr_t)FuncRecordsBuffer,
1171 '\0');
1172 }
1173 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1174 "consistent init");
1175 FuncRecords = std::move(WritableBuffer);
1176 }
1177
1178 if (BinaryID)
1179 *BinaryID = getBuildID(OF.get());
1180
1182 CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
1183 BytesInAddress, Endian, CompilationDir);
1184}
1185
1186/// Determine whether \p Arch is invalid or empty, given \p Bin.
1188 // If we have a universal binary and Arch doesn't identify any of its slices,
1189 // it's user error.
1190 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
1191 for (auto &ObjForArch : Universal->objects())
1192 if (Arch == ObjForArch.getArchFlagName())
1193 return false;
1194 return true;
1195 }
1196 return false;
1197}
1198
1201 MemoryBufferRef ObjectBuffer, StringRef Arch,
1202 SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
1203 StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
1204 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1205
1206 if (ObjectBuffer.getBuffer().size() > sizeof(TestingFormatMagic)) {
1207 uint64_t Magic =
1208 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
1209 *reinterpret_cast<const uint64_t *>(ObjectBuffer.getBufferStart()));
1210 if (Magic == TestingFormatMagic) {
1211 // This is a special format used for testing.
1212 auto ReaderOrErr =
1213 loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir);
1214 if (!ReaderOrErr)
1215 return ReaderOrErr.takeError();
1216 Readers.push_back(std::move(ReaderOrErr.get()));
1217 return std::move(Readers);
1218 }
1219 }
1220
1221 auto BinOrErr = createBinary(ObjectBuffer);
1222 if (!BinOrErr)
1223 return BinOrErr.takeError();
1224 std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
1225
1226 if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
1227 return make_error<CoverageMapError>(
1229
1230 // MachO universal binaries which contain archives need to be treated as
1231 // archives, not as regular binaries.
1232 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1233 for (auto &ObjForArch : Universal->objects()) {
1234 // Skip slices within the universal binary which target the wrong arch.
1235 std::string ObjArch = ObjForArch.getArchFlagName();
1236 if (Arch != ObjArch)
1237 continue;
1238
1239 auto ArchiveOrErr = ObjForArch.getAsArchive();
1240 if (!ArchiveOrErr) {
1241 // If this is not an archive, try treating it as a regular object.
1242 consumeError(ArchiveOrErr.takeError());
1243 break;
1244 }
1245
1247 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1248 CompilationDir, BinaryIDs);
1249 }
1250 }
1251
1252 // Load coverage out of archive members.
1253 if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
1254 Error Err = Error::success();
1255 for (auto &Child : Ar->children(Err)) {
1256 Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
1257 if (!ChildBufOrErr)
1258 return ChildBufOrErr.takeError();
1259
1260 auto ChildReadersOrErr = BinaryCoverageReader::create(
1261 ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
1262 BinaryIDs);
1263 if (!ChildReadersOrErr)
1264 return ChildReadersOrErr.takeError();
1265 for (auto &Reader : ChildReadersOrErr.get())
1266 Readers.push_back(std::move(Reader));
1267 }
1268 if (Err)
1269 return std::move(Err);
1270
1271 // Thin archives reference object files outside of the archive file, i.e.
1272 // files which reside in memory not owned by the caller. Transfer ownership
1273 // to the caller.
1274 if (Ar->isThin())
1275 for (auto &Buffer : Ar->takeThinBuffers())
1276 ObjectFileBuffers.push_back(std::move(Buffer));
1277
1278 return std::move(Readers);
1279 }
1280
1281 object::BuildIDRef BinaryID;
1282 auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
1283 BinaryIDs ? &BinaryID : nullptr);
1284 if (!ReaderOrErr)
1285 return ReaderOrErr.takeError();
1286 Readers.push_back(std::move(ReaderOrErr.get()));
1287 if (!BinaryID.empty())
1288 BinaryIDs->push_back(BinaryID);
1289 return std::move(Readers);
1290}
1291
1293 if (CurrentRecord >= MappingRecords.size())
1294 return make_error<CoverageMapError>(coveragemap_error::eof);
1295
1296 FunctionsFilenames.clear();
1297 Expressions.clear();
1298 MappingRegions.clear();
1299 auto &R = MappingRecords[CurrentRecord];
1300 auto F = ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1301 RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames,
1302 Expressions, MappingRegions);
1303 if (auto Err = Reader.read())
1304 return Err;
1305
1306 Record.FunctionName = R.FunctionName;
1307 Record.FunctionHash = R.FunctionHash;
1308 Record.Filenames = FunctionsFilenames;
1309 Record.Expressions = Expressions;
1310 Record.MappingRegions = MappingRegions;
1311
1312 ++CurrentRecord;
1313 return Error::success();
1314}
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error readCoverageMappingData(InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, std::vector< BinaryCoverageReader::ProfileMappingRecord > &Records, StringRef CompilationDir, std::vector< std::string > &Filenames)
static Expected< std::unique_ptr< BinaryCoverageReader > > loadBinaryFormat(std::unique_ptr< Binary > Bin, StringRef Arch, StringRef CompilationDir="", object::BuildIDRef *BinaryID=nullptr)
static Expected< std::unique_ptr< BinaryCoverageReader > > loadTestingFormat(StringRef Data, StringRef CompilationDir)
static Expected< std::vector< SectionRef > > lookupSections(ObjectFile &OF, InstrProfSectKind IPSK)
Find all sections that match IPSK name.
static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch)
Determine whether Arch is invalid or empty, given Bin.
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
static const unsigned EncodingExpansionRegionBit
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines the DenseMap class.
std::string Name
uint64_t Size
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
endianness Endian
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
Value * RHS
Value * LHS
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition: ArrayRef.h:195
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
iterator end()
Definition: DenseMap.h:84
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
Error takeError()
Take ownership of the stored error.
Definition: Error.h:601
reference get()
Returns a reference to the stored T value.
Definition: Error.h:571
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
Definition: InstrProf.h:429
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function's PGO name from the function name's symbol address in the object file.
const char * getBufferStart() const
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void resize(size_type N)
Definition: SmallVector.h:651
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:567
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
const unsigned char * bytes_begin() const
Definition: StringRef.h:115
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:416
LLVM Value Representation.
Definition: Value.h:74
static std::unique_ptr< WritableMemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="", std::optional< Align > Alignment=std::nullopt)
Allocate a new MemoryBuffer of the specified size that is not initialized.
Reader for the coverage mapping data that is emitted by the frontend and stored in an object file.
static Expected< std::vector< std::unique_ptr< BinaryCoverageReader > > > create(MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl< std::unique_ptr< MemoryBuffer > > &ObjectFileBuffers, StringRef CompilationDir="", SmallVectorImpl< object::BuildIDRef > *BinaryIDs=nullptr)
std::unique_ptr< MemoryBuffer > FuncRecordsStorage
Error readNextRecord(CoverageMappingRecord &Record) override
static Expected< std::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, FuncRecordsStorage &&FuncRecords, InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress, llvm::endianness Endian, StringRef CompilationDir="")
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
void dump(const Counter &C, raw_ostream &OS) const
coveragemap_error get() const
A file format agnostic iterator over coverage mapping data.
virtual Error readNextRecord(CoverageMappingRecord &Record)=0
The mapping of profile information to coverage data.
Reader for the raw coverage filenames.
Checks if the given coverage mapping data is exported for an unused function.
Reader for the raw coverage mapping data.
Error readIntMax(uint64_t &Result, uint64_t MaxPlus1)
Triple::ObjectFormatType getTripleObjectFormat() const
Definition: Binary.h:163
This class is the base class for all object file types.
Definition: ObjectFile.h:229
section_iterator_range sections() const
Definition: ObjectFile.h:328
virtual bool isRelocatableObject() const =0
True if this is a relocatable object (.o/.obj).
Represents a GOFF physical record.
Definition: GOFF.h:31
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
uint64_t ComputeHash(StringRef K)
Definition: InstrProf.h:1051
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
Definition: RecordsSlice.h:197
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
Definition: MCDCTypes.h:52
constexpr uint64_t TestingFormatMagic
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
BuildIDRef getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
Definition: BuildID.cpp:56
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:45
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
Definition: Path.cpp:716
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:672
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:457
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
@ Length
Definition: DWP.cpp:456
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:970
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
Definition: LEB128.h:131
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
Definition: Alignment.h:203
std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
Definition: InstrProf.cpp:222
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
InstrProfSectKind
Definition: InstrProf.h:58
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:103
endianness
Definition: bit.h:70
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1041
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition: Alignment.h:150
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
Definition: Alignment.h:187
#define N
#define NC
Definition: regutils.h:42
A range of filename indices.
FilenameRange(unsigned StartingIndex, unsigned Length)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
A Counter expression is a value that represents an arithmetic operation with two counters.
A Counter mapping region associates a source range with a specific counter.
@ ExpansionRegion
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
@ MCDCDecisionRegion
A DecisionRegion represents a top-level boolean expression and is associated with a variable length b...
@ MCDCBranchRegion
A Branch Region can be extended to include IDs to facilitate MC/DC.
@ SkippedRegion
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
@ GapRegion
A GapRegion is like a CodeRegion, but its count is only set as the line execution count when its the ...
@ BranchRegion
A BranchRegion represents leaf-level boolean expressions and is associated with two counters,...
@ CodeRegion
A CodeRegion associates some code with a counter.
A Counter is an abstract value that describes how to compute the execution count for a region of code...
static const unsigned EncodingTagBits
static Counter getZero()
Return the counter that represents the number zero.
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
static const unsigned EncodingTagMask
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
Coverage mapping information for a single function.