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