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