[llvm] r312782 - [dwarfdump] Verify line table prologue
Jonas Devlieghere via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 8 02:48:52 PDT 2017
Author: jdevlieghere
Date: Fri Sep 8 02:48:51 2017
New Revision: 312782
URL: http://llvm.org/viewvc/llvm-project?rev=312782&view=rev
Log:
[dwarfdump] Verify line table prologue
This patch adds prologue verification, which is already present in
Apple's dwarfdump. It checks for invalid directory indices and warns
about duplicate file paths.
Differential revision: https://reviews.llvm.org/D37511
Modified:
llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=312782&r1=312781&r2=312782&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Fri Sep 8 02:48:51 2017
@@ -417,10 +417,50 @@ void DWARFVerifier::verifyDebugLineRows(
// .debug_info verifier or in verifyDebugLineStmtOffsets().
if (!LineTable)
continue;
+
+ // Verify prologue.
uint32_t MaxFileIndex = LineTable->Prologue.FileNames.size();
+ uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
+ uint32_t FileIndex = 1;
+ StringMap<uint16_t> FullPathMap;
+ for (const auto &FileName : LineTable->Prologue.FileNames) {
+ // 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";
+ }
+
+ // Check file paths for duplicates.
+ std::string FullPath;
+ const bool HasFullPath = LineTable->getFileNameByIndex(
+ FileIndex, CU->getCompilationDir(),
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FullPath);
+ assert(HasFullPath && "Invalid index?");
+ (void)HasFullPath;
+ auto It = FullPathMap.find(FullPath);
+ 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";
+ }
+
+ FileIndex++;
+ }
+
+ // Verify rows.
uint64_t PrevAddress = 0;
uint32_t RowIndex = 0;
for (const auto &Row : LineTable->Rows) {
+ // Verify row address.
if (Row.Address < PrevAddress) {
++NumDebugLineErrors;
OS << "error: .debug_line["
@@ -436,6 +476,7 @@ void DWARFVerifier::verifyDebugLineRows(
OS << '\n';
}
+ // Verify file index.
if (Row.File > MaxFileIndex) {
++NumDebugLineErrors;
OS << "error: .debug_line["
Modified: llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp?rev=312782&r1=312781&r2=312782&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp Fri Sep 8 02:48:51 2017
@@ -1658,6 +1658,13 @@ TEST(DWARFDebugInfo, TestImplicitConstAb
EXPECT_EQ(DIEs.find(Val2)->second, AbbrevPtrVal2);
}
+void VerifyWarning(DWARFContext &DwarfContext, StringRef Error) {
+ SmallString<1024> Str;
+ raw_svector_ostream Strm(Str);
+ EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All));
+ EXPECT_TRUE(Str.str().contains(Error));
+}
+
void VerifyError(DWARFContext &DwarfContext, StringRef Error) {
SmallString<1024> Str;
raw_svector_ostream Strm(Str);
@@ -2062,6 +2069,156 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
"file index 5 (valid values are [1,1]):");
}
+TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineTablePorlogueDirIndex) {
+ // Create a single compile unit whose line table has a prologue with an
+ // invalid dir index.
+ StringRef yamldata = R"(
+ debug_str:
+ - ''
+ - /tmp/main.c
+ debug_abbrev:
+ - Code: 0x00000001
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_stmt_list
+ Form: DW_FORM_sec_offset
+ debug_info:
+ - Length:
+ TotalLength: 16
+ Version: 4
+ AbbrOffset: 0
+ AddrSize: 8
+ Entries:
+ - AbbrCode: 0x00000001
+ Values:
+ - Value: 0x0000000000000001
+ - Value: 0x0000000000000000
+ debug_line:
+ - Length:
+ TotalLength: 61
+ Version: 2
+ PrologueLength: 34
+ MinInstLength: 1
+ DefaultIsStmt: 1
+ LineBase: 251
+ LineRange: 14
+ OpcodeBase: 13
+ StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+ IncludeDirs:
+ - /tmp
+ Files:
+ - Name: main.c
+ DirIdx: 2
+ ModTime: 0
+ Length: 0
+ Opcodes:
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 9
+ SubOpcode: DW_LNE_set_address
+ Data: 4096
+ - Opcode: DW_LNS_advance_line
+ SData: 9
+ Data: 4096
+ - Opcode: DW_LNS_copy
+ Data: 4096
+ - Opcode: DW_LNS_advance_pc
+ Data: 16
+ - Opcode: DW_LNS_set_file
+ Data: 1
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 1
+ SubOpcode: DW_LNE_end_sequence
+ Data: 1
+ )";
+ auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
+ ASSERT_TRUE((bool)ErrOrSections);
+ std::unique_ptr<DWARFContext> DwarfContext =
+ DWARFContext::create(*ErrOrSections, 8);
+ VerifyError(*DwarfContext,
+ "error: .debug_line[0x00000000].prologue."
+ "file_names[1].dir_idx contains an invalid index: 2");
+}
+
+TEST(DWARFDebugInfo, TestDwarfVerifyDuplicateFileWarning) {
+ // Create a single compile unit whose line table has a prologue with an
+ // invalid dir index.
+ StringRef yamldata = R"(
+ debug_str:
+ - ''
+ - /tmp/main.c
+ debug_abbrev:
+ - Code: 0x00000001
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_stmt_list
+ Form: DW_FORM_sec_offset
+ debug_info:
+ - Length:
+ TotalLength: 16
+ Version: 4
+ AbbrOffset: 0
+ AddrSize: 8
+ Entries:
+ - AbbrCode: 0x00000001
+ Values:
+ - Value: 0x0000000000000001
+ - Value: 0x0000000000000000
+ debug_line:
+ - Length:
+ TotalLength: 71
+ Version: 2
+ PrologueLength: 44
+ MinInstLength: 1
+ DefaultIsStmt: 1
+ LineBase: 251
+ LineRange: 14
+ OpcodeBase: 13
+ StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+ IncludeDirs:
+ - /tmp
+ Files:
+ - Name: main.c
+ DirIdx: 1
+ ModTime: 0
+ Length: 0
+ - Name: main.c
+ DirIdx: 1
+ ModTime: 0
+ Length: 0
+ Opcodes:
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 9
+ SubOpcode: DW_LNE_set_address
+ Data: 4096
+ - Opcode: DW_LNS_advance_line
+ SData: 9
+ Data: 4096
+ - Opcode: DW_LNS_copy
+ Data: 4096
+ - Opcode: DW_LNS_advance_pc
+ Data: 16
+ - Opcode: DW_LNS_set_file
+ Data: 1
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 1
+ SubOpcode: DW_LNE_end_sequence
+ Data: 2
+ )";
+ auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
+ ASSERT_TRUE((bool)ErrOrSections);
+ std::unique_ptr<DWARFContext> DwarfContext =
+ DWARFContext::create(*ErrOrSections, 8);
+ VerifyWarning(*DwarfContext,
+ "warning: .debug_line[0x00000000].prologue.file_names[2] is "
+ "a duplicate of file_names[1]");
+}
+
TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
// Create a two compile units where both compile units share the same
// DW_AT_stmt_list value and verify we report the error correctly.
More information about the llvm-commits
mailing list