Skip to content

Commit b6a2eb0

Browse files
authored
Add support for verifying local type units in .debug_names. (#101133)
This patch adds support for verifying local type units in .debug_names section. It adds a test to test if the TU index is valid, and a test that tests that an error is found inside the name entry for a type unit. We don't need to test all other errors in the name entry because these are essentially identical to compile unit entries, they just use a different DWARF unit offset index.
1 parent 1762e01 commit b6a2eb0

File tree

4 files changed

+264
-15
lines changed

4 files changed

+264
-15
lines changed

llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,9 +1481,9 @@ unsigned DWARFVerifier::verifyNameIndexAttribute(
14811481

14821482
unsigned
14831483
DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
1484-
if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
1485-
warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
1486-
"not currently supported.\n",
1484+
if (NI.getForeignTUCount() > 0) {
1485+
warn() << formatv("Name Index @ {0:x}: Verifying indexes of foreign type "
1486+
"units is not currently supported.\n",
14871487
NI.getUnitOffset());
14881488
return 0;
14891489
}
@@ -1512,10 +1512,12 @@ DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
15121512
NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
15131513
}
15141514

1515-
if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
1515+
if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit) &&
1516+
!Attributes.count(dwarf::DW_IDX_type_unit)) {
15161517
ErrorCategory.Report("Abbreviation contains no attribute", [&]() {
15171518
error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
1518-
"and abbreviation {1:x} has no {2} attribute.\n",
1519+
"and abbreviation {1:x} has no DW_IDX_compile_unit "
1520+
"or DW_IDX_type_unit attribute.\n",
15191521
NI.getUnitOffset(), Abbrev.Code,
15201522
dwarf::DW_IDX_compile_unit);
15211523
});
@@ -1574,8 +1576,8 @@ static SmallVector<std::string, 3> getNames(const DWARFDie &DIE,
15741576
unsigned DWARFVerifier::verifyNameIndexEntries(
15751577
const DWARFDebugNames::NameIndex &NI,
15761578
const DWARFDebugNames::NameTableEntry &NTE) {
1577-
// Verifying type unit indexes not supported.
1578-
if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
1579+
// Verifying foreign type unit indexes not supported.
1580+
if (NI.getForeignTUCount() > 0)
15791581
return 0;
15801582

15811583
const char *CStr = NTE.getString();
@@ -1596,18 +1598,35 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
15961598
Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
15971599
for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
15981600
EntryOr = NI.getEntry(&NextEntryID)) {
1599-
uint32_t CUIndex = *EntryOr->getCUIndex();
1600-
if (CUIndex > NI.getCUCount()) {
1601+
1602+
std::optional<uint64_t> CUIndex = EntryOr->getCUIndex();
1603+
std::optional<uint64_t> TUIndex = EntryOr->getLocalTUIndex();
1604+
if (CUIndex && *CUIndex >= NI.getCUCount()) {
16011605
ErrorCategory.Report("Name Index entry contains invalid CU index", [&]() {
16021606
error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
16031607
"invalid CU index ({2}).\n",
1604-
NI.getUnitOffset(), EntryID, CUIndex);
1608+
NI.getUnitOffset(), EntryID, *CUIndex);
16051609
});
16061610
++NumErrors;
16071611
continue;
16081612
}
1609-
uint64_t CUOffset = NI.getCUOffset(CUIndex);
1610-
uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
1613+
if (TUIndex && *TUIndex >= NI.getLocalTUCount()) {
1614+
ErrorCategory.Report("Name Index entry contains invalid TU index", [&]() {
1615+
error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
1616+
"invalid TU index ({2}).\n",
1617+
NI.getUnitOffset(), EntryID, *TUIndex);
1618+
});
1619+
++NumErrors;
1620+
continue;
1621+
}
1622+
std::optional<uint64_t> UnitOffset;
1623+
if (TUIndex)
1624+
UnitOffset = NI.getLocalTUOffset(*TUIndex);
1625+
else if (CUIndex)
1626+
UnitOffset = NI.getCUOffset(*CUIndex);
1627+
if (!UnitOffset)
1628+
continue;
1629+
uint64_t DIEOffset = *UnitOffset + *EntryOr->getDIEUnitOffset();
16111630
DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
16121631
if (!DIE) {
16131632
ErrorCategory.Report("NameIndex references nonexistent DIE", [&]() {
@@ -1618,12 +1637,12 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
16181637
++NumErrors;
16191638
continue;
16201639
}
1621-
if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
1640+
if (DIE.getDwarfUnit()->getOffset() != *UnitOffset) {
16221641
ErrorCategory.Report("Name index contains mismatched CU of DIE", [&]() {
16231642
error() << formatv(
16241643
"Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
16251644
"DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
1626-
NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
1645+
NI.getUnitOffset(), EntryID, DIEOffset, *UnitOffset,
16271646
DIE.getDwarfUnit()->getOffset());
16281647
});
16291648
++NumErrors;

llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-forms.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# CHECK: NameIndex @ 0x0: Abbreviation 0x1: DW_IDX_die_offset uses an unknown form: DW_FORM_unknown_1fff.
1010
# CHECK: warning: NameIndex @ 0x0: Abbreviation 0x3 references an unknown tag: DW_TAG_unknown_8080.
1111
# CHECK: error: NameIndex @ 0x0: Abbreviation 0x5 has no DW_IDX_die_offset attribute.
12-
# CHECK: error: NameIndex @ 0x55: Indexing multiple compile units and abbreviation 0x1 has no DW_IDX_compile_unit attribute.
12+
# CHECK: error: NameIndex @ 0x55: Indexing multiple compile units and abbreviation 0x1 has no DW_IDX_compile_unit or DW_IDX_type_unit attribute.
1313

1414
.section .debug_str,"MS",@progbits,1
1515
.Lstring_producer:
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# RUN: yaml2obj %s -o - | not llvm-dwarfdump -verify - | FileCheck %s
2+
3+
# Verifying local type units. Local type units and compile units are identical
4+
# except that the DWARF Unit offset for the type unit is specified using a
5+
# DW_IDX_type_unit. This is a single test that tests if we get an error for a
6+
# local type unit. We only need to verify that errors work for type units and
7+
# we can rely on the test for compile units to verify all other errors that can
8+
# happen in the .debug_names entries.
9+
10+
# CHECK: Verifying .debug_names...
11+
# CHECK: error: Name Index @ 0x0: Entry @ 0x7f references a non-existing DIE @ 0x25.
12+
# CHECK: error: Aggregated error counts:
13+
# CHECK: error: NameIndex references nonexistent DIE occurred 1 time(s).
14+
# Errors detected.
15+
16+
--- !ELF
17+
FileHeader:
18+
Class: ELFCLASS64
19+
Data: ELFDATA2LSB
20+
Type: ET_EXEC
21+
Machine: EM_X86_64
22+
ProgramHeaders:
23+
- Type: PT_PHDR
24+
Flags: [ PF_R ]
25+
VAddr: 0x200040
26+
Align: 0x8
27+
Offset: 0x40
28+
- Type: PT_LOAD
29+
Flags: [ PF_R ]
30+
FirstSec: .eh_frame
31+
LastSec: .eh_frame
32+
VAddr: 0x200000
33+
Align: 0x1000
34+
Offset: 0x0
35+
- Type: PT_LOAD
36+
Flags: [ PF_X, PF_R ]
37+
FirstSec: .text
38+
LastSec: .text
39+
VAddr: 0x201160
40+
Align: 0x1000
41+
Offset: 0x160
42+
- Type: PT_GNU_STACK
43+
Flags: [ PF_W, PF_R ]
44+
Align: 0x0
45+
Offset: 0x0
46+
Sections:
47+
- Name: .eh_frame
48+
Type: SHT_PROGBITS
49+
Flags: [ SHF_ALLOC ]
50+
Address: 0x200120
51+
AddressAlign: 0x8
52+
Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000201000000F00000000410E108602430D064A0C070800000000000000
53+
- Name: .text
54+
Type: SHT_PROGBITS
55+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
56+
Address: 0x201160
57+
AddressAlign: 0x10
58+
Content: 554889E5C745FC0000000031C05DC3
59+
- Name: .debug_info
60+
Type: SHT_PROGBITS
61+
AddressAlign: 0x1
62+
Content: 260000000500020800000000F23532F3E4235D67230000000121000000000008000000020506010001004800000005000108000000000300210001080000000000000002000F0000000800000004000F00000001560300033E0000000502917B05000442000000000604050407F23532F3E4235D6700
63+
- Name: .debug_abbrev
64+
Type: SHT_PROGBITS
65+
AddressAlign: 0x1
66+
Content: 0141011305101772170000021300360B03250B0B3A0B3B0B0000031101252513050325721710171B25111B120673170000042E01111B1206401803253A0B3B0B49133F190000053400021803253A0B3B0B4913000006240003253E0B0B0B00000713003C196920000000
67+
- Name: .debug_str_offsets
68+
Type: SHT_PROGBITS
69+
AddressAlign: 0x1
70+
Content: 20000000050000000400000096000000A80000009F000000A400000000000000D1000000
71+
- Name: .debug_names
72+
Type: SHT_PROGBITS
73+
AddressAlign: 0x4
74+
Content: 900000000500000001000000010000000000000003000000030000001B000000080000004C4C564D303730302A000000000000000100000002000000030000008973880B6A7F9A7C3080880BD10000009F000000A400000000000000070000000D0000000113020B031304190000022E03130419000003240313041900000001002500000000022300000000033E000000000000
75+
- Name: .comment
76+
Type: SHT_PROGBITS
77+
Flags: [ SHF_MERGE, SHF_STRINGS ]
78+
AddressAlign: 0x1
79+
EntSize: 0x1
80+
Content: 46616365626F6F6B20636C616E672076657273696F6E2031352E302E30202868747470733A2F2F6769742E696E7465726E616C2E7466626E772E6E65742F7265706F732F6769742F726F2F6F736D6574612F65787465726E616C2F6C6C766D2D70726F6A656374203864356561396432616431633161356139303862623632343663303261626162323235643562633829004C696E6B65723A204C4C442031392E302E300000
81+
- Name: .debug_line
82+
Type: SHT_PROGBITS
83+
AddressAlign: 0x1
84+
Content: 590000000500080037000000010101FB0E0D00010101010000000100000101011F010900000003011F020F051E01000000000014E7C4DFD187393499D4332D94A1154D040000090260112000000000001405030AAE060B2E0202000101
85+
- Name: .debug_line_str
86+
Type: SHT_PROGBITS
87+
Flags: [ SHF_MERGE, SHF_STRINGS ]
88+
AddressAlign: 0x1
89+
EntSize: 0x1
90+
Content: 6D61696E2E637070002F55736572732F67636C6179746F6E2F446F63756D656E74732F7372632F7665726966792D74757300
91+
Symbols:
92+
- Name: main.cpp
93+
Type: STT_FILE
94+
Index: SHN_ABS
95+
- Name: main
96+
Type: STT_FUNC
97+
Section: .text
98+
Binding: STB_GLOBAL
99+
Value: 0x201160
100+
Size: 0xF
101+
DWARF:
102+
debug_str:
103+
- foo
104+
- 'Facebook clang version 15.0.0 (https://git.internal.tfbnw.net/repos/git/ro/osmeta/external/llvm-project 8d5ea9d2ad1c1a5a908bb6246c02abab225d5bc8)'
105+
- main.cpp
106+
- main
107+
- int
108+
- '/Users/gclayton/Documents/src/verify-tus'
109+
- Foo
110+
debug_addr:
111+
- Length: 0xC
112+
Version: 0x5
113+
AddressSize: 0x8
114+
Entries:
115+
- Address: 0x201160
116+
...
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# RUN: yaml2obj %s -o - | not llvm-dwarfdump -verify - | FileCheck %s
2+
3+
# Verifying local type units. Local type units and compile units are identical
4+
# except that the DWARF Unit offset for the type unit is specified using a
5+
# DW_IDX_type_unit. This is a single test that tests that the type unit index
6+
# in the DW_IDX_type_unit value is valid.
7+
8+
# CHECK: Verifying .debug_names...
9+
# CHECK: error: Name Index @ 0x0: Entry @ 0x7f contains an invalid TU index (1).
10+
# CHECK: error: Aggregated error counts:
11+
# CHECK: error: Name Index entry contains invalid TU index occurred 1 time(s).
12+
# Errors detected.
13+
14+
--- !ELF
15+
FileHeader:
16+
Class: ELFCLASS64
17+
Data: ELFDATA2LSB
18+
Type: ET_EXEC
19+
Machine: EM_X86_64
20+
ProgramHeaders:
21+
- Type: PT_PHDR
22+
Flags: [ PF_R ]
23+
VAddr: 0x200040
24+
Align: 0x8
25+
Offset: 0x40
26+
- Type: PT_LOAD
27+
Flags: [ PF_R ]
28+
FirstSec: .eh_frame
29+
LastSec: .eh_frame
30+
VAddr: 0x200000
31+
Align: 0x1000
32+
Offset: 0x0
33+
- Type: PT_LOAD
34+
Flags: [ PF_X, PF_R ]
35+
FirstSec: .text
36+
LastSec: .text
37+
VAddr: 0x201160
38+
Align: 0x1000
39+
Offset: 0x160
40+
- Type: PT_GNU_STACK
41+
Flags: [ PF_W, PF_R ]
42+
Align: 0x0
43+
Offset: 0x0
44+
Sections:
45+
- Name: .eh_frame
46+
Type: SHT_PROGBITS
47+
Flags: [ SHF_ALLOC ]
48+
Address: 0x200120
49+
AddressAlign: 0x8
50+
Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000201000000F00000000410E108602430D064A0C070800000000000000
51+
- Name: .text
52+
Type: SHT_PROGBITS
53+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
54+
Address: 0x201160
55+
AddressAlign: 0x10
56+
Content: 554889E5C745FC0000000031C05DC3
57+
- Name: .debug_info
58+
Type: SHT_PROGBITS
59+
AddressAlign: 0x1
60+
Content: 260000000500020800000000F23532F3E4235D67230000000121000000000008000000020506010001004800000005000108000000000300210001080000000000000002000F0000000800000004000F00000001560300033E0000000502917B05000442000000000604050407F23532F3E4235D6700
61+
- Name: .debug_abbrev
62+
Type: SHT_PROGBITS
63+
AddressAlign: 0x1
64+
Content: 0141011305101772170000021300360B03250B0B3A0B3B0B0000031101252513050325721710171B25111B120673170000042E01111B1206401803253A0B3B0B49133F190000053400021803253A0B3B0B4913000006240003253E0B0B0B00000713003C196920000000
65+
- Name: .debug_str_offsets
66+
Type: SHT_PROGBITS
67+
AddressAlign: 0x1
68+
Content: 20000000050000000400000096000000A80000009F000000A400000000000000D1000000
69+
- Name: .debug_names
70+
Type: SHT_PROGBITS
71+
AddressAlign: 0x4
72+
Content: 900000000500000001000000010000000000000003000000030000001B000000080000004C4C564D303730302A000000000000000100000002000000030000008973880B6A7F9A7C3080880BD10000009F000000A400000000000000070000000D0000000113020B031304190000022E03130419000003240313041900000001012500000000022300000000033E000000000000
73+
- Name: .comment
74+
Type: SHT_PROGBITS
75+
Flags: [ SHF_MERGE, SHF_STRINGS ]
76+
AddressAlign: 0x1
77+
EntSize: 0x1
78+
Content: 46616365626F6F6B20636C616E672076657273696F6E2031352E302E30202868747470733A2F2F6769742E696E7465726E616C2E7466626E772E6E65742F7265706F732F6769742F726F2F6F736D6574612F65787465726E616C2F6C6C766D2D70726F6A656374203864356561396432616431633161356139303862623632343663303261626162323235643562633829004C696E6B65723A204C4C442031392E302E300000
79+
- Name: .debug_line
80+
Type: SHT_PROGBITS
81+
AddressAlign: 0x1
82+
Content: 590000000500080037000000010101FB0E0D00010101010000000100000101011F010900000003011F020F051E01000000000014E7C4DFD187393499D4332D94A1154D040000090260112000000000001405030AAE060B2E0202000101
83+
- Name: .debug_line_str
84+
Type: SHT_PROGBITS
85+
Flags: [ SHF_MERGE, SHF_STRINGS ]
86+
AddressAlign: 0x1
87+
EntSize: 0x1
88+
Content: 6D61696E2E637070002F55736572732F67636C6179746F6E2F446F63756D656E74732F7372632F7665726966792D74757300
89+
Symbols:
90+
- Name: main.cpp
91+
Type: STT_FILE
92+
Index: SHN_ABS
93+
- Name: main
94+
Type: STT_FUNC
95+
Section: .text
96+
Binding: STB_GLOBAL
97+
Value: 0x201160
98+
Size: 0xF
99+
DWARF:
100+
debug_str:
101+
- foo
102+
- 'Facebook clang version 15.0.0 (https://git.internal.tfbnw.net/repos/git/ro/osmeta/external/llvm-project 8d5ea9d2ad1c1a5a908bb6246c02abab225d5bc8)'
103+
- main.cpp
104+
- main
105+
- int
106+
- '/Users/gclayton/Documents/src/verify-tus'
107+
- Foo
108+
debug_addr:
109+
- Length: 0xC
110+
Version: 0x5
111+
AddressSize: 0x8
112+
Entries:
113+
- Address: 0x201160
114+
...

0 commit comments

Comments
 (0)