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() {
72 "the size of ULEB128 is too big");
80 if (Result >= MaxPlus1)
81 return make_error<CoverageMapError>(
83 "the value of ULEB128 is greater than or equal to MaxPlus1");
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) {
128 return make_error<CoverageMapError>(
138 arrayRefFromStringRef(CompressedFilenames), StorageBuf,
142 return make_error<CoverageMapError>(
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");
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()))
315 return make_error<CoverageMapError>(
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())
389 return make_error<CoverageMapError>(
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;
454 for (
auto &R : MappingRegions) {
455 if (FileIDExpansionRegionMapping[R.FileID]) {
456 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
457 FileIDExpansionRegionMapping[R.FileID] =
nullptr;
469 return std::move(Err);
470 if (NumFileMappings != 1)
475 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
476 return std::move(Err);
479 return std::move(Err);
480 if (NumExpressions != 0)
484 return std::move(Err);
489 std::numeric_limits<unsigned>::max()))
490 return std::move(Err);
500 Address = Section.getAddress();
548struct CovMapFuncRecordReader {
549 virtual ~CovMapFuncRecordReader() =
default;
559 const char *CovBufEnd) = 0;
572 readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
573 std::optional<FilenameRange> OutOfLineFileRange,
574 const char *OutOfLineMappingBuf,
575 const char *OutOfLineMappingBufEnd) = 0;
577 template <
class IntPtrT, llvm::endianness Endian>
580 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
581 std::vector<std::string> &
F);
585template <CovMapVersion Version,
class IntPtrT, llvm::endianness Endian>
586class VersionedCovMapFuncRecordReader :
public CovMapFuncRecordReader {
587 using FuncRecordType =
596 std::vector<std::string> &Filenames;
597 std::vector<BinaryCoverageReader::ProfileMappingRecord> &
Records;
609 Error insertFunctionRecordIfNeeded(
const FuncRecordType *CFR,
613 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
614 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
616 FunctionRecords.
insert(std::make_pair(NameRef,
Records.size()));
617 if (InsertResult.second) {
619 if (
Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
621 if (FuncName.
empty())
622 return make_error<InstrProfError>(instrprof_error::malformed,
623 "function name is empty");
624 ++CovMapNumUsedRecords;
625 Records.emplace_back(Version, FuncName, FuncHash, Mapping,
630 size_t OldRecordIndex = InsertResult.first->second;
637 if (!*OldIsDummyExpected)
643 if (*NewIsDummyExpected)
645 ++CovMapNumUsedRecords;
654 VersionedCovMapFuncRecordReader(
656 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
657 std::vector<std::string> &
F)
658 : ProfileNames(
P), CompilationDir(
D), Filenames(
F),
Records(
R) {}
660 ~VersionedCovMapFuncRecordReader()
override =
default;
663 const char *CovBufEnd)
override {
664 using namespace support;
667 return make_error<CoverageMapError>(
668 coveragemap_error::malformed,
669 "coverage mapping header section is larger than buffer size");
670 auto CovHeader =
reinterpret_cast<const CovMapHeader *
>(CovBuf);
675 CovBuf =
reinterpret_cast<const char *
>(CovHeader + 1);
680 const char *FuncRecBuf =
nullptr;
681 const char *FuncRecBufEnd =
nullptr;
682 if (Version < CovMapVersion::Version4)
684 CovBuf += NRecords *
sizeof(FuncRecordType);
685 if (Version < CovMapVersion::Version4)
686 FuncRecBufEnd = CovBuf;
689 if (CovBuf + FilenamesSize > CovBufEnd)
690 return make_error<CoverageMapError>(
691 coveragemap_error::malformed,
692 "filenames section is larger than buffer size");
693 size_t FilenamesBegin = Filenames.size();
694 StringRef FilenameRegion(CovBuf, FilenamesSize);
697 if (
auto Err = Reader.read(Version))
698 return std::move(Err);
699 CovBuf += FilenamesSize;
700 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
702 if (Version >= CovMapVersion::Version4) {
705 int64_t FilenamesRef =
708 FileRangeMap.
insert(std::make_pair(FilenamesRef, FileRange));
712 auto It = Filenames.begin();
719 FileRange = OrigRange;
729 const char *MappingBuf = CovBuf;
730 if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
731 return make_error<CoverageMapError>(coveragemap_error::malformed,
732 "coverage mapping size is not zero");
733 CovBuf += CoverageSize;
734 const char *MappingEnd = CovBuf;
736 if (CovBuf > CovBufEnd)
737 return make_error<CoverageMapError>(
738 coveragemap_error::malformed,
739 "function records section is larger than buffer size");
741 if (Version < CovMapVersion::Version4) {
743 if (
Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
744 MappingBuf, MappingEnd))
755 Error readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
756 std::optional<FilenameRange> OutOfLineFileRange,
757 const char *OutOfLineMappingBuf,
758 const char *OutOfLineMappingBufEnd)
override {
759 auto CFR =
reinterpret_cast<const FuncRecordType *
>(FuncRecBuf);
760 while ((
const char *)CFR < FuncRecBufEnd) {
762 const char *NextMappingBuf;
763 const FuncRecordType *NextCFR;
764 std::tie(NextMappingBuf, NextCFR) =
765 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
766 if (Version < CovMapVersion::Version4)
767 if (NextMappingBuf > OutOfLineMappingBufEnd)
768 return make_error<CoverageMapError>(
769 coveragemap_error::malformed,
770 "next mapping buffer is larger than buffer size");
773 std::optional<FilenameRange> FileRange;
774 if (Version < CovMapVersion::Version4) {
775 FileRange = OutOfLineFileRange;
777 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
778 auto It = FileRangeMap.
find(FilenamesRef);
779 if (It == FileRangeMap.
end())
780 return make_error<CoverageMapError>(
781 coveragemap_error::malformed,
782 "no filename found for function with hash=0x" +
785 FileRange = It->getSecond();
789 if (FileRange && !FileRange->isInvalid()) {
791 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
792 if (Version >= CovMapVersion::Version4 &&
793 Mapping.
data() + Mapping.
size() > FuncRecBufEnd)
794 return make_error<CoverageMapError>(
795 coveragemap_error::malformed,
796 "coverage mapping data is larger than buffer size");
797 if (
Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
801 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
809template <
class IntPtrT, llvm::endianness Endian>
812 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
813 std::vector<std::string> &
F) {
814 using namespace coverage;
818 return std::make_unique<VersionedCovMapFuncRecordReader<
827 if (
Error E =
P.create(
P.getNameData()))
830 return std::make_unique<VersionedCovMapFuncRecordReader<
833 return std::make_unique<VersionedCovMapFuncRecordReader<
836 return std::make_unique<VersionedCovMapFuncRecordReader<
839 return std::make_unique<VersionedCovMapFuncRecordReader<
842 return std::make_unique<VersionedCovMapFuncRecordReader<
845 return std::make_unique<VersionedCovMapFuncRecordReader<
851template <
typename T, llvm::endianness Endian>
854 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
855 StringRef CompilationDir, std::vector<std::string> &Filenames) {
856 using namespace coverage;
865 CovMapFuncRecordReader::get<T, Endian>(
Version, ProfileNames, Records,
866 CompilationDir, Filenames);
869 auto Reader = std::move(ReaderExpected.
get());
870 const char *CovBuf = CovMap.
data();
871 const char *CovBufEnd = CovBuf + CovMap.
size();
872 const char *FuncRecBuf = FuncRecords.
data();
873 const char *FuncRecBufEnd = FuncRecords.
data() + FuncRecords.
size();
874 while (CovBuf < CovBufEnd) {
881 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
882 if (
auto E = NextOrErr.takeError())
884 CovBuf = NextOrErr.get();
889 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
897 std::unique_ptr<InstrProfSymtab> ProfileNamesPtr, uint8_t BytesInAddress,
899 if (ProfileNamesPtr ==
nullptr)
901 "Caller must provide ProfileNames");
903 std::move(ProfileNamesPtr), std::move(FuncRecords)));
905 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
907 if (
Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>(
908 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
909 CompilationDir, Reader->Filenames))
912 if (
Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>(
913 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
914 CompilationDir, Reader->Filenames))
917 if (
Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>(
918 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
919 CompilationDir, Reader->Filenames))
922 if (
Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>(
923 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
924 CompilationDir, Reader->Filenames))
927 return make_error<CoverageMapError>(
929 "not supported endianness or bytes in address");
930 return std::move(Reader);
935 uint8_t BytesInAddress = 8;
942 "the size of data is too small");
943 auto TestingVersion =
944 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
954 return make_error<CoverageMapError>(
956 "the size of TestingFormatMagic is too big");
964 "the size of ULEB128 is too big");
966 if (
Data.size() < ProfileNamesSize)
968 "the size of ProfileNames is too big");
969 auto ProfileNames = std::make_unique<InstrProfSymtab>();
972 Data =
Data.substr(ProfileNamesSize);
981 "the size of ULEB128 is too big");
984 return make_error<CoverageMapError>(
986 "the size of CoverageMapping is teoo small");
993 if (
Data.size() < Pad)
995 "insufficient padding");
998 return make_error<CoverageMapError>(
1000 "coverage mapping header section is larger than data size");
1001 auto const *CovHeader =
reinterpret_cast<const CovMapHeader *
>(
1009 CoverageMappingSize =
Data.size();
1011 auto FilenamesSize =
1013 CoverageMappingSize =
sizeof(
CovMapHeader) + FilenamesSize;
1018 Data =
Data.substr(CoverageMappingSize);
1024 "data is not empty");
1029 if (
Data.size() < Pad)
1031 "insufficient padding");
1039 BytesInAddress,
Endian, CompilationDir);
1052 bool IsCOFF = isa<COFFObjectFile>(OF);
1054 return IsCOFF ?
N.split(
'$').first :
N;
1058 std::vector<SectionRef> Sections;
1059 for (
const auto &Section : OF.
sections()) {
1063 if (stripSuffix(*NameOrErr) ==
Name) {
1066 if (IsCOFF && IPSK == IPSK_name && Section.getSize() == 2)
1068 Sections.push_back(Section);
1071 if (Sections.empty())
1080 std::unique_ptr<ObjectFile> OF;
1081 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
1084 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1085 if (!ObjectFileOrErr)
1086 return ObjectFileOrErr.takeError();
1087 OF = std::move(ObjectFileOrErr.get());
1088 }
else if (isa<ObjectFile>(
Bin.get())) {
1090 OF.reset(cast<ObjectFile>(
Bin.release()));
1092 if (!Arch.
empty() && OF->getArch() !=
Triple(Arch).getArch())
1097 "binary is not an object file");
1100 uint8_t BytesInAddress = OF->getBytesInAddress();
1105 auto ProfileNames = std::make_unique<InstrProfSymtab>();
1106 std::vector<SectionRef> NamesSectionRefs;
1110 if (
auto E = NamesSection.takeError()) {
1113 if (
auto E = NamesSection.takeError())
1114 return std::move(E);
1116 NamesSectionRefs = *NamesSection;
1118 if (NamesSectionRefs.size() != 1)
1119 return make_error<CoverageMapError>(
1121 "the size of coverage mapping section is not one");
1122 if (
Error E = ProfileNames->
create(NamesSectionRefs.back()))
1123 return std::move(E);
1126 if (
auto E = CoverageSection.takeError())
1127 return std::move(E);
1128 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1129 if (CoverageSectionRefs.size() != 1)
1131 "the size of name section is not one");
1132 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1133 if (!CoverageMappingOrErr)
1134 return CoverageMappingOrErr.takeError();
1141 if (
auto E = CoverageRecordsSections.takeError()) {
1149 const Align RecordAlignment(8);
1151 for (
SectionRef Section : *CoverageRecordsSections) {
1152 auto CoverageRecordsOrErr = Section.getContents();
1153 if (!CoverageRecordsOrErr)
1154 return CoverageRecordsOrErr.takeError();
1155 FuncRecordsSize +=
alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1157 auto WritableBuffer =
1159 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1161 "Allocated memory is correctly aligned");
1163 for (
SectionRef Section : *CoverageRecordsSections) {
1164 auto CoverageRecordsOrErr = Section.getContents();
1165 if (!CoverageRecordsOrErr)
1166 return CoverageRecordsOrErr.takeError();
1167 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1168 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1169 CoverageRecords.end(), FuncRecordsBuffer);
1171 std::fill_n(FuncRecordsBuffer,
1172 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1173 (uintptr_t)FuncRecordsBuffer,
1176 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1178 FuncRecords = std::move(WritableBuffer);
1186 BytesInAddress,
Endian, CompilationDir);
1193 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin)) {
1194 for (
auto &ObjForArch : Universal->objects())
1195 if (Arch == ObjForArch.getArchFlagName())
1207 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1211 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
1218 return ReaderOrErr.takeError();
1219 Readers.push_back(std::move(ReaderOrErr.get()));
1220 return std::move(Readers);
1226 return BinOrErr.takeError();
1227 std::unique_ptr<Binary>
Bin = std::move(BinOrErr.get());
1230 return make_error<CoverageMapError>(
1235 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
1236 for (
auto &ObjForArch : Universal->objects()) {
1238 std::string ObjArch = ObjForArch.getArchFlagName();
1239 if (Arch != ObjArch)
1242 auto ArchiveOrErr = ObjForArch.getAsArchive();
1243 if (!ArchiveOrErr) {
1250 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1251 CompilationDir, BinaryIDs);
1256 if (
auto *Ar = dyn_cast<Archive>(
Bin.get())) {
1258 for (
auto &Child : Ar->children(Err)) {
1264 ChildBufOrErr.
get(), Arch, ObjectFileBuffers, CompilationDir,
1266 if (!ChildReadersOrErr)
1267 return ChildReadersOrErr.takeError();
1268 for (
auto &Reader : ChildReadersOrErr.get())
1269 Readers.push_back(std::move(Reader));
1272 return std::move(Err);
1278 for (
auto &Buffer : Ar->takeThinBuffers())
1279 ObjectFileBuffers.push_back(std::move(Buffer));
1281 return std::move(Readers);
1286 BinaryIDs ? &BinaryID :
nullptr);
1288 return ReaderOrErr.takeError();
1289 Readers.push_back(std::move(ReaderOrErr.get()));
1290 if (!BinaryID.
empty())
1292 return std::move(Readers);
1296 if (CurrentRecord >= MappingRecords.size())
1299 FunctionsFilenames.clear();
1300 Expressions.clear();
1301 MappingRegions.clear();
1302 auto &R = MappingRecords[CurrentRecord];
1303 auto F =
ArrayRef(Filenames).
slice(R.FilenamesBegin, R.FilenamesSize);
1305 Expressions, MappingRegions);
1306 if (
auto Err = Reader.
read())
1309 Record.FunctionName = R.FunctionName;
1310 Record.FunctionHash = R.FunctionHash;
1311 Record.Filenames = FunctionsFilenames;
1312 Record.Expressions = Expressions;
1313 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 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 Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
static const unsigned EncodingExpansionRegionBit
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 [IR]PGO name look-up with keys (such as pointers,...
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function's PGO name from the function name's symbol address in the object file.
const char * getBufferStart() const
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Pass interface - Implemented by all 'passes'.
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.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
const unsigned char * bytes_begin() const
Triple - Helper class for working with autoconf configuration names.
static Twine utohexstr(const uint64_t &Val)
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::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, FuncRecordsStorage &&FuncRecords, std::unique_ptr< InstrProfSymtab > ProfileNamesPtr, uint8_t BytesInAddress, llvm::endianness Endian, StringRef CompilationDir="")
static Expected< std::vector< std::unique_ptr< BinaryCoverageReader > > > create(MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl< std::unique_ptr< MemoryBuffer > > &ObjectFileBuffers, StringRef CompilationDir="", SmallVectorImpl< object::BuildIDRef > *BinaryIDs=nullptr)
std::unique_ptr< MemoryBuffer > FuncRecordsStorage
Error readNextRecord(CoverageMappingRecord &Record) override
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
void dump(const Counter &C, raw_ostream &OS) const
coveragemap_error get() const
A file format agnostic iterator over coverage mapping data.
virtual Error readNextRecord(CoverageMappingRecord &Record)=0
The mapping of profile information to coverage data.
Reader for the raw coverage filenames.
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)
Triple::ObjectFormatType getTripleObjectFormat() const
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)
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
@ invalid_or_missing_arch_specifier
constexpr uint64_t TestingFormatMagic
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
BuildIDRef getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
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.
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...
@ MCDCDecisionRegion
A DecisionRegion represents a top-level boolean expression and is associated with a variable length b...
@ MCDCBranchRegion
A Branch Region can be extended to include IDs to facilitate MC/DC.
@ SkippedRegion
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
@ GapRegion
A GapRegion is like a CodeRegion, but its count is only set as the line execution count when its the ...
@ BranchRegion
A BranchRegion represents leaf-level boolean expressions and is associated with two counters,...
@ CodeRegion
A CodeRegion associates some code with a counter.
A Counter is an abstract value that describes how to compute the execution count for a region of code...
static const unsigned EncodingTagBits
static Counter getZero()
Return the counter that represents the number zero.
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
static const unsigned EncodingTagMask
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
Coverage mapping information for a single function.