diff options
Diffstat (limited to 'lib/ProfileData/CoverageMappingReader.cpp')
-rw-r--r-- | lib/ProfileData/CoverageMappingReader.cpp | 161 |
1 files changed, 72 insertions, 89 deletions
diff --git a/lib/ProfileData/CoverageMappingReader.cpp b/lib/ProfileData/CoverageMappingReader.cpp index 6476d28..d32f1da 100644 --- a/lib/ProfileData/CoverageMappingReader.cpp +++ b/lib/ProfileData/CoverageMappingReader.cpp @@ -173,15 +173,12 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray( } // Read the source range. - uint64_t LineStartDelta, CodeBeforeColumnStart, NumLines, ColumnEnd; + uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd; if (auto Err = readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max())) return Err; - if (auto Err = readULEB128(CodeBeforeColumnStart)) + if (auto Err = readULEB128(ColumnStart)) return Err; - bool HasCodeBefore = CodeBeforeColumnStart & 1; - uint64_t ColumnStart = CodeBeforeColumnStart >> - CounterMappingRegion::EncodingHasCodeBeforeBits; if (ColumnStart > std::numeric_limits<unsigned>::max()) return error(instrprof_error::malformed); if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max())) @@ -214,14 +211,13 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray( }); MappingRegions.push_back(CounterMappingRegion( - C, InferredFileID, LineStart, ColumnStart, LineStart + NumLines, - ColumnEnd, HasCodeBefore, Kind)); - MappingRegions.back().ExpandedFileID = ExpandedFileID; + C, InferredFileID, ExpandedFileID, LineStart, ColumnStart, + LineStart + NumLines, ColumnEnd, Kind)); } return success(); } -std::error_code RawCoverageMappingReader::read(CoverageMappingRecord &Record) { +std::error_code RawCoverageMappingReader::read() { // Read the virtual file mapping. llvm::SmallVector<unsigned, 8> VirtualFileMapping; @@ -287,23 +283,9 @@ std::error_code RawCoverageMappingReader::read(CoverageMappingRecord &Record) { } } - Record.FunctionName = FunctionName; - Record.Filenames = Filenames; - Record.Expressions = Expressions; - Record.MappingRegions = MappingRegions; return success(); } -ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader( - StringRef FileName) - : CurrentRecord(0) { - auto File = llvm::object::ObjectFile::createObjectFile(FileName); - if (!File) - error(File.getError()); - else - Object = std::move(File.get()); -} - namespace { /// \brief The coverage mapping data for a single function. /// It points to the function's name. @@ -352,7 +334,7 @@ struct SectionData { template <typename T> std::error_code readCoverageMappingData( SectionData &ProfileNames, StringRef Data, - std::vector<ObjectFileCoverageMappingReader::ProfileMappingRecord> &Records, + std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records, std::vector<StringRef> &Filenames) { llvm::DenseSet<T> UniqueFunctionMappingData; @@ -418,7 +400,7 @@ std::error_code readCoverageMappingData( ProfileNames.get(MappingRecord.FunctionNamePtr, MappingRecord.FunctionNameSize, FunctionName)) return Err; - Records.push_back(ObjectFileCoverageMappingReader::ProfileMappingRecord( + Records.push_back(BinaryCoverageReader::ProfileMappingRecord( Version, FunctionName, MappingRecord.FunctionHash, Mapping, FilenamesBegin, Filenames.size() - FilenamesBegin)); } @@ -429,9 +411,12 @@ std::error_code readCoverageMappingData( static const char *TestingFormatMagic = "llvmcovmtestdata"; -static std::error_code decodeTestingFormat(StringRef Data, - SectionData &ProfileNames, - StringRef &CoverageMapping) { +static std::error_code loadTestingFormat(StringRef Data, + SectionData &ProfileNames, + StringRef &CoverageMapping, + uint8_t &BytesInAddress) { + BytesInAddress = 8; + Data = Data.substr(StringRef(TestingFormatMagic).size()); if (Data.size() < 1) return instrprof_error::truncated; @@ -456,98 +441,96 @@ static std::error_code decodeTestingFormat(StringRef Data, return instrprof_error::success; } -ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader( - std::unique_ptr<MemoryBuffer> &ObjectBuffer, sys::fs::file_magic Type) - : CurrentRecord(0) { - if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic)) { - // This is a special format used for testing. - SectionData ProfileNames; - StringRef CoverageMapping; - if (auto Err = decodeTestingFormat(ObjectBuffer->getBuffer(), ProfileNames, - CoverageMapping)) { - error(Err); - return; - } - error(readCoverageMappingData<uint64_t>(ProfileNames, CoverageMapping, - MappingRecords, Filenames)); - Object = OwningBinary<ObjectFile>(std::unique_ptr<ObjectFile>(), - std::move(ObjectBuffer)); - return; - } - - auto File = object::ObjectFile::createObjectFile( - ObjectBuffer->getMemBufferRef(), Type); - if (!File) - error(File.getError()); - else - Object = OwningBinary<ObjectFile>(std::move(File.get()), - std::move(ObjectBuffer)); -} - -std::error_code ObjectFileCoverageMappingReader::readHeader() { - const ObjectFile *OF = Object.getBinary(); - if (!OF) - return getError(); - auto BytesInAddress = OF->getBytesInAddress(); - if (BytesInAddress != 4 && BytesInAddress != 8) - return error(instrprof_error::malformed); +static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer, + SectionData &ProfileNames, + StringRef &CoverageMapping, + uint8_t &BytesInAddress) { + auto ObjectFileOrErr = object::ObjectFile::createObjectFile(ObjectBuffer); + if (std::error_code EC = ObjectFileOrErr.getError()) + return EC; + auto OF = std::move(ObjectFileOrErr.get()); + BytesInAddress = OF->getBytesInAddress(); // Look for the sections that we are interested in. int FoundSectionCount = 0; - SectionRef ProfileNames, CoverageMapping; + SectionRef NamesSection, CoverageSection; for (const auto &Section : OF->sections()) { StringRef Name; if (auto Err = Section.getName(Name)) return Err; if (Name == "__llvm_prf_names") { - ProfileNames = Section; + NamesSection = Section; } else if (Name == "__llvm_covmap") { - CoverageMapping = Section; + CoverageSection = Section; } else continue; ++FoundSectionCount; } if (FoundSectionCount != 2) - return error(instrprof_error::bad_header); + return instrprof_error::bad_header; // Get the contents of the given sections. - StringRef Data; - if (auto Err = CoverageMapping.getContents(Data)) - return Err; - SectionData ProfileNamesData; - if (auto Err = ProfileNamesData.load(ProfileNames)) - return Err; + if (std::error_code EC = CoverageSection.getContents(CoverageMapping)) + return EC; + if (std::error_code EC = ProfileNames.load(NamesSection)) + return EC; - // Load the data from the found sections. - std::error_code Err; - if (BytesInAddress == 4) - Err = readCoverageMappingData<uint32_t>(ProfileNamesData, Data, - MappingRecords, Filenames); + return std::error_code(); +} + +ErrorOr<std::unique_ptr<BinaryCoverageReader>> +BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer) { + std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader()); + + SectionData Profile; + StringRef Coverage; + uint8_t BytesInAddress; + std::error_code EC; + if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic)) + // This is a special format used for testing. + EC = loadTestingFormat(ObjectBuffer->getBuffer(), Profile, Coverage, + BytesInAddress); else - Err = readCoverageMappingData<uint64_t>(ProfileNamesData, Data, - MappingRecords, Filenames); - if (Err) - return error(Err); + EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Profile, Coverage, + BytesInAddress); + if (EC) + return EC; - return success(); + if (BytesInAddress == 4) + EC = readCoverageMappingData<uint32_t>( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else if (BytesInAddress == 8) + EC = readCoverageMappingData<uint64_t>( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else + return instrprof_error::malformed; + if (EC) + return EC; + return std::move(Reader); } std::error_code -ObjectFileCoverageMappingReader::readNextRecord(CoverageMappingRecord &Record) { +BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) { if (CurrentRecord >= MappingRecords.size()) - return error(instrprof_error::eof); + return instrprof_error::eof; FunctionsFilenames.clear(); Expressions.clear(); MappingRegions.clear(); auto &R = MappingRecords[CurrentRecord]; RawCoverageMappingReader Reader( - R.FunctionName, R.CoverageMapping, - makeArrayRef(Filenames.data() + R.FilenamesBegin, R.FilenamesSize), + R.CoverageMapping, + makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize), FunctionsFilenames, Expressions, MappingRegions); - if (auto Err = Reader.read(Record)) + if (auto Err = Reader.read()) return Err; + + Record.FunctionName = R.FunctionName; Record.FunctionHash = R.FunctionHash; + Record.Filenames = FunctionsFilenames; + Record.Expressions = Expressions; + Record.MappingRegions = MappingRegions; + ++CurrentRecord; - return success(); + return std::error_code(); } |