summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp175
-rw-r--r--llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp15
-rw-r--r--llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h16
3 files changed, 118 insertions, 88 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index eadb982ba72..7f5ef1567ca 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "SyntaxHighlighting.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
@@ -23,6 +24,7 @@
using namespace llvm;
using namespace dwarf;
using namespace object;
+using namespace syntax;
DWARFVerifier::DieRangeInfo::address_range_iterator
DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
@@ -148,19 +150,20 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
!ValidType) {
Success = false;
- OS << format("Units[%d] - start offset: 0x%08x \n", UnitIndex, OffsetStart);
+ error() << format("Units[%d] - start offset: 0x%08x \n", UnitIndex,
+ OffsetStart);
if (!ValidLength)
- OS << "\tError: The length for this unit is too "
+ note() << "The length for this unit is too "
"large for the .debug_info provided.\n";
if (!ValidVersion)
- OS << "\tError: The 16 bit unit header version is not valid.\n";
+ note() << "The 16 bit unit header version is not valid.\n";
if (!ValidType)
- OS << "\tError: The unit type encoding is not valid.\n";
+ note() << "The unit type encoding is not valid.\n";
if (!ValidAbbrevOffset)
- OS << "\tError: The offset into the .debug_abbrev section is "
+ note() << "The offset into the .debug_abbrev section is "
"not valid.\n";
if (!ValidAddrSize)
- OS << "\tError: The address size is unsupported.\n";
+ note() << "The address size is unsupported.\n";
}
*Offset = OffsetStart + Length + 4;
return Success;
@@ -183,7 +186,7 @@ bool DWARFVerifier::verifyUnitContents(DWARFUnit Unit) {
DieRangeInfo RI;
NumUnitErrors += verifyDieRanges(Die, RI);
} else {
- OS << "error: Compilation unit without unit DIE.\n";
+ error() << "Compilation unit without unit DIE.\n";
NumUnitErrors++;
}
@@ -200,8 +203,8 @@ unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
for (auto Attribute : AbbrDecl.attributes()) {
auto Result = AttributeSet.insert(Attribute.Attr);
if (!Result.second) {
- OS << "Error: Abbreviation declaration contains multiple "
- << AttributeString(Attribute.Attr) << " attributes.\n";
+ error() << "Abbreviation declaration contains multiple "
+ << AttributeString(Attribute.Attr) << " attributes.\n";
AbbrDecl.dump(OS);
++NumErrors;
}
@@ -290,7 +293,7 @@ bool DWARFVerifier::handleDebugInfo() {
++UnitIdx;
}
if (UnitIdx == 0 && !hasDIE) {
- OS << "Warning: .debug_info is empty.\n";
+ warn() << ".debug_info is empty.\n";
isHeaderChainValid = true;
}
NumDebugInfoErrors += verifyDebugInfoReferences();
@@ -312,9 +315,9 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
for (auto Range : Ranges) {
if (!Range.valid()) {
++NumErrors;
- OS << format("error: Invalid address range [0x%08" PRIx64
- " - 0x%08" PRIx64 "].\n",
- Range.LowPC, Range.HighPC);
+ error() << format("Invalid address range [0x%08" PRIx64 " - 0x%08" PRIx64
+ "].\n",
+ Range.LowPC, Range.HighPC);
continue;
}
@@ -322,11 +325,11 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
const auto IntersectingRange = RI.insert(Range);
if (IntersectingRange != RI.Ranges.end()) {
++NumErrors;
- OS << format("error: DIE has overlapping address ranges: [0x%08" PRIx64
- " - 0x%08" PRIx64 "] and [0x%08" PRIx64 " - 0x%08" PRIx64
- "].\n",
- Range.LowPC, Range.HighPC, IntersectingRange->LowPC,
- IntersectingRange->HighPC);
+ error() << format("DIE has overlapping address ranges: [0x%08" PRIx64
+ " - 0x%08" PRIx64 "] and [0x%08" PRIx64
+ " - 0x%08" PRIx64 "].\n",
+ Range.LowPC, Range.HighPC, IntersectingRange->LowPC,
+ IntersectingRange->HighPC);
break;
}
}
@@ -335,7 +338,7 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
const auto IntersectingChild = ParentRI.insert(RI);
if (IntersectingChild != ParentRI.Children.end()) {
++NumErrors;
- OS << "error: DIEs have overlapping address ranges:";
+ error() << "DIEs have overlapping address ranges:";
Die.dump(OS, 0);
IntersectingChild->Die.dump(OS, 0);
OS << "\n";
@@ -347,8 +350,8 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
ParentRI.Die.getTag() == DW_TAG_subprogram);
if (ShouldBeContained && !ParentRI.contains(RI)) {
++NumErrors;
- OS << "error: DIE address ranges are not "
- "contained in its parent's ranges:";
+ error() << "DIE address ranges are not "
+ "contained in its parent's ranges:";
Die.dump(OS, 0);
ParentRI.Die.dump(OS, 0);
OS << "\n";
@@ -372,14 +375,14 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
if (*SectionOffset >= DObj.getRangeSection().Data.size()) {
++NumErrors;
- OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
- "bounds:\n";
+ error() << "DW_AT_ranges offset is beyond .debug_ranges "
+ "bounds:\n";
Die.dump(OS, 0, DumpOpts);
OS << "\n";
}
} else {
++NumErrors;
- OS << "error: DIE has invalid DW_AT_ranges encoding:\n";
+ error() << "DIE has invalid DW_AT_ranges encoding:\n";
Die.dump(OS, 0, DumpOpts);
OS << "\n";
}
@@ -389,15 +392,15 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
if (*SectionOffset >= DObj.getLineSection().Data.size()) {
++NumErrors;
- OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
- "bounds: "
- << format("0x%08" PRIx64, *SectionOffset) << "\n";
+ error() << "DW_AT_stmt_list offset is beyond .debug_line "
+ "bounds: "
+ << format("0x%08" PRIx64, *SectionOffset) << "\n";
Die.dump(OS, 0, DumpOpts);
OS << "\n";
}
} else {
++NumErrors;
- OS << "error: DIE has invalid DW_AT_stmt_list encoding:\n";
+ error() << "DIE has invalid DW_AT_stmt_list encoding:\n";
Die.dump(OS, 0, DumpOpts);
OS << "\n";
}
@@ -429,10 +432,10 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
auto CUOffset = AttrValue.Value.getRawUValue();
if (CUOffset >= CUSize) {
++NumErrors;
- OS << "error: " << FormEncodingString(Form) << " CU offset "
- << format("0x%08" PRIx64, CUOffset)
- << " is invalid (must be less than CU size of "
- << format("0x%08" PRIx32, CUSize) << "):\n";
+ error() << FormEncodingString(Form) << " CU offset "
+ << format("0x%08" PRIx64, CUOffset)
+ << " is invalid (must be less than CU size of "
+ << format("0x%08" PRIx32, CUSize) << "):\n";
Die.dump(OS, 0, DumpOpts);
OS << "\n";
} else {
@@ -451,8 +454,8 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
if (RefVal) {
if (*RefVal >= DObj.getInfoSection().Data.size()) {
++NumErrors;
- OS << "error: DW_FORM_ref_addr offset beyond .debug_info "
- "bounds:\n";
+ error() << "DW_FORM_ref_addr offset beyond .debug_info "
+ "bounds:\n";
Die.dump(OS, 0, DumpOpts);
OS << "\n";
} else {
@@ -468,7 +471,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
assert(SecOffset); // DW_FORM_strp is a section offset.
if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
++NumErrors;
- OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n";
+ error() << "DW_FORM_strp offset beyond .debug_str bounds:\n";
Die.dump(OS, 0, DumpOpts);
OS << "\n";
}
@@ -490,8 +493,8 @@ unsigned DWARFVerifier::verifyDebugInfoReferences() {
if (Die)
continue;
++NumErrors;
- OS << "error: invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
- << ". Offset is in between DIEs:\n";
+ error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
+ << ". Offset is in between DIEs:\n";
for (auto Offset : Pair.second) {
auto ReferencingDie = DCtx.getDIEForOffset(Offset);
ReferencingDie.dump(OS, 0, DumpOpts);
@@ -517,8 +520,8 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() {
if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
if (!LineTable) {
++NumDebugLineErrors;
- OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
- << "] was not able to be parsed for CU:\n";
+ error() << ".debug_line[" << format("0x%08" PRIx32, LineTableOffset)
+ << "] was not able to be parsed for CU:\n";
Die.dump(OS, 0, DumpOpts);
OS << '\n';
continue;
@@ -533,10 +536,10 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() {
auto Iter = StmtListToDie.find(LineTableOffset);
if (Iter != StmtListToDie.end()) {
++NumDebugLineErrors;
- OS << "error: two compile unit DIEs, "
- << format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
- << format("0x%08" PRIx32, Die.getOffset())
- << ", have the same DW_AT_stmt_list section offset:\n";
+ error() << "two compile unit DIEs, "
+ << format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
+ << format("0x%08" PRIx32, Die.getOffset())
+ << ", have the same DW_AT_stmt_list section offset:\n";
Iter->second.dump(OS, 0, DumpOpts);
Die.dump(OS, 0, DumpOpts);
OS << '\n';
@@ -565,12 +568,12 @@ void DWARFVerifier::verifyDebugLineRows() {
// Verify directory index.
if (FileName.DirIdx > MaxDirIndex) {
++NumDebugLineErrors;
- OS << "error: .debug_line["
- << format("0x%08" PRIx64,
- *toSectionOffset(Die.find(DW_AT_stmt_list)))
- << "].prologue.file_names[" << FileIndex
- << "].dir_idx contains an invalid index: " << FileName.DirIdx
- << "\n";
+ error() << ".debug_line["
+ << format("0x%08" PRIx64,
+ *toSectionOffset(Die.find(DW_AT_stmt_list)))
+ << "].prologue.file_names[" << FileIndex
+ << "].dir_idx contains an invalid index: " << FileName.DirIdx
+ << "\n";
}
// Check file paths for duplicates.
@@ -584,11 +587,11 @@ void DWARFVerifier::verifyDebugLineRows() {
if (It == FullPathMap.end())
FullPathMap[FullPath] = FileIndex;
else if (It->second != FileIndex) {
- OS << "warning: .debug_line["
- << format("0x%08" PRIx64,
- *toSectionOffset(Die.find(DW_AT_stmt_list)))
- << "].prologue.file_names[" << FileIndex
- << "] is a duplicate of file_names[" << It->second << "]\n";
+ warn() << ".debug_line["
+ << format("0x%08" PRIx64,
+ *toSectionOffset(Die.find(DW_AT_stmt_list)))
+ << "].prologue.file_names[" << FileIndex
+ << "] is a duplicate of file_names[" << It->second << "]\n";
}
FileIndex++;
@@ -601,11 +604,11 @@ void DWARFVerifier::verifyDebugLineRows() {
// Verify row address.
if (Row.Address < PrevAddress) {
++NumDebugLineErrors;
- OS << "error: .debug_line["
- << format("0x%08" PRIx64,
- *toSectionOffset(Die.find(DW_AT_stmt_list)))
- << "] row[" << RowIndex
- << "] decreases in address from previous row:\n";
+ error() << ".debug_line["
+ << format("0x%08" PRIx64,
+ *toSectionOffset(Die.find(DW_AT_stmt_list)))
+ << "] row[" << RowIndex
+ << "] decreases in address from previous row:\n";
DWARFDebugLine::Row::dumpTableHeader(OS);
if (RowIndex > 0)
@@ -617,11 +620,11 @@ void DWARFVerifier::verifyDebugLineRows() {
// Verify file index.
if (Row.File > MaxFileIndex) {
++NumDebugLineErrors;
- OS << "error: .debug_line["
- << format("0x%08" PRIx64,
- *toSectionOffset(Die.find(DW_AT_stmt_list)))
- << "][" << RowIndex << "] has invalid file index " << Row.File
- << " (valid values are [1," << MaxFileIndex << "]):\n";
+ error() << ".debug_line["
+ << format("0x%08" PRIx64,
+ *toSectionOffset(Die.find(DW_AT_stmt_list)))
+ << "][" << RowIndex << "] has invalid file index " << Row.File
+ << " (valid values are [1," << MaxFileIndex << "]):\n";
DWARFDebugLine::Row::dumpTableHeader(OS);
Row.dump(OS);
OS << '\n';
@@ -652,17 +655,19 @@ unsigned DWARFVerifier::verifyAccelTable(const DWARFSection *AccelSection,
DWARFAcceleratorTable AccelTable(AccelSectionData, *StrData);
OS << "Verifying " << SectionName << "...\n";
- // Verify that the fixed part of the header is not too short.
+ // Verify that the fixed part of the header is not too short.
if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
- OS << "\terror: Section is too small to fit a section header.\n";
+ error() << "Section is too small to fit a section header.\n";
return 1;
}
+
// Verify that the section is not too short.
if (!AccelTable.extract()) {
- OS << "\terror: Section is smaller than size described in section header.\n";
+ error() << "Section is smaller than size described in section header.\n";
return 1;
}
+
// Verify that all buckets have a valid hash index or are empty.
uint32_t NumBuckets = AccelTable.getNumBuckets();
uint32_t NumHashes = AccelTable.getNumHashes();
@@ -674,18 +679,18 @@ unsigned DWARFVerifier::verifyAccelTable(const DWARFSection *AccelSection,
for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
- OS << format("\terror: Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
- HashIdx);
+ error() << format("Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
+ HashIdx);
++NumErrors;
}
}
uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
if (NumAtoms == 0) {
- OS << "\terror: no atoms; failed to read HashData.\n";
+ error() << "No atoms: failed to read HashData.\n";
return 1;
}
if (!AccelTable.validateForms()) {
- OS << "\terror: unsupported form; failed to read HashData.\n";
+ error() << "Unsupported form: failed to read HashData.\n";
return 1;
}
@@ -696,8 +701,8 @@ unsigned DWARFVerifier::verifyAccelTable(const DWARFSection *AccelSection,
uint32_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
sizeof(uint64_t))) {
- OS << format("\terror: Hash[%d] has invalid HashData offset: 0x%08x.\n",
- HashIdx, HashDataOffset);
+ error() << format("Hash[%d] has invalid HashData offset: 0x%08x.\n",
+ HashIdx, HashDataOffset);
++NumErrors;
}
@@ -721,8 +726,8 @@ unsigned DWARFVerifier::verifyAccelTable(const DWARFSection *AccelSection,
if (!Name)
Name = "<NULL>";
- OS << format(
- "\terror: %s Bucket[%d] Hash[%d] = 0x%08x "
+ error() << format(
+ "%s Bucket[%d] Hash[%d] = 0x%08x "
"Str[%u] = 0x%08x "
"DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n",
SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
@@ -732,10 +737,10 @@ unsigned DWARFVerifier::verifyAccelTable(const DWARFSection *AccelSection,
continue;
}
if ((Tag != dwarf::DW_TAG_null) && (Die.getTag() != Tag)) {
- OS << "\terror: Tag " << dwarf::TagString(Tag)
- << " in accelerator table does not match Tag "
- << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
- << "].\n";
+ error() << "Tag " << dwarf::TagString(Tag)
+ << " in accelerator table does not match Tag "
+ << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
+ << "].\n";
++NumErrors;
}
}
@@ -763,3 +768,15 @@ bool DWARFVerifier::handleAccelTables() {
verifyAccelTable(&D.getAppleObjCSection(), &StrData, ".apple_objc");
return NumErrors == 0;
}
+
+raw_ostream &DWARFVerifier::error() const {
+ return WithColor(OS, syntax::Error).get() << "error: ";
+}
+
+raw_ostream &DWARFVerifier::warn() const {
+ return WithColor(OS, syntax::Warning).get() << "warning: ";
+}
+
+raw_ostream &DWARFVerifier::note() const {
+ return WithColor(OS, syntax::Note).get() << "note: ";
+}
diff --git a/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp b/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp
index d4f44e44695..65d66fc8f51 100644
--- a/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp
+++ b/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp
@@ -24,12 +24,15 @@ WithColor::WithColor(raw_ostream &OS, enum HighlightColor Type) : OS(OS) {
// Detect color from terminal type unless the user passed the --color option.
if (UseColor == cl::BOU_UNSET ? OS.has_colors() : UseColor == cl::BOU_TRUE) {
switch (Type) {
- case Address: OS.changeColor(raw_ostream::YELLOW); break;
- case String: OS.changeColor(raw_ostream::GREEN); break;
- case Tag: OS.changeColor(raw_ostream::BLUE); break;
- case Attribute: OS.changeColor(raw_ostream::CYAN); break;
- case Enumerator: OS.changeColor(raw_ostream::MAGENTA); break;
- case Macro: OS.changeColor(raw_ostream::RED); break;
+ case Address: OS.changeColor(raw_ostream::YELLOW); break;
+ case String: OS.changeColor(raw_ostream::GREEN); break;
+ case Tag: OS.changeColor(raw_ostream::BLUE); break;
+ case Attribute: OS.changeColor(raw_ostream::CYAN); break;
+ case Enumerator: OS.changeColor(raw_ostream::MAGENTA); break;
+ case Macro: OS.changeColor(raw_ostream::RED); break;
+ case Error: OS.changeColor(raw_ostream::RED, true); break;
+ case Warning: OS.changeColor(raw_ostream::MAGENTA, true); break;
+ case Note: OS.changeColor(raw_ostream::BLACK, true); break;
}
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h b/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h
index 277de973dbf..686cf2c7760 100644
--- a/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h
+++ b/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h
@@ -18,7 +18,17 @@ namespace dwarf {
namespace syntax {
// Symbolic names for various syntax elements.
-enum HighlightColor { Address, String, Tag, Attribute, Enumerator, Macro };
+enum HighlightColor {
+ Address,
+ String,
+ Tag,
+ Attribute,
+ Enumerator,
+ Macro,
+ Error,
+ Warning,
+ Note
+};
/// An RAII object that temporarily switches an output stream to a
/// specific color.
@@ -30,8 +40,8 @@ public:
WithColor(raw_ostream &OS, enum HighlightColor Type);
~WithColor();
- raw_ostream& get() { return OS; }
- operator raw_ostream& () { return OS; }
+ raw_ostream &get() { return OS; }
+ operator raw_ostream &() { return OS; }
};
} // end namespace syntax
OpenPOWER on IntegriCloud