@@ -26,14 +26,15 @@ use crate::{
2626 calling_convention:: CoreCallingConvention ,
2727 data_buffer:: DataBuffer ,
2828 disassembly:: InstructionTextToken ,
29- function:: Function ,
29+ function:: { Function , Location , NativeBlock } ,
3030 platform:: Platform ,
3131 rc:: * ,
3232 relocation:: CoreRelocationHandler ,
3333 string:: { IntoCStr , * } ,
3434 types:: { NameAndType , Type } ,
3535 Endianness ,
3636} ;
37+ use std:: collections:: { HashMap , HashSet } ;
3738use std:: ops:: Deref ;
3839use std:: {
3940 borrow:: Borrow ,
@@ -47,7 +48,9 @@ use std::ptr::NonNull;
4748use crate :: function_recognizer:: FunctionRecognizer ;
4849use crate :: relocation:: { CustomRelocationHandlerHandle , RelocationHandler } ;
4950
51+ use crate :: basic_block:: BasicBlock ;
5052use crate :: confidence:: Conf ;
53+ use crate :: logger:: Logger ;
5154use crate :: low_level_il:: expression:: ValueExpr ;
5255use crate :: low_level_il:: lifting:: {
5356 get_default_flag_cond_llil, get_default_flag_write_llil, LowLevelILFlagWriteOp ,
@@ -591,13 +594,133 @@ pub trait ArchitectureWithFunctionContext: Architecture {
591594
592595pub struct FunctionLifterContext {
593596 pub ( crate ) handle : * mut BNFunctionLifterContext ,
597+ pub function : * mut BNLowLevelILFunction ,
598+ pub platform : Ref < Platform > ,
599+ pub logger : Ref < Logger > ,
600+ pub blocks : Vec < Ref < BasicBlock < NativeBlock > > > ,
601+ pub no_return_calls : HashSet < Location > ,
602+ pub contextual_returns : HashMap < Location , bool > ,
603+ pub inlined_remapping : HashMap < Location , Location > ,
604+ pub user_indirect_branches : HashMap < Location , HashSet < Location > > ,
605+ pub auto_indirect_branches : HashMap < Location , HashSet < Location > > ,
606+ //pub inlined_calls: HashSet<u64>,
607+ }
608+
609+ unsafe fn lifter_context_slice < ' a , T > ( ptr : * const T , len : usize ) -> & ' a [ T ] {
610+ if len == 0 {
611+ & [ ]
612+ } else {
613+ debug_assert ! ( !ptr. is_null( ) ) ;
614+ unsafe { std:: slice:: from_raw_parts ( ptr, len) }
615+ }
594616}
595617
596618impl FunctionLifterContext {
597- pub unsafe fn from_raw ( handle : * mut BNFunctionLifterContext ) -> Self {
619+ pub unsafe fn from_raw (
620+ function : * mut BNLowLevelILFunction ,
621+ handle : * mut BNFunctionLifterContext ,
622+ ) -> Self {
623+ debug_assert ! ( !function. is_null( ) ) ;
598624 debug_assert ! ( !handle. is_null( ) ) ;
625+ let flc_ref = & * handle;
626+ let platform = unsafe { Platform :: ref_from_raw ( BNNewPlatformReference ( flc_ref. platform ) ) } ;
627+ let logger = unsafe { Logger :: ref_from_raw ( BNNewLoggerReference ( flc_ref. logger ) ) } ;
628+
629+ let mut blocks = Vec :: new ( ) ;
630+ for i in 0 ..flc_ref. basicBlockCount {
631+ let block = unsafe {
632+ Some ( BasicBlock :: ref_from_raw (
633+ BNNewBasicBlockReference ( * flc_ref. basicBlocks . add ( i) ) ,
634+ NativeBlock :: new ( ) ,
635+ ) )
636+ } ;
637+
638+ blocks. push ( block. unwrap ( ) ) ;
639+ }
640+
641+ let raw_no_return_calls: & [ BNArchitectureAndAddress ] =
642+ lifter_context_slice ( flc_ref. noReturnCalls , flc_ref. noReturnCallsCount ) ;
643+ let no_return_calls: HashSet < Location > =
644+ raw_no_return_calls. iter ( ) . map ( Location :: from) . collect ( ) ;
645+
646+ let raw_contextual_return_locs: & [ BNArchitectureAndAddress ] = unsafe {
647+ lifter_context_slice (
648+ flc_ref. contextualFunctionReturnLocations ,
649+ flc_ref. contextualFunctionReturnCount ,
650+ )
651+ } ;
652+ let raw_contextual_return_vals: & [ bool ] = unsafe {
653+ lifter_context_slice (
654+ flc_ref. contextualFunctionReturnValues ,
655+ flc_ref. contextualFunctionReturnCount ,
656+ )
657+ } ;
658+ let contextual_returns: HashMap < Location , bool > = raw_contextual_return_locs
659+ . iter ( )
660+ . map ( Location :: from)
661+ . zip ( raw_contextual_return_vals. iter ( ) . copied ( ) )
662+ . collect ( ) ;
663+
664+ let inlined_remapping: HashMap < Location , Location > = {
665+ let raw_inline_remap_locs: & [ BNArchitectureAndAddress ] = lifter_context_slice (
666+ flc_ref. inlinedRemappingKeys ,
667+ flc_ref. inlinedRemappingEntryCount ,
668+ ) ;
669+
670+ let raw_inline_remap_dests: & [ BNArchitectureAndAddress ] = lifter_context_slice (
671+ flc_ref. inlinedRemappingValues ,
672+ flc_ref. inlinedRemappingEntryCount ,
673+ ) ;
674+
675+ raw_inline_remap_locs
676+ . iter ( )
677+ . map ( Location :: from)
678+ . zip ( raw_inline_remap_dests. iter ( ) . map ( Location :: from) )
679+ . collect ( )
680+ } ;
599681
600- FunctionLifterContext { handle }
682+ let mut user_indirect_branches: HashMap < Location , HashSet < Location > > = HashMap :: new ( ) ;
683+ let mut auto_indirect_branches: HashMap < Location , HashSet < Location > > = HashMap :: new ( ) ;
684+ for i in 0 ..flc_ref. indirectBranchesCount {
685+ let entry = unsafe { * flc_ref. indirectBranches . add ( i) } ;
686+ let src = Location :: new (
687+ Some ( CoreArchitecture :: from_raw ( entry. sourceArch ) ) ,
688+ entry. sourceAddr ,
689+ ) ;
690+ let dest = Location :: new (
691+ Some ( CoreArchitecture :: from_raw ( entry. destArch ) ) ,
692+ entry. destAddr ,
693+ ) ;
694+ if entry. autoDefined {
695+ auto_indirect_branches. entry ( src) . or_default ( ) . insert ( dest) ;
696+ } else {
697+ user_indirect_branches. entry ( src) . or_default ( ) . insert ( dest) ;
698+ }
699+ }
700+
701+ FunctionLifterContext {
702+ handle,
703+ function : BNNewLowLevelILFunctionReference ( function) ,
704+ platform,
705+ logger,
706+ blocks,
707+ no_return_calls,
708+ contextual_returns,
709+ inlined_remapping,
710+ user_indirect_branches,
711+ auto_indirect_branches,
712+ }
713+ }
714+
715+ pub fn prepare_block_translation (
716+ & self ,
717+ func : & LowLevelILMutableFunction ,
718+ arch : & CoreArchitecture ,
719+ address : u64 ,
720+ ) {
721+ unsafe {
722+ BNPrepareBlockTranslation ( func. handle , arch. handle , address) ;
723+ }
601724 }
602725
603726 pub fn get_function_arch_context < A : ArchitectureWithFunctionContext > (
@@ -615,6 +738,14 @@ impl FunctionLifterContext {
615738 }
616739}
617740
741+ impl Drop for FunctionLifterContext {
742+ fn drop ( & mut self ) {
743+ if !self . function . is_null ( ) {
744+ unsafe { BNFreeLowLevelILFunction ( self . function ) } ;
745+ }
746+ }
747+ }
748+
618749// TODO: WTF?!?!?!?
619750pub struct CoreArchitectureList ( * mut * mut BNArchitecture , usize ) ;
620751
@@ -1622,12 +1753,12 @@ where
16221753 A : ' static + Architecture < Handle = CustomArchitectureHandle < A > > + Send + Sync ,
16231754 {
16241755 let custom_arch = unsafe { & * ( ctxt as * mut A ) } ;
1625- let function = unsafe {
1756+ let llil = unsafe {
16261757 LowLevelILMutableFunction :: from_raw_with_arch ( function, Some ( * custom_arch. as_ref ( ) ) )
16271758 } ;
1628- let mut context : FunctionLifterContext =
1629- unsafe { FunctionLifterContext :: from_raw ( context) } ;
1630- custom_arch. lift_function ( function , & mut context )
1759+
1760+ let mut ctx = unsafe { FunctionLifterContext :: from_raw ( function , context) } ;
1761+ custom_arch. lift_function ( llil , & mut ctx )
16311762 }
16321763
16331764 extern "C" fn cb_reg_name < A > ( ctxt : * mut c_void , reg : u32 ) -> * mut c_char
@@ -2622,7 +2753,6 @@ where
26222753
26232754 unsafe {
26242755 let res = BNRegisterArchitecture ( name. as_ptr ( ) , & mut custom_arch as * mut _ ) ;
2625-
26262756 assert ! ( !res. is_null( ) ) ;
26272757
26282758 ( * raw) . arch . assume_init_mut ( )
0 commit comments