summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/ProfileData/CoverageMappingReader.cpp44
-rwxr-xr-xllvm/test/tools/llvm-cov/Inputs/binary-formats.macho32bbin0 -> 9352 bytes
-rw-r--r--llvm/test/tools/llvm-cov/binary-formats.c1
3 files changed, 29 insertions, 16 deletions
diff --git a/llvm/lib/ProfileData/CoverageMappingReader.cpp b/llvm/lib/ProfileData/CoverageMappingReader.cpp
index fde6874fe40..0ca42e4bfdb 100644
--- a/llvm/lib/ProfileData/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/CoverageMappingReader.cpp
@@ -315,7 +315,7 @@ struct SectionData {
};
}
-template <typename T>
+template <typename T, support::endianness Endian>
std::error_code readCoverageMappingData(
SectionData &ProfileNames, StringRef Data,
std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
@@ -327,10 +327,10 @@ std::error_code readCoverageMappingData(
for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
if (Buf + 4 * sizeof(uint32_t) > End)
return instrprof_error::malformed;
- uint32_t NRecords = endian::readNext<uint32_t, little, unaligned>(Buf);
- uint32_t FilenamesSize = endian::readNext<uint32_t, little, unaligned>(Buf);
- uint32_t CoverageSize = endian::readNext<uint32_t, little, unaligned>(Buf);
- uint32_t Version = endian::readNext<uint32_t, little, unaligned>(Buf);
+ uint32_t NRecords = 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 Version = endian::readNext<uint32_t, Endian, unaligned>(Buf);
switch (Version) {
case CoverageMappingVersion1:
@@ -362,10 +362,10 @@ std::error_code readCoverageMappingData(
while (FunBuf < FunEnd) {
// Read the function information
- T NamePtr = endian::readNext<T, little, unaligned>(FunBuf);
- uint32_t NameSize = endian::readNext<uint32_t, little, unaligned>(FunBuf);
- uint32_t DataSize = endian::readNext<uint32_t, little, unaligned>(FunBuf);
- uint64_t FuncHash = endian::readNext<uint64_t, little, unaligned>(FunBuf);
+ T NamePtr = endian::readNext<T, Endian, unaligned>(FunBuf);
+ uint32_t NameSize = endian::readNext<uint32_t, Endian, unaligned>(FunBuf);
+ uint32_t DataSize = endian::readNext<uint32_t, Endian, unaligned>(FunBuf);
+ uint64_t FuncHash = endian::readNext<uint64_t, Endian, unaligned>(FunBuf);
// Now use that to read the coverage data.
if (CovBuf + DataSize > CovEnd)
@@ -397,8 +397,10 @@ static const char *TestingFormatMagic = "llvmcovmtestdata";
static std::error_code loadTestingFormat(StringRef Data,
SectionData &ProfileNames,
StringRef &CoverageMapping,
- uint8_t &BytesInAddress) {
+ uint8_t &BytesInAddress,
+ support::endianness &Endian) {
BytesInAddress = 8;
+ Endian = support::endianness::little;
Data = Data.substr(StringRef(TestingFormatMagic).size());
if (Data.size() < 1)
@@ -428,6 +430,7 @@ static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
SectionData &ProfileNames,
StringRef &CoverageMapping,
uint8_t &BytesInAddress,
+ support::endianness &Endian,
Triple::ArchType Arch) {
auto BinOrErr = object::createBinary(ObjectBuffer);
if (std::error_code EC = BinOrErr.getError())
@@ -453,6 +456,8 @@ static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
// The coverage uses native pointer sizes for the object it's written in.
BytesInAddress = OF->getBytesInAddress();
+ Endian = OF->isLittleEndian() ? support::endianness::little
+ : support::endianness::big;
// Look for the sections that we are interested in.
int FoundSectionCount = 0;
@@ -489,22 +494,29 @@ BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
SectionData Profile;
StringRef Coverage;
uint8_t BytesInAddress;
+ support::endianness Endian;
std::error_code EC;
if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
// This is a special format used for testing.
EC = loadTestingFormat(ObjectBuffer->getBuffer(), Profile, Coverage,
- BytesInAddress);
+ BytesInAddress, Endian);
else
EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Profile, Coverage,
- BytesInAddress, Arch);
+ BytesInAddress, Endian, Arch);
if (EC)
return EC;
- if (BytesInAddress == 4)
- EC = readCoverageMappingData<uint32_t>(
+ if (BytesInAddress == 4 && Endian == support::endianness::little)
+ EC = readCoverageMappingData<uint32_t, support::endianness::little>(
Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
- else if (BytesInAddress == 8)
- EC = readCoverageMappingData<uint64_t>(
+ else if (BytesInAddress == 4 && Endian == support::endianness::big)
+ EC = readCoverageMappingData<uint32_t, support::endianness::big>(
+ Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
+ else if (BytesInAddress == 8 && Endian == support::endianness::little)
+ EC = readCoverageMappingData<uint64_t, support::endianness::little>(
+ Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
+ else if (BytesInAddress == 8 && Endian == support::endianness::big)
+ EC = readCoverageMappingData<uint64_t, support::endianness::big>(
Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
else
return instrprof_error::malformed;
diff --git a/llvm/test/tools/llvm-cov/Inputs/binary-formats.macho32b b/llvm/test/tools/llvm-cov/Inputs/binary-formats.macho32b
new file mode 100755
index 00000000000..bb9f356c9dc
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/binary-formats.macho32b
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/binary-formats.c b/llvm/test/tools/llvm-cov/binary-formats.c
index e03b8b5739e..6ebd089fbe9 100644
--- a/llvm/test/tools/llvm-cov/binary-formats.c
+++ b/llvm/test/tools/llvm-cov/binary-formats.c
@@ -6,3 +6,4 @@ int main(int argc, const char *argv[]) {}
// RUN: llvm-profdata merge %S/Inputs/binary-formats.proftext -o %t.profdata
// RUN: llvm-cov show %S/Inputs/binary-formats.macho32l -instr-profile %t.profdata -no-colors -filename-equivalence %s | FileCheck %s
// RUN: llvm-cov show %S/Inputs/binary-formats.macho64l -instr-profile %t.profdata -no-colors -filename-equivalence %s | FileCheck %s
+// RUN: llvm-cov show %S/Inputs/binary-formats.macho32b -instr-profile %t.profdata -no-colors -filename-equivalence %s | FileCheck %s
OpenPOWER on IntegriCloud