Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[DWARF] Generalized verification of .debug_abbrev to be applicable to…
Browse files Browse the repository at this point in the history
… both .debug_abbrev and .debug_abbrev.dwo sections.

Differential Revision: https://reviews.llvm.org/D35698

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308703 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Spyridoula Gravani committed Jul 21, 2017
1 parent 6bf1d9e commit e95e315
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 23 deletions.
24 changes: 20 additions & 4 deletions include/llvm/DebugInfo/DWARF/DWARFVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class DWARFDie;
class DWARFUnit;
class DWARFAcceleratorTable;
class DWARFDataExtractor;
class DWARFDebugAbbrev;

/// A class that verifies DWARF debug information given a DWARF Context.
class DWARFVerifier {
Expand All @@ -34,6 +35,18 @@ class DWARFVerifier {
uint32_t NumDebugLineErrors = 0;
uint32_t NumAppleNamesErrors = 0;

/// Verifies the abbreviations section.
///
/// This function currently checks that:
/// --No abbreviation declaration has more than one attributes with the same
/// name.
///
/// \param Abbrev Pointer to the abbreviations section we are verifying
/// Abbrev can be a pointer to either .debug_abbrev or debug_abbrev.dwo.
///
/// \returns The number of errors that occured during verification.
unsigned verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev);

/// Verifies the header of a unit in the .debug_info section.
///
/// This function currently checks for:
Expand Down Expand Up @@ -114,13 +127,16 @@ class DWARFVerifier {
public:
DWARFVerifier(raw_ostream &S, DWARFContext &D)
: OS(S), DCtx(D) {}
/// Verify the information in the .debug_abbrev section.
/// Verify the information in any of the following sections, if available:
/// .debug_abbrev, debug_abbrev.dwo
///
/// Currently, we check that no Abbreviation Declaration has more than one
/// attributes with the same name.
/// Any errors are reported to the stream that was this object was
/// constructed with.
///
/// \returns true if the .debug_abbrev verifies successfully, false otherwise.
/// \returns true if .debug_abbrev and .debug_abbrev.dwo verify 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
Expand Down
38 changes: 24 additions & 14 deletions lib/DebugInfo/DWARF/DWARFVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,8 @@ 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 DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
unsigned NumErrors = 0;
const DWARFDebugAbbrev *Abbrev = DCtx.getDebugAbbrev();
if (Abbrev) {
const DWARFAbbreviationDeclarationSet *AbbrDecls =
Abbrev->getAbbreviationDeclarationSet(0);
Expand All @@ -121,15 +112,34 @@ bool DWARFVerifier::handleDebugAbbrev() {
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";
OS << "Error: Abbreviation declaration contains multiple "
<< AttributeString(Attribute.Attr) << " attributes.\n";
AbbrDecl.dump(OS);
++NumErrors;
}
}
}
}
return NumErrors;
}

bool DWARFVerifier::handleDebugAbbrev() {
OS << "Verifying .debug_abbrev...\n";

const DWARFObject &DObj = DCtx.getDWARFObj();
bool noDebugAbbrev = DObj.getAbbrevSection().empty();
bool noDebugAbbrevDWO = DObj.getAbbrevDWOSection().empty();

if (noDebugAbbrev && noDebugAbbrevDWO) {
return true;
}

unsigned NumErrors = 0;
if (!noDebugAbbrev)
NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrev());

if (!noDebugAbbrevDWO)
NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrevDWO());
return NumErrors == 0;
}

Expand Down
44 changes: 44 additions & 0 deletions test/tools/llvm-dwarfdump/X86/verify_debug_abbrev.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# RUN: llvm-mc %s -filetype obj -triple x86_64-unknown-linux-gnu -o - \
# RUN: | not llvm-dwarfdump -verify - \
# RUN: | FileCheck %s

# CHECK: Verifying .debug_abbrev...
# CHECK-NEXT: Error: Abbreviation declaration contains multiple DW_AT_stmt_list attributes.
# CHECK-NEXT:[1] DW_TAG_compile_unit DW_CHILDREN_no
# CHECK-NEXT: DW_AT_stmt_list DW_FORM_sec_offset
# CHECK-NEXT: DW_AT_GNU_dwo_name DW_FORM_strp
# CHECK-NEXT: DW_AT_stmt_list DW_FORM_strp{{[[:space:]]}}
# CHECK-NEXT: Error: Abbreviation declaration contains multiple DW_AT_producer attributes.
# CHECK-NEXT:[1] DW_TAG_compile_unit DW_CHILDREN_yes
# CHECK-NEXT: DW_AT_GNU_dwo_name DW_FORM_GNU_str_index
# CHECK-NEXT: DW_AT_producer DW_FORM_GNU_str_index
# CHECK-NEXT: DW_AT_producer DW_FORM_data2


.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 0 # DW_CHILDREN_no
.byte 16 # DW_AT_stmt_list
.byte 23 # DW_FORM_sec_offset
.ascii "\260B" # DW_AT_GNU_dwo_name
.byte 14 # DW_FORM_strp
.byte 16 # DW_AT_stmt_list -- Error: Abbreviation declaration contains multiple DW_AT_stmt_list attributes.
.byte 14 # DW_FORM_strp
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_abbrev.dwo,"",@progbits
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.ascii "\260B" # DW_AT_GNU_dwo_name
.ascii "\202>" # DW_FORM_GNU_str_index
.byte 37 # DW_AT_producer
.ascii "\202>" # DW_FORM_GNU_str_index
.byte 37 # DW_AT_producer -- Error: Abbreviation declaration contains multiple DW_AT_producer attributes.
.byte 5 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)

7 changes: 2 additions & 5 deletions test/tools/llvm-dwarfdump/X86/verify_debug_info.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
# RUN: | not llvm-dwarfdump -verify - \
# RUN: | FileCheck %s

# 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: 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)")
# CHECK-NEXT: DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
Expand Down Expand Up @@ -82,7 +79,7 @@ Lsection_abbrev:
.byte 1 ## DW_CHILDREN_yes
.byte 17 ## DW_AT_low_pc
.byte 1 ## DW_FORM_addr
.byte 17 ## DW_AT_low_pc -- Error: Die at offset 0x0000002b contains multiple DW_AT_low_pc attributes.
.byte 18 ## DW_AT_high_pc
.byte 6 ## DW_FORM_data4
.byte 64 ## DW_AT_frame_base
.byte 24 ## DW_FORM_exprloc
Expand Down

0 comments on commit e95e315

Please sign in to comment.