1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

InstrProf: Give coverage its own errors instead of piggy backing on instrprof

Since the coverage mapping reader and the instrprof reader were
emitting a shared set of error codes, the error messages you'd get
back from llvm-cov were ambiguous about what was actually wrong. Add
another error category to fix this.

I've also improved the wording on a couple of the instrprof errors,
for consistency.

llvm-svn: 236665
This commit is contained in:
Justin Bogner 2015-05-06 23:19:35 +00:00
parent a01489eaf6
commit aa99b531f2
5 changed files with 84 additions and 34 deletions

View File

@ -484,7 +484,26 @@ template<> struct DenseMapInfo<coverage::CounterExpression> {
}
};
const std::error_category &coveragemap_category();
enum class coveragemap_error {
success = 0,
eof,
no_data_found,
unsupported_version,
truncated,
malformed
};
inline std::error_code make_error_code(coveragemap_error E) {
return std::error_code(static_cast<int>(E), coveragemap_category());
}
} // end namespace llvm
namespace std {
template <>
struct is_error_code_enum<llvm::coveragemap_error> : std::true_type {};
}
#endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_

View File

@ -20,6 +20,7 @@
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
@ -495,3 +496,33 @@ CoverageMapping::getCoverageForExpansion(const ExpansionRecord &Expansion) {
return ExpansionCoverage;
}
namespace {
class CoverageMappingErrorCategoryType : public std::error_category {
const char *name() const LLVM_NOEXCEPT override { return "llvm.coveragemap"; }
std::string message(int IE) const override {
auto E = static_cast<coveragemap_error>(IE);
switch (E) {
case coveragemap_error::success:
return "Success";
case coveragemap_error::eof:
return "End of File";
case coveragemap_error::no_data_found:
return "No coverage data found";
case coveragemap_error::unsupported_version:
return "Unsupported coverage format version";
case coveragemap_error::truncated:
return "Truncated coverage data";
case coveragemap_error::malformed:
return "Malformed coverage data";
}
llvm_unreachable("A value of coveragemap_error has no message.");
}
};
}
static ManagedStatic<CoverageMappingErrorCategoryType> ErrorCategory;
const std::error_category &llvm::coveragemap_category() {
return *ErrorCategory;
}

View File

@ -36,11 +36,11 @@ void CoverageMappingIterator::increment() {
std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
if (Data.size() < 1)
return instrprof_error::truncated;
return coveragemap_error::truncated;
unsigned N = 0;
Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
if (N > Data.size())
return instrprof_error::malformed;
return coveragemap_error::malformed;
Data = Data.substr(N);
return std::error_code();
}
@ -50,7 +50,7 @@ std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
if (auto Err = readULEB128(Result))
return Err;
if (Result >= MaxPlus1)
return instrprof_error::malformed;
return coveragemap_error::malformed;
return std::error_code();
}
@ -59,7 +59,7 @@ std::error_code RawCoverageReader::readSize(uint64_t &Result) {
return Err;
// Sanity check the number.
if (Result > Data.size())
return instrprof_error::malformed;
return coveragemap_error::malformed;
return std::error_code();
}
@ -104,13 +104,13 @@ std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
case CounterExpression::Add: {
auto ID = Value >> Counter::EncodingTagBits;
if (ID >= Expressions.size())
return instrprof_error::malformed;
return coveragemap_error::malformed;
Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
C = Counter::getExpression(ID);
break;
}
default:
return instrprof_error::malformed;
return coveragemap_error::malformed;
}
return std::error_code();
}
@ -159,7 +159,7 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
ExpandedFileID = EncodedCounterAndRegion >>
Counter::EncodingCounterTagAndExpansionRegionTagBits;
if (ExpandedFileID >= NumFileIDs)
return instrprof_error::malformed;
return coveragemap_error::malformed;
} else {
switch (EncodedCounterAndRegion >>
Counter::EncodingCounterTagAndExpansionRegionTagBits) {
@ -170,7 +170,7 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
Kind = CounterMappingRegion::SkippedRegion;
break;
default:
return instrprof_error::malformed;
return coveragemap_error::malformed;
}
}
}
@ -183,7 +183,7 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
if (auto Err = readULEB128(ColumnStart))
return Err;
if (ColumnStart > std::numeric_limits<unsigned>::max())
return instrprof_error::malformed;
return coveragemap_error::malformed;
if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
return Err;
if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
@ -301,17 +301,17 @@ struct SectionData {
if (auto Err = Section.getContents(Data))
return Err;
Address = Section.getAddress();
return instrprof_error::success;
return std::error_code();
}
std::error_code get(uint64_t Pointer, size_t Size, StringRef &Result) {
if (Pointer < Address)
return instrprof_error::malformed;
return coveragemap_error::malformed;
auto Offset = Pointer - Address;
if (Offset + Size > Data.size())
return instrprof_error::malformed;
return coveragemap_error::malformed;
Result = Data.substr(Pointer - Address, Size);
return instrprof_error::success;
return std::error_code();
}
};
}
@ -327,7 +327,7 @@ std::error_code readCoverageMappingData(
// Read the records in the coverage data section.
for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
if (Buf + 4 * sizeof(uint32_t) > End)
return instrprof_error::malformed;
return coveragemap_error::malformed;
uint32_t NRecords = endian::readNext<uint32_t, Endian, unaligned>(Buf);
uint32_t FilenamesSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
uint32_t CoverageSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
@ -337,7 +337,7 @@ std::error_code readCoverageMappingData(
case CoverageMappingVersion1:
break;
default:
return instrprof_error::unsupported_version;
return coveragemap_error::unsupported_version;
}
// Skip past the function records, saving the start and end for later.
@ -347,7 +347,7 @@ std::error_code readCoverageMappingData(
// Get the filenames.
if (Buf + FilenamesSize > End)
return instrprof_error::malformed;
return coveragemap_error::malformed;
size_t FilenamesBegin = Filenames.size();
RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
if (auto Err = Reader.read())
@ -359,7 +359,7 @@ std::error_code readCoverageMappingData(
Buf += CoverageSize;
const char *CovEnd = Buf;
if (Buf > End)
return instrprof_error::malformed;
return coveragemap_error::malformed;
while (FunBuf < FunEnd) {
// Read the function information
@ -370,7 +370,7 @@ std::error_code readCoverageMappingData(
// Now use that to read the coverage data.
if (CovBuf + DataSize > CovEnd)
return instrprof_error::malformed;
return coveragemap_error::malformed;
auto Mapping = StringRef(CovBuf, DataSize);
CovBuf += DataSize;
@ -390,7 +390,7 @@ std::error_code readCoverageMappingData(
}
}
return instrprof_error::success;
return std::error_code();
}
static const char *TestingFormatMagic = "llvmcovmtestdata";
@ -405,26 +405,26 @@ static std::error_code loadTestingFormat(StringRef Data,
Data = Data.substr(StringRef(TestingFormatMagic).size());
if (Data.size() < 1)
return instrprof_error::truncated;
return coveragemap_error::truncated;
unsigned N = 0;
auto ProfileNamesSize =
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
if (N > Data.size())
return instrprof_error::malformed;
return coveragemap_error::malformed;
Data = Data.substr(N);
if (Data.size() < 1)
return instrprof_error::truncated;
return coveragemap_error::truncated;
N = 0;
ProfileNames.Address =
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
if (N > Data.size())
return instrprof_error::malformed;
return coveragemap_error::malformed;
Data = Data.substr(N);
if (Data.size() < ProfileNamesSize)
return instrprof_error::malformed;
return coveragemap_error::malformed;
ProfileNames.Data = Data.substr(0, ProfileNamesSize);
CoverageMapping = Data.substr(ProfileNamesSize);
return instrprof_error::success;
return std::error_code();
}
static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
@ -453,7 +453,7 @@ static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
return object_error::arch_not_found;
} else
// We can only handle object files.
return instrprof_error::malformed;
return coveragemap_error::malformed;
// The coverage uses native pointer sizes for the object it's written in.
BytesInAddress = OF->getBytesInAddress();
@ -476,7 +476,7 @@ static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
++FoundSectionCount;
}
if (FoundSectionCount != 2)
return instrprof_error::bad_header;
return coveragemap_error::no_data_found;
// Get the contents of the given sections.
if (std::error_code EC = CoverageSection.getContents(CoverageMapping))
@ -520,7 +520,7 @@ BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
EC = readCoverageMappingData<uint64_t, support::endianness::big>(
Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
else
return instrprof_error::malformed;
return coveragemap_error::malformed;
if (EC)
return EC;
return std::move(Reader);
@ -529,7 +529,7 @@ BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
std::error_code
BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
if (CurrentRecord >= MappingRecords.size())
return instrprof_error::eof;
return coveragemap_error::eof;
FunctionsFilenames.clear();
Expressions.clear();

View File

@ -29,13 +29,13 @@ class InstrProfErrorCategoryType : public std::error_category {
case instrprof_error::eof:
return "End of File";
case instrprof_error::bad_magic:
return "Invalid file format (bad magic)";
return "Invalid profile data (bad magic)";
case instrprof_error::bad_header:
return "Invalid header";
return "Invalid profile data (file header is corrupt)";
case instrprof_error::unsupported_version:
return "Unsupported format version";
return "Unsupported profiling format version";
case instrprof_error::unsupported_hash_type:
return "Unsupported hash function";
return "Unsupported profiling hash";
case instrprof_error::too_large:
return "Too much profile data";
case instrprof_error::truncated:

View File

@ -3,4 +3,4 @@ RUN: not llvm-profdata show %t 2>&1 | FileCheck %s
RUN: printf '\377lprofr\201' > %t
RUN: not llvm-profdata show %t 2>&1 | FileCheck %s
CHECK: error: {{.+}}: Invalid header
CHECK: error: {{.+}}: Invalid profile data (file header is corrupt)