@@ -2,6 +2,7 @@ use binaryninjacore_sys::*;
22use std:: fmt:: { Debug , Formatter } ;
33
44use crate :: rc:: { Guard , RefCountable } ;
5+ use crate :: types:: TypeContainer ;
56use crate :: {
67 architecture:: CoreArchitecture ,
78 metadata:: Metadata ,
@@ -13,6 +14,20 @@ use crate::{
1314use std:: path:: Path ;
1415use std:: ptr:: NonNull ;
1516
17+ // Used for doc comments
18+ #[ allow( unused_imports) ]
19+ use crate :: binary_view:: BinaryView ;
20+
21+ // TODO: Introduce a FinalizedTypeLibrary that cannot be mutated, so we do not have APIs that are unusable.
22+
23+ /// A [`TypeLibrary`] is a collection of function symbols and their associated types and metadata that
24+ /// correspond to a shared library or are used in conjunction with a shared library. Type libraries
25+ /// are the main way external functions in a binary view are annotated and are crucial to allowing
26+ /// proper analysis of the binary.
27+ ///
28+ /// Type libraries can share common types between them by forwarding named type references to a specified
29+ /// source type library. If a type library is made available to a view, it may also pull in other type
30+ /// libraries, it is important to not treat a type library as a complete source of information.
1631#[ repr( transparent) ]
1732pub struct TypeLibrary {
1833 handle : NonNull < BNTypeLibrary > ,
@@ -32,7 +47,12 @@ impl TypeLibrary {
3247 & mut * self . handle . as_ptr ( )
3348 }
3449
35- pub fn new_duplicated ( & self ) -> Ref < Self > {
50+ /// Duplicate the type library. This creates a new, non-finalized type library object that shares
51+ /// the same underlying name and architecture.
52+ ///
53+ /// IMPORTANT: This does not *actually* duplicate the type library currently, you still need to
54+ /// copy over the named types, named objects, platforms, and metadata.
55+ pub fn duplicate ( & self ) -> Ref < Self > {
3656 unsafe { Self :: ref_from_raw ( NonNull :: new ( BNDuplicateTypeLibrary ( self . as_raw ( ) ) ) . unwrap ( ) ) }
3757 }
3858
@@ -50,21 +70,25 @@ impl TypeLibrary {
5070 unsafe { Array :: new ( result, count, ( ) ) }
5171 }
5272
53- /// Decompresses a type library file to a file on disk .
73+ /// Decompresses a type library file to a JSON file at the given `output_path` .
5474 pub fn decompress_to_file ( path : & Path , output_path : & Path ) -> bool {
5575 let path = path. to_cstr ( ) ;
5676 let output = output_path. to_cstr ( ) ;
5777 unsafe { BNTypeLibraryDecompressToFile ( path. as_ptr ( ) , output. as_ptr ( ) ) }
5878 }
5979
60- /// Loads a finalized type library instance from file
80+ /// Loads a finalized type library instance from the given `path`.
81+ ///
82+ /// The returned type library cannot be modified.
6183 pub fn load_from_file ( path : & Path ) -> Option < Ref < TypeLibrary > > {
6284 let path = path. to_cstr ( ) ;
6385 let handle = unsafe { BNLoadTypeLibraryFromFile ( path. as_ptr ( ) ) } ;
6486 NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: ref_from_raw ( h) } )
6587 }
6688
67- /// Saves a finalized type library instance to file
89+ /// Saves a type library at the given `path` on disk, overwriting any existing file.
90+ ///
91+ /// The path must be writable, and the parent directory must exist.
6892 pub fn write_to_file ( & self , path : & Path ) -> bool {
6993 let path = path. to_cstr ( ) ;
7094 unsafe { BNWriteTypeLibraryToFile ( self . as_raw ( ) , path. as_ptr ( ) ) }
@@ -92,21 +116,25 @@ impl TypeLibrary {
92116 NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: ref_from_raw ( h) } )
93117 }
94118
95- /// The Architecture this type library is associated with
119+ /// The [`CoreArchitecture`] this type library is associated with.
120+ ///
121+ /// Type libraries will always have a single architecture associated with it. It can have multiple
122+ /// platforms associated with it, see [`TypeLibrary::platform_names`] for more detail.
96123 pub fn arch ( & self ) -> CoreArchitecture {
97124 let arch = unsafe { BNGetTypeLibraryArchitecture ( self . as_raw ( ) ) } ;
98125 assert ! ( !arch. is_null( ) ) ;
99126 unsafe { CoreArchitecture :: from_raw ( arch) }
100127 }
101128
102- /// The primary name associated with this type library
129+ /// The primary name associated with this type library, this will not be used for importing type
130+ /// libraries automatically into a binary view, that is the job of [`TypeLibrary::dependency_name`].
103131 pub fn name ( & self ) -> String {
104132 let result = unsafe { BNGetTypeLibraryName ( self . as_raw ( ) ) } ;
105133 assert ! ( !result. is_null( ) ) ;
106134 unsafe { BnString :: into_string ( result) }
107135 }
108136
109- /// Sets the name of a type library instance that has not been finalized
137+ /// Sets the name of a type library that has not been finalized.
110138 pub fn set_name ( & self , value : & str ) {
111139 let value = value. to_cstr ( ) ;
112140 unsafe { BNSetTypeLibraryName ( self . as_raw ( ) , value. as_ptr ( ) ) }
@@ -136,13 +164,13 @@ impl TypeLibrary {
136164 unsafe { BnString :: into_string ( result) }
137165 }
138166
139- /// Sets the GUID of a type library instance that has not been finalized
167+ /// Sets the GUID of a type library instance that has not been finalized.
140168 pub fn set_guid ( & self , value : & str ) {
141169 let value = value. to_cstr ( ) ;
142170 unsafe { BNSetTypeLibraryGuid ( self . as_raw ( ) , value. as_ptr ( ) ) }
143171 }
144172
145- /// A list of extra names that will be considered a match by [Platform::get_type_libraries_by_name]
173+ /// A list of extra names that will be considered a match by [` Platform::get_type_libraries_by_name` ]
146174 pub fn alternate_names ( & self ) -> Array < BnString > {
147175 let mut count = 0 ;
148176 let result = unsafe { BNGetTypeLibraryAlternateNames ( self . as_raw ( ) , & mut count) } ;
@@ -170,76 +198,66 @@ impl TypeLibrary {
170198
171199 /// Associate a platform with a type library instance that has not been finalized.
172200 ///
173- /// This will cause the library to be searchable by [Platform::get_type_libraries_by_name]
201+ /// This will cause the library to be searchable by [` Platform::get_type_libraries_by_name` ]
174202 /// when loaded.
175203 ///
176- /// This does not have side affects until finalization of the type library.
204+ /// This does not have side effects until finalization of the type library.
177205 pub fn add_platform ( & self , plat : & Platform ) {
178206 unsafe { BNAddTypeLibraryPlatform ( self . as_raw ( ) , plat. handle ) }
179207 }
180208
181- /// Clears the list of platforms associated with a type library instance that has not been finalized
209+ /// Clears the list of platforms associated with a type library instance that has not been finalized.
182210 pub fn clear_platforms ( & self ) {
183211 unsafe { BNClearTypeLibraryPlatforms ( self . as_raw ( ) ) }
184212 }
185213
186- /// Flags a newly created type library instance as finalized and makes it available for Platform and Architecture
187- /// type library searches
214+ /// Flags a newly created type library instance as finalized and makes it available for Platform
215+ /// and Architecture type library searches.
188216 pub fn finalize ( & self ) -> bool {
189217 unsafe { BNFinalizeTypeLibrary ( self . as_raw ( ) ) }
190218 }
191219
192- /// Retrieves a metadata associated with the given key stored in the type library
220+ /// Retrieves the metadata associated with the given key stored in the type library.
193221 pub fn query_metadata ( & self , key : & str ) -> Option < Ref < Metadata > > {
194222 let key = key. to_cstr ( ) ;
195223 let result = unsafe { BNTypeLibraryQueryMetadata ( self . as_raw ( ) , key. as_ptr ( ) ) } ;
196224 ( !result. is_null ( ) ) . then ( || unsafe { Metadata :: ref_from_raw ( result) } )
197225 }
198226
199- /// Stores an object for the given key in the current type library. Objects stored using
200- /// `store_metadata` can be retrieved from any reference to the library. Objects stored are not arbitrary python
201- /// objects! The values stored must be able to be held in a Metadata object. See [Metadata]
202- /// for more information. Python objects could obviously be serialized using pickle but this intentionally
203- /// a task left to the user since there is the potential security issues.
227+ /// Stores a [`Metadata`] object in the given key for the type library.
204228 ///
205229 /// This is primarily intended as a way to store Platform specific information relevant to BinaryView implementations;
206- /// for example the PE BinaryViewType uses type library metadata to retrieve ordinal information, when available.
207- ///
208- /// * `key` - key value to associate the Metadata object with
209- /// * `md` - object to store.
230+ /// for example, the PE BinaryViewType uses type library metadata to retrieve ordinal information, when available.
210231 pub fn store_metadata ( & self , key : & str , md : & Metadata ) {
211232 let key = key. to_cstr ( ) ;
212233 unsafe { BNTypeLibraryStoreMetadata ( self . as_raw ( ) , key. as_ptr ( ) , md. handle ) }
213234 }
214235
215- /// Removes the metadata associated with key from the current type library.
236+ /// Removes the metadata associated with key from the type library.
216237 pub fn remove_metadata ( & self , key : & str ) {
217238 let key = key. to_cstr ( ) ;
218239 unsafe { BNTypeLibraryRemoveMetadata ( self . as_raw ( ) , key. as_ptr ( ) ) }
219240 }
220241
221- /// Retrieves the metadata associated with the current type library.
242+ /// Retrieves the metadata associated with the type library.
222243 pub fn metadata ( & self ) -> Ref < Metadata > {
223244 let md_handle = unsafe { BNTypeLibraryGetMetadata ( self . as_raw ( ) ) } ;
224245 assert ! ( !md_handle. is_null( ) ) ;
225246 unsafe { Metadata :: ref_from_raw ( md_handle) }
226247 }
227248
228- // TODO: implement TypeContainer
229- // /// Type Container for all TYPES within the Type Library. Objects are not included.
230- // /// The Type Container's Platform will be the first platform associated with the Type Library.
231- // pub fn type_container(&self) -> TypeContainer {
232- // let result = unsafe{ BNGetTypeLibraryTypeContainer(self.as_raw())};
233- // unsafe{TypeContainer::from_raw(NonNull::new(result).unwrap())}
234- // }
249+ pub fn type_container ( & self ) -> TypeContainer {
250+ let result = unsafe { BNGetTypeLibraryTypeContainer ( self . as_raw ( ) ) } ;
251+ unsafe { TypeContainer :: from_raw ( NonNull :: new ( result) . unwrap ( ) ) }
252+ }
235253
236254 /// Directly inserts a named object into the type library's object store.
237- /// This is not done recursively, so care should be taken that types referring to other types
238- /// through NamedTypeReferences are already appropriately prepared.
239255 ///
240- /// To add types and objects from an existing BinaryView, it is recommended to use
241- /// `export_object_to_library <binaryview.BinaryView.export_object_to_library>`, which will automatically pull in
242- /// all referenced types and record additional dependencies as needed.
256+ /// Referenced types will not automatically be added, so make sure to add referenced types to the
257+ /// library or use [`TypeLibrary::add_type_source`] to mark the references originating source.
258+ ///
259+ /// To add objects from a binary view, prefer using [`BinaryView::export_object_to_library`] which
260+ /// will automatically pull in all referenced types and record additional dependencies as needed.
243261 pub fn add_named_object ( & self , name : QualifiedName , type_ : & Type ) {
244262 let mut raw_name = QualifiedName :: into_raw ( name) ;
245263 unsafe { BNAddTypeLibraryNamedObject ( self . as_raw ( ) , & mut raw_name, type_. handle ) }
@@ -274,35 +292,35 @@ impl TypeLibrary {
274292 QualifiedName :: free_raw ( raw_name) ;
275293 }
276294
277- /// Direct extracts a reference to a contained object -- when
278- /// attempting to extract types from a library into a BinaryView, consider using
279- /// `import_library_object <binaryview. BinaryView.import_library_object>` instead .
295+ /// Get the object (function) associated with the given name, if any.
296+ ///
297+ /// Prefer [` BinaryView::import_type_library_object`] as it will recursively import types required .
280298 pub fn get_named_object ( & self , name : QualifiedName ) -> Option < Ref < Type > > {
281299 let mut raw_name = QualifiedName :: into_raw ( name) ;
282300 let t = unsafe { BNGetTypeLibraryNamedObject ( self . as_raw ( ) , & mut raw_name) } ;
283301 QualifiedName :: free_raw ( raw_name) ;
284302 ( !t. is_null ( ) ) . then ( || unsafe { Type :: ref_from_raw ( t) } )
285303 }
286304
287- /// Direct extracts a reference to a contained type -- when
288- /// attempting to extract types from a library into a BinaryView, consider using
289- /// `import_library_type <binaryview. BinaryView.import_library_type>` instead .
305+ /// Get the type associated with the given name, if any.
306+ ///
307+ /// Prefer [` BinaryView::import_type_library_type`] as it will recursively import types required .
290308 pub fn get_named_type ( & self , name : QualifiedName ) -> Option < Ref < Type > > {
291309 let mut raw_name = QualifiedName :: into_raw ( name) ;
292310 let t = unsafe { BNGetTypeLibraryNamedType ( self . as_raw ( ) , & mut raw_name) } ;
293311 QualifiedName :: free_raw ( raw_name) ;
294312 ( !t. is_null ( ) ) . then ( || unsafe { Type :: ref_from_raw ( t) } )
295313 }
296314
297- /// A dict containing all named objects (functions, exported variables) provided by a type library
315+ /// The list of all named objects provided by a type library
298316 pub fn named_objects ( & self ) -> Array < QualifiedNameAndType > {
299317 let mut count = 0 ;
300318 let result = unsafe { BNGetTypeLibraryNamedObjects ( self . as_raw ( ) , & mut count) } ;
301319 assert ! ( !result. is_null( ) ) ;
302320 unsafe { Array :: new ( result, count, ( ) ) }
303321 }
304322
305- /// A dict containing all named types provided by a type library
323+ /// The list of all named types provided by a type library
306324 pub fn named_types ( & self ) -> Array < QualifiedNameAndType > {
307325 let mut count = 0 ;
308326 let result = unsafe { BNGetTypeLibraryNamedTypes ( self . as_raw ( ) , & mut count) } ;
0 commit comments