diff options
| author | Mason Reed <mason@vector35.com> | 2025-12-11 14:45:23 -0500 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-12-15 19:29:56 -0500 |
| commit | ca0e32efb1e5b9eba157e9fd2eef178d9367c578 (patch) | |
| tree | 12f9eab134807a4b2821e04ada4795e6611ea45f /rust/src/types.rs | |
| parent | a83f2082799695b85b732987adb21112d042b152 (diff) | |
[Rust] Restructure type APIs into `types` module
This helps with documentation, giving a single module for those working with types to find related APIs
Also split out enumeration and structure APIs into their own file, since they have their own backing data separate from `Type`.
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); |
