diff options
| author | Josh Ferrell <josh@vector35.com> | 2025-10-18 21:08:23 -0400 |
|---|---|---|
| committer | Josh Ferrell <josh@vector35.com> | 2025-10-18 21:08:23 -0400 |
| commit | 3bf1ef60401d046600c2a3f0c804a5537b63e348 (patch) | |
| tree | c8a282e139b92c84367191ec4d9fecb08d5a82d4 /plugins/dwarf | |
| parent | b2622b292d99133084e0b38f4516591c25480548 (diff) | |
[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
Diffstat (limited to 'plugins/dwarf')
| -rw-r--r-- | plugins/dwarf/dwarf_import/src/types.rs | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/plugins/dwarf/dwarf_import/src/types.rs b/plugins/dwarf/dwarf_import/src/types.rs index 8242aa8b..e692e8ca 100644 --- a/plugins/dwarf/dwarf_import/src/types.rs +++ b/plugins/dwarf/dwarf_import/src/types.rs @@ -191,12 +191,13 @@ fn do_structure_parse<R: ReaderType>( }; let mut children = tree_root.children(); while let Ok(Some(child)) = children.next() { - match child.entry().tag() { + let child_entry = child.entry(); + match child_entry.tag() { constants::DW_TAG_member => { let Some(child_type_id) = get_type( dwarf, unit, - child.entry(), + child_entry, debug_info_builder_context, debug_info_builder, ) else { @@ -209,7 +210,7 @@ fn do_structure_parse<R: ReaderType>( let child_type = child_dbg_ty.get_type(); let Some(child_name) = debug_info_builder_context - .get_name(dwarf, unit, child.entry()) + .get_name(dwarf, unit, child_entry) .or_else(|| match child_type.type_class() { TypeClass::StructureTypeClass => Some(String::new()), _ => None, @@ -218,19 +219,50 @@ fn do_structure_parse<R: ReaderType>( continue; }; - // TODO : support DW_AT_data_bit_offset for offset as well + /* + TODO: apply correct member size when that's supported + let child_type_width = get_size_as_u64(child_entry).unwrap_or_else(|| child_type.width()); + */ if let Ok(Some(raw_struct_offset)) = - child.entry().attr(constants::DW_AT_data_member_location) + child_entry.attr(constants::DW_AT_data_member_location) { - // TODO : Let this fail; don't unwrap_or_default get_expr_value - let struct_offset = get_attr_as_u64(&raw_struct_offset).unwrap_or_else(|| { - get_expr_value(unit, raw_struct_offset).unwrap_or_default() - }); + let Some(struct_offset_bytes) = get_attr_as_u64(&raw_struct_offset) + .or_else(|| get_expr_value(unit, raw_struct_offset)) + else { + log::warn!( + "Failed to get DW_AT_data_member_location for offset {:#x} in unit {:?}", + child_entry.offset().0, + unit.header.offset() + ); + continue; + }; + + structure_builder.insert( + &child_type, + &child_name, + struct_offset_bytes, + false, + MemberAccess::NoAccess, // TODO : Resolve actual scopes, if possible + MemberScope::NoScope, + ); + } else if let Ok(Some(raw_struct_offset_bits)) = + child_entry.attr(constants::DW_AT_data_bit_offset) + { + let Some(struct_offset_bits) = get_attr_as_u64(&raw_struct_offset_bits) + .or_else(|| get_expr_value(unit, raw_struct_offset_bits)) + else { + log::warn!( + "Failed to get DW_AT_data_bit_offset for offset {:#x} in unit {:?}", + child_entry.offset().0, + unit.header.offset() + ); + continue; + }; structure_builder.insert( &child_type, &child_name, - struct_offset, + struct_offset_bits / 8, false, MemberAccess::NoAccess, // TODO : Resolve actual scopes, if possible MemberScope::NoScope, @@ -248,7 +280,7 @@ fn do_structure_parse<R: ReaderType>( let Some(base_type_id) = get_type( dwarf, unit, - child.entry(), + child_entry, debug_info_builder_context, debug_info_builder, ) else { @@ -261,7 +293,7 @@ fn do_structure_parse<R: ReaderType>( let base_type = base_dbg_ty.get_type(); let Ok(Some(raw_data_member_location)) = - child.entry().attr(constants::DW_AT_data_member_location) + child_entry.attr(constants::DW_AT_data_member_location) else { warn!("Failed to get DW_AT_data_member_location for inheritance"); continue; |
