aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ProfileData/CoverageMappingReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ProfileData/CoverageMappingReader.cpp')
-rw-r--r--lib/ProfileData/CoverageMappingReader.cpp161
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();
}