llvm.org GIT mirror llvm / 1a443ce
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312782 91177308-0d34-0410-b5e6-96231b3b80d8 Jonas Devlieghere 2 years ago
2 changed file(s) with 198 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
416416 // .debug_info verifier or in verifyDebugLineStmtOffsets().
417417 if (!LineTable)
418418 continue;
419
420 // Verify prologue.
419421 uint32_t MaxFileIndex = LineTable->Prologue.FileNames.size();
422 uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
423 uint32_t FileIndex = 1;
424 StringMap FullPathMap;
425 for (const auto &FileName : LineTable->Prologue.FileNames) {
426 // Verify directory index.
427 if (FileName.DirIdx > MaxDirIndex) {
428 ++NumDebugLineErrors;
429 OS << "error: .debug_line["
430 << format("0x%08" PRIx64,
431 *toSectionOffset(Die.find(DW_AT_stmt_list)))
432 << "].prologue.file_names[" << FileIndex
433 << "].dir_idx contains an invalid index: " << FileName.DirIdx
434 << "\n";
435 }
436
437 // Check file paths for duplicates.
438 std::string FullPath;
439 const bool HasFullPath = LineTable->getFileNameByIndex(
440 FileIndex, CU->getCompilationDir(),
441 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FullPath);
442 assert(HasFullPath && "Invalid index?");
443 (void)HasFullPath;
444 auto It = FullPathMap.find(FullPath);
445 if (It == FullPathMap.end())
446 FullPathMap[FullPath] = FileIndex;
447 else if (It->second != FileIndex) {
448 OS << "warning: .debug_line["
449 << format("0x%08" PRIx64,
450 *toSectionOffset(Die.find(DW_AT_stmt_list)))
451 << "].prologue.file_names[" << FileIndex
452 << "] is a duplicate of file_names[" << It->second << "]\n";
453 }
454
455 FileIndex++;
456 }
457
458 // Verify rows.
420459 uint64_t PrevAddress = 0;
421460 uint32_t RowIndex = 0;
422461 for (const auto &Row : LineTable->Rows) {
462 // Verify row address.
423463 if (Row.Address < PrevAddress) {
424464 ++NumDebugLineErrors;
425465 OS << "error: .debug_line["
435475 OS << '\n';
436476 }
437477
478 // Verify file index.
438479 if (Row.File > MaxFileIndex) {
439480 ++NumDebugLineErrors;
440481 OS << "error: .debug_line["
16551655 for (auto it = Val1Range.first; it != Val1Range.second; ++it)
16561656 EXPECT_EQ(it->second, AbbrevPtrVal1);
16571657 EXPECT_EQ(DIEs.find(Val2)->second, AbbrevPtrVal2);
1658 }
1659
1660 void VerifyWarning(DWARFContext &DwarfContext, StringRef Error) {
1661 SmallString<1024> Str;
1662 raw_svector_ostream Strm(Str);
1663 EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All));
1664 EXPECT_TRUE(Str.str().contains(Error));
16581665 }
16591666
16601667 void VerifyError(DWARFContext &DwarfContext, StringRef Error) {
20592066 DWARFContext::create(*ErrOrSections, 8);
20602067 VerifyError(*DwarfContext, "error: .debug_line[0x00000000][1] has invalid "
20612068 "file index 5 (valid values are [1,1]):");
2069 }
2070
2071 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineTablePorlogueDirIndex) {
2072 // Create a single compile unit whose line table has a prologue with an
2073 // invalid dir index.
2074 StringRef yamldata = R"(
2075 debug_str:
2076 - ''
2077 - /tmp/main.c
2078 debug_abbrev:
2079 - Code: 0x00000001
2080 Tag: DW_TAG_compile_unit
2081 Children: DW_CHILDREN_no
2082 Attributes:
2083 - Attribute: DW_AT_name
2084 Form: DW_FORM_strp
2085 - Attribute: DW_AT_stmt_list
2086 Form: DW_FORM_sec_offset
2087 debug_info:
2088 - Length:
2089 TotalLength: 16
2090 Version: 4
2091 AbbrOffset: 0
2092 AddrSize: 8
2093 Entries:
2094 - AbbrCode: 0x00000001
2095 Values:
2096 - Value: 0x0000000000000001
2097 - Value: 0x0000000000000000
2098 debug_line:
2099 - Length:
2100 TotalLength: 61
2101 Version: 2
2102 PrologueLength: 34
2103 MinInstLength: 1
2104 DefaultIsStmt: 1
2105 LineBase: 251
2106 LineRange: 14
2107 OpcodeBase: 13
2108 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
2109 IncludeDirs:
2110 - /tmp
2111 Files:
2112 - Name: main.c
2113 DirIdx: 2
2114 ModTime: 0
2115 Length: 0
2116 Opcodes:
2117 - Opcode: DW_LNS_extended_op
2118 ExtLen: 9
2119 SubOpcode: DW_LNE_set_address
2120 Data: 4096
2121 - Opcode: DW_LNS_advance_line
2122 SData: 9
2123 Data: 4096
2124 - Opcode: DW_LNS_copy
2125 Data: 4096
2126 - Opcode: DW_LNS_advance_pc
2127 Data: 16
2128 - Opcode: DW_LNS_set_file
2129 Data: 1
2130 - Opcode: DW_LNS_extended_op
2131 ExtLen: 1
2132 SubOpcode: DW_LNE_end_sequence
2133 Data: 1
2134 )";
2135 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2136 ASSERT_TRUE((bool)ErrOrSections);
2137 std::unique_ptr DwarfContext =
2138 DWARFContext::create(*ErrOrSections, 8);
2139 VerifyError(*DwarfContext,
2140 "error: .debug_line[0x00000000].prologue."
2141 "file_names[1].dir_idx contains an invalid index: 2");
2142 }
2143
2144 TEST(DWARFDebugInfo, TestDwarfVerifyDuplicateFileWarning) {
2145 // Create a single compile unit whose line table has a prologue with an
2146 // invalid dir index.
2147 StringRef yamldata = R"(
2148 debug_str:
2149 - ''
2150 - /tmp/main.c
2151 debug_abbrev:
2152 - Code: 0x00000001
2153 Tag: DW_TAG_compile_unit
2154 Children: DW_CHILDREN_no
2155 Attributes:
2156 - Attribute: DW_AT_name
2157 Form: DW_FORM_strp
2158 - Attribute: DW_AT_stmt_list
2159 Form: DW_FORM_sec_offset
2160 debug_info:
2161 - Length:
2162 TotalLength: 16
2163 Version: 4
2164 AbbrOffset: 0
2165 AddrSize: 8
2166 Entries:
2167 - AbbrCode: 0x00000001
2168 Values:
2169 - Value: 0x0000000000000001
2170 - Value: 0x0000000000000000
2171 debug_line:
2172 - Length:
2173 TotalLength: 71
2174 Version: 2
2175 PrologueLength: 44
2176 MinInstLength: 1
2177 DefaultIsStmt: 1
2178 LineBase: 251
2179 LineRange: 14
2180 OpcodeBase: 13
2181 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
2182 IncludeDirs:
2183 - /tmp
2184 Files:
2185 - Name: main.c
2186 DirIdx: 1
2187 ModTime: 0
2188 Length: 0
2189 - Name: main.c
2190 DirIdx: 1
2191 ModTime: 0
2192 Length: 0
2193 Opcodes:
2194 - Opcode: DW_LNS_extended_op
2195 ExtLen: 9
2196 SubOpcode: DW_LNE_set_address
2197 Data: 4096
2198 - Opcode: DW_LNS_advance_line
2199 SData: 9
2200 Data: 4096
2201 - Opcode: DW_LNS_copy
2202 Data: 4096
2203 - Opcode: DW_LNS_advance_pc
2204 Data: 16
2205 - Opcode: DW_LNS_set_file
2206 Data: 1
2207 - Opcode: DW_LNS_extended_op
2208 ExtLen: 1
2209 SubOpcode: DW_LNE_end_sequence
2210 Data: 2
2211 )";
2212 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2213 ASSERT_TRUE((bool)ErrOrSections);
2214 std::unique_ptr DwarfContext =
2215 DWARFContext::create(*ErrOrSections, 8);
2216 VerifyWarning(*DwarfContext,
2217 "warning: .debug_line[0x00000000].prologue.file_names[2] is "
2218 "a duplicate of file_names[1]");
20622219 }
20632220
20642221 TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {