diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -874,16 +874,43 @@ InstrProfSymtab ProfileNames; if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address)) return std::move(E); - StringRef CoverageMapping = Data.substr(ProfileNamesSize); + Data = Data.substr(ProfileNamesSize); // Skip the padding bytes because coverage map data has an alignment of 8. - if (CoverageMapping.empty()) - return make_error(coveragemap_error::truncated); - size_t Pad = offsetToAlignedAddr(CoverageMapping.data(), Align(8)); - if (CoverageMapping.size() < Pad) + size_t Pad = offsetToAlignedAddr(Data.data(), Align(8)); + if (Data.size() < Pad) + return make_error(coveragemap_error::malformed); + Data = Data.substr(Pad); + if (Data.size() < sizeof(CovMapHeader)) return make_error(coveragemap_error::malformed); - CoverageMapping = CoverageMapping.substr(Pad); + auto const *CovHeader = reinterpret_cast( + Data.substr(0, sizeof(CovMapHeader)).data()); + CovMapVersion Version = + (CovMapVersion)CovHeader->getVersion(); + StringRef CoverageMapping, CoverageRecords; + if (Version < CovMapVersion::Version4) { + CoverageMapping = Data; + if (CoverageMapping.empty()) + return make_error(coveragemap_error::truncated); + } else { + uint32_t FilenamesSize = + CovHeader->getFilenamesSize(); + uint32_t CoverageMappingSize = sizeof(CovMapHeader) + FilenamesSize; + CoverageMapping = Data.substr(0, CoverageMappingSize); + if (CoverageMapping.empty()) + return make_error(coveragemap_error::truncated); + Data = Data.substr(CoverageMappingSize); + // Skip the padding bytes because coverage records data has an alignment + // of 8. + Pad = offsetToAlignedAddr(Data.data(), Align(8)); + if (Data.size() < Pad) + return make_error(coveragemap_error::malformed); + CoverageRecords = Data.substr(Pad); + if (CoverageRecords.empty()) + return make_error(coveragemap_error::truncated); + } return BinaryCoverageReader::createCoverageReaderFromBuffer( - CoverageMapping, "", std::move(ProfileNames), BytesInAddress, Endian); + CoverageMapping, CoverageRecords.str(), std::move(ProfileNames), + BytesInAddress, Endian); } /// Find all sections that match \p Name. There may be more than one if comdats diff --git a/llvm/tools/llvm-cov/TestingSupport.cpp b/llvm/tools/llvm-cov/TestingSupport.cpp --- a/llvm/tools/llvm-cov/TestingSupport.cpp +++ b/llvm/tools/llvm-cov/TestingSupport.cpp @@ -47,7 +47,7 @@ // Look for the sections that we are interested in. int FoundSectionCount = 0; - SectionRef ProfileNames, CoverageMapping; + SectionRef ProfileNames, CoverageMapping, CoverageRecords; auto ObjFormat = OF->getTripleObjectFormat(); for (const auto &Section : OF->sections()) { StringRef Name; @@ -64,16 +64,20 @@ } else if (Name == llvm::getInstrProfSectionName( IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)) { CoverageMapping = Section; + } else if (Name == llvm::getInstrProfSectionName( + IPSK_covfun, ObjFormat, /*AddSegmentInfo=*/false)) { + CoverageRecords = Section; } else continue; ++FoundSectionCount; } - if (FoundSectionCount != 2) + if (FoundSectionCount != 3) return 1; // Get the contents of the given sections. uint64_t ProfileNamesAddress = ProfileNames.getAddress(); StringRef CoverageMappingData; + StringRef CoverageRecordsData; StringRef ProfileNamesData; if (Expected E = CoverageMapping.getContents()) CoverageMappingData = *E; @@ -81,6 +85,12 @@ consumeError(E.takeError()); return 1; } + if (Expected E = CoverageRecords.getContents()) + CoverageRecordsData = *E; + else { + consumeError(E.takeError()); + return 1; + } if (Expected E = ProfileNames.getContents()) ProfileNamesData = *E; else { @@ -103,6 +113,10 @@ for (unsigned Pad = offsetToAlignment(OS.tell(), Align(8)); Pad; --Pad) OS.write(uint8_t(0)); OS << CoverageMappingData; + // Coverage records data is expected to have an alignment of 8. + for (unsigned Pad = offsetToAlignment(OS.tell(), Align(8)); Pad; --Pad) + OS.write(uint8_t(0)); + OS << CoverageRecordsData; return 0; }