@@ -19,7 +19,8 @@ use crate::{die_handlers::*, ReaderType};
1919use binaryninja:: {
2020 rc:: * ,
2121 types:: {
22- MemberAccess , MemberScope , ReferenceType , StructureBuilder , StructureType , Type , TypeClass ,
22+ BaseStructure , MemberAccess , MemberScope , ReferenceType , StructureBuilder , StructureType ,
23+ Type , TypeClass ,
2324 } ,
2425} ;
2526
@@ -172,63 +173,101 @@ fn do_structure_parse<R: ReaderType>(
172173 debug_info_builder. add_type ( get_uid ( dwarf, unit, entry) , full_name, ntr, false ) ;
173174 }
174175
175- // Get all the children and populate
176+ // Get all the children and base classes to populate
177+ let mut base_structures = Vec :: new ( ) ;
176178 let mut tree = unit. entries_tree ( Some ( entry. offset ( ) ) ) . unwrap ( ) ;
177179 let mut children = tree. root ( ) . unwrap ( ) . children ( ) ;
178180 while let Ok ( Some ( child) ) = children. next ( ) {
179- if child. entry ( ) . tag ( ) == constants:: DW_TAG_member {
180- if let Some ( child_type_id) = get_type (
181- dwarf,
182- unit,
183- child. entry ( ) ,
184- debug_info_builder_context,
185- debug_info_builder,
186- ) {
187- if let Some ( t) = debug_info_builder. get_type ( child_type_id) {
188- let child_type = t. get_type ( ) ;
189- if let Some ( child_name) = debug_info_builder_context
190- . get_name ( dwarf, unit, child. entry ( ) )
191- . map_or (
192- if child_type. type_class ( ) == TypeClass :: StructureTypeClass {
193- Some ( "" . to_string ( ) )
194- } else {
195- None
196- } ,
197- Some ,
198- )
199- {
200- // TODO : support DW_AT_data_bit_offset for offset as well
201- if let Ok ( Some ( raw_struct_offset) ) =
202- child. entry ( ) . attr ( constants:: DW_AT_data_member_location )
203- {
204- // TODO : Let this fail; don't unwrap_or_default get_expr_value
205- let struct_offset =
206- get_attr_as_u64 ( & raw_struct_offset) . unwrap_or_else ( || {
207- get_expr_value ( unit, raw_struct_offset) . unwrap_or_default ( )
208- } ) ;
209-
210- structure_builder. insert (
211- child_type. as_ref ( ) ,
212- child_name,
213- struct_offset,
214- false ,
215- MemberAccess :: NoAccess , // TODO : Resolve actual scopes, if possible
216- MemberScope :: NoScope ,
217- ) ;
218- } else {
219- structure_builder. append (
220- child_type. as_ref ( ) ,
221- child_name,
222- MemberAccess :: NoAccess ,
223- MemberScope :: NoScope ,
224- ) ;
225- }
226- }
181+ match child. entry ( ) . tag ( ) {
182+ constants:: DW_TAG_member => {
183+ let Some ( child_type_id) = get_type (
184+ dwarf,
185+ unit,
186+ child. entry ( ) ,
187+ debug_info_builder_context,
188+ debug_info_builder,
189+ ) else {
190+ continue ;
191+ } ;
192+
193+ let Some ( child_dbg_ty) = debug_info_builder. get_type ( child_type_id) else {
194+ continue ;
195+ } ;
196+ let child_type = child_dbg_ty. get_type ( ) ;
197+
198+ let Some ( child_name) = debug_info_builder_context
199+ . get_name ( dwarf, unit, child. entry ( ) )
200+ . or_else ( || match child_type. type_class ( ) {
201+ TypeClass :: StructureTypeClass => Some ( String :: new ( ) ) ,
202+ _ => None ,
203+ } )
204+ else {
205+ continue ;
206+ } ;
207+
208+ // TODO : support DW_AT_data_bit_offset for offset as well
209+ if let Ok ( Some ( raw_struct_offset) ) =
210+ child. entry ( ) . attr ( constants:: DW_AT_data_member_location )
211+ {
212+ // TODO : Let this fail; don't unwrap_or_default get_expr_value
213+ let struct_offset = get_attr_as_u64 ( & raw_struct_offset) . unwrap_or_else ( || {
214+ get_expr_value ( unit, raw_struct_offset) . unwrap_or_default ( )
215+ } ) ;
216+
217+ structure_builder. insert (
218+ child_type. as_ref ( ) ,
219+ child_name,
220+ struct_offset,
221+ false ,
222+ MemberAccess :: NoAccess , // TODO : Resolve actual scopes, if possible
223+ MemberScope :: NoScope ,
224+ ) ;
225+ } else {
226+ structure_builder. append (
227+ child_type. as_ref ( ) ,
228+ child_name,
229+ MemberAccess :: NoAccess ,
230+ MemberScope :: NoScope ,
231+ ) ;
232+ }
233+ }
234+ constants:: DW_TAG_inheritance => {
235+ let Some ( base_type_id) = get_type (
236+ dwarf,
237+ unit,
238+ child. entry ( ) ,
239+ debug_info_builder_context,
240+ debug_info_builder,
241+ ) else {
242+ warn ! ( "Failed to get base type for inheritance" ) ;
243+ continue ;
244+ } ;
245+ let Some ( base_dbg_ty) = debug_info_builder. get_type ( base_type_id) else {
246+ continue ;
247+ } ;
248+ let base_type = base_dbg_ty. get_type ( ) ;
249+
250+ let Ok ( Some ( raw_data_member_location) ) =
251+ child. entry ( ) . attr ( constants:: DW_AT_data_member_location )
252+ else {
253+ warn ! ( "Failed to get DW_AT_data_member_location for inheritance" ) ;
254+ continue ;
255+ } ;
256+
257+ let base_offset = get_attr_as_u64 ( & raw_data_member_location) . unwrap_or_else ( || {
258+ get_expr_value ( unit, raw_data_member_location) . unwrap_or_default ( )
259+ } ) ;
260+
261+ if let Some ( ntr) = base_type. get_named_type_reference ( ) {
262+ let base_struct = BaseStructure :: new ( ntr, base_offset, 0 ) ;
263+ base_structures. push ( base_struct) ;
227264 }
228265 }
266+ _ => { }
229267 }
230268 }
231269
270+ structure_builder. base_structures ( & base_structures) ;
232271 let finalized_structure = Type :: structure ( & structure_builder. finalize ( ) ) ;
233272 if let Some ( full_name) = full_name {
234273 debug_info_builder. add_type (
0 commit comments