Skip to content

Commit 3bf1ef6

Browse files
committed
[DWARF] Support parsing struct member offsets from DW_AT_data_bit_offset, fix struct members being put at wrong offset when location fails to be parsed
1 parent b2622b2 commit 3bf1ef6

File tree

1 file changed

+44
-12
lines changed

1 file changed

+44
-12
lines changed

plugins/dwarf/dwarf_import/src/types.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,13 @@ fn do_structure_parse<R: ReaderType>(
191191
};
192192
let mut children = tree_root.children();
193193
while let Ok(Some(child)) = children.next() {
194-
match child.entry().tag() {
194+
let child_entry = child.entry();
195+
match child_entry.tag() {
195196
constants::DW_TAG_member => {
196197
let Some(child_type_id) = get_type(
197198
dwarf,
198199
unit,
199-
child.entry(),
200+
child_entry,
200201
debug_info_builder_context,
201202
debug_info_builder,
202203
) else {
@@ -209,7 +210,7 @@ fn do_structure_parse<R: ReaderType>(
209210
let child_type = child_dbg_ty.get_type();
210211

211212
let Some(child_name) = debug_info_builder_context
212-
.get_name(dwarf, unit, child.entry())
213+
.get_name(dwarf, unit, child_entry)
213214
.or_else(|| match child_type.type_class() {
214215
TypeClass::StructureTypeClass => Some(String::new()),
215216
_ => None,
@@ -218,19 +219,50 @@ fn do_structure_parse<R: ReaderType>(
218219
continue;
219220
};
220221

221-
// TODO : support DW_AT_data_bit_offset for offset as well
222+
/*
223+
TODO: apply correct member size when that's supported
224+
let child_type_width = get_size_as_u64(child_entry).unwrap_or_else(|| child_type.width());
225+
*/
222226
if let Ok(Some(raw_struct_offset)) =
223-
child.entry().attr(constants::DW_AT_data_member_location)
227+
child_entry.attr(constants::DW_AT_data_member_location)
224228
{
225-
// TODO : Let this fail; don't unwrap_or_default get_expr_value
226-
let struct_offset = get_attr_as_u64(&raw_struct_offset).unwrap_or_else(|| {
227-
get_expr_value(unit, raw_struct_offset).unwrap_or_default()
228-
});
229+
let Some(struct_offset_bytes) = get_attr_as_u64(&raw_struct_offset)
230+
.or_else(|| get_expr_value(unit, raw_struct_offset))
231+
else {
232+
log::warn!(
233+
"Failed to get DW_AT_data_member_location for offset {:#x} in unit {:?}",
234+
child_entry.offset().0,
235+
unit.header.offset()
236+
);
237+
continue;
238+
};
239+
240+
structure_builder.insert(
241+
&child_type,
242+
&child_name,
243+
struct_offset_bytes,
244+
false,
245+
MemberAccess::NoAccess, // TODO : Resolve actual scopes, if possible
246+
MemberScope::NoScope,
247+
);
248+
} else if let Ok(Some(raw_struct_offset_bits)) =
249+
child_entry.attr(constants::DW_AT_data_bit_offset)
250+
{
251+
let Some(struct_offset_bits) = get_attr_as_u64(&raw_struct_offset_bits)
252+
.or_else(|| get_expr_value(unit, raw_struct_offset_bits))
253+
else {
254+
log::warn!(
255+
"Failed to get DW_AT_data_bit_offset for offset {:#x} in unit {:?}",
256+
child_entry.offset().0,
257+
unit.header.offset()
258+
);
259+
continue;
260+
};
229261

230262
structure_builder.insert(
231263
&child_type,
232264
&child_name,
233-
struct_offset,
265+
struct_offset_bits / 8,
234266
false,
235267
MemberAccess::NoAccess, // TODO : Resolve actual scopes, if possible
236268
MemberScope::NoScope,
@@ -248,7 +280,7 @@ fn do_structure_parse<R: ReaderType>(
248280
let Some(base_type_id) = get_type(
249281
dwarf,
250282
unit,
251-
child.entry(),
283+
child_entry,
252284
debug_info_builder_context,
253285
debug_info_builder,
254286
) else {
@@ -261,7 +293,7 @@ fn do_structure_parse<R: ReaderType>(
261293
let base_type = base_dbg_ty.get_type();
262294

263295
let Ok(Some(raw_data_member_location)) =
264-
child.entry().attr(constants::DW_AT_data_member_location)
296+
child_entry.attr(constants::DW_AT_data_member_location)
265297
else {
266298
warn!("Failed to get DW_AT_data_member_location for inheritance");
267299
continue;

0 commit comments

Comments
 (0)