|
|
@@ -36,11 +36,11 @@ void CoverageMappingIterator::increment() {
|
|
|
|
|
|
|
|
|
|
|
|
std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
|
|
|
|
std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
|
|
|
|
if (Data.size() < 1)
|
|
|
|
if (Data.size() < 1)
|
|
|
|
return instrprof_error::truncated;
|
|
|
|
return coveragemap_error::truncated;
|
|
|
|
unsigned N = 0;
|
|
|
|
unsigned N = 0;
|
|
|
|
Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
|
|
|
|
Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
|
|
|
|
if (N > Data.size())
|
|
|
|
if (N > Data.size())
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
Data = Data.substr(N);
|
|
|
|
Data = Data.substr(N);
|
|
|
|
return std::error_code();
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -50,7 +50,7 @@ std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
|
|
|
|
if (auto Err = readULEB128(Result))
|
|
|
|
if (auto Err = readULEB128(Result))
|
|
|
|
return Err;
|
|
|
|
return Err;
|
|
|
|
if (Result >= MaxPlus1)
|
|
|
|
if (Result >= MaxPlus1)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
return std::error_code();
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -59,7 +59,7 @@ std::error_code RawCoverageReader::readSize(uint64_t &Result) {
|
|
|
|
return Err;
|
|
|
|
return Err;
|
|
|
|
// Sanity check the number.
|
|
|
|
// Sanity check the number.
|
|
|
|
if (Result > Data.size())
|
|
|
|
if (Result > Data.size())
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
return std::error_code();
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -104,13 +104,13 @@ std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
|
|
|
|
case CounterExpression::Add: {
|
|
|
|
case CounterExpression::Add: {
|
|
|
|
auto ID = Value >> Counter::EncodingTagBits;
|
|
|
|
auto ID = Value >> Counter::EncodingTagBits;
|
|
|
|
if (ID >= Expressions.size())
|
|
|
|
if (ID >= Expressions.size())
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
|
|
|
|
Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
|
|
|
|
C = Counter::getExpression(ID);
|
|
|
|
C = Counter::getExpression(ID);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::error_code();
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -159,7 +159,7 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
|
|
|
|
ExpandedFileID = EncodedCounterAndRegion >>
|
|
|
|
ExpandedFileID = EncodedCounterAndRegion >>
|
|
|
|
Counter::EncodingCounterTagAndExpansionRegionTagBits;
|
|
|
|
Counter::EncodingCounterTagAndExpansionRegionTagBits;
|
|
|
|
if (ExpandedFileID >= NumFileIDs)
|
|
|
|
if (ExpandedFileID >= NumFileIDs)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
switch (EncodedCounterAndRegion >>
|
|
|
|
switch (EncodedCounterAndRegion >>
|
|
|
|
Counter::EncodingCounterTagAndExpansionRegionTagBits) {
|
|
|
|
Counter::EncodingCounterTagAndExpansionRegionTagBits) {
|
|
|
@@ -170,7 +170,7 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
|
|
|
|
Kind = CounterMappingRegion::SkippedRegion;
|
|
|
|
Kind = CounterMappingRegion::SkippedRegion;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -183,7 +183,7 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
|
|
|
|
if (auto Err = readULEB128(ColumnStart))
|
|
|
|
if (auto Err = readULEB128(ColumnStart))
|
|
|
|
return Err;
|
|
|
|
return Err;
|
|
|
|
if (ColumnStart > std::numeric_limits<unsigned>::max())
|
|
|
|
if (ColumnStart > std::numeric_limits<unsigned>::max())
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
|
|
|
|
if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
|
|
|
|
return Err;
|
|
|
|
return Err;
|
|
|
|
if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
|
|
|
|
if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
|
|
|
@@ -301,17 +301,17 @@ struct SectionData {
|
|
|
|
if (auto Err = Section.getContents(Data))
|
|
|
|
if (auto Err = Section.getContents(Data))
|
|
|
|
return Err;
|
|
|
|
return Err;
|
|
|
|
Address = Section.getAddress();
|
|
|
|
Address = Section.getAddress();
|
|
|
|
return instrprof_error::success;
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::error_code get(uint64_t Pointer, size_t Size, StringRef &Result) {
|
|
|
|
std::error_code get(uint64_t Pointer, size_t Size, StringRef &Result) {
|
|
|
|
if (Pointer < Address)
|
|
|
|
if (Pointer < Address)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
auto Offset = Pointer - Address;
|
|
|
|
auto Offset = Pointer - Address;
|
|
|
|
if (Offset + Size > Data.size())
|
|
|
|
if (Offset + Size > Data.size())
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
Result = Data.substr(Pointer - Address, Size);
|
|
|
|
Result = Data.substr(Pointer - Address, Size);
|
|
|
|
return instrprof_error::success;
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -327,7 +327,7 @@ std::error_code readCoverageMappingData(
|
|
|
|
// Read the records in the coverage data section.
|
|
|
|
// Read the records in the coverage data section.
|
|
|
|
for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
|
|
|
|
for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
|
|
|
|
if (Buf + 4 * sizeof(uint32_t) > End)
|
|
|
|
if (Buf + 4 * sizeof(uint32_t) > End)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
uint32_t NRecords = endian::readNext<uint32_t, Endian, unaligned>(Buf);
|
|
|
|
uint32_t NRecords = endian::readNext<uint32_t, Endian, unaligned>(Buf);
|
|
|
|
uint32_t FilenamesSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
|
|
|
|
uint32_t FilenamesSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
|
|
|
|
uint32_t CoverageSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
|
|
|
|
uint32_t CoverageSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
|
|
|
@@ -337,7 +337,7 @@ std::error_code readCoverageMappingData(
|
|
|
|
case CoverageMappingVersion1:
|
|
|
|
case CoverageMappingVersion1:
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return instrprof_error::unsupported_version;
|
|
|
|
return coveragemap_error::unsupported_version;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Skip past the function records, saving the start and end for later.
|
|
|
|
// Skip past the function records, saving the start and end for later.
|
|
|
@@ -347,7 +347,7 @@ std::error_code readCoverageMappingData(
|
|
|
|
|
|
|
|
|
|
|
|
// Get the filenames.
|
|
|
|
// Get the filenames.
|
|
|
|
if (Buf + FilenamesSize > End)
|
|
|
|
if (Buf + FilenamesSize > End)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
size_t FilenamesBegin = Filenames.size();
|
|
|
|
size_t FilenamesBegin = Filenames.size();
|
|
|
|
RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
|
|
|
|
RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
|
|
|
|
if (auto Err = Reader.read())
|
|
|
|
if (auto Err = Reader.read())
|
|
|
@@ -359,7 +359,7 @@ std::error_code readCoverageMappingData(
|
|
|
|
Buf += CoverageSize;
|
|
|
|
Buf += CoverageSize;
|
|
|
|
const char *CovEnd = Buf;
|
|
|
|
const char *CovEnd = Buf;
|
|
|
|
if (Buf > End)
|
|
|
|
if (Buf > End)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
|
|
|
|
|
|
|
|
while (FunBuf < FunEnd) {
|
|
|
|
while (FunBuf < FunEnd) {
|
|
|
|
// Read the function information
|
|
|
|
// Read the function information
|
|
|
@@ -370,7 +370,7 @@ std::error_code readCoverageMappingData(
|
|
|
|
|
|
|
|
|
|
|
|
// Now use that to read the coverage data.
|
|
|
|
// Now use that to read the coverage data.
|
|
|
|
if (CovBuf + DataSize > CovEnd)
|
|
|
|
if (CovBuf + DataSize > CovEnd)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
auto Mapping = StringRef(CovBuf, DataSize);
|
|
|
|
auto Mapping = StringRef(CovBuf, DataSize);
|
|
|
|
CovBuf += DataSize;
|
|
|
|
CovBuf += DataSize;
|
|
|
|
|
|
|
|
|
|
|
@@ -390,7 +390,7 @@ std::error_code readCoverageMappingData(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return instrprof_error::success;
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const char *TestingFormatMagic = "llvmcovmtestdata";
|
|
|
|
static const char *TestingFormatMagic = "llvmcovmtestdata";
|
|
|
@@ -405,26 +405,26 @@ static std::error_code loadTestingFormat(StringRef Data,
|
|
|
|
|
|
|
|
|
|
|
|
Data = Data.substr(StringRef(TestingFormatMagic).size());
|
|
|
|
Data = Data.substr(StringRef(TestingFormatMagic).size());
|
|
|
|
if (Data.size() < 1)
|
|
|
|
if (Data.size() < 1)
|
|
|
|
return instrprof_error::truncated;
|
|
|
|
return coveragemap_error::truncated;
|
|
|
|
unsigned N = 0;
|
|
|
|
unsigned N = 0;
|
|
|
|
auto ProfileNamesSize =
|
|
|
|
auto ProfileNamesSize =
|
|
|
|
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
|
|
|
|
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
|
|
|
|
if (N > Data.size())
|
|
|
|
if (N > Data.size())
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
Data = Data.substr(N);
|
|
|
|
Data = Data.substr(N);
|
|
|
|
if (Data.size() < 1)
|
|
|
|
if (Data.size() < 1)
|
|
|
|
return instrprof_error::truncated;
|
|
|
|
return coveragemap_error::truncated;
|
|
|
|
N = 0;
|
|
|
|
N = 0;
|
|
|
|
ProfileNames.Address =
|
|
|
|
ProfileNames.Address =
|
|
|
|
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
|
|
|
|
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
|
|
|
|
if (N > Data.size())
|
|
|
|
if (N > Data.size())
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
Data = Data.substr(N);
|
|
|
|
Data = Data.substr(N);
|
|
|
|
if (Data.size() < ProfileNamesSize)
|
|
|
|
if (Data.size() < ProfileNamesSize)
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
ProfileNames.Data = Data.substr(0, ProfileNamesSize);
|
|
|
|
ProfileNames.Data = Data.substr(0, ProfileNamesSize);
|
|
|
|
CoverageMapping = Data.substr(ProfileNamesSize);
|
|
|
|
CoverageMapping = Data.substr(ProfileNamesSize);
|
|
|
|
return instrprof_error::success;
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
|
|
|
|
static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
|
|
|
@@ -453,7 +453,7 @@ static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
|
|
|
|
return object_error::arch_not_found;
|
|
|
|
return object_error::arch_not_found;
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
// We can only handle object files.
|
|
|
|
// We can only handle object files.
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
|
|
|
|
|
|
|
|
// The coverage uses native pointer sizes for the object it's written in.
|
|
|
|
// The coverage uses native pointer sizes for the object it's written in.
|
|
|
|
BytesInAddress = OF->getBytesInAddress();
|
|
|
|
BytesInAddress = OF->getBytesInAddress();
|
|
|
@@ -476,7 +476,7 @@ static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
|
|
|
|
++FoundSectionCount;
|
|
|
|
++FoundSectionCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (FoundSectionCount != 2)
|
|
|
|
if (FoundSectionCount != 2)
|
|
|
|
return instrprof_error::bad_header;
|
|
|
|
return coveragemap_error::no_data_found;
|
|
|
|
|
|
|
|
|
|
|
|
// Get the contents of the given sections.
|
|
|
|
// Get the contents of the given sections.
|
|
|
|
if (std::error_code EC = CoverageSection.getContents(CoverageMapping))
|
|
|
|
if (std::error_code EC = CoverageSection.getContents(CoverageMapping))
|
|
|
@@ -520,7 +520,7 @@ BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
|
|
|
|
EC = readCoverageMappingData<uint64_t, support::endianness::big>(
|
|
|
|
EC = readCoverageMappingData<uint64_t, support::endianness::big>(
|
|
|
|
Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
|
|
|
|
Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return instrprof_error::malformed;
|
|
|
|
return coveragemap_error::malformed;
|
|
|
|
if (EC)
|
|
|
|
if (EC)
|
|
|
|
return EC;
|
|
|
|
return EC;
|
|
|
|
return std::move(Reader);
|
|
|
|
return std::move(Reader);
|
|
|
@@ -529,7 +529,7 @@ BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
|
|
|
|
std::error_code
|
|
|
|
std::error_code
|
|
|
|
BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
|
|
|
|
BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
|
|
|
|
if (CurrentRecord >= MappingRecords.size())
|
|
|
|
if (CurrentRecord >= MappingRecords.size())
|
|
|
|
return instrprof_error::eof;
|
|
|
|
return coveragemap_error::eof;
|
|
|
|
|
|
|
|
|
|
|
|
FunctionsFilenames.clear();
|
|
|
|
FunctionsFilenames.clear();
|
|
|
|
Expressions.clear();
|
|
|
|
Expressions.clear();
|
|
|
|