From 489a3531a42fe97c7fa00255fc5e8d31a610492d Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Thu, 15 Apr 2021 01:22:04 -0700 Subject: [llvm-cov] Support for v4 format in convert-for-testing v4 moves function records to a dedicated section so we need to write and read it separately. https://reviews.llvm.org/D100535 --- .../ProfileData/Coverage/CoverageMappingReader.cpp | 41 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp') diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index 3f1249a..d7352f2 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -875,16 +875,43 @@ loadTestingFormat(StringRef Data) { 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 -- cgit v1.1