forked from OSchip/llvm-project
[DWARF] Added check that verifies that no abbreviation declaration has more than one attribute with the same name.
SUMMARY This patch adds a verification check on the abbreviation declarations in the .debug_abbrev section. The check makes sure that no abbreviation declaration has more than one attributes with the same name. Differential Revision: https://reviews.llvm.org/D35643 llvm-svn: 308579
This commit is contained in:
parent
7af8fa41d3
commit
364b535234
|
@ -114,6 +114,13 @@ class DWARFVerifier {
|
|||
public:
|
||||
DWARFVerifier(raw_ostream &S, DWARFContext &D)
|
||||
: OS(S), DCtx(D) {}
|
||||
/// Verify the information in the .debug_abbrev section.
|
||||
///
|
||||
/// Currently, we check that no Abbreviation Declaration has more than one
|
||||
/// attributes with the same name.
|
||||
///
|
||||
/// \returns true if the .debug_abbrev verifies successfully, false otherwise.
|
||||
bool handleDebugAbbrev();
|
||||
/// Verify the information in the .debug_info section.
|
||||
///
|
||||
/// Any errors are reported to the stream that was this object was
|
||||
|
|
|
@ -418,6 +418,7 @@ DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
|
|||
bool DWARFContext::verify(raw_ostream &OS, DIDumpType DumpType) {
|
||||
bool Success = true;
|
||||
DWARFVerifier verifier(OS, *this);
|
||||
Success &= verifier.handleDebugAbbrev();
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_Info) {
|
||||
if (!verifier.handleDebugInfo())
|
||||
Success = false;
|
||||
|
|
|
@ -102,6 +102,37 @@ bool DWARFVerifier::verifyUnitContents(DWARFUnit Unit) {
|
|||
return NumUnitErrors == 0;
|
||||
}
|
||||
|
||||
bool DWARFVerifier::handleDebugAbbrev() {
|
||||
OS << "Verifying .debug_abbrev...\n";
|
||||
|
||||
const DWARFObject &DObj = DCtx.getDWARFObj();
|
||||
if (DObj.getAbbrevSection().empty()) {
|
||||
OS << "Warning: .debug_abbrev is empty.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned NumErrors = 0;
|
||||
const DWARFDebugAbbrev *Abbrev = DCtx.getDebugAbbrev();
|
||||
if (Abbrev) {
|
||||
const DWARFAbbreviationDeclarationSet *AbbrDecls =
|
||||
Abbrev->getAbbreviationDeclarationSet(0);
|
||||
for (auto AbbrDecl : *AbbrDecls) {
|
||||
SmallDenseSet<uint16_t> AttributeSet;
|
||||
for (auto Attribute : AbbrDecl.attributes()) {
|
||||
auto Result = AttributeSet.insert(Attribute.Attr);
|
||||
if (!Result.second) {
|
||||
OS << format("Error: Abbreviation declaration with code %d ",
|
||||
AbbrDecl.getCode());
|
||||
OS << "contains multiple " << AttributeString(Attribute.Attr)
|
||||
<< " attributes.\n";
|
||||
++NumErrors;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NumErrors == 0;
|
||||
}
|
||||
|
||||
bool DWARFVerifier::handleDebugInfo() {
|
||||
OS << "Verifying .debug_info Unit Header Chain...\n";
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
# RUN: | not llvm-dwarfdump -verify - \
|
||||
# RUN: | FileCheck %s
|
||||
|
||||
# CHECK: Verifying .debug_info Unit Header Chain...
|
||||
# CHECK: Verifying .debug_abbrev...
|
||||
# CHECK-NEXT: Error: Abbreviation declaration with code 2 contains multiple DW_AT_low_pc attributes.
|
||||
# CHECK-NEXT: Verifying .debug_info Unit Header Chain...
|
||||
# CHECK-NEXT: error: DIE has invalid DW_AT_stmt_list encoding:{{[[:space:]]}}
|
||||
# CHECK-NEXT: 0x0000000c: DW_TAG_compile_unit [1] *
|
||||
# CHECK-NEXT: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000000] = "clang version 5.0.0 (trunk 308185) (llvm/trunk 308186)")
|
||||
|
@ -80,7 +82,7 @@ Lsection_abbrev:
|
|||
.byte 1 ## DW_CHILDREN_yes
|
||||
.byte 17 ## DW_AT_low_pc
|
||||
.byte 1 ## DW_FORM_addr
|
||||
.byte 18 ## DW_AT_high_pc
|
||||
.byte 17 ## DW_AT_low_pc -- Error: Die at offset 0x0000002b contains multiple DW_AT_low_pc attributes.
|
||||
.byte 6 ## DW_FORM_data4
|
||||
.byte 64 ## DW_AT_frame_base
|
||||
.byte 24 ## DW_FORM_exprloc
|
||||
|
|
Loading…
Reference in New Issue