summaryrefslogtreecommitdiff
path: root/unittests/DebugInfo/DWARF
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2017-05-02 20:28:33 +0000
committerGreg Clayton <gclayton@apple.com>2017-05-02 20:28:33 +0000
commitedadbde29ab34a14b1463318f59ba44bb432fe3d (patch)
tree35b98606d31b5ff72b6e79ffd4d6c09cee3d3c8d /unittests/DebugInfo/DWARF
parentdbb0e70756a73eb34af6e5c89ff16a977a5408ba (diff)
Verify that all references point to actual DIEs in "llvm-dwarfdump --verify"
LTO and other fancy linking previously led to DWARF that contained invalid references. We already validate that CU relative references fall into the CU, and the DW_FORM_ref_addr references fall inside the .debug_info section, but we didn't validate that the references pointed to correct DIE offsets. This new verification will ensure that all references refer to actual DIEs and not an offset in between. This caught a bug in DWARFUnit::getDIEForOffset() where if you gave it any offset, it would match the DIE that mathes the offset _or_ the next DIE. This has been fixed. Differential Revision: https://reviews.llvm.org/D32722 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301971 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/DebugInfo/DWARF')
-rw-r--r--unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
index 3f0e3dab72b..af1637827df 100644
--- a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -1908,4 +1908,60 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidStrp) {
EXPECT_TRUE(strm.str().find(err) != std::string::npos);
}
+TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddrBetween) {
+ // Create a single compile unit with a single function that has a DW_AT_type
+ // with a valid .debug_info offset, but the offset is between two DIEs.
+ const char *yamldata = R"(
+ debug_str:
+ - ''
+ - /tmp/main.c
+ - main
+ debug_abbrev:
+ - Code: 0x00000001
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Code: 0x00000002
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref_addr
+ debug_info:
+ - Length:
+ TotalLength: 22
+ Version: 4
+ AbbrOffset: 0
+ AddrSize: 8
+ Entries:
+ - AbbrCode: 0x00000001
+ Values:
+ - Value: 0x0000000000000001
+ - AbbrCode: 0x00000002
+ Values:
+ - Value: 0x000000000000000D
+ - Value: 0x0000000000000011
+ - AbbrCode: 0x00000000
+ Values:
+ )";
+ auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
+ ASSERT_TRUE((bool)ErrOrSections);
+
+ auto &DebugSections = *ErrOrSections;
+
+ DWARFContextInMemory DwarfContext(DebugSections, 8);
+
+ std::string str;
+ raw_string_ostream strm(str);
+ EXPECT_FALSE(DwarfContext.verify(strm, DIDT_All));
+ strm.flush();
+ const char *err = "error: invalid DIE reference 0x00000011. Offset is in "
+ "between DIEs:";
+ EXPECT_TRUE(strm.str().find(err) != std::string::npos);
+}
+
} // end anonymous namespace