42using namespace coverage;
43using namespace object;
45#define DEBUG_TYPE "coverage-mapping"
47STATISTIC(CovMapNumRecords,
"The # of coverage function records");
48STATISTIC(CovMapNumUsedRecords,
"The # of used coverage function records");
50void CoverageMappingIterator::increment() {
79 if (Result >= MaxPlus1)
103 if (
auto Err =
readSize(NumFilenames))
109 return readUncompressed(Version, NumFilenames);
118 if (
auto Err =
readSize(CompressedLen))
121 if (CompressedLen > 0) {
123 return make_error<CoverageMapError>(
133 arrayRefFromStringRef(CompressedFilenames), StorageBuf,
137 return make_error<CoverageMapError>(
143 return Delegate.readUncompressed(Version, NumFilenames);
146 return readUncompressed(Version, NumFilenames);
153 for (
size_t I = 0;
I < NumFilenames; ++
I) {
157 Filenames.push_back(Filename.str());
163 Filenames.push_back(CWD.
str());
165 for (
size_t I = 1;
I < NumFilenames; ++
I) {
170 Filenames.push_back(Filename.str());
173 if (!CompilationDir.
empty())
174 P.assign(CompilationDir);
179 Filenames.push_back(
static_cast<std::string
>(
P.str()));
203 if (
ID >= Expressions.size())
218 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
220 if (
auto Err = decodeCounter(EncodedCounter,
C))
231Error RawCoverageMappingReader::readMappingRegionsSubArray(
232 std::vector<CounterMappingRegion> &MappingRegions,
unsigned InferredFileID,
235 if (
auto Err =
readSize(NumRegions))
237 unsigned LineStart = 0;
238 for (
size_t I = 0;
I < NumRegions; ++
I) {
244 if (
auto Err =
readIntMax(EncodedCounterAndRegion,
245 std::numeric_limits<unsigned>::max()))
262 if (
auto Err = decodeCounter(EncodedCounterAndRegion,
C))
268 ExpandedFileID = EncodedCounterAndRegion >>
270 if (ExpandedFileID >= NumFileIDs)
273 switch (EncodedCounterAndRegion >>
284 if (
auto Err = readCounter(
C))
286 if (
auto Err = readCounter(C2))
296 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
298 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
302 if (ColumnStart > std::numeric_limits<unsigned>::max())
304 if (
auto Err =
readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
306 if (
auto Err =
readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
308 LineStart += LineStartDelta;
311 if (ColumnEnd & (1U << 31)) {
313 ColumnEnd &= ~(1U << 31);
324 if (ColumnStart == 0 && ColumnEnd == 0) {
326 ColumnEnd = std::numeric_limits<unsigned>::max();
330 dbgs() <<
"Counter in file " << InferredFileID <<
" " << LineStart <<
":"
331 << ColumnStart <<
" -> " << (LineStart + NumLines) <<
":"
332 << ColumnEnd <<
", ";
334 dbgs() <<
"Expands to file " << ExpandedFileID;
341 LineStart, ColumnStart,
342 LineStart + NumLines, ColumnEnd,
Kind);
343 if (CMR.startLoc() > CMR.endLoc())
345 MappingRegions.push_back(CMR);
354 if (
auto Err =
readSize(NumFileMappings))
356 for (
size_t I = 0;
I < NumFileMappings; ++
I) {
358 if (
auto Err =
readIntMax(FilenameIndex, TranslationUnitFilenames.
size()))
360 VirtualFileMapping.
push_back(FilenameIndex);
364 for (
auto I : VirtualFileMapping) {
365 Filenames.push_back(TranslationUnitFilenames[
I]);
370 if (
auto Err =
readSize(NumExpressions))
378 for (
size_t I = 0;
I < NumExpressions; ++
I) {
379 if (
auto Err = readCounter(Expressions[
I].
LHS))
381 if (
auto Err = readCounter(Expressions[
I].
RHS))
386 for (
unsigned InferredFileID = 0, S = VirtualFileMapping.
size();
387 InferredFileID < S; ++InferredFileID) {
388 if (
auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
389 VirtualFileMapping.
size()))
399 FileIDExpansionRegionMapping.
resize(VirtualFileMapping.
size(),
nullptr);
401 for (
auto &R : MappingRegions) {
404 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
405 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
407 for (
auto &R : MappingRegions) {
408 if (FileIDExpansionRegionMapping[R.FileID]) {
409 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
410 FileIDExpansionRegionMapping[R.FileID] =
nullptr;
422 return std::move(Err);
423 if (NumFileMappings != 1)
428 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
429 return std::move(Err);
432 return std::move(Err);
433 if (NumExpressions != 0)
437 return std::move(Err);
442 std::numeric_limits<unsigned>::max()))
443 return std::move(Err);
453 Address = Section.getAddress();
497struct CovMapFuncRecordReader {
498 virtual ~CovMapFuncRecordReader() =
default;
508 const char *CovBufEnd) = 0;
521 readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
522 std::optional<FilenameRange> OutOfLineFileRange,
523 const char *OutOfLineMappingBuf,
524 const char *OutOfLineMappingBufEnd) = 0;
526 template <
class IntPtrT, support::endianness Endian>
529 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
530 std::vector<std::string> &
F);
534template <CovMapVersion Version,
class IntPtrT, support::endianness Endian>
535class VersionedCovMapFuncRecordReader :
public CovMapFuncRecordReader {
536 using FuncRecordType =
545 std::vector<std::string> &Filenames;
546 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
558 Error insertFunctionRecordIfNeeded(
const FuncRecordType *CFR,
562 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
563 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
565 FunctionRecords.
insert(std::make_pair(NameRef, Records.size()));
566 if (InsertResult.second) {
568 if (
Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
570 if (FuncName.
empty())
571 return make_error<InstrProfError>(instrprof_error::malformed,
572 "function name is empty");
573 ++CovMapNumUsedRecords;
574 Records.emplace_back(Version, FuncName, FuncHash, Mapping,
579 size_t OldRecordIndex = InsertResult.first->second;
581 Records[OldRecordIndex];
586 if (!*OldIsDummyExpected)
592 if (*NewIsDummyExpected)
594 ++CovMapNumUsedRecords;
603 VersionedCovMapFuncRecordReader(
605 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
606 std::vector<std::string> &
F)
607 : ProfileNames(
P), CompilationDir(
D), Filenames(
F), Records(
R) {}
609 ~VersionedCovMapFuncRecordReader()
override =
default;
612 const char *CovBufEnd)
override {
613 using namespace support;
616 return make_error<CoverageMapError>(coveragemap_error::malformed);
617 auto CovHeader =
reinterpret_cast<const CovMapHeader *
>(CovBuf);
622 CovBuf =
reinterpret_cast<const char *
>(CovHeader + 1);
627 const char *FuncRecBuf =
nullptr;
628 const char *FuncRecBufEnd =
nullptr;
629 if (Version < CovMapVersion::Version4)
631 CovBuf += NRecords *
sizeof(FuncRecordType);
632 if (Version < CovMapVersion::Version4)
633 FuncRecBufEnd = CovBuf;
636 if (CovBuf + FilenamesSize > CovBufEnd)
637 return make_error<CoverageMapError>(coveragemap_error::malformed);
638 size_t FilenamesBegin = Filenames.size();
639 StringRef FilenameRegion(CovBuf, FilenamesSize);
642 if (
auto Err = Reader.read(Version))
643 return std::move(Err);
644 CovBuf += FilenamesSize;
645 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
647 if (Version >= CovMapVersion::Version4) {
650 int64_t FilenamesRef =
653 FileRangeMap.
insert(std::make_pair(FilenamesRef, FileRange));
657 auto It = Filenames.begin();
664 FileRange = OrigRange;
674 const char *MappingBuf = CovBuf;
675 if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
676 return make_error<CoverageMapError>(coveragemap_error::malformed);
677 CovBuf += CoverageSize;
678 const char *MappingEnd = CovBuf;
680 if (CovBuf > CovBufEnd)
681 return make_error<CoverageMapError>(coveragemap_error::malformed);
683 if (Version < CovMapVersion::Version4) {
685 if (
Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
686 MappingBuf, MappingEnd))
697 Error readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
698 std::optional<FilenameRange> OutOfLineFileRange,
699 const char *OutOfLineMappingBuf,
700 const char *OutOfLineMappingBufEnd)
override {
701 auto CFR =
reinterpret_cast<const FuncRecordType *
>(FuncRecBuf);
702 while ((
const char *)CFR < FuncRecBufEnd) {
704 const char *NextMappingBuf;
705 const FuncRecordType *NextCFR;
706 std::tie(NextMappingBuf, NextCFR) =
707 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
708 if (Version < CovMapVersion::Version4)
709 if (NextMappingBuf > OutOfLineMappingBufEnd)
710 return make_error<CoverageMapError>(coveragemap_error::malformed);
713 std::optional<FilenameRange> FileRange;
714 if (Version < CovMapVersion::Version4) {
715 FileRange = OutOfLineFileRange;
717 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
718 auto It = FileRangeMap.
find(FilenamesRef);
719 if (It == FileRangeMap.
end())
720 return make_error<CoverageMapError>(coveragemap_error::malformed);
722 FileRange = It->getSecond();
726 if (FileRange && !FileRange->isInvalid()) {
728 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
729 if (Version >= CovMapVersion::Version4 &&
730 Mapping.
data() + Mapping.
size() > FuncRecBufEnd)
731 return make_error<CoverageMapError>(coveragemap_error::malformed);
732 if (
Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
736 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
744template <
class IntPtrT, support::endianness Endian>
747 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
748 std::vector<std::string> &
F) {
749 using namespace coverage;
753 return std::make_unique<VersionedCovMapFuncRecordReader<
761 if (
Error E =
P.create(
P.getNameData()))
764 return std::make_unique<VersionedCovMapFuncRecordReader<
767 return std::make_unique<VersionedCovMapFuncRecordReader<
770 return std::make_unique<VersionedCovMapFuncRecordReader<
773 return std::make_unique<VersionedCovMapFuncRecordReader<
776 return std::make_unique<VersionedCovMapFuncRecordReader<
782template <
typename T, support::endianness Endian>
785 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
786 StringRef CompilationDir, std::vector<std::string> &Filenames) {
787 using namespace coverage;
796 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
797 CompilationDir, Filenames);
800 auto Reader = std::move(ReaderExpected.
get());
801 const char *CovBuf = CovMap.
data();
802 const char *CovBufEnd = CovBuf + CovMap.
size();
803 const char *FuncRecBuf = FuncRecords.
data();
804 const char *FuncRecBufEnd = FuncRecords.
data() + FuncRecords.
size();
805 while (CovBuf < CovBufEnd) {
812 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
813 if (
auto E = NextOrErr.takeError())
815 CovBuf = NextOrErr.get();
820 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
832 std::unique_ptr<BinaryCoverageReader> Reader(
834 Reader->ProfileNames = std::move(ProfileNames);
835 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
836 if (BytesInAddress == 4 &&
Endian == support::endianness::little) {
838 readCoverageMappingData<uint32_t, support::endianness::little>(
839 Reader->ProfileNames, Coverage, FuncRecordsRef,
840 Reader->MappingRecords, CompilationDir, Reader->Filenames))
842 }
else if (BytesInAddress == 4 &&
Endian == support::endianness::big) {
843 if (
Error E = readCoverageMappingData<uint32_t, support::endianness::big>(
844 Reader->ProfileNames, Coverage, FuncRecordsRef,
845 Reader->MappingRecords, CompilationDir, Reader->Filenames))
847 }
else if (BytesInAddress == 8 &&
Endian == support::endianness::little) {
849 readCoverageMappingData<uint64_t, support::endianness::little>(
850 Reader->ProfileNames, Coverage, FuncRecordsRef,
851 Reader->MappingRecords, CompilationDir, Reader->Filenames))
853 }
else if (BytesInAddress == 8 &&
Endian == support::endianness::big) {
854 if (
Error E = readCoverageMappingData<uint64_t, support::endianness::big>(
855 Reader->ProfileNames, Coverage, FuncRecordsRef,
856 Reader->MappingRecords, CompilationDir, Reader->Filenames))
860 return std::move(Reader);
865 uint8_t BytesInAddress = 8;
883 if (
Data.size() < ProfileNamesSize)
888 Data =
Data.substr(ProfileNamesSize);
891 if (
Data.size() < Pad)
896 auto const *CovHeader =
reinterpret_cast<const CovMapHeader *
>(
899 (
CovMapVersion)CovHeader->getVersion<support::endianness::little>();
909 CovHeader->getFilenamesSize<support::endianness::little>();
914 Data =
Data.substr(CoverageMappingSize);
918 if (
Data.size() < Pad)
921 if (CoverageRecords->getBufferSize() == 0)
926 BytesInAddress,
Endian, CompilationDir);
936 bool IsCOFF = isa<COFFObjectFile>(OF);
938 return IsCOFF ?
N.split(
'$').first :
N;
942 std::vector<SectionRef> Sections;
943 for (
const auto &Section : OF.
sections()) {
947 if (stripSuffix(*NameOrErr) ==
Name)
948 Sections.push_back(Section);
950 if (Sections.empty())
959 std::unique_ptr<ObjectFile> OF;
960 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
963 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
964 if (!ObjectFileOrErr)
965 return ObjectFileOrErr.takeError();
966 OF = std::move(ObjectFileOrErr.get());
967 }
else if (isa<ObjectFile>(
Bin.get())) {
969 OF.reset(cast<ObjectFile>(
Bin.release()));
971 if (!Arch.
empty() && OF->getArch() !=
Triple(Arch).getArch())
978 uint8_t BytesInAddress = OF->getBytesInAddress();
980 ? support::endianness::little
981 : support::endianness::big;
984 auto ObjFormat = OF->getTripleObjectFormat();
988 if (
auto E = NamesSection.takeError())
990 auto CoverageSection =
993 if (
auto E = CoverageSection.takeError())
995 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
996 if (CoverageSectionRefs.size() != 1)
998 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
999 if (!CoverageMappingOrErr)
1000 return CoverageMappingOrErr.takeError();
1004 std::vector<SectionRef> NamesSectionRefs = *NamesSection;
1005 if (NamesSectionRefs.size() != 1)
1007 if (
Error E = ProfileNames.
create(NamesSectionRefs.back()))
1008 return std::move(
E);
1011 auto CoverageRecordsSections =
1016 if (
auto E = CoverageRecordsSections.takeError()) {
1024 const Align RecordAlignment(8);
1026 for (
SectionRef Section : *CoverageRecordsSections) {
1027 auto CoverageRecordsOrErr = Section.getContents();
1028 if (!CoverageRecordsOrErr)
1029 return CoverageRecordsOrErr.takeError();
1030 FuncRecordsSize +=
alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1032 auto WritableBuffer =
1034 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1036 "Allocated memory is correctly aligned");
1038 for (
SectionRef Section : *CoverageRecordsSections) {
1039 auto CoverageRecordsOrErr = Section.getContents();
1040 if (!CoverageRecordsOrErr)
1041 return CoverageRecordsOrErr.takeError();
1042 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1043 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1044 CoverageRecords.end(), FuncRecordsBuffer);
1046 std::fill_n(FuncRecordsBuffer,
1047 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1048 (uintptr_t)FuncRecordsBuffer,
1051 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1053 FuncRecords = std::move(WritableBuffer);
1061 BytesInAddress,
Endian, CompilationDir);
1068 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin)) {
1069 for (
auto &ObjForArch : Universal->objects())
1070 if (Arch == ObjForArch.getArchFlagName())
1082 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1089 return ReaderOrErr.takeError();
1090 Readers.push_back(std::move(ReaderOrErr.get()));
1091 return std::move(Readers);
1096 return BinOrErr.takeError();
1097 std::unique_ptr<Binary>
Bin = std::move(BinOrErr.get());
1100 return make_error<CoverageMapError>(
1105 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
1106 for (
auto &ObjForArch : Universal->objects()) {
1108 std::string ObjArch = ObjForArch.getArchFlagName();
1109 if (Arch != ObjArch)
1112 auto ArchiveOrErr = ObjForArch.getAsArchive();
1113 if (!ArchiveOrErr) {
1120 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1121 CompilationDir, BinaryIDs);
1126 if (
auto *Ar = dyn_cast<Archive>(
Bin.get())) {
1128 for (
auto &Child : Ar->children(Err)) {
1134 ChildBufOrErr.
get(), Arch, ObjectFileBuffers, CompilationDir,
1136 if (!ChildReadersOrErr)
1137 return ChildReadersOrErr.takeError();
1138 for (
auto &Reader : ChildReadersOrErr.get())
1139 Readers.push_back(std::move(Reader));
1142 return std::move(Err);
1148 for (
auto &Buffer : Ar->takeThinBuffers())
1149 ObjectFileBuffers.push_back(std::move(Buffer));
1151 return std::move(Readers);
1156 BinaryIDs ? &BinaryID :
nullptr);
1158 return ReaderOrErr.takeError();
1159 Readers.push_back(std::move(ReaderOrErr.get()));
1160 if (!BinaryID.
empty())
1162 return std::move(Readers);
1166 if (CurrentRecord >= MappingRecords.size())
1169 FunctionsFilenames.clear();
1170 Expressions.clear();
1171 MappingRegions.clear();
1172 auto &R = MappingRecords[CurrentRecord];
1173 auto F =
ArrayRef(Filenames).
slice(R.FilenamesBegin, R.FilenamesSize);
1175 Expressions, MappingRegions);
1176 if (
auto Err = Reader.
read())
1179 Record.FunctionName = R.FunctionName;
1180 Record.FunctionHash = R.FunctionHash;
1181 Record.Filenames = FunctionsFilenames;
1182 Record.Expressions = Expressions;
1183 Record.MappingRegions = MappingRegions;
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error readCoverageMappingData(InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, std::vector< BinaryCoverageReader::ProfileMappingRecord > &Records, StringRef CompilationDir, std::vector< std::string > &Filenames)
static Expected< std::unique_ptr< BinaryCoverageReader > > loadBinaryFormat(std::unique_ptr< Binary > Bin, StringRef Arch, StringRef CompilationDir="", object::BuildIDRef *BinaryID=nullptr)
static Expected< std::unique_ptr< BinaryCoverageReader > > loadTestingFormat(StringRef Data, StringRef CompilationDir)
static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch)
Determine whether Arch is invalid or empty, given Bin.
static const char * TestingFormatMagic
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
static const unsigned EncodingExpansionRegionBit
static Expected< std::vector< SectionRef > > lookupSections(ObjectFile &OF, StringRef Name)
Find all sections that match Name.
This file defines the DenseMap class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
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.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
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.
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Pass interface - Implemented by all 'passes'.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
const unsigned char * bytes_begin() const
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Triple - Helper class for working with autoconf configuration names.
LLVM Value Representation.
static std::unique_ptr< WritableMemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="", std::optional< Align > Alignment=std::nullopt)
Allocate a new MemoryBuffer of the specified size that is not initialized.
Reader for the coverage mapping data that is emitted by the frontend and stored in an object file.
static Expected< std::vector< std::unique_ptr< BinaryCoverageReader > > > create(MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl< std::unique_ptr< MemoryBuffer > > &ObjectFileBuffers, StringRef CompilationDir="", SmallVectorImpl< object::BuildIDRef > *BinaryIDs=nullptr)
static Expected< std::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, FuncRecordsStorage &&FuncRecords, InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress, support::endianness Endian, StringRef CompilationDir="")
std::unique_ptr< MemoryBuffer > FuncRecordsStorage
Error readNextRecord(CoverageMappingRecord &Record) override
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
void dump(const Counter &C, raw_ostream &OS) const
coveragemap_error get() const
A file format agnostic iterator over coverage mapping data.
virtual Error readNextRecord(CoverageMappingRecord &Record)=0
The mapping of profile information to coverage data.
Reader for the raw coverage filenames.
Error read(CovMapVersion Version)
Checks if the given coverage mapping data is exported for an unused function.
Expected< bool > isDummy()
Reader for the raw coverage mapping data.
Error readSize(uint64_t &Result)
Error readIntMax(uint64_t &Result, uint64_t MaxPlus1)
Error readULEB128(uint64_t &Result)
Error readString(StringRef &Result)
This class is the base class for all object file types.
section_iterator_range sections() const
virtual bool isRelocatableObject() const =0
True if this is a relocatable object (.o/.obj).
Represents a GOFF physical record.
This is a value type class that represents a single section in the list of sections in the object fil...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
uint64_t ComputeHash(StringRef K)
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
@ invalid_or_missing_arch_specifier
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
BuildIDRef getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
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.
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
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.
StringRef CoverageMapping
A Counter expression is a value that represents an arithmetic operation with two counters.
A Counter mapping region associates a source range with a specific counter.
@ ExpansionRegion
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
@ SkippedRegion
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
@ GapRegion
A GapRegion is like a CodeRegion, but its count is only set as the line execution count when its the ...
@ BranchRegion
A BranchRegion represents leaf-level boolean expressions and is associated with two counters,...
@ CodeRegion
A CodeRegion associates some code with a counter.
A Counter is an abstract value that describes how to compute the execution count for a region of code...
static const unsigned EncodingTagBits
static Counter getZero()
Return the counter that represents the number zero.
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
static const unsigned EncodingTagMask
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
Coverage mapping information for a single function.