From a438717638bfe7e67f82de167306a898571ce925 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Mon, 16 Mar 2015 21:40:18 +0000 Subject: [PATCH] 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 --- llvm/lib/ProfileData/CoverageMappingReader.cpp | 44 +++++++++++++-------- .../tools/llvm-cov/Inputs/binary-formats.macho32b | Bin 0 -> 9352 bytes llvm/test/tools/llvm-cov/binary-formats.c | 1 + 3 files changed, 29 insertions(+), 16 deletions(-) create mode 100755 llvm/test/tools/llvm-cov/Inputs/binary-formats.macho32b diff --git a/llvm/lib/ProfileData/CoverageMappingReader.cpp b/llvm/lib/ProfileData/CoverageMappingReader.cpp index fde6874..0ca42e4 100644 --- a/llvm/lib/ProfileData/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/CoverageMappingReader.cpp @@ -315,7 +315,7 @@ struct SectionData { }; } -template +template std::error_code readCoverageMappingData( SectionData &ProfileNames, StringRef Data, std::vector &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(Buf); - uint32_t FilenamesSize = endian::readNext(Buf); - uint32_t CoverageSize = endian::readNext(Buf); - uint32_t Version = endian::readNext(Buf); + uint32_t NRecords = endian::readNext(Buf); + uint32_t FilenamesSize = endian::readNext(Buf); + uint32_t CoverageSize = endian::readNext(Buf); + uint32_t Version = endian::readNext(Buf); switch (Version) { case CoverageMappingVersion1: @@ -362,10 +362,10 @@ std::error_code readCoverageMappingData( while (FunBuf < FunEnd) { // Read the function information - T NamePtr = endian::readNext(FunBuf); - uint32_t NameSize = endian::readNext(FunBuf); - uint32_t DataSize = endian::readNext(FunBuf); - uint64_t FuncHash = endian::readNext(FunBuf); + T NamePtr = endian::readNext(FunBuf); + uint32_t NameSize = endian::readNext(FunBuf); + uint32_t DataSize = endian::readNext(FunBuf); + uint64_t FuncHash = endian::readNext(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 &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( + if (BytesInAddress == 4 && Endian == support::endianness::little) + EC = readCoverageMappingData( Profile, Coverage, Reader->MappingRecords, Reader->Filenames); - else if (BytesInAddress == 8) - EC = readCoverageMappingData( + else if (BytesInAddress == 4 && Endian == support::endianness::big) + EC = readCoverageMappingData( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else if (BytesInAddress == 8 && Endian == support::endianness::little) + EC = readCoverageMappingData( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else if (BytesInAddress == 8 && Endian == support::endianness::big) + EC = readCoverageMappingData( 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 0000000000000000000000000000000000000000..bb9f356c9dc48b8efd074ccb6aa0af5d7e684ad3 GIT binary patch literal 9352 zcmeHNUu+!38UOBbzy({$sWqx4yY@QCLnt8!EkbAFsCMK~Td|DQxN2H~CVP8x_Ts(W zV|UN&(MxYbK}ys}H4+a^6{TqvMMXj=4}EA=Rq)b^3Iq@EKpTWC!2<|Y?L%Mq>;Aso zx%0+%rR_`AhaGu#zW+1xn>l&soBjN+AHPOKUqa=QMZKNqmIG*?M$Mp>gjkyS*75Hj z|Mo-Rx~0&i`VjET9ZPtAqkJ#N+&PA^_u+RB(H?GjzEMGpydn!i7@qH%_KFhp#uy)l>K&rJ z+;(H^pn*YlNQl{)Z9U_|qU_aGQ*AD|odQm8MnchU^zZgBF+-xJ||Y8y6ug{ojn^AS`(t+$Li%7CaX8 zYgy|xQFp7t)@#!1Gne~dhP_bWwr^1}3}?Nj*J05oMhW6s#NalX|IR?z6Hcw>*d2MF z7%k}7pG$Hs*azLhG=5JD^NS~r&(1G*@^JyP2lf3x_Arp z0O}G8Q5Y|-cc6|a8cn}4aRJiZeKdO@8$}%~HaxdzndRd4HsIeW`i;hg_2S>+|8>E> zBHk0g4eP;ZqITznxvdz6@DAU57*jOMP@~-J<3O^*=Va6KW$o~>q*LUXK2iiy1X2W2 z1X2Y43j|sZ3!p|so#GuS~e^7X!b@eYpbNHX# z-lTjhpS?CUP4wc#)_X@aqSmGTL900uw0?J20RKGv!;P{wxN%;~v)#rowcObQ_}_P) z=*+$o!SrP+vESsKfsZdLwvdpGL6Dm;Ok(5N{w#{}0w5c@VN=+E925@+XN9x6qnLe+yrZ z`ePgDNB@-`fz?@>DjDOWbCmfg%wSHt(Z}GfxQ|#r4gCW2f1Zl@ z68O{L|D^ai@B#SWDt-a{2KeU`zXbj|_>18TO~-S|9712EcuW}$^qiuHKrbjd4|++B z`_sc6%_Pd`1$?-!z4F8+fq*SI%t31-PCPy*1Ney*v z{MB;>J1KKwYwIl@`_6ugKZ>xP;<>c1ei)Rl zP%b$xr61+_CFO_k20i`cXU`wmqD=eef1jSYv~@^fI13CnF`w^*I?XEoJopB$G4KEO zQ||_Cc_YA{7;ZoKM$q2>O0a=-hs`AFBS%A`vlle&%=ul{n4Y{)AmFF*yw9#_2hLzG zGY^)ymhe~%DbhdvW9=aOb?m_(+QHw`;o*vN0>Aum$Q{22g z&oL8yES{XHR9xwK4^?9m*5NJIDL-l;1~>BKL*Cp!vKX?ukzS8mDe9?#&VO8sDM)LeXsb++KW906FIsURQD! z+(4QL_8gM_1{?MbksG*G(NBTiujq52=M{~+%gn=y-T=L>=x0Gcqv)T4enHWfK){08pTr7KrV+-bU^>LN9T%vRMwADwG= zr)nbI#YrpV!I1XpXmFV>UCwjiO1;jXN{Gc%GwuqKPf@$hhW}Ydb=O&ml43&CR)q|t z(eNea5~srq-8Wcj$hvPjws3XRlZ2dGA29>tf3Z@S6>0mX-$V$@G1i1`>Bx$?vTi|C zaWEZpXFI-GZ6fEVSE8x+XlzG#(nh|{>rvGm*XL}Z^kt<-$xgzt4Ga=}dGaya@xGwT zJ_b8_?qkt2fIc>faY%dJbn#t-T3%Ng(p;Cq(`$80dKB+9EasYQ)>d3md0cm^Uk6}n r(|FS0bpZ~-@K;?%jB}&HbsD~DW1d)%0EtK;UDw9OikS%Io9zAxv8@KI literal 0 HcmV?d00001 diff --git a/llvm/test/tools/llvm-cov/binary-formats.c b/llvm/test/tools/llvm-cov/binary-formats.c index e03b8b5..6ebd089 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 -- 2.7.4