diff --git a/include/llvm/ProfileData/CoverageMappingReader.h b/include/llvm/ProfileData/CoverageMappingReader.h index 8226793a5d0..671436608ff 100644 --- a/include/llvm/ProfileData/CoverageMappingReader.h +++ b/include/llvm/ProfileData/CoverageMappingReader.h @@ -161,8 +161,6 @@ public: }; private: - std::error_code LastError; - object::OwningBinary Object; std::vector Filenames; std::vector MappingRecords; size_t CurrentRecord; @@ -173,28 +171,13 @@ private: BinaryCoverageReader(const BinaryCoverageReader &) = delete; BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete; - /// \brief Set the current error_code and return same. - std::error_code error(std::error_code EC) { - LastError = EC; - return EC; - } - - /// \brief Clear the current error code and return a successful one. - std::error_code success() { return error(instrprof_error::success); } + BinaryCoverageReader() : CurrentRecord(0) {} public: - BinaryCoverageReader(std::unique_ptr &ObjectBuffer); + static ErrorOr> + create(std::unique_ptr &ObjectBuffer); - std::error_code readHeader(); std::error_code readNextRecord(CoverageMappingRecord &Record) override; - - /// \brief Return true if the reader has finished reading the profile data. - bool isEOF() { return LastError == instrprof_error::eof; } - /// \brief Return true if the reader encountered an error reading profiling - /// data. - bool hasError() { return LastError && !isEOF(); } - /// \brief Get the current error code. - std::error_code getError() { return LastError; } }; } // end namespace coverage diff --git a/lib/ProfileData/CoverageMapping.cpp b/lib/ProfileData/CoverageMapping.cpp index 915aae3e594..31213d7fb2d 100644 --- a/lib/ProfileData/CoverageMapping.cpp +++ b/lib/ProfileData/CoverageMapping.cpp @@ -219,16 +219,18 @@ CoverageMapping::load(CoverageMappingReader &CoverageReader, ErrorOr> CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename) { auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename); - if (auto EC = CounterMappingBuff.getError()) + if (std::error_code EC = CounterMappingBuff.getError()) return EC; - BinaryCoverageReader CoverageReader(CounterMappingBuff.get()); - if (auto EC = CoverageReader.readHeader()) + auto CoverageReaderOrErr = + BinaryCoverageReader::create(CounterMappingBuff.get()); + if (std::error_code EC = CoverageReaderOrErr.getError()) return EC; + auto CoverageReader = std::move(CoverageReaderOrErr.get()); auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename); if (auto EC = ProfileReaderOrErr.getError()) return EC; auto ProfileReader = std::move(ProfileReaderOrErr.get()); - return load(CoverageReader, *ProfileReader); + return load(*CoverageReader, *ProfileReader); } namespace { diff --git a/lib/ProfileData/CoverageMappingReader.cpp b/lib/ProfileData/CoverageMappingReader.cpp index 168115a1534..d32f1dac456 100644 --- a/lib/ProfileData/CoverageMappingReader.cpp +++ b/lib/ProfileData/CoverageMappingReader.cpp @@ -411,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; @@ -438,86 +441,78 @@ static std::error_code decodeTestingFormat(StringRef Data, return instrprof_error::success; } -BinaryCoverageReader::BinaryCoverageReader( - std::unique_ptr &ObjectBuffer) - : 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(ProfileNames, CoverageMapping, - MappingRecords, Filenames)); - Object = OwningBinary(std::unique_ptr(), - std::move(ObjectBuffer)); - return; - } - - auto File = - object::ObjectFile::createObjectFile(ObjectBuffer->getMemBufferRef()); - if (!File) - error(File.getError()); - else - Object = OwningBinary(std::move(File.get()), - std::move(ObjectBuffer)); -} - -std::error_code BinaryCoverageReader::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(ProfileNamesData, Data, - MappingRecords, Filenames); + return std::error_code(); +} + +ErrorOr> +BinaryCoverageReader::create(std::unique_ptr &ObjectBuffer) { + std::unique_ptr 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(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( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else if (BytesInAddress == 8) + EC = readCoverageMappingData( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else + return instrprof_error::malformed; + if (EC) + return EC; + return std::move(Reader); } std::error_code BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) { if (CurrentRecord >= MappingRecords.size()) - return error(instrprof_error::eof); + return instrprof_error::eof; FunctionsFilenames.clear(); Expressions.clear(); @@ -537,5 +532,5 @@ BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) { Record.MappingRegions = MappingRegions; ++CurrentRecord; - return success(); + return std::error_code(); }