Skip to content

Commit c0e1ad7

Browse files
authored
[lldb] Skip declaration DIEs in the debug_names index (#94744)
This makes sure we try to process declaration DIEs that are erroneously present in the index. Until bd5c636, clang was emitting index entries for declaration DIEs with DW_AT_signature attributes. This makes sure to avoid returning those DIEs as the definitions of a type, but also makes sure to pass through DIEs referring to static constexpr member variables, which is a (probably nonconforming) extension used by dsymutil. It adds test cases for both of the scenarios. It is essentially a recommit of #91808.
1 parent d83f37f commit c0e1ad7

File tree

3 files changed

+439
-0
lines changed

3 files changed

+439
-0
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ bool DebugNamesDWARFIndex::ProcessEntry(
8585
DWARFDIE die = GetDIE(entry);
8686
if (!die)
8787
return true;
88+
// Clang used to erroneously emit index entries for declaration DIEs in case
89+
// when the definition is in a type unit (llvm.org/pr77696).
90+
if (die.IsStructUnionOrClass() &&
91+
die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))
92+
return true;
8893
return callback(die);
8994
}
9095

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
## Test that we can correctly complete types even if the debug_names index
2+
## contains entries referring to declaration dies (clang emitted entries like
3+
## that until bd5c6367bd7).
4+
##
5+
## This test consists of two compile units and one type unit. CU1 has the
6+
## definition of a variable, but only a forward-declaration of its type. When
7+
## attempting to find a definition, the debug_names lookup will return the DIE
8+
## in CU0, which is also a forward-declaration (with a reference to a type
9+
## unit). LLDB needs to find the definition of the type within the type unit.
10+
11+
# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t
12+
# RUN: %lldb %t -o "target variable s" -o exit | FileCheck %s
13+
14+
# CHECK: (lldb) target variable s
15+
# CHECK-NEXT: (Struct) s = (member = 47)
16+
17+
.data
18+
.p2align 2, 0x0
19+
.long 0
20+
s:
21+
.long 47 # 0x2f
22+
23+
.section .debug_abbrev,"",@progbits
24+
.byte 1 # Abbreviation Code
25+
.byte 65 # DW_TAG_type_unit
26+
.byte 1 # DW_CHILDREN_yes
27+
.byte 19 # DW_AT_language
28+
.byte 5 # DW_FORM_data2
29+
.byte 0 # EOM(1)
30+
.byte 0 # EOM(2)
31+
.byte 2 # Abbreviation Code
32+
.byte 19 # DW_TAG_structure_type
33+
.byte 1 # DW_CHILDREN_yes
34+
.byte 54 # DW_AT_calling_convention
35+
.byte 11 # DW_FORM_data1
36+
.byte 3 # DW_AT_name
37+
.byte 14 # DW_FORM_strp
38+
.byte 11 # DW_AT_byte_size
39+
.byte 11 # DW_FORM_data1
40+
.byte 0 # EOM(1)
41+
.byte 0 # EOM(2)
42+
.byte 3 # Abbreviation Code
43+
.byte 13 # DW_TAG_member
44+
.byte 0 # DW_CHILDREN_no
45+
.byte 3 # DW_AT_name
46+
.byte 14 # DW_FORM_strp
47+
.byte 73 # DW_AT_type
48+
.byte 19 # DW_FORM_ref4
49+
.byte 56 # DW_AT_data_member_location
50+
.byte 11 # DW_FORM_data1
51+
.byte 0 # EOM(1)
52+
.byte 0 # EOM(2)
53+
.byte 4 # Abbreviation Code
54+
.byte 36 # DW_TAG_base_type
55+
.byte 0 # DW_CHILDREN_no
56+
.byte 3 # DW_AT_name
57+
.byte 14 # DW_FORM_strp
58+
.byte 62 # DW_AT_encoding
59+
.byte 11 # DW_FORM_data1
60+
.byte 11 # DW_AT_byte_size
61+
.byte 11 # DW_FORM_data1
62+
.byte 0 # EOM(1)
63+
.byte 0 # EOM(2)
64+
.byte 5 # Abbreviation Code
65+
.byte 17 # DW_TAG_compile_unit
66+
.byte 1 # DW_CHILDREN_yes
67+
.byte 37 # DW_AT_producer
68+
.byte 8 # DW_FORM_string
69+
.byte 19 # DW_AT_language
70+
.byte 5 # DW_FORM_data2
71+
.byte 0 # EOM(1)
72+
.byte 0 # EOM(2)
73+
.byte 6 # Abbreviation Code
74+
.byte 52 # DW_TAG_variable
75+
.byte 0 # DW_CHILDREN_no
76+
.byte 3 # DW_AT_name
77+
.byte 14 # DW_FORM_strp
78+
.byte 73 # DW_AT_type
79+
.byte 19 # DW_FORM_ref4
80+
.byte 2 # DW_AT_location
81+
.byte 24 # DW_FORM_exprloc
82+
.byte 0 # EOM(1)
83+
.byte 0 # EOM(2)
84+
.byte 7 # Abbreviation Code
85+
.byte 19 # DW_TAG_structure_type
86+
.byte 0 # DW_CHILDREN_no
87+
.byte 60 # DW_AT_declaration
88+
.byte 25 # DW_FORM_flag_present
89+
.byte 105 # DW_AT_signature
90+
.byte 32 # DW_FORM_ref_sig8
91+
.byte 0 # EOM(1)
92+
.byte 0 # EOM(2)
93+
.byte 8 # Abbreviation Code
94+
.byte 19 # DW_TAG_structure_type
95+
.byte 0 # DW_CHILDREN_no
96+
.byte 3 # DW_AT_name
97+
.byte 14 # DW_FORM_strp
98+
.byte 60 # DW_AT_declaration
99+
.byte 25 # DW_FORM_flag_present
100+
.byte 0 # EOM(1)
101+
.byte 0 # EOM(2)
102+
.byte 0 # EOM(3)
103+
104+
.section .debug_info,"",@progbits
105+
.Ltu_begin0:
106+
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
107+
.Ldebug_info_start0:
108+
.short 5 # DWARF version number
109+
.byte 2 # DWARF Unit Type
110+
.byte 8 # Address Size (in bytes)
111+
.long .debug_abbrev # Offset Into Abbrev. Section
112+
.quad 4878254330033667422 # Type Signature
113+
.long .LStruct_def-.Ltu_begin0 # Type DIE Offset
114+
.byte 1 # Abbrev [1] 0x18:0x20 DW_TAG_type_unit
115+
.short 33 # DW_AT_language
116+
.LStruct_def:
117+
.byte 2 # Abbrev [2] 0x23:0x10 DW_TAG_structure_type
118+
.byte 5 # DW_AT_calling_convention
119+
.long .Linfo_string6 # DW_AT_name
120+
.byte 4 # DW_AT_byte_size
121+
.byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member
122+
.long .Linfo_string4 # DW_AT_name
123+
.long .Lint-.Ltu_begin0 # DW_AT_type
124+
.byte 0 # DW_AT_data_member_location
125+
.byte 0 # End Of Children Mark
126+
.Lint:
127+
.byte 4 # Abbrev [4] 0x33:0x4 DW_TAG_base_type
128+
.long .Linfo_string5 # DW_AT_name
129+
.byte 5 # DW_AT_encoding
130+
.byte 4 # DW_AT_byte_size
131+
.byte 0 # End Of Children Mark
132+
.Ldebug_info_end0:
133+
134+
.Lcu_begin0:
135+
.long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
136+
.Ldebug_info_start1:
137+
.short 5 # DWARF version number
138+
.byte 1 # DWARF Unit Type
139+
.byte 8 # Address Size (in bytes)
140+
.long .debug_abbrev # Offset Into Abbrev. Section
141+
.byte 5 # Abbrev [5] 0xc:0x27 DW_TAG_compile_unit
142+
.asciz "Hand-written DWARF" # DW_AT_producer
143+
.short 33 # DW_AT_language
144+
.Ls:
145+
.byte 6 # Abbrev [6] 0x1e:0xb DW_TAG_variable
146+
.long .Linfo_string3 # DW_AT_name
147+
.long .LStruct_decl2-.Lcu_begin0 # DW_AT_type
148+
.byte 9 # DW_AT_location
149+
.byte 3
150+
.quad s
151+
.LStruct_decl2:
152+
.byte 8 # Abbrev [8] 0x29:0x9 DW_TAG_structure_type
153+
.long .Linfo_string6 # DW_AT_name
154+
# DW_AT_declaration
155+
.byte 0 # End Of Children Mark
156+
.Ldebug_info_end1:
157+
158+
.Lcu_begin1:
159+
.long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit
160+
.Ldebug_info_start2:
161+
.short 5 # DWARF version number
162+
.byte 1 # DWARF Unit Type
163+
.byte 8 # Address Size (in bytes)
164+
.long .debug_abbrev # Offset Into Abbrev. Section
165+
.byte 5 # Abbrev [5] 0xc:0x27 DW_TAG_compile_unit
166+
.asciz "Hand-written DWARF" # DW_AT_producer
167+
.short 33 # DW_AT_language
168+
.LStruct_decl:
169+
.byte 7 # Abbrev [7] 0x29:0x9 DW_TAG_structure_type
170+
# DW_AT_declaration
171+
.quad 4878254330033667422 # DW_AT_signature
172+
.byte 0 # End Of Children Mark
173+
.Ldebug_info_end2:
174+
175+
.section .debug_str,"MS",@progbits,1
176+
.Linfo_string3:
177+
.asciz "s" # string offset=60
178+
.Linfo_string4:
179+
.asciz "member" # string offset=62
180+
.Linfo_string5:
181+
.asciz "int" # string offset=69
182+
.Linfo_string6:
183+
.asciz "Struct" # string offset=73
184+
185+
.section .debug_names,"",@progbits
186+
.long .Lnames_end0-.Lnames_start0 # Header: unit length
187+
.Lnames_start0:
188+
.short 5 # Header: version
189+
.short 0 # Header: padding
190+
.long 2 # Header: compilation unit count
191+
.long 1 # Header: local type unit count
192+
.long 0 # Header: foreign type unit count
193+
.long 0 # Header: bucket count
194+
.long 3 # Header: name count
195+
.long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
196+
.long 8 # Header: augmentation string size
197+
.ascii "LLVM0700" # Header: augmentation string
198+
.long .Lcu_begin0 # Compilation unit 0
199+
.long .Lcu_begin1 # Compilation unit 1
200+
.long .Ltu_begin0 # Type unit 0
201+
.long .Linfo_string6 # String in Bucket 0: Struct
202+
.long .Linfo_string3 # String in Bucket 1: s
203+
.long .Linfo_string5 # String in Bucket 2: int
204+
.long .Lnames1-.Lnames_entries0 # Offset in Bucket 0
205+
.long .Lnames2-.Lnames_entries0 # Offset in Bucket 1
206+
.long .Lnames0-.Lnames_entries0 # Offset in Bucket 2
207+
.Lnames_abbrev_start0:
208+
.byte 1 # Abbrev code
209+
.byte 19 # DW_TAG_structure_type
210+
.byte 2 # DW_IDX_type_unit
211+
.byte 11 # DW_FORM_data1
212+
.byte 3 # DW_IDX_die_offset
213+
.byte 19 # DW_FORM_ref4
214+
.byte 0 # End of abbrev
215+
.byte 0 # End of abbrev
216+
.byte 2 # Abbrev code
217+
.byte 52 # DW_TAG_variable
218+
.byte 1 # DW_IDX_compile_unit
219+
.byte 11 # DW_FORM_data1
220+
.byte 3 # DW_IDX_die_offset
221+
.byte 19 # DW_FORM_ref4
222+
.byte 0 # End of abbrev
223+
.byte 0 # End of abbrev
224+
.byte 3 # Abbrev code
225+
.byte 36 # DW_TAG_base_type
226+
.byte 2 # DW_IDX_type_unit
227+
.byte 11 # DW_FORM_data1
228+
.byte 3 # DW_IDX_die_offset
229+
.byte 19 # DW_FORM_ref4
230+
.byte 0 # End of abbrev
231+
.byte 0 # End of abbrev
232+
.byte 4 # Abbrev code
233+
.byte 19 # DW_TAG_structure_type
234+
.byte 1 # DW_IDX_compile_unit
235+
.byte 11 # DW_FORM_data1
236+
.byte 3 # DW_IDX_die_offset
237+
.byte 19 # DW_FORM_ref4
238+
.byte 0 # End of abbrev
239+
.byte 0 # End of abbrev
240+
.byte 0 # End of abbrev list
241+
.Lnames_abbrev_end0:
242+
.Lnames_entries0:
243+
.Lnames1:
244+
.byte 4 # Abbreviation code
245+
.byte 1 # DW_IDX_compile_unit
246+
.long .LStruct_decl-.Lcu_begin1 # DW_IDX_die_offset
247+
.byte 1 # Abbreviation code
248+
.byte 0 # DW_IDX_type_unit
249+
.long .LStruct_def-.Ltu_begin0 # DW_IDX_die_offset
250+
.byte 0
251+
# End of list: Struct
252+
.Lnames2:
253+
.byte 2 # Abbreviation code
254+
.byte 0 # DW_IDX_compile_unit
255+
.long .Ls-.Lcu_begin0 # DW_IDX_die_offset
256+
.byte 0
257+
# End of list: s
258+
.Lnames0:
259+
.byte 3 # Abbreviation code
260+
.byte 0 # DW_IDX_type_unit
261+
.long .Lint-.Ltu_begin0 # DW_IDX_die_offset
262+
.byte 0
263+
# End of list: int
264+
.p2align 2, 0x0
265+
.Lnames_end0:

0 commit comments

Comments
 (0)