1414
1515//! Contains all information related to the execution environment of the binary, mainly the calling conventions used
1616
17- use std:: { borrow:: Borrow , collections :: HashMap , os :: raw , path :: Path , ptr, slice } ;
17+ use std:: { borrow:: Borrow , ffi , ptr} ;
1818
1919use binaryninjacore_sys:: * ;
2020
@@ -26,6 +26,7 @@ use crate::{
2626 typelibrary:: TypeLibrary ,
2727 types:: { QualifiedName , QualifiedNameAndType , Type } ,
2828} ;
29+ use crate :: typeparser:: { TypeParserError , TypeParserErrorSeverity , TypeParserResult } ;
2930
3031#[ derive( PartialEq , Eq , Hash ) ]
3132pub struct Platform {
@@ -260,95 +261,118 @@ impl Platform {
260261 Array :: new ( handles, count, ( ) )
261262 }
262263 }
263- }
264264
265- pub trait TypeParser {
266- fn parse_types_from_source < S : BnStrCompatible , P : AsRef < Path > > (
265+ pub fn preprocess_source (
267266 & self ,
268- _source : S ,
269- _filename : S ,
270- _include_directories : & [ P ] ,
271- _auto_type_source : S ,
272- ) -> Result < TypeParserResult , String > {
273- Err ( String :: new ( ) )
267+ source : & str ,
268+ file_name : & str ,
269+ include_dirs : & [ BnString ] ,
270+ ) -> Result < BnString , Vec < TypeParserError > > {
271+ let source_cstr = BnString :: new ( source) ;
272+ let file_name_cstr = BnString :: new ( file_name) ;
273+
274+ let mut result = ptr:: null_mut ( ) ;
275+ let mut error_string = ptr:: null_mut ( ) ;
276+ let success = unsafe {
277+ BNPreprocessSource (
278+ source_cstr. as_ptr ( ) ,
279+ file_name_cstr. as_ptr ( ) ,
280+ & mut result,
281+ & mut error_string,
282+ include_dirs. as_ptr ( ) as * mut * const ffi:: c_char ,
283+ include_dirs. len ( ) ,
284+ )
285+ } ;
286+
287+ if success {
288+ assert ! ( !result. is_null( ) ) ;
289+ Ok ( unsafe { BnString :: from_raw ( result) } )
290+ } else {
291+ assert ! ( !error_string. is_null( ) ) ;
292+ Err ( vec ! [ TypeParserError :: new(
293+ TypeParserErrorSeverity :: FatalSeverity ,
294+ unsafe { BnString :: from_raw( error_string) } ,
295+ file_name,
296+ 0 ,
297+ 0 ,
298+ ) ] )
299+ }
274300 }
275- }
276-
277- #[ derive( Clone , Default ) ]
278- pub struct TypeParserResult {
279- pub types : HashMap < QualifiedName , Ref < Type > > ,
280- pub variables : HashMap < QualifiedName , Ref < Type > > ,
281- pub functions : HashMap < QualifiedName , Ref < Type > > ,
282- }
283-
284- impl TypeParser for Platform {
285- fn parse_types_from_source < S : BnStrCompatible , P : AsRef < Path > > (
301+ pub fn parse_types_from_source (
286302 & self ,
287- source : S ,
288- filename : S ,
289- include_directories : & [ P ] ,
290- auto_type_source : S ,
291- ) -> Result < TypeParserResult , String > {
292- let mut result = BNTypeParserResult :: default ( ) ;
293- let mut type_parser_result = TypeParserResult :: default ( ) ;
294- let mut error_string: * mut raw:: c_char = ptr:: null_mut ( ) ;
295-
296- let src = source. into_bytes_with_nul ( ) ;
297- let filename = filename. into_bytes_with_nul ( ) ;
298- let auto_type_source = auto_type_source. into_bytes_with_nul ( ) ;
299-
300- let mut include_dirs = vec ! [ ] ;
301-
302- for dir in include_directories. iter ( ) {
303- let d = dir
304- . as_ref ( )
305- . to_string_lossy ( )
306- . to_string ( )
307- . into_bytes_with_nul ( ) ;
308- include_dirs. push ( d. as_ptr ( ) as _ ) ;
309- }
303+ src : & str ,
304+ filename : & str ,
305+ include_dirs : & [ BnString ] ,
306+ auto_type_source : & str ,
307+ ) -> Result < TypeParserResult , Vec < TypeParserError > > {
308+ let source_cstr = BnString :: new ( src) ;
309+ let file_name_cstr = BnString :: new ( filename) ;
310+ let auto_type_source = BnString :: new ( auto_type_source) ;
310311
311- unsafe {
312- let success = BNParseTypesFromSource (
312+ let mut result = BNTypeParserResult :: default ( ) ;
313+ let mut error_string = ptr:: null_mut ( ) ;
314+ let success = unsafe {
315+ BNParseTypesFromSource (
313316 self . handle ,
314- src . as_ref ( ) . as_ptr ( ) as _ ,
315- filename . as_ref ( ) . as_ptr ( ) as _ ,
317+ source_cstr . as_ptr ( ) ,
318+ file_name_cstr . as_ptr ( ) ,
316319 & mut result,
317320 & mut error_string,
318- include_dirs. as_mut_ptr ( ) ,
321+ include_dirs. as_ptr ( ) as * mut * const ffi :: c_char ,
319322 include_dirs. len ( ) ,
320- auto_type_source. as_ref ( ) . as_ptr ( ) as _ ,
321- ) ;
322-
323- let error_msg = BnString :: from_raw ( error_string) ;
323+ auto_type_source. as_ptr ( ) ,
324+ )
325+ } ;
324326
325- if !success {
326- return Err ( error_msg. to_string ( ) ) ;
327- }
327+ if success {
328+ Ok ( unsafe { TypeParserResult :: from_raw ( result) } )
329+ } else {
330+ assert ! ( !error_string. is_null( ) ) ;
331+ Err ( vec ! [ TypeParserError :: new(
332+ TypeParserErrorSeverity :: FatalSeverity ,
333+ unsafe { BnString :: from_raw( error_string) } ,
334+ filename,
335+ 0 ,
336+ 0 ,
337+ ) ] )
338+ }
339+ }
328340
329- for i in slice:: from_raw_parts ( result. types , result. typeCount ) {
330- let name = QualifiedName :: from ( i. name ) ;
331- type_parser_result
332- . types
333- . insert ( name, Type :: ref_from_raw ( i. type_ ) ) ;
334- }
341+ pub fn parse_types_from_source_file (
342+ & self ,
343+ filename : & str ,
344+ include_dirs : & [ BnString ] ,
345+ auto_type_source : & str ,
346+ ) -> Result < TypeParserResult , Vec < TypeParserError > > {
347+ let file_name_cstr = BnString :: new ( filename) ;
348+ let auto_type_source = BnString :: new ( auto_type_source) ;
335349
336- for i in slice:: from_raw_parts ( result. functions , result. functionCount ) {
337- let name = QualifiedName :: from ( i. name ) ;
338- type_parser_result
339- . functions
340- . insert ( name, Type :: ref_from_raw ( i. type_ ) ) ;
341- }
350+ let mut result = BNTypeParserResult :: default ( ) ;
351+ let mut error_string = ptr:: null_mut ( ) ;
352+ let success = unsafe {
353+ BNParseTypesFromSourceFile (
354+ self . handle ,
355+ file_name_cstr. as_ptr ( ) ,
356+ & mut result,
357+ & mut error_string,
358+ include_dirs. as_ptr ( ) as * mut * const ffi:: c_char ,
359+ include_dirs. len ( ) ,
360+ auto_type_source. as_ptr ( ) ,
361+ )
362+ } ;
342363
343- for i in slice:: from_raw_parts ( result. variables , result. variableCount ) {
344- let name = QualifiedName :: from ( i. name ) ;
345- type_parser_result
346- . variables
347- . insert ( name, Type :: ref_from_raw ( i. type_ ) ) ;
348- }
364+ if success {
365+ Ok ( unsafe { TypeParserResult :: from_raw ( result) } )
366+ } else {
367+ assert ! ( !error_string. is_null( ) ) ;
368+ Err ( vec ! [ TypeParserError :: new(
369+ TypeParserErrorSeverity :: FatalSeverity ,
370+ unsafe { BnString :: from_raw( error_string) } ,
371+ filename,
372+ 0 ,
373+ 0 ,
374+ ) ] )
349375 }
350-
351- Ok ( type_parser_result)
352376 }
353377}
354378
0 commit comments