diff options
| author | KyleMiles <krm504@nyu.edu> | 2023-08-25 14:08:25 -0400 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2023-09-29 12:02:59 -0400 |
| commit | 20e79d4e43a8734cdc5c4f9ca5b204a2c44aca8e (patch) | |
| tree | 067c27dd7c35158ef2d9f8fa4073e81574088406 /rust/examples/dwarf/dwarf_import/src/die_handlers.rs | |
| parent | a452691f145583f092893dff6ecab14375d0613f (diff) | |
DWARF Import : Misc code cleanup, improvements, and enabling by default changes
This includes:
Gracefully handle missing DIE references
Partially revert 7849cda
Misc DWARFv5 Fixes
Speed Improvements
Fix crash on unexpected EOF
Partially revert 0d5fe9ec8963a26361b8bf1af17e029afc87f952 and Correctly initialize DWARF Import plugin
Diffstat (limited to 'rust/examples/dwarf/dwarf_import/src/die_handlers.rs')
| -rw-r--r-- | rust/examples/dwarf/dwarf_import/src/die_handlers.rs | 75 |
1 files changed, 31 insertions, 44 deletions
diff --git a/rust/examples/dwarf/dwarf_import/src/die_handlers.rs b/rust/examples/dwarf/dwarf_import/src/die_handlers.rs index 84ad8a43..cd3ad55f 100644 --- a/rust/examples/dwarf/dwarf_import/src/die_handlers.rs +++ b/rust/examples/dwarf/dwarf_import/src/die_handlers.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::dwarfdebuginfo::{DebugInfoBuilder, TypeUID}; +use crate::dwarfdebuginfo::{DebugInfoBuilder, DebugInfoBuilderContext, TypeUID}; use crate::helpers::*; use crate::types::get_type; @@ -21,30 +21,26 @@ use binaryninja::{ types::{EnumerationBuilder, FunctionParameter, ReferenceType, Type, TypeBuilder}, }; -use gimli::{constants, AttributeValue::Encoding, DebuggingInformationEntry, Dwarf, Reader, Unit}; +use gimli::{constants, AttributeValue::Encoding, DebuggingInformationEntry, Reader, Unit}; use std::ffi::CString; -pub fn handle_base_type<R: Reader<Offset = usize>>( - dwarf: &Dwarf<R>, +pub(crate) fn handle_base_type<R: Reader<Offset = usize>>( unit: &Unit<R>, entry: &DebuggingInformationEntry<R>, - debug_info_builder: &mut DebugInfoBuilder, + debug_info_builder_context: &DebugInfoBuilderContext<R>, ) -> Option<Ref<Type>> { // All base types have: - // DW_AT_name // DW_AT_encoding (our concept of type_class) // DW_AT_byte_size and/or DW_AT_bit_size + // *DW_AT_name // *DW_AT_endianity (assumed default for arch) // *DW_AT_data_bit_offset (assumed 0) // *Some indication of signedness? // * = Optional - // TODO : By spec base types need to have a name, what if it's spec non-conforming? - let name = debug_info_builder - .get_name(dwarf, unit, entry) - .expect("DW_TAG_base does not have name attribute"); - let size = get_size_as_usize(entry).expect("DW_TAG_base does not have size attribute"); + let name = debug_info_builder_context.get_name(unit, entry)?; + let size = get_size_as_usize(entry)?; match entry.attr_value(constants::DW_AT_encoding) { Ok(Some(Encoding(encoding))) => { match encoding { @@ -62,7 +58,7 @@ pub fn handle_base_type<R: Reader<Offset = usize>>( constants::DW_ATE_edited => None, constants::DW_ATE_signed_fixed => None, constants::DW_ATE_unsigned_fixed => None, - constants::DW_ATE_decimal_float => Some(Type::named_float(size, name)), // TODO : How is this different from binary floating point, ie. DW_ATE_float? + constants::DW_ATE_decimal_float => Some(Type::named_float(size, name)), constants::DW_ATE_UTF => Some(Type::named_int(size, false, name)), // TODO : Verify constants::DW_ATE_UCS => None, constants::DW_ATE_ASCII => None, // Some sort of array? @@ -75,11 +71,10 @@ pub fn handle_base_type<R: Reader<Offset = usize>>( } } -pub fn handle_enum<R: Reader<Offset = usize>>( - dwarf: &Dwarf<R>, +pub(crate) fn handle_enum<R: Reader<Offset = usize>>( unit: &Unit<R>, entry: &DebuggingInformationEntry<R>, - debug_info_builder: &mut DebugInfoBuilder, + debug_info_builder_context: &DebugInfoBuilderContext<R>, ) -> Option<Ref<Type>> { // All base types have: // DW_AT_byte_size @@ -114,9 +109,7 @@ pub fn handle_enum<R: Reader<Offset = usize>>( let mut children = tree.root().unwrap().children(); while let Ok(Some(child)) = children.next() { if child.entry().tag() == constants::DW_TAG_enumerator { - let name = debug_info_builder - .get_name(dwarf, unit, child.entry()) - .expect("DW_TAG_enumeration_type does not have name attribute"); + let name = debug_info_builder_context.get_name(unit, child.entry())?; let value = get_attr_as_u64( &child .entry() @@ -137,7 +130,7 @@ pub fn handle_enum<R: Reader<Offset = usize>>( )) } -pub fn handle_typedef( +pub(crate) fn handle_typedef( debug_info_builder: &mut DebugInfoBuilder, entry_type: Option<TypeUID>, typedef_name: CString, @@ -150,8 +143,6 @@ pub fn handle_typedef( // This will fail in the case where we have a typedef to a type that doesn't exist (failed to parse, incomplete, etc) if let Some(entry_type_offset) = entry_type { if let Some((name, t)) = debug_info_builder.get_type(entry_type_offset) { - // return (Some(t), true); - // TODO : This doesn't filter all the bad typedefs...we should consider not typedefing pointers or arrays, or it's a bug in my parsing if typedef_name == name { return (Some(t), false); } else if typedef_name != name { @@ -164,8 +155,9 @@ pub fn handle_typedef( (None, false) } -pub fn handle_pointer<R: Reader<Offset = usize>>( +pub(crate) fn handle_pointer<R: Reader<Offset = usize>>( entry: &DebuggingInformationEntry<R>, + debug_info_builder_context: &DebugInfoBuilderContext<R>, debug_info_builder: &mut DebugInfoBuilder, entry_type: Option<TypeUID>, reference_type: ReferenceType, @@ -203,7 +195,7 @@ pub fn handle_pointer<R: Reader<Offset = usize>>( let parent_type = debug_info_builder.get_type(entry_type_offset).unwrap().1; Some(Type::pointer_of_width( parent_type.as_ref(), - debug_info_builder.default_address_size(), + debug_info_builder_context.default_address_size(), false, false, Some(reference_type), @@ -211,7 +203,7 @@ pub fn handle_pointer<R: Reader<Offset = usize>>( } else { Some(Type::pointer_of_width( Type::void().as_ref(), - debug_info_builder.default_address_size(), + debug_info_builder_context.default_address_size(), false, false, Some(reference_type), @@ -219,7 +211,7 @@ pub fn handle_pointer<R: Reader<Offset = usize>>( } } -pub fn handle_array<R: Reader<Offset = usize>>( +pub(crate) fn handle_array<R: Reader<Offset = usize>>( unit: &Unit<R>, entry: &DebuggingInformationEntry<R>, debug_info_builder: &mut DebugInfoBuilder, @@ -265,10 +257,10 @@ pub fn handle_array<R: Reader<Offset = usize>>( } } -pub fn handle_function<R: Reader<Offset = usize>>( - dwarf: &Dwarf<R>, +pub(crate) fn handle_function<R: Reader<Offset = usize>>( unit: &Unit<R>, entry: &DebuggingInformationEntry<R>, + debug_info_builder_context: &DebugInfoBuilderContext<R>, debug_info_builder: &mut DebugInfoBuilder, entry_type: Option<TypeUID>, ) -> Option<Ref<Type>> { @@ -305,7 +297,7 @@ pub fn handle_function<R: Reader<Offset = usize>>( }; // Alias function type in the case that it contains itself - if let Some(name) = debug_info_builder.get_name(dwarf, unit, entry) { + if let Some(name) = debug_info_builder_context.get_name(unit, entry) { debug_info_builder.add_type( get_uid(unit, entry), name.clone(), @@ -313,7 +305,7 @@ pub fn handle_function<R: Reader<Offset = usize>>( name, &Type::function::<String, &binaryninja::types::Type>( return_type.as_ref(), - &vec![], + &[], false, ), ), @@ -325,15 +317,19 @@ pub fn handle_function<R: Reader<Offset = usize>>( let mut variable_arguments = false; // Get all the children and populate - // TODO : Handle other attributes? let mut tree = unit.entries_tree(Some(entry.offset())).unwrap(); let mut children = tree.root().unwrap().children(); while let Ok(Some(child)) = children.next() { if child.entry().tag() == constants::DW_TAG_formal_parameter { if let (Some(child_uid), Some(name)) = { ( - get_type(dwarf, unit, child.entry(), debug_info_builder), - debug_info_builder.get_name(dwarf, unit, child.entry()), + get_type( + unit, + child.entry(), + debug_info_builder_context, + debug_info_builder, + ), + debug_info_builder_context.get_name(unit, child.entry()), ) } { let child_type = debug_info_builder.get_type(child_uid).unwrap().1; @@ -344,7 +340,7 @@ pub fn handle_function<R: Reader<Offset = usize>>( } } - if debug_info_builder.get_name(dwarf, unit, entry).is_some() { + if debug_info_builder_context.get_name(unit, entry).is_some() { debug_info_builder.remove_type(get_uid(unit, entry)); } @@ -355,7 +351,7 @@ pub fn handle_function<R: Reader<Offset = usize>>( )) } -pub fn handle_const( +pub(crate) fn handle_const( debug_info_builder: &mut DebugInfoBuilder, entry_type: Option<TypeUID>, ) -> Option<Ref<Type>> { @@ -375,7 +371,7 @@ pub fn handle_const( } } -pub fn handle_volatile( +pub(crate) fn handle_volatile( debug_info_builder: &mut DebugInfoBuilder, entry_type: Option<TypeUID>, ) -> Option<Ref<Type>> { @@ -394,12 +390,3 @@ pub fn handle_volatile( Some(TypeBuilder::void().set_volatile(true).finalize()) } } - -// Handler template: -// pub fn handle_<R: Reader<Offset = usize>>( -// dwarf: &Dwarf<R>, -// unit: &Unit<R>, -// entry: &DebuggingInformationEntry<R>, -// debug_info_builder: &mut DebugInfoBuilder, -// ) -> Option<Ref<Type>> { -// } |
