[llvm] r315121 - [dwarfdump] Verify that unit type matches root DIE
Jonas Devlieghere via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 6 15:27:31 PDT 2017
Author: jdevlieghere
Date: Fri Oct 6 15:27:31 2017
New Revision: 315121
URL: http://llvm.org/viewvc/llvm-project?rev=315121&view=rev
Log:
[dwarfdump] Verify that unit type matches root DIE
This patch adds two new verifiers:
- It checks that the root DIE of a CU is actually a valid unit DIE.
(based on its tag)
- For DWARF5 which contains a unit type int he CU header, it checks that
this matches the type of the unit DIE.
Differential revision: https://reviews.llvm.org/D38453
Modified:
llvm/trunk/include/llvm/BinaryFormat/Dwarf.h
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
llvm/trunk/test/DebugInfo/dwarfdump-header.test
llvm/trunk/test/tools/llvm-dwarfdump/X86/empty-CU.s
llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s
llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
Modified: llvm/trunk/include/llvm/BinaryFormat/Dwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Dwarf.h?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Dwarf.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Dwarf.h Fri Oct 6 15:27:31 2017
@@ -325,6 +325,33 @@ enum UnitType : unsigned char {
DW_UT_hi_user = 0xff
};
+inline bool isUnitType(uint8_t UnitType) {
+ switch (UnitType) {
+ case DW_UT_compile:
+ case DW_UT_type:
+ case DW_UT_partial:
+ case DW_UT_skeleton:
+ case DW_UT_split_compile:
+ case DW_UT_split_type:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool isUnitType(dwarf::Tag T) {
+ switch (T) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_type_unit:
+ case DW_TAG_partial_unit:
+ case DW_TAG_skeleton_unit:
+ case DW_TAG_imported_unit:
+ return true;
+ default:
+ return false;
+ }
+}
+
// Constants for the DWARF v5 Accelerator Table Proposal
enum AcceleratorTable {
// Data layout descriptors.
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Fri Oct 6 15:27:31 2017
@@ -285,12 +285,21 @@ public:
uint8_t getUnitType() const { return UnitType; }
- static bool isValidUnitType(uint8_t UnitType) {
- return UnitType == dwarf::DW_UT_compile || UnitType == dwarf::DW_UT_type ||
- UnitType == dwarf::DW_UT_partial ||
- UnitType == dwarf::DW_UT_skeleton ||
- UnitType == dwarf::DW_UT_split_compile ||
- UnitType == dwarf::DW_UT_split_type;
+ static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) {
+ switch (UnitType) {
+ case dwarf::DW_UT_compile:
+ return Tag == dwarf::DW_TAG_compile_unit;
+ case dwarf::DW_UT_type:
+ return Tag == dwarf::DW_TAG_type_unit;
+ case dwarf::DW_UT_partial:
+ return Tag == dwarf::DW_TAG_partial_unit;
+ case dwarf::DW_UT_skeleton:
+ return Tag == dwarf::DW_TAG_skeleton_unit;
+ case dwarf::DW_UT_split_compile:
+ case dwarf::DW_UT_split_type:
+ return dwarf::isUnitType(Tag);
+ }
+ return false;
}
/// \brief Return the number of bytes for the header of a unit of
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h Fri Oct 6 15:27:31 2017
@@ -136,8 +136,22 @@ private:
uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
bool &isUnitDWARF64);
-
- bool verifyUnitContents(DWARFUnit Unit);
+ /// Verifies the header of a unit in the .debug_info section.
+ ///
+ /// This function currently verifies:
+ /// - The debug info attributes.
+ /// - The debug info form=s.
+ /// - The presence of a root DIE.
+ /// - That the root DIE is a unit DIE.
+ /// - If a unit type is provided, that the unit DIE matches the unit type.
+ /// - The DIE ranges.
+ ///
+ /// \param Unit The DWARF Unit to verifiy.
+ /// \param UnitType An optional unit type which will be used to verify the
+ /// type of the unit DIE.
+ ///
+ /// \returns true if the content is verified successfully, false otherwise.
+ bool verifyUnitContents(DWARFUnit Unit, uint8_t UnitType = 0);
/// Verify that all Die ranges are valid.
///
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Fri Oct 6 15:27:31 2017
@@ -134,7 +134,7 @@ bool DWARFVerifier::verifyUnitHeader(con
UnitType = DebugInfoData.getU8(Offset);
AddrSize = DebugInfoData.getU8(Offset);
AbbrOffset = DebugInfoData.getU32(Offset);
- ValidType = DWARFUnit::isValidUnitType(UnitType);
+ ValidType = dwarf::isUnitType(UnitType);
} else {
UnitType = 0;
AbbrOffset = DebugInfoData.getU32(Offset);
@@ -169,7 +169,7 @@ bool DWARFVerifier::verifyUnitHeader(con
return Success;
}
-bool DWARFVerifier::verifyUnitContents(DWARFUnit Unit) {
+bool DWARFVerifier::verifyUnitContents(DWARFUnit Unit, uint8_t UnitType) {
uint32_t NumUnitErrors = 0;
unsigned NumDies = Unit.getNumDIEs();
for (unsigned I = 0; I < NumDies; ++I) {
@@ -182,14 +182,30 @@ bool DWARFVerifier::verifyUnitContents(D
}
}
- if (DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false)) {
- DieRangeInfo RI;
- NumUnitErrors += verifyDieRanges(Die, RI);
- } else {
- error() << "Compilation unit without unit DIE.\n";
+ DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
+ if (!Die) {
+ error() << "Compilation unit without DIE.\n";
+ NumUnitErrors++;
+ return NumUnitErrors == 0;
+ }
+
+ if (!dwarf::isUnitType(Die.getTag())) {
+ error() << "Compilation unit root DIE is not a unit DIE: "
+ << dwarf::TagString(Die.getTag()) << ".\n";
NumUnitErrors++;
}
+ if (UnitType != 0 &&
+ !DWARFUnit::isMatchingUnitTypeAndTag(UnitType, Die.getTag())) {
+ error() << "Compilation unit type (" << dwarf::UnitTypeString(UnitType)
+ << ") and root DIE (" << dwarf::TagString(Die.getTag())
+ << ") do not match.\n";
+ NumUnitErrors++;
+ }
+
+ DieRangeInfo RI;
+ NumUnitErrors += verifyDieRanges(Die, RI);
+
return NumUnitErrors == 0;
}
@@ -286,7 +302,7 @@ bool DWARFVerifier::handleDebugInfo() {
default: { llvm_unreachable("Invalid UnitType."); }
}
Unit->extract(DebugInfoData, &OffsetStart);
- if (!verifyUnitContents(*Unit))
+ if (!verifyUnitContents(*Unit, UnitType))
++NumDebugInfoErrors;
}
hasDIE = DebugInfoData.isValidOffset(Offset);
Modified: llvm/trunk/test/DebugInfo/dwarfdump-header.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/dwarfdump-header.test?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/dwarfdump-header.test (original)
+++ llvm/trunk/test/DebugInfo/dwarfdump-header.test Fri Oct 6 15:27:31 2017
@@ -1,4 +1,5 @@
RUN: llvm-dwarfdump -v %p/Inputs/dwarfdump-header.elf-x86-64 | FileCheck %s
+RUN: llvm-dwarfdump -v --verify %p/Inputs/dwarfdump-header.elf-x86-64
The input file is hand-coded assembler to generate all the units,
so we're willing to make exact checks for offsets and such.
Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/empty-CU.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/empty-CU.s?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/empty-CU.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/empty-CU.s Fri Oct 6 15:27:31 2017
@@ -1,7 +1,7 @@
# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
# RUN: | not llvm-dwarfdump --verify --debug-info - \
# RUN: | FileCheck %s
-# CHECK: error: Compilation unit without unit DIE.
+# CHECK: error: Compilation unit without DIE.
.section __DWARF,__debug_info,regular,debug
.long 8 # CU length
Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s Fri Oct 6 15:27:31 2017
@@ -11,6 +11,8 @@
# CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000003f] = "/Users/sgravani/Development/tests")
# CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
# CHECK-NEXT: DW_AT_high_pc [DW_FORM_data4] (0x00000016){{[[:space:]]}}
+# CHECK-NEXT: error: Compilation unit root DIE is not a unit DIE: DW_TAG_null.
+# CHECK-NEXT: error: Compilation unit type (DW_UT_compile) and root DIE (DW_TAG_null) do not match.
# CHECK-NEXT: error: Units[2] - start offset: 0x00000068
# CHECK-NEXT: note: The length for this unit is too large for the .debug_info provided.
# CHECK-NEXT: note: The unit type encoding is not valid.
Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s?rev=315121&r1=315120&r2=315121&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s Fri Oct 6 15:27:31 2017
@@ -9,6 +9,8 @@
# CHECK-NEXT: error: Units[2] - start offset: 0x00000026
# CHECK-NEXT: note: The 16 bit unit header version is not valid.
# CHECK-NEXT: note: The offset into the .debug_abbrev section is not valid.
+# CHECK-NEXT: error: Compilation unit root DIE is not a unit DIE: DW_TAG_null.
+# CHECK-NEXT: error: Compilation unit type (DW_UT_compile) and root DIE (DW_TAG_null) do not match.
# CHECK-NEXT: error: Units[4] - start offset: 0x00000041
# CHECK-NEXT: note: The length for this unit is too large for the .debug_info provided.
More information about the llvm-commits
mailing list