From e7fd1039c6de070144417d48ebf39a7d66556c7d Mon Sep 17 00:00:00 2001 From: Rubens Brandao Date: Thu, 13 Jun 2024 13:35:19 -0300 Subject: [PATCH 1/3] implement rust TypeLibrary --- rust/src/binaryview.rs | 214 +++++++++++++++++++++++- rust/src/lib.rs | 1 + rust/src/platform.rs | 10 ++ rust/src/typelibrary.rs | 362 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 578 insertions(+), 9 deletions(-) create mode 100644 rust/src/typelibrary.rs diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs index 7da5a744b..832493092 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -23,15 +23,11 @@ pub use binaryninjacore_sys::BNAnalysisState as AnalysisState; pub use binaryninjacore_sys::BNModificationStatus as ModificationStatus; use std::collections::HashMap; -use std::ffi::c_void; +use std::ffi::{c_char, c_void}; use std::ops::Range; -use std::os::raw::c_char; -use std::ptr; -use std::result; -use std::{ops, slice}; +use std::{ops, ptr, result, slice}; -use crate::architecture::Architecture; -use crate::architecture::CoreArchitecture; +use crate::architecture::{Architecture, CoreArchitecture}; use crate::basicblock::BasicBlock; use crate::component::{Component, ComponentBuilder, IntoComponentGuid}; use crate::databuffer::DataBuffer; @@ -40,8 +36,7 @@ use crate::fileaccessor::FileAccessor; use crate::filemetadata::FileMetadata; use crate::flowgraph::FlowGraph; use crate::function::{Function, NativeBlock}; -use crate::linearview::LinearDisassemblyLine; -use crate::linearview::LinearViewCursor; +use crate::linearview::{LinearDisassemblyLine, LinearViewCursor}; use crate::metadata::Metadata; use crate::platform::Platform; use crate::relocation::Relocation; @@ -50,6 +45,7 @@ use crate::segment::{Segment, SegmentBuilder}; use crate::settings::Settings; use crate::symbol::{Symbol, SymbolType}; use crate::tags::{Tag, TagType}; +use crate::typelibrary::TypeLibrary; use crate::types::{ Conf, DataVariable, NamedTypeReference, QualifiedName, QualifiedNameAndType, Type, }; @@ -1429,6 +1425,206 @@ pub trait BinaryViewExt: BinaryViewBase { }; unsafe { Array::new(result, count, ()) } } + + /// Make the contents of a type library available for type/import resolution + fn add_type_library(&self, library: &TypeLibrary) { + unsafe { BNAddBinaryViewTypeLibrary(self.as_ref().handle, library.as_raw()) } + } + + fn type_library_by_name(&self, name: S) -> Option { + let name = name.into_bytes_with_nul(); + let result = unsafe { + BNGetBinaryViewTypeLibrary( + self.as_ref().handle, + name.as_ref().as_ptr() as *const core::ffi::c_char, + ) + }; + core::ptr::NonNull::new(result).map(|h| unsafe { TypeLibrary::from_raw(h) }) + } + + /// Should be called by custom py:py:class:`BinaryView` implementations + /// when they have successfully imported an object from a type library (eg a symbol's type). + /// Values recorded with this function will then be queryable via [BinaryViewExt::lookup_imported_object_library]. + /// + /// * `lib` - Type Library containing the imported type + /// * `name` - Name of the object in the type library + /// * `addr` - address of symbol at import site + /// * `platform` - Platform of symbol at import site + fn record_imported_object_library( + &self, + lib: &TypeLibrary, + name: &QualifiedName, + addr: u64, + platform: &Platform, + ) { + unsafe { + BNBinaryViewRecordImportedObjectLibrary( + self.as_ref().handle, + platform.handle, + addr, + lib.as_raw(), + &name.0 as *const _ as *mut _, + ) + } + } + + /// Recursively imports a type from the specified type library, or, if + /// no library was explicitly provided, the first type library associated with the current [BinaryView] + /// that provides the name requested. + /// + /// This may have the impact of loading other type libraries as dependencies on other type libraries are lazily resolved + /// when references to types provided by them are first encountered. + /// + /// Note that the name actually inserted into the view may not match the name as it exists in the type library in + /// the event of a name conflict. To aid in this, the [Type] object returned is a `NamedTypeReference` to + /// the deconflicted name used. + fn import_type_library( + &self, + name: &QualifiedName, + mut lib: Option, + ) -> Option> { + let mut lib_ref = lib + .as_mut() + .map(|l| unsafe { l.as_raw() } as *mut _) + .unwrap_or(ptr::null_mut()); + let result = unsafe { + BNBinaryViewImportTypeLibraryType( + self.as_ref().handle, + &mut lib_ref, + &name.0 as *const _ as *mut _, + ) + }; + (!result.is_null()).then(|| unsafe { Type::ref_from_raw(result) }) + } + + /// Recursively imports an object from the specified type library, or, if + /// no library was explicitly provided, the first type library associated with the current [BinaryView] + /// that provides the name requested. + /// + /// This may have the impact of loading other type libraries as dependencies on other type libraries are lazily resolved + /// when references to types provided by them are first encountered. + /// + /// .. note:: If you are implementing a custom BinaryView and use this method to import object types, + /// you should then call [BinaryViewExt::record_imported_object_library] with the details of where the object is located. + fn import_type_object( + &self, + name: &QualifiedName, + mut lib: Option, + ) -> Option> { + let mut lib_ref = lib + .as_mut() + .map(|l| unsafe { l.as_raw() } as *mut _) + .unwrap_or(ptr::null_mut()); + let result = unsafe { + BNBinaryViewImportTypeLibraryObject( + self.as_ref().handle, + &mut lib_ref, + &name.0 as *const _ as *mut _, + ) + }; + (!result.is_null()).then(|| unsafe { Type::ref_from_raw(result) }) + } + + /// Recursively imports a type interface given its GUID. + /// + /// .. note:: To support this type of lookup a type library must have + /// contain a metadata key called "type_guids" which is a map + /// Dict[string_guid, string_type_name] or + /// Dict[string_guid, Tuple[string_type_name, type_library_name]] + fn import_type_by_guid(&self, guid: S) -> Option> { + let guid = guid.into_bytes_with_nul(); + let result = unsafe { + BNBinaryViewImportTypeLibraryTypeByGuid( + self.as_ref().handle, + guid.as_ref().as_ptr() as *const c_char, + ) + }; + (!result.is_null()).then(|| unsafe { Type::ref_from_raw(result) }) + } + + /// Recursively exports `type_obj` into `lib` as a type with name `name` + /// + /// As other referenced types are encountered, they are either copied into the destination type library or + /// else the type library that provided the referenced type is added as a dependency for the destination library. + fn export_type_to_library(&self, lib: &TypeLibrary, name: &QualifiedName, type_obj: &Type) { + unsafe { + BNBinaryViewExportTypeToTypeLibrary( + self.as_ref().handle, + lib.as_raw(), + &name.0 as *const _ as *mut _, + type_obj.handle, + ) + } + } + + /// Recursively exports `type_obj` into `lib` as a type with name `name` + /// + /// As other referenced types are encountered, they are either copied into the destination type library or + /// else the type library that provided the referenced type is added as a dependency for the destination library. + fn export_object_to_library(&self, lib: &TypeLibrary, name: &QualifiedName, type_obj: &Type) { + unsafe { + BNBinaryViewExportObjectToTypeLibrary( + self.as_ref().handle, + lib.as_raw(), + &name.0 as *const _ as *mut _, + type_obj.handle, + ) + } + } + + /// Gives you details of which type library and name was used to determine + /// the type of a symbol at a given address + /// + /// * `addr` - address of symbol at import site + /// * `platform` - Platform of symbol at import site + fn lookup_imported_object_library( + &self, + addr: u64, + platform: &Platform, + ) -> Option<(TypeLibrary, QualifiedName)> { + let mut result_lib = ptr::null_mut(); + let mut result_name = Default::default(); + let success = unsafe { + BNBinaryViewLookupImportedObjectLibrary( + self.as_ref().handle, + platform.handle, + addr, + &mut result_lib, + &mut result_name, + ) + }; + if !success { + return None; + } + let lib = unsafe { TypeLibrary::from_raw(ptr::NonNull::new(result_lib)?) }; + let name = QualifiedName(result_name); + Some((lib, name)) + } + + /// Gives you details of from which type library and name a given type in the analysis was imported. + /// + /// * `name` - Name of type in analysis + fn lookup_imported_type_library( + &self, + name: &QualifiedNameAndType, + ) -> Option<(TypeLibrary, QualifiedName)> { + let mut result_lib = ptr::null_mut(); + let mut result_name = Default::default(); + let success = unsafe { + BNBinaryViewLookupImportedTypeLibrary( + self.as_ref().handle, + &name.0 as *const _ as *mut _, + &mut result_lib, + &mut result_name, + ) + }; + if !success { + return None; + } + let lib = unsafe { TypeLibrary::from_raw(ptr::NonNull::new(result_lib)?) }; + let name = QualifiedName(result_name); + Some((lib, name)) + } } impl BinaryViewExt for T {} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 8cd6ba60b..0eb0653c7 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -166,6 +166,7 @@ pub mod string; pub mod symbol; pub mod tags; pub mod templatesimplifier; +pub mod typelibrary; pub mod typearchive; pub mod types; diff --git a/rust/src/platform.rs b/rust/src/platform.rs index 11f76284b..4e31a0a24 100644 --- a/rust/src/platform.rs +++ b/rust/src/platform.rs @@ -23,6 +23,7 @@ use crate::{ callingconvention::CallingConvention, rc::*, string::*, + typelibrary::TypeLibrary, types::{QualifiedName, QualifiedNameAndType, Type}, }; @@ -163,6 +164,15 @@ impl Platform { unsafe { CoreArchitecture::from_raw(BNGetPlatformArchitecture(self.handle)) } } + pub fn get_type_libraries_by_name(&self, name: &QualifiedName) -> Array { + let mut count = 0; + let result = unsafe { + BNGetPlatformTypeLibrariesByName(self.handle, &name.0 as *const _ as *mut _, &mut count) + }; + assert!(!result.is_null()); + unsafe { Array::new(result, count, ()) } + } + pub fn register_os(&self, os: S) { let os = os.into_bytes_with_nul(); diff --git a/rust/src/typelibrary.rs b/rust/src/typelibrary.rs new file mode 100644 index 000000000..79cb6569b --- /dev/null +++ b/rust/src/typelibrary.rs @@ -0,0 +1,362 @@ +use binaryninjacore_sys::*; + +use core::{ffi, mem, ptr}; + +use crate::{ + architecture::CoreArchitecture, + metadata::Metadata, + platform::Platform, + rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref}, + string::{BnStrCompatible, BnString}, + types::{QualifiedName, QualifiedNameAndType, Type}, +}; + +pub struct TypeLibrary { + handle: ptr::NonNull, +} + +impl TypeLibrary { + pub(crate) unsafe fn from_raw(handle: ptr::NonNull) -> Self { + Self { handle } + } + + pub(crate) unsafe fn ref_from_raw(handle: &*mut BNTypeLibrary) -> &Self { + assert!(!handle.is_null()); + mem::transmute(handle) + } + + #[allow(clippy::mut_from_ref)] + pub(crate) unsafe fn as_raw(&self) -> &mut BNTypeLibrary { + &mut *self.handle.as_ptr() + } + + pub fn new_reference(&self) -> Self { + unsafe { + Self::from_raw(ptr::NonNull::new(BNNewTypeLibraryReference(self.as_raw())).unwrap()) + } + } + + pub fn new_duplicated(&self) -> Self { + unsafe { Self::from_raw(ptr::NonNull::new(BNDuplicateTypeLibrary(self.as_raw())).unwrap()) } + } + + /// Creates an empty type library object with a random GUID and the provided name. + pub fn new(arch: CoreArchitecture, name: S) -> TypeLibrary { + let name = name.into_bytes_with_nul(); + let new_lib = + unsafe { BNNewTypeLibrary(arch.0, name.as_ref().as_ptr() as *const ffi::c_char) }; + unsafe { TypeLibrary::from_raw(ptr::NonNull::new(new_lib).unwrap()) } + } + + pub fn all(arch: CoreArchitecture) -> Array { + let mut count = 0; + let result = unsafe { BNGetArchitectureTypeLibraries(arch.0, &mut count) }; + assert!(!result.is_null()); + unsafe { Array::new(result, count, ()) } + } + + /// Decompresses a type library file to a file on disk. + pub fn decompress_to_file(path: P, output: O) -> bool { + let path = path.into_bytes_with_nul(); + let output = output.into_bytes_with_nul(); + unsafe { + BNTypeLibraryDecompressToFile( + path.as_ref().as_ptr() as *const ffi::c_char, + output.as_ref().as_ptr() as *const ffi::c_char, + ) + } + } + + /// Loads a finalized type library instance from file + pub fn load_from_file(path: S) -> Option { + let path = path.into_bytes_with_nul(); + let handle = + unsafe { BNLoadTypeLibraryFromFile(path.as_ref().as_ptr() as *const ffi::c_char) }; + ptr::NonNull::new(handle).map(|h| unsafe { TypeLibrary::from_raw(h) }) + } + + /// Saves a finalized type library instance to file + pub fn write_to_file(&self, path: S) { + let path = path.into_bytes_with_nul(); + unsafe { + BNWriteTypeLibraryToFile(self.as_raw(), path.as_ref().as_ptr() as *const ffi::c_char) + } + } + + /// Looks up the first type library found with a matching name. Keep in mind that names are not + /// necessarily unique. + pub fn from_name(arch: CoreArchitecture, name: S) -> Option { + let name = name.into_bytes_with_nul(); + let handle = unsafe { + BNLookupTypeLibraryByName(arch.0, name.as_ref().as_ptr() as *const ffi::c_char) + }; + ptr::NonNull::new(handle).map(|h| unsafe { TypeLibrary::from_raw(h) }) + } + + /// Attempts to grab a type library associated with the provided Architecture and GUID pair + pub fn from_guid(arch: CoreArchitecture, guid: S) -> Option { + let guid = guid.into_bytes_with_nul(); + let handle = unsafe { + BNLookupTypeLibraryByGuid(arch.0, guid.as_ref().as_ptr() as *const ffi::c_char) + }; + ptr::NonNull::new(handle).map(|h| unsafe { TypeLibrary::from_raw(h) }) + } + + /// The Architecture this type library is associated with + pub fn arch(&self) -> CoreArchitecture { + let arch = unsafe { BNGetTypeLibraryArchitecture(self.as_raw()) }; + assert!(!arch.is_null()); + CoreArchitecture(arch) + } + + /// The primary name associated with this type library + pub fn name(&self) -> Option { + let result = unsafe { BNGetTypeLibraryName(self.as_raw()) }; + (!result.is_null()).then(|| unsafe { BnString::from_raw(result) }) + } + + /// Sets the name of a type library instance that has not been finalized + pub fn set_name(&self, value: S) { + let value = value.into_bytes_with_nul(); + unsafe { + BNSetTypeLibraryName(self.as_raw(), value.as_ref().as_ptr() as *const ffi::c_char) + } + } + + /// The `dependency_name` of a library is the name used to record dependencies across + /// type libraries. This allows, for example, a library with the name "musl_libc" to have + /// dependencies on it recorded as "libc_generic", allowing a type library to be used across + /// multiple platforms where each has a specific libc that also provides the name "libc_generic" + /// as an `alternate_name`. + pub fn dependency_name(&self) -> Option { + let result = unsafe { BNGetTypeLibraryDependencyName(self.as_raw()) }; + (!result.is_null()).then(|| unsafe { BnString::from_raw(result) }) + } + + /// Sets the dependency name of a type library instance that has not been finalized + pub fn set_dependency_name(&self, value: S) { + let value = value.into_bytes_with_nul(); + unsafe { + BNSetTypeLibraryDependencyName( + self.as_raw(), + value.as_ref().as_ptr() as *const ffi::c_char, + ) + } + } + + /// Returns the GUID associated with the type library + pub fn guid(&self) -> Option { + let result = unsafe { BNGetTypeLibraryGuid(self.as_raw()) }; + (!result.is_null()).then(|| unsafe { BnString::from_raw(result) }) + } + + /// Sets the GUID of a type library instance that has not been finalized + pub fn set_guid(&self, value: S) { + let value = value.into_bytes_with_nul(); + unsafe { + BNSetTypeLibraryGuid(self.as_raw(), value.as_ref().as_ptr() as *const ffi::c_char) + } + } + + /// A list of extra names that will be considered a match by [Platform::get_type_libraries_by_name] + pub fn alternate_names(&self) -> Array { + let mut count = 0; + let result = unsafe { BNGetTypeLibraryAlternateNames(self.as_raw(), &mut count) }; + assert!(!result.is_null()); + unsafe { Array::new(result, count, ()) } + } + + /// Adds an extra name to this type library used during library lookups and dependency resolution + pub fn add_alternate_name(&self, value: S) { + let value = value.into_bytes_with_nul(); + unsafe { + BNAddTypeLibraryAlternateName( + self.as_raw(), + value.as_ref().as_ptr() as *const ffi::c_char, + ) + } + } + + /// Returns a list of all platform names that this type library will register with during platform + /// type registration. + /// + /// This returns strings, not Platform objects, as type libraries can be distributed with support for + /// Platforms that may not be present. + pub fn platform_names(&self) -> Array { + let mut count = 0; + let result = unsafe { BNGetTypeLibraryPlatforms(self.as_raw(), &mut count) }; + assert!(!result.is_null()); + unsafe { Array::new(result, count, ()) } + } + + /// Associate a platform with a type library instance that has not been finalized. + /// + /// This will cause the library to be searchable by [Platform::get_type_libraries_by_name] + /// when loaded. + /// + /// This does not have side affects until finalization of the type library. + pub fn add_platform(&self, plat: &Platform) { + unsafe { BNAddTypeLibraryPlatform(self.as_raw(), plat.handle) } + } + + /// Clears the list of platforms associated with a type library instance that has not been finalized + pub fn clear_platforms(&self) { + unsafe { BNClearTypeLibraryPlatforms(self.as_raw()) } + } + + /// Flags a newly created type library instance as finalized and makes it available for Platform and Architecture + /// type library searches + pub fn finalize(&self) -> bool { + unsafe { BNFinalizeTypeLibrary(self.as_raw()) } + } + + /// Retrieves a metadata associated with the given key stored in the type library + pub fn query_metadata(&self, key: S) -> Option { + let key = key.into_bytes_with_nul(); + let result = unsafe { + BNTypeLibraryQueryMetadata(self.as_raw(), key.as_ref().as_ptr() as *const ffi::c_char) + }; + (!result.is_null()).then(|| unsafe { Metadata::from_raw(result) }) + } + + /// Stores an object for the given key in the current type library. Objects stored using + /// `store_metadata` can be retrieved from any reference to the library. Objects stored are not arbitrary python + /// objects! The values stored must be able to be held in a Metadata object. See [Metadata] + /// for more information. Python objects could obviously be serialized using pickle but this intentionally + /// a task left to the user since there is the potential security issues. + /// + /// This is primarily intended as a way to store Platform specific information relevant to BinaryView implementations; + /// for example the PE BinaryViewType uses type library metadata to retrieve ordinal information, when available. + /// + /// * `key` - key value to associate the Metadata object with + /// * `md` - object to store. + pub fn store_metadata(&self, key: S, md: &Metadata) { + let key = key.into_bytes_with_nul(); + unsafe { + BNTypeLibraryStoreMetadata( + self.as_raw(), + key.as_ref().as_ptr() as *const ffi::c_char, + md.handle, + ) + } + } + + /// Removes the metadata associated with key from the current type library. + pub fn remove_metadata(&self, key: S) { + let key = key.into_bytes_with_nul(); + unsafe { + BNTypeLibraryRemoveMetadata(self.as_raw(), key.as_ref().as_ptr() as *const ffi::c_char) + } + } + + /// Retrieves the metadata associated with the current type library. + pub fn metadata(&self) -> Metadata { + let md_handle = unsafe { BNTypeLibraryGetMetadata(self.as_raw()) }; + assert!(!md_handle.is_null()); + unsafe { Metadata::from_raw(md_handle) } + } + + // TODO: implement TypeContainer + // /// Type Container for all TYPES within the Type Library. Objects are not included. + // /// The Type Container's Platform will be the first platform associated with the Type Library. + // pub fn type_container(&self) -> TypeContainer { + // let result = unsafe{ BNGetTypeLibraryTypeContainer(self.as_raw())}; + // unsafe{TypeContainer::from_raw(ptr::NonNull::new(result).unwrap())} + // } + + /// Directly inserts a named object into the type library's object store. + /// This is not done recursively, so care should be taken that types referring to other types + /// through NamedTypeReferences are already appropriately prepared. + /// + /// To add types and objects from an existing BinaryView, it is recommended to use + /// `export_object_to_library `, which will automatically pull in + /// all referenced types and record additional dependencies as needed. + pub fn add_named_object(&self, name: &QualifiedName, type_: &Type) { + unsafe { + BNAddTypeLibraryNamedObject(self.as_raw(), &name.0 as *const _ as *mut _, type_.handle) + } + } + + /// Directly inserts a named object into the type library's object store. + /// This is not done recursively, so care should be taken that types referring to other types + /// through NamedTypeReferences are already appropriately prepared. + /// + /// To add types and objects from an existing BinaryView, it is recommended to use + /// `export_type_to_library `, which will automatically pull in + /// all referenced types and record additional dependencies as needed. + pub fn add_named_type(&self, name: &QualifiedNameAndType, type_: &Type) { + unsafe { + BNAddTypeLibraryNamedType(self.as_raw(), &name.0 as *const _ as *mut _, type_.handle) + } + } + + /// Manually flag NamedTypeReferences to the given QualifiedName as originating from another source + /// TypeLibrary with the given dependency name. + /// + /// .. warning:: Use this api with extreme caution. + pub fn add_type_source(&self, name: &QualifiedName, source: S) { + let source = source.into_bytes_with_nul(); + unsafe { + BNAddTypeLibraryNamedTypeSource( + self.as_raw(), + &name.0 as *const _ as *mut _, + source.as_ref().as_ptr() as *const ffi::c_char, + ) + } + } + + /// Direct extracts a reference to a contained object -- when + /// attempting to extract types from a library into a BinaryView, consider using + /// `import_library_object ` instead. + pub fn get_named_object(&self, name: &QualifiedName) -> Option> { + let t = + unsafe { BNGetTypeLibraryNamedObject(self.as_raw(), &name.0 as *const _ as *mut _) }; + (!t.is_null()).then(|| unsafe { Type::ref_from_raw(t) }) + } + + /// Direct extracts a reference to a contained type -- when + /// attempting to extract types from a library into a BinaryView, consider using + /// `import_library_type ` instead. + pub fn get_named_type(&self, name: &QualifiedName) -> Option> { + let t = unsafe { BNGetTypeLibraryNamedType(self.as_raw(), &name.0 as *const _ as *mut _) }; + (!t.is_null()).then(|| unsafe { Type::ref_from_raw(t) }) + } + + /// A dict containing all named objects (functions, exported variables) provided by a type library + pub fn named_objects(&self) -> Array { + let mut count = 0; + let result = unsafe { BNGetTypeLibraryNamedObjects(self.as_raw(), &mut count) }; + assert!(!result.is_null()); + unsafe { Array::new(result, count, ()) } + } + + /// A dict containing all named types provided by a type library + pub fn named_types(&self) -> Array { + let mut count = 0; + let result = unsafe { BNGetTypeLibraryNamedTypes(self.as_raw(), &mut count) }; + assert!(!result.is_null()); + unsafe { Array::new(result, count, ()) } + } +} + +impl Drop for TypeLibrary { + fn drop(&mut self) { + unsafe { BNFreeTypeLibrary(self.as_raw()) } + } +} + +impl CoreArrayProvider for TypeLibrary { + type Raw = *mut BNTypeLibrary; + type Context = (); + type Wrapped<'a> = &'a Self; +} + +unsafe impl CoreArrayProviderInner for TypeLibrary { + unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) { + BNFreeTypeLibraryList(raw, count) + } + + unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { + Self::ref_from_raw(raw) + } +} From 798b88fa5aa6dfab44610b237b7e873cf63c6365 Mon Sep 17 00:00:00 2001 From: Rubens Brandao Date: Fri, 14 Jun 2024 09:01:33 -0300 Subject: [PATCH 2/3] fix doc warning --- rust/src/typelibrary.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rust/src/typelibrary.rs b/rust/src/typelibrary.rs index 79cb6569b..4940454d1 100644 --- a/rust/src/typelibrary.rs +++ b/rust/src/typelibrary.rs @@ -293,7 +293,11 @@ impl TypeLibrary { /// Manually flag NamedTypeReferences to the given QualifiedName as originating from another source /// TypeLibrary with the given dependency name. /// - /// .. warning:: Use this api with extreme caution. + ///
+ /// + /// Use this api with extreme caution. + /// + ///
(&self, name: &QualifiedName, source: S) { let source = source.into_bytes_with_nul(); unsafe { From ce863bf85cbbc459e8c02c4b42c7947094c41d14 Mon Sep 17 00:00:00 2001 From: Rubens Brandao Date: Fri, 14 Jun 2024 14:19:18 -0300 Subject: [PATCH 3/3] fix TypeLibrary representation --- rust/src/typelibrary.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/src/typelibrary.rs b/rust/src/typelibrary.rs index 4940454d1..ce0fe6f8e 100644 --- a/rust/src/typelibrary.rs +++ b/rust/src/typelibrary.rs @@ -11,6 +11,7 @@ use crate::{ types::{QualifiedName, QualifiedNameAndType, Type}, }; +#[repr(transparent)] pub struct TypeLibrary { handle: ptr::NonNull, }