45#define DEBUG_TYPE "coverage-mapping"
47STATISTIC(CovMapNumRecords,
"The # of coverage function records");
48STATISTIC(CovMapNumUsedRecords,
"The # of used coverage function records");
50void CoverageMappingIterator::increment() {
72 "the size of ULEB128 is too big");
80 if (Result >= MaxPlus1)
83 "the value of ULEB128 is greater than or equal to MaxPlus1");
90 if (Result >
Data.size())
92 "the value of ULEB128 is too big");
107 if (
auto Err =
readSize(NumFilenames))
111 "number of filenames is zero");
114 return readUncompressed(
Version, NumFilenames);
123 if (
auto Err =
readSize(CompressedLen))
126 if (CompressedLen > 0) {
135 StringRef CompressedFilenames =
Data.substr(0, CompressedLen);
148 return Delegate.readUncompressed(
Version, NumFilenames);
151 return readUncompressed(
Version, NumFilenames);
158 for (
size_t I = 0;
I < NumFilenames; ++
I) {
162 Filenames.push_back(
Filename.str());
168 Filenames.push_back(CWD.
str());
170 for (
size_t I = 1;
I < NumFilenames; ++
I) {
175 Filenames.push_back(
Filename.str());
178 if (!CompilationDir.empty())
179 P.assign(CompilationDir);
184 Filenames.push_back(
static_cast<std::string
>(
P.str()));
208 if (
ID >= Expressions.size())
210 "counter expression is invalid");
217 "counter expression kind is invalid");
223 uint64_t EncodedCounter;
225 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
227 if (
auto Err = decodeCounter(EncodedCounter,
C))
238Error RawCoverageMappingReader::readMappingRegionsSubArray(
239 std::vector<CounterMappingRegion> &MappingRegions,
unsigned InferredFileID,
242 if (
auto Err =
readSize(NumRegions))
244 unsigned LineStart = 0;
245 for (
size_t I = 0;
I < NumRegions; ++
I) {
255 if (
auto Err =
readIntMax(EncodedCounterAndRegion,
256 std::numeric_limits<unsigned>::max()))
273 if (
auto Err = decodeCounter(EncodedCounterAndRegion,
C))
279 ExpandedFileID = EncodedCounterAndRegion >>
281 if (ExpandedFileID >= NumFileIDs)
283 "ExpandedFileID is invalid");
285 switch (EncodedCounterAndRegion >>
296 if (
auto Err = readCounter(
C))
298 if (
auto Err = readCounter(C2))
304 if (
auto Err = readCounter(
C))
306 if (
auto Err = readCounter(C2))
308 if (
auto Err =
readIntMax(ID1, std::numeric_limits<int16_t>::max()))
310 if (
auto Err =
readIntMax(TID1, std::numeric_limits<int16_t>::max()))
312 if (
auto Err =
readIntMax(FID1, std::numeric_limits<int16_t>::max()))
317 "MCDCConditionID shouldn't be zero");
319 static_cast<int16_t
>(
static_cast<int16_t
>(ID1) - 1),
320 {
static_cast<int16_t
>(
static_cast<int16_t
>(FID1) - 1),
321 static_cast<int16_t
>(
static_cast<int16_t
>(TID1) - 1)}};
325 if (
auto Err =
readIntMax(BIDX, std::numeric_limits<unsigned>::max()))
327 if (
auto Err =
readIntMax(
NC, std::numeric_limits<int16_t>::max()))
334 "region kind is incorrect");
340 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
342 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
346 if (ColumnStart > std::numeric_limits<unsigned>::max())
348 "start column is too big");
349 if (
auto Err =
readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
351 if (
auto Err =
readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
353 LineStart += LineStartDelta;
356 if (ColumnEnd & (1U << 31)) {
358 ColumnEnd &= ~(1U << 31);
369 if (ColumnStart == 0 && ColumnEnd == 0) {
371 ColumnEnd = std::numeric_limits<unsigned>::max();
375 dbgs() <<
"Counter in file " << InferredFileID <<
" " << LineStart <<
":"
376 << ColumnStart <<
" -> " << (LineStart + NumLines) <<
":"
377 << ColumnEnd <<
", ";
379 dbgs() <<
"Expands to file " << ExpandedFileID;
386 C, C2, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
387 LineStart + NumLines, ColumnEnd,
Kind, Params);
388 if (CMR.startLoc() > CMR.endLoc())
391 "counter mapping region locations are incorrect");
392 MappingRegions.push_back(CMR);
401 if (
auto Err =
readSize(NumFileMappings))
403 for (
size_t I = 0;
I < NumFileMappings; ++
I) {
405 if (
auto Err =
readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
407 VirtualFileMapping.
push_back(FilenameIndex);
411 for (
auto I : VirtualFileMapping) {
412 Filenames.push_back(TranslationUnitFilenames[
I]);
417 if (
auto Err =
readSize(NumExpressions))
425 for (
size_t I = 0;
I < NumExpressions; ++
I) {
426 if (
auto Err = readCounter(Expressions[
I].LHS))
428 if (
auto Err = readCounter(Expressions[
I].RHS))
433 for (
unsigned InferredFileID = 0, S = VirtualFileMapping.
size();
434 InferredFileID < S; ++InferredFileID) {
435 if (
auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
436 VirtualFileMapping.
size()))
446 FileIDExpansionRegionMapping.
resize(VirtualFileMapping.
size(),
nullptr);
448 for (
auto &R : MappingRegions) {
451 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
452 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
455 for (
auto &R : MappingRegions) {
456 auto *&Slot = FileIDExpansionRegionMapping[R.FileID];
458 if (Slot->Count != R.Count) {
459 Slot->Count = R.Count;
476 return std::move(Err);
477 if (NumFileMappings != 1)
482 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
483 return std::move(Err);
486 return std::move(Err);
487 if (NumExpressions != 0)
491 return std::move(Err);
496 std::numeric_limits<unsigned>::max()))
497 return std::move(Err);
521 Address = Section.getAddress();
524 Data = Data.substr(1);
530 if (Pointer < Address)
532 auto Offset = Pointer - Address;
535 return Data.substr(Pointer - Address,
Size);
562struct CovMapFuncRecordReader {
563 virtual ~CovMapFuncRecordReader() =
default;
572 virtual Expected<const char *> readCoverageHeader(
const char *CovBuf,
573 const char *CovBufEnd) = 0;
586 readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
587 std::optional<FilenameRange> OutOfLineFileRange,
588 const char *OutOfLineMappingBuf,
589 const char *OutOfLineMappingBufEnd) = 0;
591 template <
class IntPtrT, llvm::endianness Endian>
592 static Expected<std::unique_ptr<CovMapFuncRecordReader>>
594 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef
D,
595 std::vector<std::string> &
F);
599template <CovMapVersion Version,
class IntPtrT, llvm::endianness Endian>
600class VersionedCovMapFuncRecordReader :
public CovMapFuncRecordReader {
601 using FuncRecordType =
607 DenseMap<NameRefType, size_t> FunctionRecords;
608 InstrProfSymtab &ProfileNames;
609 StringRef CompilationDir;
610 std::vector<std::string> &Filenames;
611 std::vector<BinaryCoverageReader::ProfileMappingRecord> &
Records;
615 DenseMap<uint64_t, FilenameRange> FileRangeMap;
623 Error insertFunctionRecordIfNeeded(
const FuncRecordType *CFR,
625 FilenameRange FileRange) {
627 uint64_t
FuncHash = CFR->template getFuncHash<Endian>();
628 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
631 if (InsertResult.second) {
633 if (
Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
635 if (FuncName.
empty())
637 "function name is empty");
638 ++CovMapNumUsedRecords;
644 size_t OldRecordIndex = InsertResult.first->second;
645 BinaryCoverageReader::ProfileMappingRecord &OldRecord =
651 if (!*OldIsDummyExpected)
653 Expected<bool> NewIsDummyExpected =
657 if (*NewIsDummyExpected)
659 ++CovMapNumUsedRecords;
668 VersionedCovMapFuncRecordReader(
670 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef
D,
671 std::vector<std::string> &
F)
672 : ProfileNames(
P), CompilationDir(
D), Filenames(
F),
Records(
R) {}
674 ~VersionedCovMapFuncRecordReader()
override =
default;
676 Expected<const char *> readCoverageHeader(
const char *CovBuf,
677 const char *CovBufEnd)
override {
678 using namespace support;
680 if (CovBuf +
sizeof(CovMapHeader) > CovBufEnd)
682 coveragemap_error::malformed,
683 "coverage mapping header section is larger than buffer size");
684 auto CovHeader =
reinterpret_cast<const CovMapHeader *
>(CovBuf);
685 uint32_t
NRecords = CovHeader->getNRecords<Endian>();
686 uint32_t
FilenamesSize = CovHeader->getFilenamesSize<Endian>();
687 uint32_t
CoverageSize = CovHeader->getCoverageSize<Endian>();
689 CovBuf =
reinterpret_cast<const char *
>(CovHeader + 1);
694 const char *FuncRecBuf =
nullptr;
695 const char *FuncRecBufEnd =
nullptr;
696 if (
Version < CovMapVersion::Version4)
698 CovBuf +=
NRecords *
sizeof(FuncRecordType);
699 if (
Version < CovMapVersion::Version4)
700 FuncRecBufEnd = CovBuf;
705 coveragemap_error::malformed,
706 "filenames section is larger than buffer size");
707 size_t FilenamesBegin = Filenames.size();
709 RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
711 if (
auto Err = Reader.read(
Version))
712 return std::move(Err);
714 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
716 if (
Version >= CovMapVersion::Version4) {
719 int64_t FilenamesRef =
722 FileRangeMap.
insert(std::make_pair(FilenamesRef, FileRange));
726 auto It = Filenames.begin();
727 FilenameRange &OrigRange =
Insert.first->getSecond();
733 FileRange = OrigRange;
743 const char *MappingBuf = CovBuf;
746 "coverage mapping size is not zero");
748 const char *MappingEnd = CovBuf;
750 if (CovBuf > CovBufEnd)
752 coveragemap_error::malformed,
753 "function records section is larger than buffer size");
755 if (
Version < CovMapVersion::Version4) {
757 if (
Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
758 MappingBuf, MappingEnd))
769 Error readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
770 std::optional<FilenameRange> OutOfLineFileRange,
771 const char *OutOfLineMappingBuf,
772 const char *OutOfLineMappingBufEnd)
override {
773 auto CFR =
reinterpret_cast<const FuncRecordType *
>(FuncRecBuf);
774 while ((
const char *)CFR < FuncRecBufEnd) {
776 const char *NextMappingBuf;
777 const FuncRecordType *NextCFR;
778 std::tie(NextMappingBuf, NextCFR) =
779 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
780 if (
Version < CovMapVersion::Version4)
781 if (NextMappingBuf > OutOfLineMappingBufEnd)
783 coveragemap_error::malformed,
784 "next mapping buffer is larger than buffer size");
787 std::optional<FilenameRange> FileRange;
788 if (
Version < CovMapVersion::Version4) {
789 FileRange = OutOfLineFileRange;
791 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
792 auto It = FileRangeMap.
find(FilenamesRef);
793 if (It == FileRangeMap.
end())
795 coveragemap_error::malformed,
796 "no filename found for function with hash=0x" +
799 FileRange = It->getSecond();
803 if (FileRange && !FileRange->isInvalid()) {
805 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
806 if (
Version >= CovMapVersion::Version4 &&
807 Mapping.
data() + Mapping.
size() > FuncRecBufEnd)
809 coveragemap_error::malformed,
810 "coverage mapping data is larger than buffer size");
811 if (
Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
815 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
823template <
class IntPtrT, llvm::endianness Endian>
824Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
826 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef
D,
827 std::vector<std::string> &
F) {
828 using namespace coverage;
832 return std::make_unique<VersionedCovMapFuncRecordReader<
841 if (
Error E =
P.create(
P.getNameData()))
844 return std::make_unique<VersionedCovMapFuncRecordReader<
847 return std::make_unique<VersionedCovMapFuncRecordReader<
850 return std::make_unique<VersionedCovMapFuncRecordReader<
853 return std::make_unique<VersionedCovMapFuncRecordReader<
856 return std::make_unique<VersionedCovMapFuncRecordReader<
859 return std::make_unique<VersionedCovMapFuncRecordReader<
865template <
typename T, llvm::endianness Endian>
868 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
869 StringRef CompilationDir, std::vector<std::string> &Filenames) {
879 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
880 CompilationDir, Filenames);
883 auto Reader = std::move(ReaderExpected.
get());
884 const char *CovBuf = CovMap.
data();
885 const char *CovBufEnd = CovBuf + CovMap.
size();
886 const char *FuncRecBuf = FuncRecords.
data();
887 const char *FuncRecBufEnd = FuncRecords.
data() + FuncRecords.
size();
888 while (CovBuf < CovBufEnd) {
895 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
896 if (
auto E = NextOrErr.takeError())
898 CovBuf = NextOrErr.get();
903 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
908Expected<std::unique_ptr<BinaryCoverageReader>>
912 std::unique_ptr<InstrProfSymtab> ProfileNamesPtr,
uint8_t BytesInAddress,
914 if (ProfileNamesPtr ==
nullptr)
916 "Caller must provide ProfileNames");
917 std::unique_ptr<BinaryCoverageReader> Reader(
918 new BinaryCoverageReader(std::move(ProfileNamesPtr),
919 std::move(FuncRecords), std::move(CoverageMap)));
921 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
924 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
925 CompilationDir, Reader->Filenames))
929 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
930 CompilationDir, Reader->Filenames))
934 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
935 CompilationDir, Reader->Filenames))
939 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
940 CompilationDir, Reader->Filenames))
945 "not supported endianness or bytes in address");
946 return std::move(Reader);
958 "the size of data is too small");
972 "the size of TestingFormatMagic is too big");
980 "the size of ULEB128 is too big");
982 if (
Data.size() < ProfileNamesSize)
984 "the size of ProfileNames is too big");
985 auto ProfileNames = std::make_unique<InstrProfSymtab>();
986 if (
Error E = ProfileNames->
create(
Data.substr(0, ProfileNamesSize), Address))
988 Data =
Data.substr(ProfileNamesSize);
997 "the size of ULEB128 is too big");
1002 "the size of CoverageMapping is teoo small");
1009 if (
Data.size() < Pad)
1011 "insufficient padding");
1016 "coverage mapping header section is larger than data size");
1017 auto const *CovHeader =
reinterpret_cast<const CovMapHeader *
>(
1025 CoverageMappingSize =
Data.size();
1034 Data =
Data.substr(CoverageMappingSize);
1040 "data is not empty");
1045 if (
Data.size() < Pad)
1047 "insufficient padding");
1055 std::move(ProfileNames), BytesInAddress, Endian, CompilationDir);
1060static Expected<std::vector<SectionRef>>
1062 auto ObjFormat = OF.getTripleObjectFormat();
1070 return IsCOFF ?
N.split(
'$').first :
N;
1072 Name = stripSuffix(Name);
1074 std::vector<SectionRef> Sections;
1075 for (
const auto &Section : OF.sections()) {
1079 if (stripSuffix(*NameOrErr) == Name) {
1083 if (IPSK == IPSK_name &&
1084 (Section.getSize() == 0 || (IsCOFF && Section.getSize() == 2)))
1086 Sections.push_back(Section);
1089 if (Sections.empty())
1097static Expected<std::pair<StringRef, uint64_t>>
1101 std::vector<const WasmSegment *> Segments;
1102 auto ObjFormat = OF.getTripleObjectFormat();
1105 for (
const auto &DebugName : WOF->debugNames()) {
1107 DebugName.Name != Name)
1109 if (DebugName.Index >= WOF->dataSegments().size())
1111 auto &Segment = WOF->dataSegments()[DebugName.Index];
1112 Segments.push_back(&Segment);
1114 if (Segments.empty())
1116 if (Segments.size() != 1)
1119 const auto &Segment = *Segments.front();
1120 auto &
Data = Segment.Data;
1121 StringRef Content(
reinterpret_cast<const char *
>(
Data.Content.data()),
1122 Data.Content.size());
1123 return std::make_pair(Content, Segment.SectionOffset);
1129 return Sections.takeError();
1130 if (Sections->size() != 1)
1133 "the size of coverage mapping section is not one");
1134 auto &Section = Sections->front();
1135 auto ContentsOrErr = Section.getContents();
1137 return ContentsOrErr.takeError();
1138 auto Content = *ContentsOrErr;
1140 Content = Content.drop_front(1);
1141 return std::make_pair(Content, Section.getAddress());
1144static Expected<std::unique_ptr<BinaryCoverageReader>>
1148 std::unique_ptr<ObjectFile> OF;
1152 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1153 if (!ObjectFileOrErr)
1154 return ObjectFileOrErr.takeError();
1155 OF = std::move(ObjectFileOrErr.get());
1160 if (!Arch.
empty() && OF->getArch() !=
Triple(Arch).getArch())
1165 "binary is not an object file");
1168 uint8_t BytesInAddress = OF->getBytesInAddress();
1173 auto ProfileNames = std::make_unique<InstrProfSymtab>();
1177 if (
auto E = NamesSection.takeError()) {
1180 if (
auto E = NamesSection.takeError())
1181 return std::move(
E);
1186 std::tie(NamesContent, NamesAddress) = *NamesSection;
1187 if (
Error E = ProfileNames->
create(NamesContent, NamesAddress))
1188 return std::move(
E);
1191 if (
auto E = CoverageSection.takeError())
1192 return std::move(
E);
1193 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1194 if (CoverageSectionRefs.size() != 1)
1196 "the size of name section is not one");
1197 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1198 if (!CoverageMappingOrErr)
1199 return CoverageMappingOrErr.takeError();
1205 std::unique_ptr<MemoryBuffer> CoverageMapCopy;
1215 if (
auto E = CoverageRecordsSections.takeError()) {
1223 const Align RecordAlignment(8);
1225 for (
SectionRef Section : *CoverageRecordsSections) {
1226 auto CoverageRecordsOrErr = Section.getContents();
1227 if (!CoverageRecordsOrErr)
1228 return CoverageRecordsOrErr.takeError();
1229 FuncRecordsSize +=
alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1231 auto WritableBuffer =
1233 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1235 "Allocated memory is correctly aligned");
1237 for (
SectionRef Section : *CoverageRecordsSections) {
1238 auto CoverageRecordsOrErr = Section.getContents();
1239 if (!CoverageRecordsOrErr)
1240 return CoverageRecordsOrErr.takeError();
1241 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1242 FuncRecordsBuffer =
llvm::copy(CoverageRecords, FuncRecordsBuffer);
1244 std::fill_n(FuncRecordsBuffer,
1245 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1246 (uintptr_t)FuncRecordsBuffer,
1249 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1251 FuncRecords = std::move(WritableBuffer);
1259 std::move(ProfileNames), BytesInAddress, Endian, CompilationDir);
1267 for (
auto &ObjForArch : Universal->objects())
1268 if (Arch == ObjForArch.getArchFlagName())
1275Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
1280 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1291 return ReaderOrErr.takeError();
1292 Readers.push_back(std::move(ReaderOrErr.get()));
1293 return std::move(Readers);
1299 return BinOrErr.takeError();
1300 std::unique_ptr<Binary>
Bin = std::move(BinOrErr.get());
1309 for (
auto &ObjForArch : Universal->objects()) {
1311 std::string ObjArch = ObjForArch.getArchFlagName();
1312 if (Arch != ObjArch)
1315 auto ArchiveOrErr = ObjForArch.getAsArchive();
1316 if (!ArchiveOrErr) {
1323 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1324 CompilationDir, BinaryIDs);
1331 for (
auto &Child : Ar->children(Err)) {
1337 ChildBufOrErr.
get(), Arch, ObjectFileBuffers, CompilationDir,
1339 if (!ChildReadersOrErr)
1340 return ChildReadersOrErr.takeError();
1341 for (
auto &Reader : ChildReadersOrErr.get())
1342 Readers.push_back(std::move(Reader));
1345 return std::move(Err);
1351 for (
auto &Buffer : Ar->takeThinBuffers())
1352 ObjectFileBuffers.push_back(std::move(Buffer));
1354 return std::move(Readers);
1359 BinaryIDs ? &BinaryID :
nullptr);
1361 return ReaderOrErr.takeError();
1362 Readers.push_back(std::move(ReaderOrErr.get()));
1363 if (!BinaryID.
empty())
1365 return std::move(Readers);
1369 if (CurrentRecord >= MappingRecords.size())
1372 FunctionsFilenames.clear();
1373 Expressions.clear();
1374 MappingRegions.clear();
1375 auto &R = MappingRecords[CurrentRecord];
1376 auto F =
ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1378 Expressions, MappingRegions);
1379 if (
auto Err = Reader.
read())
1382 Record.FunctionName = R.FunctionName;
1383 Record.FunctionHash = R.FunctionHash;
1384 Record.Filenames = FunctionsFilenames;
1385 Record.Expressions = Expressions;
1386 Record.MappingRegions = MappingRegions;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error readCoverageMappingData(InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, std::vector< BinaryCoverageReader::ProfileMappingRecord > &Records, StringRef CompilationDir, std::vector< std::string > &Filenames)
static Expected< std::pair< StringRef, uint64_t > > lookupAllocatableSection(ObjectFile &OF, InstrProfSectKind IPSK)
Find a section that matches Name and is allocatable at runtime.
static Expected< std::unique_ptr< BinaryCoverageReader > > loadBinaryFormat(std::unique_ptr< Binary > Bin, StringRef Arch, StringRef CompilationDir="", object::BuildIDRef *BinaryID=nullptr)
static Expected< std::unique_ptr< BinaryCoverageReader > > loadTestingFormat(StringRef Data, StringRef CompilationDir)
static Expected< std::vector< SectionRef > > lookupSections(ObjectFile &OF, InstrProfSectKind IPSK)
Find all sections that match IPSK name.
static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch)
Determine whether Arch is invalid or empty, given Bin.
static bool shouldSkipSectionFirstByte(SectionRef &Section)
Determine if we should skip the first byte of the section content.
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
static const unsigned EncodingExpansionRegionBit
This file defines the DenseMap class.
static constexpr StringLiteral Filename
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)
bool empty() const
empty - Check if the array is empty.
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 [IR]PGO name look-up with keys (such as pointers,...
LLVM_ABI StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize) const
Return function's PGO name from the function name's symbol address in the object file.
LLVM_ABI Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
const char * getBufferStart() const
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
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 bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr 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.
static Twine utohexstr(uint64_t Val)
static LLVM_ABI 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.
static Expected< std::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, FuncRecordsStorage &&FuncRecords, CoverageMapCopyStorage &&CoverageMap, std::unique_ptr< InstrProfSymtab > ProfileNamesPtr, uint8_t BytesInAddress, llvm::endianness Endian, StringRef CompilationDir="")
std::unique_ptr< MemoryBuffer > CoverageMapCopyStorage
static Expected< std::vector< std::unique_ptr< BinaryCoverageReader > > > create(MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl< std::unique_ptr< MemoryBuffer > > &ObjectFileBuffers, StringRef CompilationDir="", SmallVectorImpl< object::BuildIDRef > *BinaryIDs=nullptr)
std::unique_ptr< MemoryBuffer > FuncRecordsStorage
Error readNextRecord(CoverageMappingRecord &Record) override
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
LLVM_ABI void dump(const Counter &C, raw_ostream &OS) const
coveragemap_error get() const
CoverageMappingIterator()
virtual Error readNextRecord(CoverageMappingRecord &Record)=0
The mapping of profile information to coverage data.
RawCoverageFilenamesReader(StringRef Data, std::vector< std::string > &Filenames, StringRef CompilationDir="")
LLVM_ABI Error read(CovMapVersion Version)
Checks if the given coverage mapping data is exported for an unused function.
LLVM_ABI Expected< bool > isDummy()
Reader for the raw coverage mapping data.
LLVM_ABI Error readSize(uint64_t &Result)
LLVM_ABI Error readIntMax(uint64_t &Result, uint64_t MaxPlus1)
LLVM_ABI Error readULEB128(uint64_t &Result)
LLVM_ABI Error readString(StringRef &Result)
This class is the base class for all object file types.
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.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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)
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
LLVM_ABI Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
LLVM_ABI bool isAvailable()
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
@ invalid_or_missing_arch_specifier
constexpr uint64_t TestingFormatMagic
LLVM_ABI BuildIDRef getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
ArrayRef< uint8_t > BuildIDRef
A reference to a BuildID in binary form.
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
value_type byte_swap(value_type value, endianness endian)
LLVM_ABI bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
Remove '.
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
LLVM_ABI 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.
FunctionAddr VTableAddr Value
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
FunctionAddr VTableAddr uintptr_t uintptr_t FilenamesSize
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
FunctionAddr VTableAddr uintptr_t uintptr_t CoverageSize
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.
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
FunctionAddr VTableAddr uintptr_t uintptr_t Version
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
FunctionAddr VTableAddr uintptr_t uintptr_t NRecords
void consumeError(Error Err)
Consume a Error without doing anything.
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
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.
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...
@ MCDCDecisionRegion
A DecisionRegion represents a top-level boolean expression and is associated with a variable length b...
@ MCDCBranchRegion
A Branch Region can be extended to include IDs to facilitate MC/DC.
@ SkippedRegion
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
@ GapRegion
A GapRegion is like a CodeRegion, but its count is only set as the line execution count when its the ...
@ BranchRegion
A BranchRegion represents leaf-level boolean expressions and is associated with two counters,...
@ CodeRegion
A CodeRegion associates some code with a counter.
A Counter is an abstract value that describes how to compute the execution count for a region of code...
static const unsigned EncodingTagBits
static Counter getZero()
Return the counter that represents the number zero.
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
static const unsigned EncodingTagMask
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
CovMapFunctionRecordV3 CovMapFuncRecordType
Coverage mapping information for a single function.