Movatterモバイル変換


[0]ホーム

URL:


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
14#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/Statistic.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/BinaryFormat/Wasm.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"
25#include "llvm/Object/MachOUniversal.h"
26#include "llvm/Object/ObjectFile.h"
27#include "llvm/Object/Wasm.h"
28#include "llvm/ProfileData/InstrProf.h"
29#include "llvm/Support/Casting.h"
30#include "llvm/Support/Compression.h"
31#include "llvm/Support/Debug.h"
32#include "llvm/Support/Endian.h"
33#include "llvm/Support/Error.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/LEB128.h"
36#include "llvm/Support/Path.h"
37#include "llvm/Support/raw_ostream.h"
38#include "llvm/TargetParser/Triple.h"
39#include <vector>
40
41using namespacellvm;
42using namespacecoverage;
43using namespaceobject;
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() {
51if (ReadErr !=coveragemap_error::success)
52return;
53
54// Check if all the records were read or if an error occurred while reading
55// the next record.
56if (auto E = Reader->readNextRecord(Record))
57handleAllErrors(std::move(E), [&](constCoverageMapError &CME) {
58if (CME.get() ==coveragemap_error::eof)
59 *this =CoverageMappingIterator();
60else
61 ReadErr = CME.get();
62 });
63}
64
65ErrorRawCoverageReader::readULEB128(uint64_t &Result) {
66if (Data.empty())
67return make_error<CoverageMapError>(coveragemap_error::truncated);
68unsignedN = 0;
69 Result =decodeULEB128(Data.bytes_begin(), &N);
70if (N >Data.size())
71return make_error<CoverageMapError>(coveragemap_error::malformed,
72"the size of ULEB128 is too big");
73Data =Data.substr(N);
74returnError::success();
75}
76
77ErrorRawCoverageReader::readIntMax(uint64_t &Result,uint64_t MaxPlus1) {
78if (auto Err =readULEB128(Result))
79return Err;
80if (Result >= MaxPlus1)
81return make_error<CoverageMapError>(
82coveragemap_error::malformed,
83"the value of ULEB128 is greater than or equal to MaxPlus1");
84returnError::success();
85}
86
87ErrorRawCoverageReader::readSize(uint64_t &Result) {
88if (auto Err =readULEB128(Result))
89return Err;
90if (Result >Data.size())
91return make_error<CoverageMapError>(coveragemap_error::malformed,
92"the value of ULEB128 is too big");
93returnError::success();
94}
95
96ErrorRawCoverageReader::readString(StringRef &Result) {
97uint64_tLength;
98if (auto Err =readSize(Length))
99return Err;
100 Result =Data.substr(0,Length);
101Data =Data.substr(Length);
102returnError::success();
103}
104
105ErrorRawCoverageFilenamesReader::read(CovMapVersionVersion) {
106uint64_t NumFilenames;
107if (auto Err =readSize(NumFilenames))
108return Err;
109if (!NumFilenames)
110return make_error<CoverageMapError>(coveragemap_error::malformed,
111"number of filenames is zero");
112
113if (Version <CovMapVersion::Version4)
114return readUncompressed(Version, NumFilenames);
115
116// The uncompressed length may exceed the size of the encoded filenames.
117// Skip size validation.
118uint64_t UncompressedLen;
119if (auto Err =readULEB128(UncompressedLen))
120return Err;
121
122uint64_t CompressedLen;
123if (auto Err =readSize(CompressedLen))
124return Err;
125
126if (CompressedLen > 0) {
127if (!compression::zlib::isAvailable())
128return make_error<CoverageMapError>(
129coveragemap_error::decompression_failed);
130
131// Allocate memory for the decompressed filenames.
132SmallVector<uint8_t, 0> StorageBuf;
133
134// Read compressed filenames.
135StringRef CompressedFilenames =Data.substr(0, CompressedLen);
136Data =Data.substr(CompressedLen);
137auto Err =compression::zlib::decompress(
138 arrayRefFromStringRef(CompressedFilenames), StorageBuf,
139 UncompressedLen);
140if (Err) {
141consumeError(std::move(Err));
142return make_error<CoverageMapError>(
143coveragemap_error::decompression_failed);
144 }
145
146RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
147 CompilationDir);
148return Delegate.readUncompressed(Version, NumFilenames);
149 }
150
151return readUncompressed(Version, NumFilenames);
152}
153
154Error RawCoverageFilenamesReader::readUncompressed(CovMapVersionVersion,
155uint64_t NumFilenames) {
156// Read uncompressed filenames.
157if (Version <CovMapVersion::Version6) {
158for (size_tI = 0;I < NumFilenames; ++I) {
159StringRef Filename;
160if (auto Err =readString(Filename))
161return Err;
162 Filenames.push_back(Filename.str());
163 }
164 }else {
165StringRef CWD;
166if (auto Err =readString(CWD))
167return Err;
168 Filenames.push_back(CWD.str());
169
170for (size_tI = 1;I < NumFilenames; ++I) {
171StringRef Filename;
172if (auto Err =readString(Filename))
173return Err;
174if (sys::path::is_absolute(Filename)) {
175 Filenames.push_back(Filename.str());
176 }else {
177SmallString<256>P;
178if (!CompilationDir.empty())
179P.assign(CompilationDir);
180else
181P.assign(CWD);
182llvm::sys::path::append(P, Filename);
183sys::path::remove_dots(P,/*remove_dot_dot=*/true);
184 Filenames.push_back(static_cast<std::string>(P.str()));
185 }
186 }
187 }
188returnError::success();
189}
190
191Error RawCoverageMappingReader::decodeCounter(unsignedValue,Counter &C) {
192autoTag =Value &Counter::EncodingTagMask;
193switch (Tag) {
194caseCounter::Zero:
195C =Counter::getZero();
196returnError::success();
197caseCounter::CounterValueReference:
198C =Counter::getCounter(Value >>Counter::EncodingTagBits);
199returnError::success();
200default:
201break;
202 }
203Tag -=Counter::Expression;
204switch (Tag) {
205caseCounterExpression::Subtract:
206caseCounterExpression::Add: {
207autoID =Value >>Counter::EncodingTagBits;
208if (ID >= Expressions.size())
209return make_error<CoverageMapError>(coveragemap_error::malformed,
210"counter expression is invalid");
211 Expressions[ID].Kind =CounterExpression::ExprKind(Tag);
212C =Counter::getExpression(ID);
213break;
214 }
215default:
216return make_error<CoverageMapError>(coveragemap_error::malformed,
217"counter expression kind is invalid");
218 }
219returnError::success();
220}
221
222Error RawCoverageMappingReader::readCounter(Counter &C) {
223uint64_t EncodedCounter;
224if (auto Err =
225readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
226return Err;
227if (auto Err = decodeCounter(EncodedCounter,C))
228return Err;
229returnError::success();
230}
231
232staticconstunsignedEncodingExpansionRegionBit = 1
233 <<Counter::EncodingTagBits;
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,
240size_t NumFileIDs) {
241uint64_t NumRegions;
242if (auto Err =readSize(NumRegions))
243return Err;
244unsigned LineStart = 0;
245for (size_tI = 0;I < NumRegions; ++I) {
246CounterC, C2;
247uint64_t BIDX,NC;
248// They are stored as internal values plus 1 (min is -1)
249uint64_t ID1, TID1, FID1;
250mcdc::Parameters Params;
251CounterMappingRegion::RegionKindKind =CounterMappingRegion::CodeRegion;
252
253// Read the combined counter + region kind.
254uint64_t EncodedCounterAndRegion;
255if (auto Err =readIntMax(EncodedCounterAndRegion,
256 std::numeric_limits<unsigned>::max()))
257return Err;
258unsignedTag = EncodedCounterAndRegion &Counter::EncodingTagMask;
259uint64_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).
272if (Tag !=Counter::Zero) {
273if (auto Err = decodeCounter(EncodedCounterAndRegion,C))
274return Err;
275 }else {
276// Is it an expansion region?
277if (EncodedCounterAndRegion &EncodingExpansionRegionBit) {
278Kind =CounterMappingRegion::ExpansionRegion;
279 ExpandedFileID = EncodedCounterAndRegion >>
280Counter::EncodingCounterTagAndExpansionRegionTagBits;
281if (ExpandedFileID >= NumFileIDs)
282return make_error<CoverageMapError>(coveragemap_error::malformed,
283"ExpandedFileID is invalid");
284 }else {
285switch (EncodedCounterAndRegion >>
286Counter::EncodingCounterTagAndExpansionRegionTagBits) {
287caseCounterMappingRegion::CodeRegion:
288// Don't do anything when we have a code region with a zero counter.
289break;
290caseCounterMappingRegion::SkippedRegion:
291Kind =CounterMappingRegion::SkippedRegion;
292break;
293caseCounterMappingRegion::BranchRegion:
294// For a Branch Region, read two successive counters.
295Kind =CounterMappingRegion::BranchRegion;
296if (auto Err = readCounter(C))
297return Err;
298if (auto Err = readCounter(C2))
299return Err;
300break;
301caseCounterMappingRegion::MCDCBranchRegion:
302// For a MCDC Branch Region, read two successive counters and 3 IDs.
303Kind =CounterMappingRegion::MCDCBranchRegion;
304if (auto Err = readCounter(C))
305return Err;
306if (auto Err = readCounter(C2))
307return Err;
308if (auto Err =readIntMax(ID1, std::numeric_limits<int16_t>::max()))
309return Err;
310if (auto Err =readIntMax(TID1, std::numeric_limits<int16_t>::max()))
311return Err;
312if (auto Err =readIntMax(FID1, std::numeric_limits<int16_t>::max()))
313return Err;
314if (ID1 == 0)
315return make_error<CoverageMapError>(
316coveragemap_error::malformed,
317"MCDCConditionID shouldn't be zero");
318 Params =mcdc::BranchParameters{
319static_cast<int16_t>(static_cast<int16_t>(ID1) - 1),
320 {static_cast<int16_t>(static_cast<int16_t>(FID1) - 1),
321static_cast<int16_t>(static_cast<int16_t>(TID1) - 1)}};
322break;
323caseCounterMappingRegion::MCDCDecisionRegion:
324Kind =CounterMappingRegion::MCDCDecisionRegion;
325if (auto Err =readIntMax(BIDX, std::numeric_limits<unsigned>::max()))
326return Err;
327if (auto Err =readIntMax(NC, std::numeric_limits<int16_t>::max()))
328return Err;
329 Params =mcdc::DecisionParameters{static_cast<unsigned>(BIDX),
330static_cast<uint16_t>(NC)};
331break;
332default:
333return make_error<CoverageMapError>(coveragemap_error::malformed,
334"region kind is incorrect");
335 }
336 }
337 }
338
339// Read the source range.
340uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
341if (auto Err =
342readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
343return Err;
344if (auto Err =readULEB128(ColumnStart))
345return Err;
346if (ColumnStart > std::numeric_limits<unsigned>::max())
347return make_error<CoverageMapError>(coveragemap_error::malformed,
348"start column is too big");
349if (auto Err =readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
350return Err;
351if (auto Err =readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
352return Err;
353 LineStart += LineStartDelta;
354
355// If the high bit of ColumnEnd is set, this is a gap region.
356if (ColumnEnd & (1U << 31)) {
357Kind =CounterMappingRegion::GapRegion;
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.
369if (ColumnStart == 0 && ColumnEnd == 0) {
370 ColumnStart = 1;
371 ColumnEnd = std::numeric_limits<unsigned>::max();
372 }
373
374LLVM_DEBUG({
375dbgs() <<"Counter in file " << InferredFileID <<" " << LineStart <<":"
376 << ColumnStart <<" -> " << (LineStart + NumLines) <<":"
377 << ColumnEnd <<", ";
378if (Kind ==CounterMappingRegion::ExpansionRegion)
379dbgs() <<"Expands to file " << ExpandedFileID;
380else
381CounterMappingContext(Expressions).dump(C,dbgs());
382dbgs() <<"\n";
383 });
384
385auto CMR =CounterMappingRegion(
386C, C2, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
387 LineStart + NumLines, ColumnEnd,Kind, Params);
388if (CMR.startLoc() > CMR.endLoc())
389return make_error<CoverageMapError>(
390coveragemap_error::malformed,
391"counter mapping region locations are incorrect");
392 MappingRegions.push_back(CMR);
393 }
394returnError::success();
395}
396
397ErrorRawCoverageMappingReader::read() {
398// Read the virtual file mapping.
399SmallVector<unsigned, 8> VirtualFileMapping;
400uint64_t NumFileMappings;
401if (auto Err =readSize(NumFileMappings))
402return Err;
403for (size_tI = 0;I < NumFileMappings; ++I) {
404uint64_t FilenameIndex;
405if (auto Err =readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
406return Err;
407 VirtualFileMapping.push_back(FilenameIndex);
408 }
409
410// Construct the files using unique filenames and virtual file mapping.
411for (autoI : VirtualFileMapping) {
412 Filenames.push_back(TranslationUnitFilenames[I]);
413 }
414
415// Read the expressions.
416uint64_t NumExpressions;
417if (auto Err =readSize(NumExpressions))
418return 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,
424CounterExpression(CounterExpression::Subtract,Counter(),Counter()));
425for (size_tI = 0;I < NumExpressions; ++I) {
426if (auto Err = readCounter(Expressions[I].LHS))
427return Err;
428if (auto Err = readCounter(Expressions[I].RHS))
429return Err;
430 }
431
432// Read the mapping regions sub-arrays.
433for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
434 InferredFileID < S; ++InferredFileID) {
435if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
436 VirtualFileMapping.size()))
437return 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.
445SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
446 FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(),nullptr);
447for (unsignedPass = 1, S = VirtualFileMapping.size();Pass < S; ++Pass) {
448for (auto &R : MappingRegions) {
449if (R.Kind !=CounterMappingRegion::ExpansionRegion)
450continue;
451assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
452 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
453 }
454for (auto &R : MappingRegions) {
455if (FileIDExpansionRegionMapping[R.FileID]) {
456 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
457 FileIDExpansionRegionMapping[R.FileID] =nullptr;
458 }
459 }
460 }
461
462returnError::success();
463}
464
465Expected<bool>RawCoverageMappingDummyChecker::isDummy() {
466// A dummy coverage mapping data consists of just one region with zero count.
467uint64_t NumFileMappings;
468if (Error Err =readSize(NumFileMappings))
469return std::move(Err);
470if (NumFileMappings != 1)
471returnfalse;
472// We don't expect any specific value for the filename index, just skip it.
473uint64_t FilenameIndex;
474if (Error Err =
475readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
476return std::move(Err);
477uint64_t NumExpressions;
478if (Error Err =readSize(NumExpressions))
479return std::move(Err);
480if (NumExpressions != 0)
481returnfalse;
482uint64_t NumRegions;
483if (Error Err =readSize(NumRegions))
484return std::move(Err);
485if (NumRegions != 1)
486returnfalse;
487uint64_t EncodedCounterAndRegion;
488if (Error Err =readIntMax(EncodedCounterAndRegion,
489 std::numeric_limits<unsigned>::max()))
490return std::move(Err);
491unsignedTag = EncodedCounterAndRegion &Counter::EncodingTagMask;
492returnTag ==Counter::Zero;
493}
494
495/// Determine if we should skip the first byte of the section content
496staticboolshouldSkipSectionFirstByte(SectionRef &Section) {
497constObjectFile *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.
502if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
503if (Expected<StringRef> NameOrErr = Section.getName())
504if (*NameOrErr !=getInstrProfSectionName(IPSK_covname,Triple::COFF))
505returntrue;
506returnfalse;
507}
508
509ErrorInstrProfSymtab::create(SectionRef &Section) {
510Expected<StringRef> DataOrErr = Section.getContents();
511if (!DataOrErr)
512return DataOrErr.takeError();
513Data = *DataOrErr;
514Address = Section.getAddress();
515
516if (shouldSkipSectionFirstByte(Section))
517Data =Data.substr(1);
518
519returnError::success();
520}
521
522StringRefInstrProfSymtab::getFuncName(uint64_t Pointer,size_tSize) {
523if (Pointer <Address)
524returnStringRef();
525autoOffset = Pointer -Address;
526if (Offset +Size >Data.size())
527returnStringRef();
528returnData.substr(Pointer -Address,Size);
529}
530
531// Check if the mapping data is a dummy, i.e. is emitted for an unused function.
532staticExpected<bool>isCoverageMappingDummy(uint64_t Hash,StringRef Mapping) {
533// The hash value of dummy mapping records is always zero.
534if (Hash)
535returnfalse;
536returnRawCoverageMappingDummyChecker(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.
541structFilenameRange {
542unsignedStartingIndex;
543unsignedLength;
544
545FilenameRange(unsigned StartingIndex,unsignedLength)
546 : StartingIndex(StartingIndex),Length(Length) {}
547
548voidmarkInvalid() {Length = 0; }
549boolisInvalid() const{returnLength == 0; }
550};
551
552namespace{
553
554/// The interface to read coverage mapping function records for a module.
555structCovMapFuncRecordReader {
556virtual ~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.
565virtualExpected<const char *> readCoverageHeader(constchar *CovBuf,
566constchar *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.
578virtualError
579 readFunctionRecords(constchar *FuncRecBuf,constchar *FuncRecBufEnd,
580 std::optional<FilenameRange> OutOfLineFileRange,
581constchar *OutOfLineMappingBuf,
582constchar *OutOfLineMappingBufEnd) = 0;
583
584template <class IntPtrT, llvm::endianness Endian>
585staticExpected<std::unique_ptr<CovMapFuncRecordReader>>
586get(CovMapVersion Version,InstrProfSymtab &P,
587 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,StringRefD,
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>
593classVersionedCovMapFuncRecordReader :public CovMapFuncRecordReader {
594usingFuncRecordType =
595typenameCovMapTraits<Version, IntPtrT>::CovMapFuncRecordType;
596usingNameRefType =typenameCovMapTraits<Version, IntPtrT>::NameRefType;
597
598// Maps function's name references to the indexes of their records
599// in \c Records.
600DenseMap<NameRefType, size_t> FunctionRecords;
601InstrProfSymtab &ProfileNames;
602StringRef 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.
608DenseMap<uint64_t, FilenameRange> FileRangeMap;
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.
616Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
617StringRef Mapping,
618FilenameRange FileRange) {
619 ++CovMapNumRecords;
620uint64_t FuncHash = CFR->template getFuncHash<Endian>();
621 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
622auto InsertResult =
623 FunctionRecords.insert(std::make_pair(NameRef,Records.size()));
624if (InsertResult.second) {
625StringRef FuncName;
626if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
627return Err;
628if (FuncName.empty())
629return make_error<InstrProfError>(instrprof_error::malformed,
630"function name is empty");
631 ++CovMapNumUsedRecords;
632Records.emplace_back(Version, FuncName, FuncHash, Mapping,
633 FileRange.StartingIndex, FileRange.Length);
634returnError::success();
635 }
636// Update the existing record if it's a dummy and the new record is real.
637size_t OldRecordIndex = InsertResult.first->second;
638BinaryCoverageReader::ProfileMappingRecord &OldRecord =
639Records[OldRecordIndex];
640Expected<bool> OldIsDummyExpected =isCoverageMappingDummy(
641 OldRecord.FunctionHash, OldRecord.CoverageMapping);
642if (Error Err = OldIsDummyExpected.takeError())
643return Err;
644if (!*OldIsDummyExpected)
645returnError::success();
646Expected<bool> NewIsDummyExpected =
647isCoverageMappingDummy(FuncHash, Mapping);
648if (Error Err = NewIsDummyExpected.takeError())
649return Err;
650if (*NewIsDummyExpected)
651returnError::success();
652 ++CovMapNumUsedRecords;
653 OldRecord.FunctionHash = FuncHash;
654 OldRecord.CoverageMapping = Mapping;
655 OldRecord.FilenamesBegin = FileRange.StartingIndex;
656 OldRecord.FilenamesSize = FileRange.Length;
657returnError::success();
658 }
659
660public:
661 VersionedCovMapFuncRecordReader(
662InstrProfSymtab &P,
663 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,StringRefD,
664 std::vector<std::string> &F)
665 : ProfileNames(P), CompilationDir(D), Filenames(F),Records(R) {}
666
667 ~VersionedCovMapFuncRecordReader()override =default;
668
669Expected<const char *> readCoverageHeader(constchar *CovBuf,
670constchar *CovBufEnd) override{
671using namespacesupport;
672
673if (CovBuf +sizeof(CovMapHeader) > CovBufEnd)
674return make_error<CoverageMapError>(
675 coveragemap_error::malformed,
676"coverage mapping header section is larger than buffer size");
677auto CovHeader =reinterpret_cast<constCovMapHeader *>(CovBuf);
678uint32_t NRecords = CovHeader->getNRecords<Endian>();
679uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
680uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
681assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
682 CovBuf =reinterpret_cast<constchar *>(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).
687constchar *FuncRecBuf =nullptr;
688constchar *FuncRecBufEnd =nullptr;
689if (Version < CovMapVersion::Version4)
690 FuncRecBuf = CovBuf;
691 CovBuf += NRecords *sizeof(FuncRecordType);
692if (Version < CovMapVersion::Version4)
693 FuncRecBufEnd = CovBuf;
694
695// Get the filenames.
696if (CovBuf + FilenamesSize > CovBufEnd)
697return make_error<CoverageMapError>(
698 coveragemap_error::malformed,
699"filenames section is larger than buffer size");
700size_t FilenamesBegin = Filenames.size();
701StringRef FilenameRegion(CovBuf, FilenamesSize);
702RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
703 CompilationDir);
704if (auto Err = Reader.read(Version))
705return std::move(Err);
706 CovBuf += FilenamesSize;
707FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
708
709if (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 =
713llvm::IndexedInstrProf::ComputeHash(FilenameRegion);
714autoInsert =
715 FileRangeMap.insert(std::make_pair(FilenamesRef, FileRange));
716if (!Insert.second) {
717// The same filenames ref was encountered twice. It's possible that
718// the associated filenames are the same.
719auto It = Filenames.begin();
720FilenameRange &OrigRange =Insert.first->getSecond();
721if (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;
727else
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).
736constchar *MappingBuf = CovBuf;
737if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
738return make_error<CoverageMapError>(coveragemap_error::malformed,
739"coverage mapping size is not zero");
740 CovBuf += CoverageSize;
741constchar *MappingEnd = CovBuf;
742
743if (CovBuf > CovBufEnd)
744return make_error<CoverageMapError>(
745 coveragemap_error::malformed,
746"function records section is larger than buffer size");
747
748if (Version < CovMapVersion::Version4) {
749// Read each function record.
750if (ErrorE = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
751 MappingBuf, MappingEnd))
752return 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
759return CovBuf;
760 }
761
762Error readFunctionRecords(constchar *FuncRecBuf,constchar *FuncRecBufEnd,
763 std::optional<FilenameRange> OutOfLineFileRange,
764constchar *OutOfLineMappingBuf,
765constchar *OutOfLineMappingBufEnd) override{
766auto CFR =reinterpret_cast<constFuncRecordType *>(FuncRecBuf);
767while ((constchar *)CFR < FuncRecBufEnd) {
768// Validate the length of the coverage mapping for this function.
769constchar *NextMappingBuf;
770const FuncRecordType *NextCFR;
771 std::tie(NextMappingBuf, NextCFR) =
772 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
773if (Version < CovMapVersion::Version4)
774if (NextMappingBuf > OutOfLineMappingBufEnd)
775return 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;
781if (Version < CovMapVersion::Version4) {
782 FileRange = OutOfLineFileRange;
783 }else {
784uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
785auto It = FileRangeMap.find(FilenamesRef);
786if (It == FileRangeMap.end())
787return make_error<CoverageMapError>(
788 coveragemap_error::malformed,
789"no filename found for function with hash=0x" +
790Twine::utohexstr(FilenamesRef));
791else
792 FileRange = It->getSecond();
793 }
794
795// Now, read the coverage data.
796if (FileRange && !FileRange->isInvalid()) {
797StringRef Mapping =
798 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
799if (Version >= CovMapVersion::Version4 &&
800 Mapping.data() + Mapping.size() > FuncRecBufEnd)
801return make_error<CoverageMapError>(
802 coveragemap_error::malformed,
803"coverage mapping data is larger than buffer size");
804if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
805return Err;
806 }
807
808 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
809 }
810returnError::success();
811 }
812};
813
814}// end anonymous namespace
815
816template <class IntPtrT, llvm::endianness Endian>
817Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
818CovMapVersionVersion,InstrProfSymtab &P,
819 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,StringRefD,
820 std::vector<std::string> &F) {
821using namespacecoverage;
822
823switch (Version) {
824caseCovMapVersion::Version1:
825return std::make_unique<VersionedCovMapFuncRecordReader<
826CovMapVersion::Version1,IntPtrT,Endian>>(P,R,D,F);
827caseCovMapVersion::Version2:
828caseCovMapVersion::Version3:
829caseCovMapVersion::Version4:
830caseCovMapVersion::Version5:
831caseCovMapVersion::Version6:
832caseCovMapVersion::Version7:
833// Decompress the name data.
834if (Error E =P.create(P.getNameData()))
835return std::move(E);
836if (Version ==CovMapVersion::Version2)
837return std::make_unique<VersionedCovMapFuncRecordReader<
838CovMapVersion::Version2,IntPtrT,Endian>>(P,R,D,F);
839elseif (Version ==CovMapVersion::Version3)
840return std::make_unique<VersionedCovMapFuncRecordReader<
841CovMapVersion::Version3,IntPtrT,Endian>>(P,R,D,F);
842elseif (Version ==CovMapVersion::Version4)
843return std::make_unique<VersionedCovMapFuncRecordReader<
844CovMapVersion::Version4,IntPtrT,Endian>>(P,R,D,F);
845elseif (Version ==CovMapVersion::Version5)
846return std::make_unique<VersionedCovMapFuncRecordReader<
847CovMapVersion::Version5,IntPtrT,Endian>>(P,R,D,F);
848elseif (Version ==CovMapVersion::Version6)
849return std::make_unique<VersionedCovMapFuncRecordReader<
850CovMapVersion::Version6,IntPtrT,Endian>>(P,R,D,F);
851elseif (Version ==CovMapVersion::Version7)
852return std::make_unique<VersionedCovMapFuncRecordReader<
853CovMapVersion::Version7,IntPtrT,Endian>>(P,R,D,F);
854 }
855llvm_unreachable("Unsupported version");
856}
857
858template <typename T, llvm::endianness Endian>
859staticErrorreadCoverageMappingData(
860InstrProfSymtab &ProfileNames,StringRef CovMap,StringRef FuncRecords,
861 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
862StringRef CompilationDir, std::vector<std::string> &Filenames) {
863using namespacecoverage;
864
865// Read the records in the coverage data section.
866auto CovHeader =
867reinterpret_cast<constCovMapHeader *>(CovMap.data());
868CovMapVersionVersion = (CovMapVersion)CovHeader->getVersion<Endian>();
869if (Version >CovMapVersion::CurrentVersion)
870return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
871Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
872 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
873 CompilationDir, Filenames);
874if (Error E = ReaderExpected.takeError())
875return E;
876auto Reader = std::move(ReaderExpected.get());
877constchar *CovBuf = CovMap.data();
878constchar *CovBufEnd = CovBuf + CovMap.size();
879constchar *FuncRecBuf = FuncRecords.data();
880constchar *FuncRecBufEnd = FuncRecords.data() + FuncRecords.size();
881while (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.
888auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
889if (auto E = NextOrErr.takeError())
890return 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.
895if (Version >=CovMapVersion::Version4)
896return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
897nullptr,nullptr);
898returnError::success();
899}
900
901Expected<std::unique_ptr<BinaryCoverageReader>>
902BinaryCoverageReader::createCoverageReaderFromBuffer(
903StringRef Coverage,FuncRecordsStorage &&FuncRecords,
904CoverageMapCopyStorage &&CoverageMap,
905 std::unique_ptr<InstrProfSymtab> ProfileNamesPtr,uint8_t BytesInAddress,
906llvm::endianness Endian,StringRef CompilationDir) {
907if (ProfileNamesPtr ==nullptr)
908return make_error<CoverageMapError>(coveragemap_error::malformed,
909"Caller must provide ProfileNames");
910 std::unique_ptr<BinaryCoverageReader> Reader(
911newBinaryCoverageReader(std::move(ProfileNamesPtr),
912 std::move(FuncRecords), std::move(CoverageMap)));
913InstrProfSymtab &ProfileNames = *Reader->ProfileNames;
914StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
915if (BytesInAddress == 4 &&Endian ==llvm::endianness::little) {
916if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>(
917 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
918 CompilationDir, Reader->Filenames))
919return std::move(E);
920 }elseif (BytesInAddress == 4 &&Endian ==llvm::endianness::big) {
921if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>(
922 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
923 CompilationDir, Reader->Filenames))
924return std::move(E);
925 }elseif (BytesInAddress == 8 &&Endian ==llvm::endianness::little) {
926if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>(
927 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
928 CompilationDir, Reader->Filenames))
929return std::move(E);
930 }elseif (BytesInAddress == 8 &&Endian ==llvm::endianness::big) {
931if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>(
932 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
933 CompilationDir, Reader->Filenames))
934return std::move(E);
935 }else
936return make_error<CoverageMapError>(
937coveragemap_error::malformed,
938"not supported endianness or bytes in address");
939return std::move(Reader);
940}
941
942staticExpected<std::unique_ptr<BinaryCoverageReader>>
943loadTestingFormat(StringRefData,StringRef CompilationDir) {
944uint8_t BytesInAddress = 8;
945llvm::endiannessEndian =llvm::endianness::little;
946
947// Read the magic and version.
948Data =Data.substr(sizeof(TestingFormatMagic));
949if (Data.size() <sizeof(uint64_t))
950return make_error<CoverageMapError>(coveragemap_error::malformed,
951"the size of data is too small");
952auto TestingVersion =
953 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
954 *reinterpret_cast<constuint64_t *>(Data.data()));
955Data =Data.substr(sizeof(uint64_t));
956
957// Read the ProfileNames data.
958if (Data.empty())
959return make_error<CoverageMapError>(coveragemap_error::truncated);
960unsignedN = 0;
961uint64_t ProfileNamesSize =decodeULEB128(Data.bytes_begin(), &N);
962if (N >Data.size())
963return make_error<CoverageMapError>(
964coveragemap_error::malformed,
965"the size of TestingFormatMagic is too big");
966Data =Data.substr(N);
967if (Data.empty())
968return make_error<CoverageMapError>(coveragemap_error::truncated);
969N = 0;
970uint64_tAddress =decodeULEB128(Data.bytes_begin(), &N);
971if (N >Data.size())
972return make_error<CoverageMapError>(coveragemap_error::malformed,
973"the size of ULEB128 is too big");
974Data =Data.substr(N);
975if (Data.size() < ProfileNamesSize)
976return make_error<CoverageMapError>(coveragemap_error::malformed,
977"the size of ProfileNames is too big");
978auto ProfileNames = std::make_unique<InstrProfSymtab>();
979if (Error E = ProfileNames->create(Data.substr(0, ProfileNamesSize),Address))
980return std::move(E);
981Data =Data.substr(ProfileNamesSize);
982
983// In Version2, the size of CoverageMapping is stored directly.
984uint64_t CoverageMappingSize;
985if (TestingVersion ==uint64_t(TestingFormatVersion::Version2)) {
986N = 0;
987 CoverageMappingSize =decodeULEB128(Data.bytes_begin(), &N);
988if (N >Data.size())
989return make_error<CoverageMapError>(coveragemap_error::malformed,
990"the size of ULEB128 is too big");
991Data =Data.substr(N);
992if (CoverageMappingSize <sizeof(CovMapHeader))
993return make_error<CoverageMapError>(
994coveragemap_error::malformed,
995"the size of CoverageMapping is teoo small");
996 }elseif (TestingVersion !=uint64_t(TestingFormatVersion::Version1)) {
997return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
998 }
999
1000// Skip the padding bytes because coverage map data has an alignment of 8.
1001auto Pad =offsetToAlignedAddr(Data.data(),Align(8));
1002if (Data.size() < Pad)
1003return make_error<CoverageMapError>(coveragemap_error::malformed,
1004"insufficient padding");
1005Data =Data.substr(Pad);
1006if (Data.size() <sizeof(CovMapHeader))
1007return make_error<CoverageMapError>(
1008coveragemap_error::malformed,
1009"coverage mapping header section is larger than data size");
1010autoconst *CovHeader =reinterpret_cast<constCovMapHeader *>(
1011Data.substr(0,sizeof(CovMapHeader)).data());
1012autoVersion =
1013CovMapVersion(CovHeader->getVersion<llvm::endianness::little>());
1014
1015// In Version1, the size of CoverageMapping is calculated.
1016if (TestingVersion ==uint64_t(TestingFormatVersion::Version1)) {
1017if (Version <CovMapVersion::Version4) {
1018 CoverageMappingSize =Data.size();
1019 }else {
1020auto FilenamesSize =
1021 CovHeader->getFilenamesSize<llvm::endianness::little>();
1022 CoverageMappingSize =sizeof(CovMapHeader) + FilenamesSize;
1023 }
1024 }
1025
1026autoCoverageMapping =Data.substr(0, CoverageMappingSize);
1027Data =Data.substr(CoverageMappingSize);
1028
1029// Read the CoverageRecords data.
1030if (Version <CovMapVersion::Version4) {
1031if (!Data.empty())
1032return 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));
1038if (Data.size() < Pad)
1039return make_error<CoverageMapError>(coveragemap_error::malformed,
1040"insufficient padding");
1041Data =Data.substr(Pad);
1042 }
1043BinaryCoverageReader::FuncRecordsStorage CoverageRecords =
1044MemoryBuffer::getMemBuffer(Data);
1045
1046returnBinaryCoverageReader::createCoverageReaderFromBuffer(
1047CoverageMapping, 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.
1053staticExpected<std::vector<SectionRef>>
1054lookupSections(ObjectFile &OF,InstrProfSectKind IPSK) {
1055auto ObjFormat = OF.getTripleObjectFormat();
1056autoName =
1057getInstrProfSectionName(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.
1061bool IsCOFF = isa<COFFObjectFile>(OF);
1062auto stripSuffix = [IsCOFF](StringRefN) {
1063return IsCOFF ?N.split('$').first :N;
1064 };
1065Name = stripSuffix(Name);
1066
1067 std::vector<SectionRef> Sections;
1068for (constauto &Section : OF.sections()) {
1069Expected<StringRef> NameOrErr = Section.getName();
1070if (!NameOrErr)
1071return NameOrErr.takeError();
1072if (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.
1076if (IPSK == IPSK_name &&
1077 (Section.getSize() == 0 || (IsCOFF && Section.getSize() == 2)))
1078continue;
1079 Sections.push_back(Section);
1080 }
1081 }
1082if (Sections.empty())
1083return make_error<CoverageMapError>(coveragemap_error::no_data_found);
1084return 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.
1090staticExpected<std::pair<StringRef, uint64_t>>
1091lookupAllocatableSection(ObjectFile &OF,InstrProfSectKind IPSK) {
1092// On Wasm, allocatable sections can live only in data segments.
1093if (auto *WOF = dyn_cast<WasmObjectFile>(&OF)) {
1094 std::vector<const WasmSegment *> Segments;
1095auto ObjFormat = OF.getTripleObjectFormat();
1096autoName =
1097getInstrProfSectionName(IPSK, ObjFormat,/*AddSegmentInfo=*/false);
1098for (constauto &DebugName : WOF->debugNames()) {
1099if (DebugName.Type !=wasm::NameType::DATA_SEGMENT ||
1100 DebugName.Name !=Name)
1101continue;
1102if (DebugName.Index >= WOF->dataSegments().size())
1103return make_error<CoverageMapError>(coveragemap_error::malformed);
1104auto &Segment = WOF->dataSegments()[DebugName.Index];
1105 Segments.push_back(&Segment);
1106 }
1107if (Segments.empty())
1108return make_error<CoverageMapError>(coveragemap_error::no_data_found);
1109if (Segments.size() != 1)
1110return make_error<CoverageMapError>(coveragemap_error::malformed);
1111
1112constauto &Segment = *Segments.front();
1113auto &Data = Segment.Data;
1114StringRefContent(reinterpret_cast<constchar *>(Data.Content.data()),
1115Data.Content.size());
1116return std::make_pair(Content, Segment.SectionOffset);
1117 }
1118
1119// On other object file types, delegate to lookupSections to find the section.
1120auto Sections =lookupSections(OF, IPSK);
1121if (!Sections)
1122return Sections.takeError();
1123if (Sections->size() != 1)
1124return make_error<CoverageMapError>(
1125coveragemap_error::malformed,
1126"the size of coverage mapping section is not one");
1127auto &Section = Sections->front();
1128auto ContentsOrErr = Section.getContents();
1129if (!ContentsOrErr)
1130return ContentsOrErr.takeError();
1131autoContent = *ContentsOrErr;
1132if (shouldSkipSectionFirstByte(Section))
1133Content =Content.drop_front(1);
1134return std::make_pair(Content, Section.getAddress());
1135}
1136
1137staticExpected<std::unique_ptr<BinaryCoverageReader>>
1138loadBinaryFormat(std::unique_ptr<Binary>Bin,StringRef Arch,
1139StringRef CompilationDir ="",
1140object::BuildIDRef *BinaryID =nullptr) {
1141 std::unique_ptr<ObjectFile> OF;
1142if (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.
1145auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1146if (!ObjectFileOrErr)
1147return ObjectFileOrErr.takeError();
1148 OF = std::move(ObjectFileOrErr.get());
1149 }elseif (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.
1153if (!Arch.empty() && OF->getArch() !=Triple(Arch).getArch())
1154returnerrorCodeToError(object_error::arch_not_found);
1155 }else
1156// We can only handle object files.
1157return 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.
1161uint8_t BytesInAddress = OF->getBytesInAddress();
1162llvm::endiannessEndian =
1163 OF->isLittleEndian() ?llvm::endianness::little :llvm::endianness::big;
1164
1165// Look for the sections that we are interested in.
1166auto 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.
1169auto NamesSection =lookupAllocatableSection(*OF, IPSK_name);
1170if (auto E = NamesSection.takeError()) {
1171consumeError(std::move(E));
1172 NamesSection =lookupAllocatableSection(*OF, IPSK_covname);
1173if (auto E = NamesSection.takeError())
1174return std::move(E);
1175 }
1176
1177uint64_t NamesAddress;
1178StringRef NamesContent;
1179 std::tie(NamesContent, NamesAddress) = *NamesSection;
1180if (Error E = ProfileNames->create(NamesContent, NamesAddress))
1181return std::move(E);
1182
1183auto CoverageSection =lookupSections(*OF, IPSK_covmap);
1184if (auto E = CoverageSection.takeError())
1185return std::move(E);
1186 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1187if (CoverageSectionRefs.size() != 1)
1188return make_error<CoverageMapError>(coveragemap_error::malformed,
1189"the size of name section is not one");
1190auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1191if (!CoverageMappingOrErr)
1192return CoverageMappingOrErr.takeError();
1193StringRefCoverageMapping = 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;
1199if (!isAddrAligned(Align(8),CoverageMapping.data())) {
1200 CoverageMapCopy =MemoryBuffer::getMemBufferCopy(CoverageMapping);
1201CoverageMapping = CoverageMapCopy->getBuffer();
1202 }
1203
1204// Look for the coverage records section (Version4 only).
1205auto CoverageRecordsSections =lookupSections(*OF, IPSK_covfun);
1206
1207BinaryCoverageReader::FuncRecordsStorage FuncRecords;
1208if (auto E = CoverageRecordsSections.takeError()) {
1209consumeError(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.
1216constAlign RecordAlignment(8);
1217uint64_t FuncRecordsSize = 0;
1218for (SectionRef Section : *CoverageRecordsSections) {
1219auto CoverageRecordsOrErr = Section.getContents();
1220if (!CoverageRecordsOrErr)
1221return CoverageRecordsOrErr.takeError();
1222 FuncRecordsSize +=alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1223 }
1224auto WritableBuffer =
1225WritableMemoryBuffer::getNewUninitMemBuffer(FuncRecordsSize);
1226char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1227assert(isAddrAligned(RecordAlignment, FuncRecordsBuffer) &&
1228"Allocated memory is correctly aligned");
1229
1230for (SectionRef Section : *CoverageRecordsSections) {
1231auto CoverageRecordsOrErr = Section.getContents();
1232if (!CoverageRecordsOrErr)
1233return CoverageRecordsOrErr.takeError();
1234constauto &CoverageRecords = CoverageRecordsOrErr.get();
1235 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1236 CoverageRecords.end(), FuncRecordsBuffer);
1237 FuncRecordsBuffer =
1238 std::fill_n(FuncRecordsBuffer,
1239alignAddr(FuncRecordsBuffer, RecordAlignment) -
1240 (uintptr_t)FuncRecordsBuffer,
1241'\0');
1242 }
1243assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1244"consistent init");
1245 FuncRecords = std::move(WritableBuffer);
1246 }
1247
1248if (BinaryID)
1249 *BinaryID =getBuildID(OF.get());
1250
1251returnBinaryCoverageReader::createCoverageReaderFromBuffer(
1252CoverageMapping, 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.
1257staticboolisArchSpecifierInvalidOrMissing(Binary *Bin,StringRef Arch) {
1258// If we have a universal binary and Arch doesn't identify any of its slices,
1259// it's user error.
1260if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
1261for (auto &ObjForArch : Universal->objects())
1262if (Arch == ObjForArch.getArchFlagName())
1263returnfalse;
1264returntrue;
1265 }
1266returnfalse;
1267}
1268
1269Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
1270BinaryCoverageReader::create(
1271MemoryBufferRef ObjectBuffer,StringRef Arch,
1272SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
1273StringRef CompilationDir,SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
1274 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1275
1276if (ObjectBuffer.getBuffer().size() >sizeof(TestingFormatMagic)) {
1277uint64_t Magic =
1278 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
1279 *reinterpret_cast<constuint64_t *>(ObjectBuffer.getBufferStart()));
1280if (Magic ==TestingFormatMagic) {
1281// This is a special format used for testing.
1282auto ReaderOrErr =
1283loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir);
1284if (!ReaderOrErr)
1285return ReaderOrErr.takeError();
1286 Readers.push_back(std::move(ReaderOrErr.get()));
1287return std::move(Readers);
1288 }
1289 }
1290
1291auto BinOrErr =createBinary(ObjectBuffer);
1292if (!BinOrErr)
1293return BinOrErr.takeError();
1294 std::unique_ptr<Binary>Bin = std::move(BinOrErr.get());
1295
1296if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
1297return make_error<CoverageMapError>(
1298coveragemap_error::invalid_or_missing_arch_specifier);
1299
1300// MachO universal binaries which contain archives need to be treated as
1301// archives, not as regular binaries.
1302if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1303for (auto &ObjForArch : Universal->objects()) {
1304// Skip slices within the universal binary which target the wrong arch.
1305 std::string ObjArch = ObjForArch.getArchFlagName();
1306if (Arch != ObjArch)
1307continue;
1308
1309auto ArchiveOrErr = ObjForArch.getAsArchive();
1310if (!ArchiveOrErr) {
1311// If this is not an archive, try treating it as a regular object.
1312consumeError(ArchiveOrErr.takeError());
1313break;
1314 }
1315
1316returnBinaryCoverageReader::create(
1317 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1318 CompilationDir, BinaryIDs);
1319 }
1320 }
1321
1322// Load coverage out of archive members.
1323if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
1324Error Err =Error::success();
1325for (auto &Child : Ar->children(Err)) {
1326Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
1327if (!ChildBufOrErr)
1328return ChildBufOrErr.takeError();
1329
1330auto ChildReadersOrErr =BinaryCoverageReader::create(
1331 ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
1332 BinaryIDs);
1333if (!ChildReadersOrErr)
1334return ChildReadersOrErr.takeError();
1335for (auto &Reader : ChildReadersOrErr.get())
1336 Readers.push_back(std::move(Reader));
1337 }
1338if (Err)
1339return 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.
1344if (Ar->isThin())
1345for (auto &Buffer : Ar->takeThinBuffers())
1346 ObjectFileBuffers.push_back(std::move(Buffer));
1347
1348return std::move(Readers);
1349 }
1350
1351object::BuildIDRef BinaryID;
1352auto ReaderOrErr =loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
1353 BinaryIDs ? &BinaryID :nullptr);
1354if (!ReaderOrErr)
1355return ReaderOrErr.takeError();
1356 Readers.push_back(std::move(ReaderOrErr.get()));
1357if (!BinaryID.empty())
1358 BinaryIDs->push_back(BinaryID);
1359return std::move(Readers);
1360}
1361
1362ErrorBinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
1363if (CurrentRecord >= MappingRecords.size())
1364return make_error<CoverageMapError>(coveragemap_error::eof);
1365
1366 FunctionsFilenames.clear();
1367 Expressions.clear();
1368 MappingRegions.clear();
1369auto &R = MappingRecords[CurrentRecord];
1370autoF =ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1371RawCoverageMappingReader Reader(R.CoverageMapping,F, FunctionsFilenames,
1372 Expressions, MappingRegions);
1373if (auto Err = Reader.read())
1374return Err;
1375
1376Record.FunctionName = R.FunctionName;
1377Record.FunctionHash = R.FunctionHash;
1378Record.Filenames = FunctionsFilenames;
1379Record.Expressions = Expressions;
1380Record.MappingRegions = MappingRegions;
1381
1382 ++CurrentRecord;
1383returnError::success();
1384}
ArrayRef.h
Wasm.h
Binary.h
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Casting.h
Compression.h
readCoverageMappingData
static Error readCoverageMappingData(InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, std::vector< BinaryCoverageReader::ProfileMappingRecord > &Records, StringRef CompilationDir, std::vector< std::string > &Filenames)
Definition:CoverageMappingReader.cpp:859
lookupAllocatableSection
static Expected< std::pair< StringRef, uint64_t > > lookupAllocatableSection(ObjectFile &OF, InstrProfSectKind IPSK)
Find a section that matches Name and is allocatable at runtime.
Definition:CoverageMappingReader.cpp:1091
loadBinaryFormat
static Expected< std::unique_ptr< BinaryCoverageReader > > loadBinaryFormat(std::unique_ptr< Binary > Bin, StringRef Arch, StringRef CompilationDir="", object::BuildIDRef *BinaryID=nullptr)
Definition:CoverageMappingReader.cpp:1138
loadTestingFormat
static Expected< std::unique_ptr< BinaryCoverageReader > > loadTestingFormat(StringRef Data, StringRef CompilationDir)
Definition:CoverageMappingReader.cpp:943
lookupSections
static Expected< std::vector< SectionRef > > lookupSections(ObjectFile &OF, InstrProfSectKind IPSK)
Find all sections that match IPSK name.
Definition:CoverageMappingReader.cpp:1054
isArchSpecifierInvalidOrMissing
static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch)
Determine whether Arch is invalid or empty, given Bin.
Definition:CoverageMappingReader.cpp:1257
shouldSkipSectionFirstByte
static bool shouldSkipSectionFirstByte(SectionRef &Section)
Determine if we should skip the first byte of the section content.
Definition:CoverageMappingReader.cpp:496
isCoverageMappingDummy
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
Definition:CoverageMappingReader.cpp:532
EncodingExpansionRegionBit
static const unsigned EncodingExpansionRegionBit
Definition:CoverageMappingReader.cpp:232
CoverageMappingReader.h
Debug.h
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
DenseMap.h
This file defines the DenseMap class.
Content
T Content
Definition:ELFObjHandler.cpp:89
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
Endian.h
InstrProf.h
LEB128.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
MachOUniversal.h
ObjectFile.h
COFF.h
Wasm.h
P
#define P(N)
Path.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Endian
endianness Endian
Definition:SampleProfWriter.cpp:52
SmallVector.h
This file defines the SmallVector class.
Statistic.h
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
STATISTIC
#define STATISTIC(VARNAME, DESC)
Definition:Statistic.h:166
StringRef.h
Triple.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
IntPtrT
llvm::ArrayRef< uint8_t >
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition:ArrayRef.h:163
llvm::ArrayRef::slice
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
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition:DenseMap.h:156
llvm::DenseMapBase::end
iterator end()
Definition:DenseMap.h:84
llvm::DenseMapBase::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition:DenseMap.h:211
llvm::DenseMap
Definition:DenseMap.h:727
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition:Error.h:608
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition:Error.h:578
llvm::InstrProfSymtab
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
Definition:InstrProf.h:460
llvm::InstrProfSymtab::create
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
Definition:CoverageMappingReader.cpp:509
llvm::InstrProfSymtab::getFuncName
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function's PGO name from the function name's symbol address in the object file.
Definition:CoverageMappingReader.cpp:522
llvm::MemoryBufferRef
Definition:MemoryBufferRef.h:22
llvm::MemoryBufferRef::getBufferStart
const char * getBufferStart() const
Definition:MemoryBufferRef.h:35
llvm::MemoryBufferRef::getBuffer
StringRef getBuffer() const
Definition:MemoryBufferRef.h:32
llvm::MemoryBuffer::getMemBuffer
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Definition:MemoryBuffer.cpp:129
llvm::MemoryBuffer::getMemBufferCopy
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.
Definition:MemoryBuffer.cpp:155
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition:Pass.h:94
llvm::Record
Definition:Record.h:1596
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorImpl::resize
void resize(size_type N)
Definition:SmallVector.h:638
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition:StringRef.h:229
llvm::StringRef::substr
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
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::StringRef::data
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
llvm::StringRef::bytes_begin
const unsigned char * bytes_begin() const
Definition:StringRef.h:128
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition:Triple.h:44
llvm::Triple::COFF
@ COFF
Definition:Triple.h:310
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition:Twine.h:416
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::WritableMemoryBuffer::getNewUninitMemBuffer
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.
Definition:MemoryBuffer.cpp:308
llvm::coverage::BinaryCoverageReader
Reader for the coverage mapping data that is emitted by the frontend and stored in an object file.
Definition:CoverageMappingReader.h:164
llvm::coverage::BinaryCoverageReader::createCoverageReaderFromBuffer
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="")
Definition:CoverageMappingReader.cpp:902
llvm::coverage::BinaryCoverageReader::CoverageMapCopyStorage
std::unique_ptr< MemoryBuffer > CoverageMapCopyStorage
Definition:CoverageMappingReader.h:183
llvm::coverage::BinaryCoverageReader::create
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)
Definition:CoverageMappingReader.cpp:1270
llvm::coverage::BinaryCoverageReader::FuncRecordsStorage
std::unique_ptr< MemoryBuffer > FuncRecordsStorage
Definition:CoverageMappingReader.h:182
llvm::coverage::BinaryCoverageReader::readNextRecord
Error readNextRecord(CoverageMappingRecord &Record) override
Definition:CoverageMappingReader.cpp:1362
llvm::coverage::CounterMappingContext
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
Definition:CoverageMapping.h:674
llvm::coverage::CounterMappingContext::dump
void dump(const Counter &C, raw_ostream &OS) const
Definition:CoverageMapping.cpp:163
llvm::coverage::CoverageMapError
Definition:CoverageMapping.h:80
llvm::coverage::CoverageMapError::get
coveragemap_error get() const
Definition:CoverageMapping.h:95
llvm::coverage::CoverageMappingIterator
A file format agnostic iterator over coverage mapping data.
Definition:CoverageMappingReader.h:44
llvm::coverage::CoverageMappingReader::readNextRecord
virtual Error readNextRecord(CoverageMappingRecord &Record)=0
llvm::coverage::CoverageMapping
The mapping of profile information to coverage data.
Definition:CoverageMapping.h:980
llvm::coverage::RawCoverageFilenamesReader
Reader for the raw coverage filenames.
Definition:CoverageMappingReader.h:231
llvm::coverage::RawCoverageFilenamesReader::read
Error read(CovMapVersion Version)
Definition:CoverageMappingReader.cpp:105
llvm::coverage::RawCoverageMappingDummyChecker
Checks if the given coverage mapping data is exported for an unused function.
Definition:CoverageMappingReader.h:123
llvm::coverage::RawCoverageMappingDummyChecker::isDummy
Expected< bool > isDummy()
Definition:CoverageMappingReader.cpp:465
llvm::coverage::RawCoverageMappingReader
Reader for the raw coverage mapping data.
Definition:CoverageMappingReader.h:132
llvm::coverage::RawCoverageMappingReader::read
Error read()
Definition:CoverageMappingReader.cpp:397
llvm::coverage::RawCoverageReader::Data
StringRef Data
Definition:CoverageMappingReader.h:111
llvm::coverage::RawCoverageReader::readSize
Error readSize(uint64_t &Result)
Definition:CoverageMappingReader.cpp:87
llvm::coverage::RawCoverageReader::readIntMax
Error readIntMax(uint64_t &Result, uint64_t MaxPlus1)
Definition:CoverageMappingReader.cpp:77
llvm::coverage::RawCoverageReader::readULEB128
Error readULEB128(uint64_t &Result)
Definition:CoverageMappingReader.cpp:65
llvm::coverage::RawCoverageReader::readString
Error readString(StringRef &Result)
Definition:CoverageMappingReader.cpp:96
llvm::object::Binary
Definition:Binary.h:32
llvm::object::Binary::getTripleObjectFormat
Triple::ObjectFormatType getTripleObjectFormat() const
Definition:Binary.h:163
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition:ObjectFile.h:229
llvm::object::ObjectFile::sections
section_iterator_range sections() const
Definition:ObjectFile.h:329
llvm::object::ObjectFile::isRelocatableObject
virtual bool isRelocatableObject() const =0
True if this is a relocatable object (.o/.obj).
llvm::object::Record
Represents a GOFF physical record.
Definition:GOFF.h:31
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition:ObjectFile.h:81
uint16_t
uint32_t
uint64_t
uint8_t
unsigned
Archive.h
Error.h
ErrorHandling.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
Error.h
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm::IndexedInstrProf::ComputeHash
uint64_t ComputeHash(StringRef K)
Definition:InstrProf.h:1124
llvm::MachO::Records
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
Definition:RecordsSlice.h:197
llvm::RISCVFenceField::R
@ R
Definition:RISCVBaseInfo.h:373
llvm::cfg::UpdateKind::Insert
@ Insert
llvm::compression::zlib::decompress
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
Definition:Compression.cpp:151
llvm::compression::zlib::isAvailable
bool isAvailable()
Definition:Compression.cpp:146
llvm::coverage::mcdc::Parameters
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
Definition:MCDCTypes.h:56
llvm::coverage::CovMapVersion
CovMapVersion
Definition:CoverageMapping.h:1417
llvm::coverage::Version5
@ Version5
Definition:CoverageMapping.h:1429
llvm::coverage::Version4
@ Version4
Definition:CoverageMapping.h:1427
llvm::coverage::Version2
@ Version2
Definition:CoverageMapping.h:1422
llvm::coverage::Version7
@ Version7
Definition:CoverageMapping.h:1434
llvm::coverage::Version3
@ Version3
Definition:CoverageMapping.h:1425
llvm::coverage::CurrentVersion
@ CurrentVersion
Definition:CoverageMapping.h:1436
llvm::coverage::Version1
@ Version1
Definition:CoverageMapping.h:1418
llvm::coverage::Version6
@ Version6
Definition:CoverageMapping.h:1432
llvm::coverage::coveragemap_error::success
@ success
llvm::coverage::coveragemap_error::unsupported_version
@ unsupported_version
llvm::coverage::coveragemap_error::eof
@ eof
llvm::coverage::coveragemap_error::decompression_failed
@ decompression_failed
llvm::coverage::coveragemap_error::malformed
@ malformed
llvm::coverage::coveragemap_error::invalid_or_missing_arch_specifier
@ invalid_or_missing_arch_specifier
llvm::coverage::coveragemap_error::truncated
@ truncated
llvm::coverage::coveragemap_error::no_data_found
@ no_data_found
llvm::coverage::TestingFormatVersion::Version2
@ Version2
llvm::coverage::TestingFormatVersion::Version1
@ Version1
llvm::coverage::TestingFormatMagic
constexpr uint64_t TestingFormatMagic
Definition:CoverageMapping.h:1440
llvm::object::Kind
Kind
Definition:COFFModuleDefinition.cpp:31
llvm::object::getBuildID
BuildIDRef getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
Definition:BuildID.cpp:56
llvm::object::createBinary
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
llvm::sys::path::remove_dots
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
Definition:Path.cpp:715
llvm::sys::path::is_absolute
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition:Path.cpp:671
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition:Path.cpp:456
llvm::wasm::NameType::DATA_SEGMENT
@ DATA_SEGMENT
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::Length
@ Length
Definition:DWP.cpp:480
llvm::handleAllErrors
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
llvm::decodeULEB128
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
llvm::SubDirectoryType::Bin
@ Bin
llvm::offsetToAlignedAddr
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
Definition:Alignment.h:203
llvm::getInstrProfSectionName
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
llvm::get
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
Definition:PointerIntPair.h:270
llvm::InstrProfSectKind
InstrProfSectKind
Definition:InstrProf.h:60
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::CaptureComponents::Address
@ Address
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::HighlightColor::Tag
@ Tag
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition:Error.cpp:111
llvm::endianness
endianness
Definition:bit.h:70
llvm::endianness::little
@ little
llvm::endianness::big
@ big
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition:Error.h:1069
llvm::Version
@ Version
Definition:PGOCtxProfWriter.h:22
llvm::isAddrAligned
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition:Alignment.h:150
llvm::alignAddr
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
Definition:Alignment.h:187
raw_ostream.h
N
#define N
NC
#define NC
Definition:regutils.h:42
FilenameRange
A range of filename indices.
Definition:CoverageMappingReader.cpp:541
FilenameRange::StartingIndex
unsigned StartingIndex
Definition:CoverageMappingReader.cpp:542
FilenameRange::Length
unsigned Length
Definition:CoverageMappingReader.cpp:543
FilenameRange::FilenameRange
FilenameRange(unsigned StartingIndex, unsigned Length)
Definition:CoverageMappingReader.cpp:545
FilenameRange::markInvalid
void markInvalid()
Definition:CoverageMappingReader.cpp:548
FilenameRange::isInvalid
bool isInvalid() const
Definition:CoverageMappingReader.cpp:549
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition:Alignment.h:39
llvm::coverage::BinaryCoverageReader::ProfileMappingRecord
Definition:CoverageMappingReader.h:166
llvm::coverage::BinaryCoverageReader::ProfileMappingRecord::CoverageMapping
StringRef CoverageMapping
Definition:CoverageMappingReader.h:170
llvm::coverage::BinaryCoverageReader::ProfileMappingRecord::FilenamesBegin
size_t FilenamesBegin
Definition:CoverageMappingReader.h:171
llvm::coverage::BinaryCoverageReader::ProfileMappingRecord::FilenamesSize
size_t FilenamesSize
Definition:CoverageMappingReader.h:172
llvm::coverage::BinaryCoverageReader::ProfileMappingRecord::FunctionHash
uint64_t FunctionHash
Definition:CoverageMappingReader.h:169
llvm::coverage::CounterExpression
A Counter expression is a value that represents an arithmetic operation with two counters.
Definition:CoverageMapping.h:164
llvm::coverage::CounterExpression::ExprKind
ExprKind
Definition:CoverageMapping.h:165
llvm::coverage::CounterExpression::Add
@ Add
Definition:CoverageMapping.h:165
llvm::coverage::CounterExpression::Subtract
@ Subtract
Definition:CoverageMapping.h:165
llvm::coverage::CounterMappingRegion
A Counter mapping region associates a source range with a specific counter.
Definition:CoverageMapping.h:231
llvm::coverage::CounterMappingRegion::RegionKind
RegionKind
Definition:CoverageMapping.h:232
llvm::coverage::CounterMappingRegion::ExpansionRegion
@ ExpansionRegion
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
Definition:CoverageMapping.h:239
llvm::coverage::CounterMappingRegion::MCDCDecisionRegion
@ MCDCDecisionRegion
A DecisionRegion represents a top-level boolean expression and is associated with a variable length b...
Definition:CoverageMapping.h:256
llvm::coverage::CounterMappingRegion::MCDCBranchRegion
@ MCDCBranchRegion
A Branch Region can be extended to include IDs to facilitate MC/DC.
Definition:CoverageMapping.h:259
llvm::coverage::CounterMappingRegion::SkippedRegion
@ SkippedRegion
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
Definition:CoverageMapping.h:243
llvm::coverage::CounterMappingRegion::GapRegion
@ GapRegion
A GapRegion is like a CodeRegion, but its count is only set as the line execution count when its the ...
Definition:CoverageMapping.h:247
llvm::coverage::CounterMappingRegion::BranchRegion
@ BranchRegion
A BranchRegion represents leaf-level boolean expressions and is associated with two counters,...
Definition:CoverageMapping.h:252
llvm::coverage::CounterMappingRegion::CodeRegion
@ CodeRegion
A CodeRegion associates some code with a counter.
Definition:CoverageMapping.h:234
llvm::coverage::Counter
A Counter is an abstract value that describes how to compute the execution count for a region of code...
Definition:CoverageMapping.h:107
llvm::coverage::Counter::EncodingTagBits
static const unsigned EncodingTagBits
Definition:CoverageMapping.h:111
llvm::coverage::Counter::getZero
static Counter getZero()
Return the counter that represents the number zero.
Definition:CoverageMapping.h:148
llvm::coverage::Counter::getCounter
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
Definition:CoverageMapping.h:151
llvm::coverage::Counter::Expression
@ Expression
Definition:CoverageMapping.h:110
llvm::coverage::Counter::CounterValueReference
@ CounterValueReference
Definition:CoverageMapping.h:110
llvm::coverage::Counter::Zero
@ Zero
Definition:CoverageMapping.h:110
llvm::coverage::Counter::EncodingCounterTagAndExpansionRegionTagBits
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
Definition:CoverageMapping.h:113
llvm::coverage::Counter::EncodingTagMask
static const unsigned EncodingTagMask
Definition:CoverageMapping.h:112
llvm::coverage::Counter::getExpression
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
Definition:CoverageMapping.h:157
llvm::coverage::CovMapFunctionRecordV3
Definition:CoverageMapping.h:1339
llvm::coverage::CovMapHeader
Definition:CoverageMapping.h:1395
llvm::coverage::CoverageMappingRecord
Coverage mapping information for a single function.
Definition:CoverageMappingReader.h:35
llvm::coverage::mcdc::BranchParameters
Definition:MCDCTypes.h:41
llvm::coverage::mcdc::DecisionParameters
Definition:MCDCTypes.h:27

Generated on Fri Jul 18 2025 11:47:21 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp