diff options
author | Justin Bogner <mail@justinbogner.com> | 2015-03-16 21:40:18 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2015-03-16 21:40:18 +0000 |
commit | a438717638bfe7e67f82de167306a898571ce925 (patch) | |
tree | 14dcce95e2f10b40e2aa6befc74bbcef6477bb1f /llvm/lib | |
parent | a20616ec1062e53915c0f7715cde009abe527b73 (diff) | |
download | bcm5719-llvm-a438717638bfe7e67f82de167306a898571ce925.tar.gz bcm5719-llvm-a438717638bfe7e67f82de167306a898571ce925.zip |
InstrProf: Fix CoverageMappingReader on big endian
This makes the reader check the endianness of the object file its
given and behave appropriately. For the test I dug up a really old
linker and created a ppc-apple-darwin file for llvm-cov to read.
llvm-svn: 232422
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/ProfileData/CoverageMappingReader.cpp | 44 |
1 files changed, 28 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; |