mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-08 03:26:34 +00:00
[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
This commit is contained in:
parent
8277ad7473
commit
1a443ce0dd
@ -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["
|
||||
|
@ -1658,6 +1658,13 @@ TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) {
|
||||
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, TestDwarfVerifyInvalidLineFileIndex) {
|
||||
"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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user