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"
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;
248
249 // Read the combined counter + region kind.
250 uint64_t EncodedCounterAndRegion;
251 if (auto Err = readIntMax(EncodedCounterAndRegion,
252 std::numeric_limits<unsigned>::max()))
253 return Err;
254 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
255 uint64_t ExpandedFileID = 0;
256
257 // If Tag does not represent a ZeroCounter, then it is understood to refer
258 // to a counter or counter expression with region kind assumed to be
259 // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the
260 // referenced counter or counter expression (and nothing else).
261 //
262 // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set,
263 // then EncodedCounterAndRegion is interpreted to represent an
264 // ExpansionRegion. In all other cases, EncodedCounterAndRegion is
265 // interpreted to refer to a specific region kind, after which additional
266 // fields may be read (e.g. BranchRegions have two encoded counters that
267 // follow an encoded region kind value).
268 if (Tag != Counter::Zero) {
269 if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
270 return Err;
271 } else {
272 // Is it an expansion region?
273 if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
275 ExpandedFileID = EncodedCounterAndRegion >>
277 if (ExpandedFileID >= NumFileIDs)
278 return make_error<CoverageMapError>(coveragemap_error::malformed,
279 "ExpandedFileID is invalid");
280 } else {
281 switch (EncodedCounterAndRegion >>
284 // Don't do anything when we have a code region with a zero counter.
285 break;
288 break;
290 // For a Branch Region, read two successive counters.
292 if (auto Err = readCounter(C))
293 return Err;
294 if (auto Err = readCounter(C2))
295 return Err;
296 break;
297 default:
298 return make_error<CoverageMapError>(coveragemap_error::malformed,
299 "region kind is incorrect");
300 }
301 }
302 }
303
304 // Read the source range.
305 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
306 if (auto Err =
307 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
308 return Err;
309 if (auto Err = readULEB128(ColumnStart))
310 return Err;
311 if (ColumnStart > std::numeric_limits<unsigned>::max())
312 return make_error<CoverageMapError>(coveragemap_error::malformed,
313 "start column is too big");
314 if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
315 return Err;
316 if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
317 return Err;
318 LineStart += LineStartDelta;
319
320 // If the high bit of ColumnEnd is set, this is a gap region.
321 if (ColumnEnd & (1U << 31)) {
323 ColumnEnd &= ~(1U << 31);
324 }
325
326 // Adjust the column locations for the empty regions that are supposed to
327 // cover whole lines. Those regions should be encoded with the
328 // column range (1 -> std::numeric_limits<unsigned>::max()), but because
329 // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
330 // we set the column range to (0 -> 0) to ensure that the column start and
331 // column end take up one byte each.
332 // The std::numeric_limits<unsigned>::max() is used to represent a column
333 // position at the end of the line without knowing the length of that line.
334 if (ColumnStart == 0 && ColumnEnd == 0) {
335 ColumnStart = 1;
336 ColumnEnd = std::numeric_limits<unsigned>::max();
337 }
338
339 LLVM_DEBUG({
340 dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
341 << ColumnStart << " -> " << (LineStart + NumLines) << ":"
342 << ColumnEnd << ", ";
344 dbgs() << "Expands to file " << ExpandedFileID;
345 else
346 CounterMappingContext(Expressions).dump(C, dbgs());
347 dbgs() << "\n";
348 });
349
350 auto CMR = CounterMappingRegion(C, C2, InferredFileID, ExpandedFileID,
351 LineStart, ColumnStart,
352 LineStart + NumLines, ColumnEnd, Kind);
353 if (CMR.startLoc() > CMR.endLoc())
354 return make_error<CoverageMapError>(
356 "counter mapping region locations are incorrect");
357 MappingRegions.push_back(CMR);
358 }
359 return Error::success();
360}
361
363 // Read the virtual file mapping.
364 SmallVector<unsigned, 8> VirtualFileMapping;
365 uint64_t NumFileMappings;
366 if (auto Err = readSize(NumFileMappings))
367 return Err;
368 for (size_t I = 0; I < NumFileMappings; ++I) {
369 uint64_t FilenameIndex;
370 if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
371 return Err;
372 VirtualFileMapping.push_back(FilenameIndex);
373 }
374
375 // Construct the files using unique filenames and virtual file mapping.
376 for (auto I : VirtualFileMapping) {
377 Filenames.push_back(TranslationUnitFilenames[I]);
378 }
379
380 // Read the expressions.
381 uint64_t NumExpressions;
382 if (auto Err = readSize(NumExpressions))
383 return Err;
384 // Create an array of dummy expressions that get the proper counters
385 // when the expressions are read, and the proper kinds when the counters
386 // are decoded.
387 Expressions.resize(
388 NumExpressions,
390 for (size_t I = 0; I < NumExpressions; ++I) {
391 if (auto Err = readCounter(Expressions[I].LHS))
392 return Err;
393 if (auto Err = readCounter(Expressions[I].RHS))
394 return Err;
395 }
396
397 // Read the mapping regions sub-arrays.
398 for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
399 InferredFileID < S; ++InferredFileID) {
400 if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
401 VirtualFileMapping.size()))
402 return Err;
403 }
404
405 // Set the counters for the expansion regions.
406 // i.e. Counter of expansion region = counter of the first region
407 // from the expanded file.
408 // Perform multiple passes to correctly propagate the counters through
409 // all the nested expansion regions.
410 SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
411 FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
412 for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
413 for (auto &R : MappingRegions) {
415 continue;
416 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
417 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
418 }
419 for (auto &R : MappingRegions) {
420 if (FileIDExpansionRegionMapping[R.FileID]) {
421 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
422 FileIDExpansionRegionMapping[R.FileID] = nullptr;
423 }
424 }
425 }
426
427 return Error::success();
428}
429
431 // A dummy coverage mapping data consists of just one region with zero count.
432 uint64_t NumFileMappings;
433 if (Error Err = readSize(NumFileMappings))
434 return std::move(Err);
435 if (NumFileMappings != 1)
436 return false;
437 // We don't expect any specific value for the filename index, just skip it.
438 uint64_t FilenameIndex;
439 if (Error Err =
440 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
441 return std::move(Err);
442 uint64_t NumExpressions;
443 if (Error Err = readSize(NumExpressions))
444 return std::move(Err);
445 if (NumExpressions != 0)
446 return false;
447 uint64_t NumRegions;
448 if (Error Err = readSize(NumRegions))
449 return std::move(Err);
450 if (NumRegions != 1)
451 return false;
452 uint64_t EncodedCounterAndRegion;
453 if (Error Err = readIntMax(EncodedCounterAndRegion,
454 std::numeric_limits<unsigned>::max()))
455 return std::move(Err);
456 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
457 return Tag == Counter::Zero;
458}
459
461 Expected<StringRef> DataOrErr = Section.getContents();
462 if (!DataOrErr)
463 return DataOrErr.takeError();
464 Data = *DataOrErr;
465 Address = Section.getAddress();
466
467 // If this is a linked PE/COFF file, then we have to skip over the null byte
468 // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
469 const ObjectFile *Obj = Section.getObject();
470 if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
471 Data = Data.drop_front(1);
472
473 return Error::success();
474}
475
477 if (Pointer < Address)
478 return StringRef();
479 auto Offset = Pointer - Address;
480 if (Offset + Size > Data.size())
481 return StringRef();
482 return Data.substr(Pointer - Address, Size);
483}
484
485// Check if the mapping data is a dummy, i.e. is emitted for an unused function.
487 // The hash value of dummy mapping records is always zero.
488 if (Hash)
489 return false;
490 return RawCoverageMappingDummyChecker(Mapping).isDummy();
491}
492
493/// A range of filename indices. Used to specify the location of a batch of
494/// filenames in a vector-like container.
497 unsigned Length;
498
499 FilenameRange(unsigned StartingIndex, unsigned Length)
500 : StartingIndex(StartingIndex), Length(Length) {}
501
502 void markInvalid() { Length = 0; }
503 bool isInvalid() const { return Length == 0; }
504};
505
506namespace {
507
508/// The interface to read coverage mapping function records for a module.
509struct CovMapFuncRecordReader {
510 virtual ~CovMapFuncRecordReader() = default;
511
512 // Read a coverage header.
513 //
514 // \p CovBuf points to the buffer containing the \c CovHeader of the coverage
515 // mapping data associated with the module.
516 //
517 // Returns a pointer to the next \c CovHeader if it exists, or to an address
518 // greater than \p CovEnd if not.
519 virtual Expected<const char *> readCoverageHeader(const char *CovBuf,
520 const char *CovBufEnd) = 0;
521
522 // Read function records.
523 //
524 // \p FuncRecBuf points to the buffer containing a batch of function records.
525 // \p FuncRecBufEnd points past the end of the batch of records.
526 //
527 // Prior to Version4, \p OutOfLineFileRange points to a sequence of filenames
528 // associated with the function records. It is unused in Version4.
529 //
530 // Prior to Version4, \p OutOfLineMappingBuf points to a sequence of coverage
531 // mappings associated with the function records. It is unused in Version4.
532 virtual Error
533 readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
534 std::optional<FilenameRange> OutOfLineFileRange,
535 const char *OutOfLineMappingBuf,
536 const char *OutOfLineMappingBufEnd) = 0;
537
538 template <class IntPtrT, llvm::endianness Endian>
541 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
542 std::vector<std::string> &F);
543};
544
545// A class for reading coverage mapping function records for a module.
546template <CovMapVersion Version, class IntPtrT, llvm::endianness Endian>
547class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
548 using FuncRecordType =
550 using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
551
552 // Maps function's name references to the indexes of their records
553 // in \c Records.
554 DenseMap<NameRefType, size_t> FunctionRecords;
555 InstrProfSymtab &ProfileNames;
556 StringRef CompilationDir;
557 std::vector<std::string> &Filenames;
558 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
559
560 // Maps a hash of the filenames in a TU to a \c FileRange. The range
561 // specifies the location of the hashed filenames in \c Filenames.
563
564 // Add the record to the collection if we don't already have a record that
565 // points to the same function name. This is useful to ignore the redundant
566 // records for the functions with ODR linkage.
567 // In addition, prefer records with real coverage mapping data to dummy
568 // records, which were emitted for inline functions which were seen but
569 // not used in the corresponding translation unit.
570 Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
571 StringRef Mapping,
572 FilenameRange FileRange) {
573 ++CovMapNumRecords;
574 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
575 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
576 auto InsertResult =
577 FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
578 if (InsertResult.second) {
579 StringRef FuncName;
580 if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
581 return Err;
582 if (FuncName.empty())
583 return make_error<InstrProfError>(instrprof_error::malformed,
584 "function name is empty");
585 ++CovMapNumUsedRecords;
586 Records.emplace_back(Version, FuncName, FuncHash, Mapping,
587 FileRange.StartingIndex, FileRange.Length);
588 return Error::success();
589 }
590 // Update the existing record if it's a dummy and the new record is real.
591 size_t OldRecordIndex = InsertResult.first->second;
593 Records[OldRecordIndex];
594 Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
595 OldRecord.FunctionHash, OldRecord.CoverageMapping);
596 if (Error Err = OldIsDummyExpected.takeError())
597 return Err;
598 if (!*OldIsDummyExpected)
599 return Error::success();
600 Expected<bool> NewIsDummyExpected =
601 isCoverageMappingDummy(FuncHash, Mapping);
602 if (Error Err = NewIsDummyExpected.takeError())
603 return Err;
604 if (*NewIsDummyExpected)
605 return Error::success();
606 ++CovMapNumUsedRecords;
607 OldRecord.FunctionHash = FuncHash;
608 OldRecord.CoverageMapping = Mapping;
609 OldRecord.FilenamesBegin = FileRange.StartingIndex;
610 OldRecord.FilenamesSize = FileRange.Length;
611 return Error::success();
612 }
613
614public:
615 VersionedCovMapFuncRecordReader(
617 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
618 std::vector<std::string> &F)
619 : ProfileNames(P), CompilationDir(D), Filenames(F), Records(R) {}
620
621 ~VersionedCovMapFuncRecordReader() override = default;
622
623 Expected<const char *> readCoverageHeader(const char *CovBuf,
624 const char *CovBufEnd) override {
625 using namespace support;
626
627 if (CovBuf + sizeof(CovMapHeader) > CovBufEnd)
628 return make_error<CoverageMapError>(
629 coveragemap_error::malformed,
630 "coverage mapping header section is larger than buffer size");
631 auto CovHeader = reinterpret_cast<const CovMapHeader *>(CovBuf);
632 uint32_t NRecords = CovHeader->getNRecords<Endian>();
633 uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
634 uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
635 assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
636 CovBuf = reinterpret_cast<const char *>(CovHeader + 1);
637
638 // Skip past the function records, saving the start and end for later.
639 // This is a no-op in Version4 (function records are read after all headers
640 // are read).
641 const char *FuncRecBuf = nullptr;
642 const char *FuncRecBufEnd = nullptr;
643 if (Version < CovMapVersion::Version4)
644 FuncRecBuf = CovBuf;
645 CovBuf += NRecords * sizeof(FuncRecordType);
646 if (Version < CovMapVersion::Version4)
647 FuncRecBufEnd = CovBuf;
648
649 // Get the filenames.
650 if (CovBuf + FilenamesSize > CovBufEnd)
651 return make_error<CoverageMapError>(
652 coveragemap_error::malformed,
653 "filenames section is larger than buffer size");
654 size_t FilenamesBegin = Filenames.size();
655 StringRef FilenameRegion(CovBuf, FilenamesSize);
656 RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
657 CompilationDir);
658 if (auto Err = Reader.read(Version))
659 return std::move(Err);
660 CovBuf += FilenamesSize;
661 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
662
663 if (Version >= CovMapVersion::Version4) {
664 // Map a hash of the filenames region to the filename range associated
665 // with this coverage header.
666 int64_t FilenamesRef =
668 auto Insert =
669 FileRangeMap.insert(std::make_pair(FilenamesRef, FileRange));
670 if (!Insert.second) {
671 // The same filenames ref was encountered twice. It's possible that
672 // the associated filenames are the same.
673 auto It = Filenames.begin();
674 FilenameRange &OrigRange = Insert.first->getSecond();
675 if (std::equal(It + OrigRange.StartingIndex,
676 It + OrigRange.StartingIndex + OrigRange.Length,
677 It + FileRange.StartingIndex,
678 It + FileRange.StartingIndex + FileRange.Length))
679 // Map the new range to the original one.
680 FileRange = OrigRange;
681 else
682 // This is a hash collision. Mark the filenames ref invalid.
683 OrigRange.markInvalid();
684 }
685 }
686
687 // We'll read the coverage mapping records in the loop below.
688 // This is a no-op in Version4 (coverage mappings are not affixed to the
689 // coverage header).
690 const char *MappingBuf = CovBuf;
691 if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
692 return make_error<CoverageMapError>(coveragemap_error::malformed,
693 "coverage mapping size is not zero");
694 CovBuf += CoverageSize;
695 const char *MappingEnd = CovBuf;
696
697 if (CovBuf > CovBufEnd)
698 return make_error<CoverageMapError>(
699 coveragemap_error::malformed,
700 "function records section is larger than buffer size");
701
702 if (Version < CovMapVersion::Version4) {
703 // Read each function record.
704 if (Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
705 MappingBuf, MappingEnd))
706 return std::move(E);
707 }
708
709 // Each coverage map has an alignment of 8, so we need to adjust alignment
710 // before reading the next map.
711 CovBuf += offsetToAlignedAddr(CovBuf, Align(8));
712
713 return CovBuf;
714 }
715
716 Error readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
717 std::optional<FilenameRange> OutOfLineFileRange,
718 const char *OutOfLineMappingBuf,
719 const char *OutOfLineMappingBufEnd) override {
720 auto CFR = reinterpret_cast<const FuncRecordType *>(FuncRecBuf);
721 while ((const char *)CFR < FuncRecBufEnd) {
722 // Validate the length of the coverage mapping for this function.
723 const char *NextMappingBuf;
724 const FuncRecordType *NextCFR;
725 std::tie(NextMappingBuf, NextCFR) =
726 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
727 if (Version < CovMapVersion::Version4)
728 if (NextMappingBuf > OutOfLineMappingBufEnd)
729 return make_error<CoverageMapError>(
730 coveragemap_error::malformed,
731 "next mapping buffer is larger than buffer size");
732
733 // Look up the set of filenames associated with this function record.
734 std::optional<FilenameRange> FileRange;
735 if (Version < CovMapVersion::Version4) {
736 FileRange = OutOfLineFileRange;
737 } else {
738 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
739 auto It = FileRangeMap.find(FilenamesRef);
740 if (It == FileRangeMap.end())
741 return make_error<CoverageMapError>(
742 coveragemap_error::malformed,
743 "no filename found for function with hash=0x" +
744 Twine::utohexstr(FilenamesRef));
745 else
746 FileRange = It->getSecond();
747 }
748
749 // Now, read the coverage data.
750 if (FileRange && !FileRange->isInvalid()) {
751 StringRef Mapping =
752 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
753 if (Version >= CovMapVersion::Version4 &&
754 Mapping.data() + Mapping.size() > FuncRecBufEnd)
755 return make_error<CoverageMapError>(
756 coveragemap_error::malformed,
757 "coverage mapping data is larger than buffer size");
758 if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
759 return Err;
760 }
761
762 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
763 }
764 return Error::success();
765 }
766};
767
768} // end anonymous namespace
769
770template <class IntPtrT, llvm::endianness Endian>
771Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
773 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
774 std::vector<std::string> &F) {
775 using namespace coverage;
776
777 switch (Version) {
779 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 else if (Version == CovMapVersion::Version7)
806 return std::make_unique<VersionedCovMapFuncRecordReader<
808 }
809 llvm_unreachable("Unsupported version");
810}
811
812template <typename T, llvm::endianness Endian>
814 InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords,
815 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
816 StringRef CompilationDir, std::vector<std::string> &Filenames) {
817 using namespace coverage;
818
819 // Read the records in the coverage data section.
820 auto CovHeader =
821 reinterpret_cast<const CovMapHeader *>(CovMap.data());
822 CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
823 if (Version > CovMapVersion::CurrentVersion)
824 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
826 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
827 CompilationDir, Filenames);
828 if (Error E = ReaderExpected.takeError())
829 return E;
830 auto Reader = std::move(ReaderExpected.get());
831 const char *CovBuf = CovMap.data();
832 const char *CovBufEnd = CovBuf + CovMap.size();
833 const char *FuncRecBuf = FuncRecords.data();
834 const char *FuncRecBufEnd = FuncRecords.data() + FuncRecords.size();
835 while (CovBuf < CovBufEnd) {
836 // Read the current coverage header & filename data.
837 //
838 // Prior to Version4, this also reads all function records affixed to the
839 // header.
840 //
841 // Return a pointer to the next coverage header.
842 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
843 if (auto E = NextOrErr.takeError())
844 return E;
845 CovBuf = NextOrErr.get();
846 }
847 // In Version4, function records are not affixed to coverage headers. Read
848 // the records from their dedicated section.
849 if (Version >= CovMapVersion::Version4)
850 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
851 nullptr, nullptr);
852 return Error::success();
853}
854
857 StringRef Coverage, FuncRecordsStorage &&FuncRecords,
858 InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress,
859 llvm::endianness Endian, StringRef CompilationDir) {
860 std::unique_ptr<BinaryCoverageReader> Reader(
861 new BinaryCoverageReader(std::move(FuncRecords)));
862 Reader->ProfileNames = std::move(ProfileNames);
863 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
864 if (BytesInAddress == 4 && Endian == llvm::endianness::little) {
865 if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>(
866 Reader->ProfileNames, Coverage, FuncRecordsRef,
867 Reader->MappingRecords, CompilationDir, Reader->Filenames))
868 return std::move(E);
869 } else if (BytesInAddress == 4 && Endian == llvm::endianness::big) {
870 if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>(
871 Reader->ProfileNames, Coverage, FuncRecordsRef,
872 Reader->MappingRecords, CompilationDir, Reader->Filenames))
873 return std::move(E);
874 } else if (BytesInAddress == 8 && Endian == llvm::endianness::little) {
875 if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>(
876 Reader->ProfileNames, Coverage, FuncRecordsRef,
877 Reader->MappingRecords, CompilationDir, Reader->Filenames))
878 return std::move(E);
879 } else if (BytesInAddress == 8 && Endian == llvm::endianness::big) {
880 if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>(
881 Reader->ProfileNames, Coverage, FuncRecordsRef,
882 Reader->MappingRecords, CompilationDir, Reader->Filenames))
883 return std::move(E);
884 } else
885 return make_error<CoverageMapError>(
887 "not supported endianness or bytes in address");
888 return std::move(Reader);
889}
890
893 uint8_t BytesInAddress = 8;
895
896 // Read the magic and version.
897 Data = Data.substr(sizeof(TestingFormatMagic));
898 if (Data.size() < sizeof(uint64_t))
899 return make_error<CoverageMapError>(coveragemap_error::malformed,
900 "the size of data is too small");
901 auto TestingVersion =
902 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
903 *reinterpret_cast<const uint64_t *>(Data.data()));
904 Data = Data.substr(sizeof(uint64_t));
905
906 // Read the ProfileNames data.
907 if (Data.empty())
908 return make_error<CoverageMapError>(coveragemap_error::truncated);
909 unsigned N = 0;
910 uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
911 if (N > Data.size())
912 return make_error<CoverageMapError>(
914 "the size of TestingFormatMagic is too big");
915 Data = Data.substr(N);
916 if (Data.empty())
917 return make_error<CoverageMapError>(coveragemap_error::truncated);
918 N = 0;
919 uint64_t Address = decodeULEB128(Data.bytes_begin(), &N);
920 if (N > Data.size())
921 return make_error<CoverageMapError>(coveragemap_error::malformed,
922 "the size of ULEB128 is too big");
923 Data = Data.substr(N);
924 if (Data.size() < ProfileNamesSize)
925 return make_error<CoverageMapError>(coveragemap_error::malformed,
926 "the size of ProfileNames is too big");
927 InstrProfSymtab ProfileNames;
928 if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
929 return std::move(E);
930 Data = Data.substr(ProfileNamesSize);
931
932 // In Version2, the size of CoverageMapping is stored directly.
933 uint64_t CoverageMappingSize;
934 if (TestingVersion == uint64_t(TestingFormatVersion::Version2)) {
935 N = 0;
936 CoverageMappingSize = decodeULEB128(Data.bytes_begin(), &N);
937 if (N > Data.size())
938 return make_error<CoverageMapError>(coveragemap_error::malformed,
939 "the size of ULEB128 is too big");
940 Data = Data.substr(N);
941 if (CoverageMappingSize < sizeof(CovMapHeader))
942 return make_error<CoverageMapError>(
944 "the size of CoverageMapping is teoo small");
945 } else if (TestingVersion != uint64_t(TestingFormatVersion::Version1)) {
946 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
947 }
948
949 // Skip the padding bytes because coverage map data has an alignment of 8.
950 auto Pad = offsetToAlignedAddr(Data.data(), Align(8));
951 if (Data.size() < Pad)
952 return make_error<CoverageMapError>(coveragemap_error::malformed,
953 "insufficient padding");
954 Data = Data.substr(Pad);
955 if (Data.size() < sizeof(CovMapHeader))
956 return make_error<CoverageMapError>(
958 "coverage mapping header section is larger than data size");
959 auto const *CovHeader = reinterpret_cast<const CovMapHeader *>(
960 Data.substr(0, sizeof(CovMapHeader)).data());
961 auto Version =
962 CovMapVersion(CovHeader->getVersion<llvm::endianness::little>());
963
964 // In Version1, the size of CoverageMapping is calculated.
965 if (TestingVersion == uint64_t(TestingFormatVersion::Version1)) {
966 if (Version < CovMapVersion::Version4) {
967 CoverageMappingSize = Data.size();
968 } else {
969 auto FilenamesSize =
970 CovHeader->getFilenamesSize<llvm::endianness::little>();
971 CoverageMappingSize = sizeof(CovMapHeader) + FilenamesSize;
972 }
973 }
974
975 auto CoverageMapping = Data.substr(0, CoverageMappingSize);
976 Data = Data.substr(CoverageMappingSize);
977
978 // Read the CoverageRecords data.
979 if (Version < CovMapVersion::Version4) {
980 if (!Data.empty())
981 return make_error<CoverageMapError>(coveragemap_error::malformed,
982 "data is not empty");
983 } else {
984 // Skip the padding bytes because coverage records data has an alignment
985 // of 8.
986 Pad = offsetToAlignedAddr(Data.data(), Align(8));
987 if (Data.size() < Pad)
988 return make_error<CoverageMapError>(coveragemap_error::malformed,
989 "insufficient padding");
990 Data = Data.substr(Pad);
991 }
994
996 CoverageMapping, std::move(CoverageRecords), std::move(ProfileNames),
997 BytesInAddress, Endian, CompilationDir);
998}
999
1000/// Find all sections that match \p Name. There may be more than one if comdats
1001/// are in use, e.g. for the __llvm_covfun section on ELF.
1003 StringRef Name) {
1004 // On COFF, the object file section name may end in "$M". This tells the
1005 // linker to sort these sections between "$A" and "$Z". The linker removes the
1006 // dollar and everything after it in the final binary. Do the same to match.
1007 bool IsCOFF = isa<COFFObjectFile>(OF);
1008 auto stripSuffix = [IsCOFF](StringRef N) {
1009 return IsCOFF ? N.split('$').first : N;
1010 };
1011 Name = stripSuffix(Name);
1012
1013 std::vector<SectionRef> Sections;
1014 for (const auto &Section : OF.sections()) {
1015 Expected<StringRef> NameOrErr = Section.getName();
1016 if (!NameOrErr)
1017 return NameOrErr.takeError();
1018 if (stripSuffix(*NameOrErr) == Name)
1019 Sections.push_back(Section);
1020 }
1021 if (Sections.empty())
1022 return make_error<CoverageMapError>(coveragemap_error::no_data_found);
1023 return Sections;
1024}
1025
1027loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
1028 StringRef CompilationDir = "",
1029 object::BuildIDRef *BinaryID = nullptr) {
1030 std::unique_ptr<ObjectFile> OF;
1031 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1032 // If we have a universal binary, try to look up the object for the
1033 // appropriate architecture.
1034 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1035 if (!ObjectFileOrErr)
1036 return ObjectFileOrErr.takeError();
1037 OF = std::move(ObjectFileOrErr.get());
1038 } else if (isa<ObjectFile>(Bin.get())) {
1039 // For any other object file, upcast and take ownership.
1040 OF.reset(cast<ObjectFile>(Bin.release()));
1041 // If we've asked for a particular arch, make sure they match.
1042 if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
1043 return errorCodeToError(object_error::arch_not_found);
1044 } else
1045 // We can only handle object files.
1046 return make_error<CoverageMapError>(coveragemap_error::malformed,
1047 "binary is not an object file");
1048
1049 // The coverage uses native pointer sizes for the object it's written in.
1050 uint8_t BytesInAddress = OF->getBytesInAddress();
1052 OF->isLittleEndian() ? llvm::endianness::little : llvm::endianness::big;
1053
1054 // Look for the sections that we are interested in.
1055 auto ObjFormat = OF->getTripleObjectFormat();
1056 auto NamesSection =
1057 lookupSections(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
1058 /*AddSegmentInfo=*/false));
1059 if (auto E = NamesSection.takeError())
1060 return std::move(E);
1061 auto CoverageSection =
1062 lookupSections(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
1063 /*AddSegmentInfo=*/false));
1064 if (auto E = CoverageSection.takeError())
1065 return std::move(E);
1066 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1067 if (CoverageSectionRefs.size() != 1)
1068 return make_error<CoverageMapError>(coveragemap_error::malformed,
1069 "the size of name section is not one");
1070 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1071 if (!CoverageMappingOrErr)
1072 return CoverageMappingOrErr.takeError();
1073 StringRef CoverageMapping = CoverageMappingOrErr.get();
1074
1075 InstrProfSymtab ProfileNames;
1076 std::vector<SectionRef> NamesSectionRefs = *NamesSection;
1077 if (NamesSectionRefs.size() != 1)
1078 return make_error<CoverageMapError>(
1080 "the size of coverage mapping section is not one");
1081 if (Error E = ProfileNames.create(NamesSectionRefs.back()))
1082 return std::move(E);
1083
1084 // Look for the coverage records section (Version4 only).
1085 auto CoverageRecordsSections =
1086 lookupSections(*OF, getInstrProfSectionName(IPSK_covfun, ObjFormat,
1087 /*AddSegmentInfo=*/false));
1088
1090 if (auto E = CoverageRecordsSections.takeError()) {
1091 consumeError(std::move(E));
1092 FuncRecords = MemoryBuffer::getMemBuffer("");
1093 } else {
1094 // Compute the FuncRecordsBuffer of the buffer, taking into account the
1095 // padding between each record, and making sure the first block is aligned
1096 // in memory to maintain consistency between buffer address and size
1097 // alignment.
1098 const Align RecordAlignment(8);
1099 uint64_t FuncRecordsSize = 0;
1100 for (SectionRef Section : *CoverageRecordsSections) {
1101 auto CoverageRecordsOrErr = Section.getContents();
1102 if (!CoverageRecordsOrErr)
1103 return CoverageRecordsOrErr.takeError();
1104 FuncRecordsSize += alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1105 }
1106 auto WritableBuffer =
1108 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1109 assert(isAddrAligned(RecordAlignment, FuncRecordsBuffer) &&
1110 "Allocated memory is correctly aligned");
1111
1112 for (SectionRef Section : *CoverageRecordsSections) {
1113 auto CoverageRecordsOrErr = Section.getContents();
1114 if (!CoverageRecordsOrErr)
1115 return CoverageRecordsOrErr.takeError();
1116 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1117 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1118 CoverageRecords.end(), FuncRecordsBuffer);
1119 FuncRecordsBuffer =
1120 std::fill_n(FuncRecordsBuffer,
1121 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1122 (uintptr_t)FuncRecordsBuffer,
1123 '\0');
1124 }
1125 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1126 "consistent init");
1127 FuncRecords = std::move(WritableBuffer);
1128 }
1129
1130 if (BinaryID)
1131 *BinaryID = getBuildID(OF.get());
1132
1134 CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
1135 BytesInAddress, Endian, CompilationDir);
1136}
1137
1138/// Determine whether \p Arch is invalid or empty, given \p Bin.
1140 // If we have a universal binary and Arch doesn't identify any of its slices,
1141 // it's user error.
1142 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
1143 for (auto &ObjForArch : Universal->objects())
1144 if (Arch == ObjForArch.getArchFlagName())
1145 return false;
1146 return true;
1147 }
1148 return false;
1149}
1150
1153 MemoryBufferRef ObjectBuffer, StringRef Arch,
1154 SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
1155 StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
1156 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1157
1158 if (ObjectBuffer.getBuffer().size() > sizeof(TestingFormatMagic)) {
1159 uint64_t Magic =
1160 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
1161 *reinterpret_cast<const uint64_t *>(ObjectBuffer.getBufferStart()));
1162 if (Magic == TestingFormatMagic) {
1163 // This is a special format used for testing.
1164 auto ReaderOrErr =
1165 loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir);
1166 if (!ReaderOrErr)
1167 return ReaderOrErr.takeError();
1168 Readers.push_back(std::move(ReaderOrErr.get()));
1169 return std::move(Readers);
1170 }
1171 }
1172
1173 auto BinOrErr = createBinary(ObjectBuffer);
1174 if (!BinOrErr)
1175 return BinOrErr.takeError();
1176 std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
1177
1178 if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
1179 return make_error<CoverageMapError>(
1181
1182 // MachO universal binaries which contain archives need to be treated as
1183 // archives, not as regular binaries.
1184 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1185 for (auto &ObjForArch : Universal->objects()) {
1186 // Skip slices within the universal binary which target the wrong arch.
1187 std::string ObjArch = ObjForArch.getArchFlagName();
1188 if (Arch != ObjArch)
1189 continue;
1190
1191 auto ArchiveOrErr = ObjForArch.getAsArchive();
1192 if (!ArchiveOrErr) {
1193 // If this is not an archive, try treating it as a regular object.
1194 consumeError(ArchiveOrErr.takeError());
1195 break;
1196 }
1197
1199 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1200 CompilationDir, BinaryIDs);
1201 }
1202 }
1203
1204 // Load coverage out of archive members.
1205 if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
1206 Error Err = Error::success();
1207 for (auto &Child : Ar->children(Err)) {
1208 Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
1209 if (!ChildBufOrErr)
1210 return ChildBufOrErr.takeError();
1211
1212 auto ChildReadersOrErr = BinaryCoverageReader::create(
1213 ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
1214 BinaryIDs);
1215 if (!ChildReadersOrErr)
1216 return ChildReadersOrErr.takeError();
1217 for (auto &Reader : ChildReadersOrErr.get())
1218 Readers.push_back(std::move(Reader));
1219 }
1220 if (Err)
1221 return std::move(Err);
1222
1223 // Thin archives reference object files outside of the archive file, i.e.
1224 // files which reside in memory not owned by the caller. Transfer ownership
1225 // to the caller.
1226 if (Ar->isThin())
1227 for (auto &Buffer : Ar->takeThinBuffers())
1228 ObjectFileBuffers.push_back(std::move(Buffer));
1229
1230 return std::move(Readers);
1231 }
1232
1233 object::BuildIDRef BinaryID;
1234 auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
1235 BinaryIDs ? &BinaryID : nullptr);
1236 if (!ReaderOrErr)
1237 return ReaderOrErr.takeError();
1238 Readers.push_back(std::move(ReaderOrErr.get()));
1239 if (!BinaryID.empty())
1240 BinaryIDs->push_back(BinaryID);
1241 return std::move(Readers);
1242}
1243
1245 if (CurrentRecord >= MappingRecords.size())
1246 return make_error<CoverageMapError>(coveragemap_error::eof);
1247
1248 FunctionsFilenames.clear();
1249 Expressions.clear();
1250 MappingRegions.clear();
1251 auto &R = MappingRecords[CurrentRecord];
1252 auto F = ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1253 RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames,
1254 Expressions, MappingRegions);
1255 if (auto Err = Reader.read())
1256 return Err;
1257
1258 Record.FunctionName = R.FunctionName;
1259 Record.FunctionHash = R.FunctionHash;
1260 Record.Filenames = FunctionsFilenames;
1261 Record.Expressions = Expressions;
1262 Record.MappingRegions = MappingRegions;
1263
1264 ++CurrentRecord;
1265 return Error::success();
1266}
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 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
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
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:425
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, 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)
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:1031
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: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:224
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
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
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.