diff options
Diffstat (limited to 'rust/src/types.rs')
| -rw-r--r-- | rust/src/types.rs | 923 |
1 files changed, 25 insertions, 898 deletions
diff --git a/rust/src/types.rs b/rust/src/types.rs index 1387ffb3..cfdc865b 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -11,16 +11,19 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -#![allow(unused)] -// TODO : More widely enforce the use of ref_from_raw vs just from_raw to simplify internal binding usage? Perhaps remove from_raw functions? -// TODO : Add documentation and fix examples -// TODO : Test the get_enumeration and get_structure methods +pub mod archive; +pub mod container; +pub mod enumeration; +pub mod library; +pub mod parser; +pub mod printer; +pub mod structure; use binaryninjacore_sys::*; use crate::{ - architecture::{Architecture, CoreArchitecture}, + architecture::Architecture, binary_view::{BinaryView, BinaryViewExt}, calling_convention::CoreCallingConvention, rc::*, @@ -29,19 +32,30 @@ use crate::{ use crate::confidence::{Conf, MAX_CONFIDENCE, MIN_CONFIDENCE}; use crate::string::{raw_to_string, strings_to_string_list}; -use crate::type_container::TypeContainer; use crate::variable::{Variable, VariableSourceType}; use std::borrow::Cow; use std::num::NonZeroUsize; use std::ops::{Index, IndexMut}; use std::{ collections::HashSet, - ffi::CStr, fmt::{Debug, Display, Formatter}, hash::{Hash, Hasher}, iter::IntoIterator, }; +pub use archive::{TypeArchive, TypeArchiveId, TypeArchiveSnapshotId}; +pub use container::TypeContainer; +pub use enumeration::{Enumeration, EnumerationBuilder, EnumerationMember}; +pub use library::TypeLibrary; +pub use parser::{ + CoreTypeParser, ParsedType, TypeParser, TypeParserError, TypeParserErrorSeverity, + TypeParserResult, +}; +pub use printer::{CoreTypePrinter, TypePrinter}; +pub use structure::{ + BaseStructure, InheritedStructureMember, Structure, StructureBuilder, StructureMember, +}; + pub type StructureType = BNStructureVariant; pub type ReferenceType = BNReferenceType; pub type TypeClass = BNTypeClass; @@ -970,7 +984,7 @@ impl Debug for Type { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { // You might be tempted to rip this atrocity out and make this more "sensible". READ BELOW! // Type is a one-size fits all structure, these are actually its fields! If we wanted to - // omit some fields for different type classes what you really want to do is implement your + // omit some fields for different type classes, what you really want to do is implement your // own formatter. This is supposed to represent the structure entirely, it's not supposed to be pretty! f.debug_struct("Type") .field("type_class", &self.type_class()) @@ -1048,27 +1062,6 @@ unsafe impl CoreArrayProviderInner for Type { } } -// TODO: Remove this struct, or make it not a ZST with a terrible array provider. -/// ZST used only for `Array<ComponentReferencedType>`. -pub struct ComponentReferencedType; - -impl CoreArrayProvider for ComponentReferencedType { - type Raw = *mut BNType; - type Context = (); - type Wrapped<'a> = &'a Type; -} - -unsafe impl CoreArrayProviderInner for ComponentReferencedType { - unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) { - BNComponentFreeReferencedTypes(raw, count) - } - - unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - // SAFETY: &*mut BNType == &Type (*mut BNType == Type) - std::mem::transmute(raw) - } -} - #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct FunctionParameter { pub ty: Conf<Ref<Type>>, @@ -1105,6 +1098,7 @@ impl FunctionParameter { } } + #[allow(unused)] pub(crate) fn from_owned_raw(value: BNFunctionParameter) -> Self { let owned = Self::from_raw(&value); Self::free_raw(value); @@ -1136,875 +1130,6 @@ impl FunctionParameter { } } -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct EnumerationMember { - pub name: String, - /// The associated constant value for the member. - pub value: u64, - /// Whether this is the default member for the associated [`Enumeration`]. - pub default: bool, -} - -impl EnumerationMember { - pub(crate) fn from_raw(value: &BNEnumerationMember) -> Self { - Self { - name: raw_to_string(value.name).unwrap(), - value: value.value, - default: value.isDefault, - } - } - - pub(crate) fn from_owned_raw(value: BNEnumerationMember) -> Self { - let owned = Self::from_raw(&value); - Self::free_raw(value); - owned - } - - pub(crate) fn into_raw(value: Self) -> BNEnumerationMember { - let bn_name = BnString::new(value.name); - BNEnumerationMember { - name: BnString::into_raw(bn_name), - value: value.value, - isDefault: value.default, - } - } - - pub(crate) fn free_raw(value: BNEnumerationMember) { - unsafe { BnString::free_raw(value.name) }; - } - - pub fn new(name: String, value: u64, default: bool) -> Self { - Self { - name, - value, - default, - } - } -} - -#[derive(PartialEq, Eq, Hash)] -pub struct EnumerationBuilder { - pub(crate) handle: *mut BNEnumerationBuilder, -} - -impl EnumerationBuilder { - pub fn new() -> Self { - Self { - handle: unsafe { BNCreateEnumerationBuilder() }, - } - } - - pub(crate) unsafe fn from_raw(handle: *mut BNEnumerationBuilder) -> Self { - Self { handle } - } - - pub fn finalize(&self) -> Ref<Enumeration> { - unsafe { Enumeration::ref_from_raw(BNFinalizeEnumerationBuilder(self.handle)) } - } - - pub fn append(&mut self, name: &str) -> &mut Self { - let name = name.to_cstr(); - unsafe { - BNAddEnumerationBuilderMember(self.handle, name.as_ref().as_ptr() as _); - } - self - } - - pub fn insert(&mut self, name: &str, value: u64) -> &mut Self { - let name = name.to_cstr(); - unsafe { - BNAddEnumerationBuilderMemberWithValue(self.handle, name.as_ref().as_ptr() as _, value); - } - self - } - - pub fn replace(&mut self, id: usize, name: &str, value: u64) -> &mut Self { - let name = name.to_cstr(); - unsafe { - BNReplaceEnumerationBuilderMember(self.handle, id, name.as_ref().as_ptr() as _, value); - } - self - } - - pub fn remove(&mut self, id: usize) -> &mut Self { - unsafe { - BNRemoveEnumerationBuilderMember(self.handle, id); - } - - self - } - - pub fn members(&self) -> Vec<EnumerationMember> { - unsafe { - let mut count = 0; - let members_raw_ptr = BNGetEnumerationBuilderMembers(self.handle, &mut count); - let members_raw: &[BNEnumerationMember] = - std::slice::from_raw_parts(members_raw_ptr, count); - let members = members_raw - .iter() - .map(EnumerationMember::from_raw) - .collect(); - BNFreeEnumerationMemberList(members_raw_ptr, count); - members - } - } -} - -impl Default for EnumerationBuilder { - fn default() -> Self { - Self::new() - } -} - -impl From<&Enumeration> for EnumerationBuilder { - fn from(enumeration: &Enumeration) -> Self { - unsafe { - Self::from_raw(BNCreateEnumerationBuilderFromEnumeration( - enumeration.handle, - )) - } - } -} - -impl Drop for EnumerationBuilder { - fn drop(&mut self) { - unsafe { BNFreeEnumerationBuilder(self.handle) }; - } -} - -#[derive(PartialEq, Eq, Hash)] -pub struct Enumeration { - pub(crate) handle: *mut BNEnumeration, -} - -impl Enumeration { - pub(crate) unsafe fn ref_from_raw(handle: *mut BNEnumeration) -> Ref<Self> { - debug_assert!(!handle.is_null()); - Ref::new(Self { handle }) - } - - pub fn builder() -> EnumerationBuilder { - EnumerationBuilder::new() - } - - pub fn members(&self) -> Vec<EnumerationMember> { - unsafe { - let mut count = 0; - let members_raw_ptr = BNGetEnumerationMembers(self.handle, &mut count); - debug_assert!(!members_raw_ptr.is_null()); - let members_raw: &[BNEnumerationMember] = - std::slice::from_raw_parts(members_raw_ptr, count); - let members = members_raw - .iter() - .map(EnumerationMember::from_raw) - .collect(); - BNFreeEnumerationMemberList(members_raw_ptr, count); - members - } - } -} - -impl Debug for Enumeration { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Enumeration") - .field("members", &self.members()) - .finish() - } -} - -unsafe impl RefCountable for Enumeration { - unsafe fn inc_ref(handle: &Self) -> Ref<Self> { - Self::ref_from_raw(BNNewEnumerationReference(handle.handle)) - } - - unsafe fn dec_ref(handle: &Self) { - BNFreeEnumeration(handle.handle); - } -} - -impl ToOwned for Enumeration { - type Owned = Ref<Self>; - - fn to_owned(&self) -> Self::Owned { - unsafe { RefCountable::inc_ref(self) } - } -} - -#[derive(PartialEq, Eq, Hash)] -pub struct StructureBuilder { - pub(crate) handle: *mut BNStructureBuilder, -} - -/// ```no_run -/// // Includes -/// # use binaryninja::binary_view::BinaryViewExt; -/// use binaryninja::types::{MemberAccess, MemberScope, Structure, StructureBuilder, Type}; -/// -/// // Types to use in the members -/// let field_1_ty = Type::named_int(5, false, "my_weird_int_type"); -/// let field_2_ty = Type::int(4, false); -/// let field_3_ty = Type::int(8, false); -/// -/// // Assign those fields -/// let mut my_custom_struct = StructureBuilder::new(); -/// my_custom_struct -/// .insert( -/// &field_1_ty, -/// "field_1", -/// 0, -/// false, -/// MemberAccess::PublicAccess, -/// MemberScope::NoScope, -/// ) -/// .insert( -/// &field_2_ty, -/// "field_2", -/// 5, -/// false, -/// MemberAccess::PublicAccess, -/// MemberScope::NoScope, -/// ) -/// .insert( -/// &field_3_ty, -/// "field_3", -/// 9, -/// false, -/// MemberAccess::PublicAccess, -/// MemberScope::NoScope, -/// ) -/// .append( -/// &field_1_ty, -/// "field_4", -/// MemberAccess::PublicAccess, -/// MemberScope::NoScope, -/// ); -/// -/// // Convert structure to type -/// let my_custom_structure_type = Type::structure(&my_custom_struct.finalize()); -/// -/// // Add the struct to the binary view to use in analysis -/// let bv = binaryninja::load("example").unwrap(); -/// bv.define_user_type("my_custom_struct", &my_custom_structure_type); -/// ``` -impl StructureBuilder { - pub fn new() -> Self { - Self { - handle: unsafe { BNCreateStructureBuilder() }, - } - } - - pub(crate) unsafe fn from_raw(handle: *mut BNStructureBuilder) -> Self { - debug_assert!(!handle.is_null()); - Self { handle } - } - - // TODO: Document the width adjustment with alignment. - pub fn finalize(&self) -> Ref<Structure> { - let raw_struct_ptr = unsafe { BNFinalizeStructureBuilder(self.handle) }; - unsafe { Structure::ref_from_raw(raw_struct_ptr) } - } - - /// Sets the width of the [`StructureBuilder`] to the new width. - /// - /// This will remove all previously inserted members outside the new width. This is done by computing - /// the member access range (member offset + member width) and if it is larger than the new width - /// it will be removed. - pub fn width(&mut self, width: u64) -> &mut Self { - unsafe { - BNSetStructureBuilderWidth(self.handle, width); - } - self - } - - pub fn alignment(&mut self, alignment: usize) -> &mut Self { - unsafe { - BNSetStructureBuilderAlignment(self.handle, alignment); - } - self - } - - /// Sets whether the [`StructureBuilder`] is packed. - /// - /// If set the alignment of the structure will be `1`. You do not need to set the alignment to `1`. - pub fn packed(&mut self, packed: bool) -> &mut Self { - unsafe { - BNSetStructureBuilderPacked(self.handle, packed); - } - self - } - - pub fn structure_type(&mut self, t: StructureType) -> &mut Self { - unsafe { BNSetStructureBuilderType(self.handle, t) }; - self - } - - pub fn pointer_offset(&mut self, offset: i64) -> &mut Self { - unsafe { BNSetStructureBuilderPointerOffset(self.handle, offset) }; - self - } - - pub fn propagates_data_var_refs(&mut self, propagates: bool) -> &mut Self { - unsafe { BNSetStructureBuilderPropagatesDataVariableReferences(self.handle, propagates) }; - self - } - - pub fn base_structures(&mut self, bases: &[BaseStructure]) -> &mut Self { - let raw_base_structs: Vec<BNBaseStructure> = - bases.iter().map(BaseStructure::into_owned_raw).collect(); - unsafe { - BNSetBaseStructuresForStructureBuilder( - self.handle, - raw_base_structs.as_ptr() as *mut _, - raw_base_structs.len(), - ) - }; - self - } - - /// Append a member at the next available byte offset. - /// - /// Otherwise, consider using: - /// - /// - [`StructureBuilder::insert_member`] - /// - [`StructureBuilder::insert`] - /// - [`StructureBuilder::insert_bitwise`] - pub fn append<'a, T: Into<Conf<&'a Type>>>( - &mut self, - ty: T, - name: &str, - access: MemberAccess, - scope: MemberScope, - ) -> &mut Self { - let name = name.to_cstr(); - let owned_raw_ty = Conf::<&Type>::into_raw(ty.into()); - unsafe { - BNAddStructureBuilderMember( - self.handle, - &owned_raw_ty, - name.as_ref().as_ptr() as _, - access, - scope, - ); - } - self - } - - /// Insert an already constructed [`StructureMember`]. - /// - /// Otherwise, consider using: - /// - /// - [`StructureBuilder::append`] - /// - [`StructureBuilder::insert`] - /// - [`StructureBuilder::insert_bitwise`] - pub fn insert_member( - &mut self, - member: StructureMember, - overwrite_existing: bool, - ) -> &mut Self { - self.insert_bitwise( - &member.ty, - &member.name, - member.bit_offset(), - member.bit_width, - overwrite_existing, - member.access, - member.scope, - ); - self - } - - /// Inserts a member at the `offset` (in bytes). - /// - /// If you need to insert a member at a specific bit within a given byte (like a bitfield), you - /// can use [`StructureBuilder::insert_bitwise`]. - pub fn insert<'a, T: Into<Conf<&'a Type>>>( - &mut self, - ty: T, - name: &str, - offset: u64, - overwrite_existing: bool, - access: MemberAccess, - scope: MemberScope, - ) -> &mut Self { - self.insert_bitwise( - ty, - name, - offset * 8, - None, - overwrite_existing, - access, - scope, - ) - } - - /// Inserts a member at `bit_offset` with an optional `bit_width`. - /// - /// NOTE: The `bit_offset` is relative to the start of the structure, for example, passing `8` will place - /// the field at the start of the byte `0x1`. - pub fn insert_bitwise<'a, T: Into<Conf<&'a Type>>>( - &mut self, - ty: T, - name: &str, - bit_offset: u64, - bit_width: Option<u8>, - overwrite_existing: bool, - access: MemberAccess, - scope: MemberScope, - ) -> &mut Self { - let name = name.to_cstr(); - let owned_raw_ty = Conf::<&Type>::into_raw(ty.into()); - let byte_offset = bit_offset / 8; - let bit_position = bit_offset % 8; - unsafe { - BNAddStructureBuilderMemberAtOffset( - self.handle, - &owned_raw_ty, - name.as_ref().as_ptr() as _, - byte_offset, - overwrite_existing, - access, - scope, - bit_position as u8, - bit_width.unwrap_or(0), - ); - } - self - } - - pub fn replace<'a, T: Into<Conf<&'a Type>>>( - &mut self, - index: usize, - ty: T, - name: &str, - overwrite_existing: bool, - ) -> &mut Self { - let name = name.to_cstr(); - let owned_raw_ty = Conf::<&Type>::into_raw(ty.into()); - unsafe { - BNReplaceStructureBuilderMember( - self.handle, - index, - &owned_raw_ty, - name.as_ref().as_ptr() as _, - overwrite_existing, - ) - } - self - } - - /// Removes the member at a given index. - pub fn remove(&mut self, index: usize) -> &mut Self { - unsafe { BNRemoveStructureBuilderMember(self.handle, index) }; - self - } - - // TODO: We should add BNGetStructureBuilderAlignedWidth - /// Gets the current **unaligned** width of the structure. - /// - /// This cannot be used to accurately get the width of a non-packed structure. - pub fn current_width(&self) -> u64 { - unsafe { BNGetStructureBuilderWidth(self.handle) } - } -} - -impl From<&Structure> for StructureBuilder { - fn from(structure: &Structure) -> StructureBuilder { - unsafe { Self::from_raw(BNCreateStructureBuilderFromStructure(structure.handle)) } - } -} - -impl From<Vec<StructureMember>> for StructureBuilder { - fn from(members: Vec<StructureMember>) -> StructureBuilder { - let mut builder = StructureBuilder::new(); - for member in members { - builder.insert_member(member, false); - } - builder - } -} - -impl Drop for StructureBuilder { - fn drop(&mut self) { - unsafe { BNFreeStructureBuilder(self.handle) }; - } -} - -impl Default for StructureBuilder { - fn default() -> Self { - Self::new() - } -} - -#[derive(PartialEq, Eq, Hash)] -pub struct Structure { - pub(crate) handle: *mut BNStructure, -} - -impl Structure { - pub(crate) unsafe fn ref_from_raw(handle: *mut BNStructure) -> Ref<Self> { - debug_assert!(!handle.is_null()); - Ref::new(Self { handle }) - } - - pub fn builder() -> StructureBuilder { - StructureBuilder::new() - } - - pub fn width(&self) -> u64 { - unsafe { BNGetStructureWidth(self.handle) } - } - - pub fn structure_type(&self) -> StructureType { - unsafe { BNGetStructureType(self.handle) } - } - - /// Retrieve the members that are accessible at a given offset. - /// - /// The reason for this being plural is that members may overlap and the offset is in bytes - /// where a bitfield may contain multiple members at the given byte. - /// - /// Unions are also represented as structures and will cause this function to return - /// **all** members that can reach that offset. - /// - /// We must pass a [`TypeContainer`] here so that we can resolve base structure members, as they - /// are treated as members through this function. Typically, you get the [`TypeContainer`] - /// through the binary view with [`BinaryViewExt::type_container`]. - pub fn members_at_offset( - &self, - container: &TypeContainer, - offset: u64, - ) -> Vec<StructureMember> { - self.members_including_inherited(container) - .into_iter() - .filter(|m| m.member.is_offset_valid(offset)) - .map(|m| m.member) - .collect() - } - - /// Return the list of non-inherited structure members. - /// - /// If you want to get all members, including ones inherited from base structures, - /// use [`Structure::members_including_inherited`] instead. - pub fn members(&self) -> Vec<StructureMember> { - unsafe { - let mut count = 0; - let members_raw_ptr: *mut BNStructureMember = - BNGetStructureMembers(self.handle, &mut count); - debug_assert!(!members_raw_ptr.is_null()); - let members_raw = std::slice::from_raw_parts(members_raw_ptr, count); - let members = members_raw.iter().map(StructureMember::from_raw).collect(); - BNFreeStructureMemberList(members_raw_ptr, count); - members - } - } - - /// Returns the list of all structure members, including inherited ones. - /// - /// Because we must traverse through base structures, we have to provide the [`TypeContainer`]; - /// in most cases it is ok to provide the binary views container via [`BinaryViewExt::type_container`]. - pub fn members_including_inherited( - &self, - container: &TypeContainer, - ) -> Vec<InheritedStructureMember> { - unsafe { - let mut count = 0; - let members_raw_ptr: *mut BNInheritedStructureMember = - BNGetStructureMembersIncludingInherited( - self.handle, - container.handle.as_ptr(), - &mut count, - ); - debug_assert!(!members_raw_ptr.is_null()); - let members_raw = std::slice::from_raw_parts(members_raw_ptr, count); - let members = members_raw - .iter() - .map(InheritedStructureMember::from_raw) - .collect(); - BNFreeInheritedStructureMemberList(members_raw_ptr, count); - members - } - } - - /// Retrieve the list of base structures for the structure. These base structures are what give - /// a structure inherited members. - pub fn base_structures(&self) -> Vec<BaseStructure> { - let mut count = 0; - let bases_raw_ptr = unsafe { BNGetBaseStructuresForStructure(self.handle, &mut count) }; - debug_assert!(!bases_raw_ptr.is_null()); - let bases_raw = unsafe { std::slice::from_raw_parts(bases_raw_ptr, count) }; - let bases = bases_raw.iter().map(BaseStructure::from_raw).collect(); - unsafe { BNFreeBaseStructureList(bases_raw_ptr, count) }; - bases - } - - /// Whether the structure is packed or not. - pub fn is_packed(&self) -> bool { - unsafe { BNIsStructurePacked(self.handle) } - } - - pub fn alignment(&self) -> usize { - unsafe { BNGetStructureAlignment(self.handle) } - } -} - -impl Debug for Structure { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Structure") - .field("width", &self.width()) - .field("alignment", &self.alignment()) - .field("packed", &self.is_packed()) - .field("structure_type", &self.structure_type()) - .field("base_structures", &self.base_structures()) - .field("members", &self.members()) - .finish() - } -} - -unsafe impl RefCountable for Structure { - unsafe fn inc_ref(handle: &Self) -> Ref<Self> { - Self::ref_from_raw(BNNewStructureReference(handle.handle)) - } - - unsafe fn dec_ref(handle: &Self) { - BNFreeStructure(handle.handle); - } -} - -impl ToOwned for Structure { - type Owned = Ref<Self>; - - fn to_owned(&self) -> Self::Owned { - unsafe { RefCountable::inc_ref(self) } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct StructureMember { - pub ty: Conf<Ref<Type>>, - // TODO: Shouldnt this be a QualifiedName? The ffi says no... - pub name: String, - /// The byte offset of the member. - pub offset: u64, - pub access: MemberAccess, - pub scope: MemberScope, - /// The bit position relative to the byte offset. - pub bit_position: Option<u8>, - pub bit_width: Option<u8>, -} - -impl StructureMember { - pub(crate) fn from_raw(value: &BNStructureMember) -> Self { - Self { - ty: Conf::new( - unsafe { Type::from_raw(value.type_) }.to_owned(), - value.typeConfidence, - ), - // TODO: I dislike using this function here. - name: raw_to_string(value.name as *mut _).unwrap(), - offset: value.offset, - access: value.access, - scope: value.scope, - bit_position: match value.bitPosition { - 0 => None, - _ => Some(value.bitPosition), - }, - bit_width: match value.bitWidth { - 0 => None, - _ => Some(value.bitWidth), - }, - } - } - - pub(crate) fn from_owned_raw(value: BNStructureMember) -> Self { - let owned = Self::from_raw(&value); - Self::free_raw(value); - owned - } - - pub(crate) fn into_raw(value: Self) -> BNStructureMember { - let bn_name = BnString::new(value.name); - BNStructureMember { - type_: unsafe { Ref::into_raw(value.ty.contents) }.handle, - name: BnString::into_raw(bn_name), - offset: value.offset, - typeConfidence: value.ty.confidence, - access: value.access, - scope: value.scope, - bitPosition: value.bit_position.unwrap_or(0), - bitWidth: value.bit_width.unwrap_or(0), - } - } - - pub(crate) fn free_raw(value: BNStructureMember) { - let _ = unsafe { Type::ref_from_raw(value.type_) }; - unsafe { BnString::free_raw(value.name) }; - } - - pub fn new( - ty: Conf<Ref<Type>>, - name: String, - offset: u64, - access: MemberAccess, - scope: MemberScope, - ) -> Self { - Self { - ty, - name, - offset, - access, - scope, - bit_position: None, - bit_width: None, - } - } - - pub fn new_bitfield( - ty: Conf<Ref<Type>>, - name: String, - bit_offset: u64, - bit_width: u8, - access: MemberAccess, - scope: MemberScope, - ) -> Self { - Self { - ty, - name, - offset: bit_offset / 8, - access, - scope, - bit_position: Some((bit_offset % 8) as u8), - bit_width: Some(bit_width), - } - } - - // TODO: Do we count bitwidth here? - /// Whether the offset within the accessible range of the member. - pub fn is_offset_valid(&self, offset: u64) -> bool { - self.offset <= offset && offset < self.offset + self.ty.contents.width() - } - - /// Member offset in bits. - pub fn bit_offset(&self) -> u64 { - (self.offset * 8) + self.bit_position.unwrap_or(0) as u64 - } -} - -impl CoreArrayProvider for StructureMember { - type Raw = BNStructureMember; - type Context = (); - type Wrapped<'a> = Self; -} - -unsafe impl CoreArrayProviderInner for StructureMember { - unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) { - BNFreeStructureMemberList(raw, count) - } - - unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - Self::from_raw(raw) - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct InheritedStructureMember { - pub base: Ref<NamedTypeReference>, - pub base_offset: u64, - pub member: StructureMember, - pub member_index: usize, -} - -impl InheritedStructureMember { - pub(crate) fn from_raw(value: &BNInheritedStructureMember) -> Self { - Self { - base: unsafe { NamedTypeReference::from_raw(value.base) }.to_owned(), - base_offset: value.baseOffset, - member: StructureMember::from_raw(&value.member), - member_index: value.memberIndex, - } - } - - pub(crate) fn from_owned_raw(value: BNInheritedStructureMember) -> Self { - let owned = Self::from_raw(&value); - Self::free_raw(value); - owned - } - - pub(crate) fn into_raw(value: Self) -> BNInheritedStructureMember { - BNInheritedStructureMember { - base: unsafe { Ref::into_raw(value.base) }.handle, - baseOffset: value.base_offset, - member: StructureMember::into_raw(value.member), - memberIndex: value.member_index, - } - } - - pub(crate) fn free_raw(value: BNInheritedStructureMember) { - let _ = unsafe { NamedTypeReference::ref_from_raw(value.base) }; - StructureMember::free_raw(value.member); - } - - pub fn new( - base: Ref<NamedTypeReference>, - base_offset: u64, - member: StructureMember, - member_index: usize, - ) -> Self { - Self { - base, - base_offset, - member, - member_index, - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct BaseStructure { - pub ty: Ref<NamedTypeReference>, - pub offset: u64, - pub width: u64, -} - -impl BaseStructure { - pub(crate) fn from_raw(value: &BNBaseStructure) -> Self { - Self { - ty: unsafe { NamedTypeReference::from_raw(value.type_) }.to_owned(), - offset: value.offset, - width: value.width, - } - } - - pub(crate) fn from_owned_raw(value: BNBaseStructure) -> Self { - let owned = Self::from_raw(&value); - Self::free_raw(value); - owned - } - - pub(crate) fn into_raw(value: Self) -> BNBaseStructure { - BNBaseStructure { - type_: unsafe { Ref::into_raw(value.ty) }.handle, - offset: value.offset, - width: value.width, - } - } - - pub(crate) fn into_owned_raw(value: &Self) -> BNBaseStructure { - BNBaseStructure { - type_: value.ty.handle, - offset: value.offset, - width: value.width, - } - } - - pub(crate) fn free_raw(value: BNBaseStructure) { - let _ = unsafe { NamedTypeReference::ref_from_raw(value.type_) }; - } - - pub fn new(ty: Ref<NamedTypeReference>, offset: u64, width: u64) -> Self { - Self { ty, offset, width } - } -} - #[derive(PartialEq, Eq, Hash)] pub struct NamedTypeReference { pub(crate) handle: *mut BNNamedTypeReference, @@ -2435,6 +1560,7 @@ impl QualifiedNameTypeAndId { } } + #[allow(unused)] pub(crate) fn from_owned_raw(value: BNQualifiedNameTypeAndId) -> Self { let owned = Self::from_raw(&value); Self::free_raw(value); @@ -2495,6 +1621,7 @@ impl NameAndType { } } + #[allow(unused)] pub(crate) fn from_owned_raw(value: BNNameAndType) -> Self { let owned = Self::from_raw(&value); Self::free_raw(value); |
