@@ -27,14 +27,15 @@ use crate::{
2727 data_buffer:: DataBuffer ,
2828 disassembly:: InstructionTextToken ,
2929 ffi:: INVALID_REGISTER ,
30- function:: Function ,
30+ function:: { Function , Location , NativeBlock } ,
3131 platform:: Platform ,
3232 rc:: * ,
3333 relocation:: CoreRelocationHandler ,
3434 string:: { IntoCStr , * } ,
3535 types:: { NameAndType , Type } ,
3636 Endianness ,
3737} ;
38+ use std:: collections:: { HashMap , HashSet } ;
3839use std:: ops:: Deref ;
3940use std:: {
4041 borrow:: Borrow ,
@@ -48,7 +49,9 @@ use std::ptr::NonNull;
4849use crate :: function_recognizer:: FunctionRecognizer ;
4950use crate :: relocation:: { CustomRelocationHandlerHandle , RelocationHandler } ;
5051
52+ use crate :: basic_block:: BasicBlock ;
5153use crate :: confidence:: Conf ;
54+ use crate :: logger:: Logger ;
5255use crate :: low_level_il:: expression:: ValueExpr ;
5356use crate :: low_level_il:: lifting:: {
5457 get_default_flag_cond_llil, get_default_flag_write_llil, LowLevelILFlagWriteOp ,
@@ -592,13 +595,133 @@ pub trait ArchitectureWithFunctionContext: Architecture {
592595
593596pub struct FunctionLifterContext {
594597 pub ( crate ) handle : * mut BNFunctionLifterContext ,
598+ pub function : * mut BNLowLevelILFunction ,
599+ pub platform : Ref < Platform > ,
600+ pub logger : Ref < Logger > ,
601+ pub blocks : Vec < Ref < BasicBlock < NativeBlock > > > ,
602+ pub no_return_calls : HashSet < Location > ,
603+ pub contextual_returns : HashMap < Location , bool > ,
604+ pub inlined_remapping : HashMap < Location , Location > ,
605+ pub user_indirect_branches : HashMap < Location , HashSet < Location > > ,
606+ pub auto_indirect_branches : HashMap < Location , HashSet < Location > > ,
607+ //pub inlined_calls: HashSet<u64>,
608+ }
609+
610+ unsafe fn lifter_context_slice < ' a , T > ( ptr : * const T , len : usize ) -> & ' a [ T ] {
611+ if len == 0 {
612+ & [ ]
613+ } else {
614+ debug_assert ! ( !ptr. is_null( ) ) ;
615+ unsafe { std:: slice:: from_raw_parts ( ptr, len) }
616+ }
595617}
596618
597619impl FunctionLifterContext {
598- pub unsafe fn from_raw ( handle : * mut BNFunctionLifterContext ) -> Self {
620+ pub unsafe fn from_raw (
621+ function : * mut BNLowLevelILFunction ,
622+ handle : * mut BNFunctionLifterContext ,
623+ ) -> Self {
624+ debug_assert ! ( !function. is_null( ) ) ;
599625 debug_assert ! ( !handle. is_null( ) ) ;
626+ let flc_ref = & * handle;
627+ let platform = unsafe { Platform :: ref_from_raw ( BNNewPlatformReference ( flc_ref. platform ) ) } ;
628+ let logger = unsafe { Logger :: ref_from_raw ( BNNewLoggerReference ( flc_ref. logger ) ) } ;
629+
630+ let mut blocks = Vec :: new ( ) ;
631+ for i in 0 ..flc_ref. basicBlockCount {
632+ let block = unsafe {
633+ Some ( BasicBlock :: ref_from_raw (
634+ BNNewBasicBlockReference ( * flc_ref. basicBlocks . add ( i) ) ,
635+ NativeBlock :: new ( ) ,
636+ ) )
637+ } ;
638+
639+ blocks. push ( block. unwrap ( ) ) ;
640+ }
641+
642+ let raw_no_return_calls: & [ BNArchitectureAndAddress ] =
643+ lifter_context_slice ( flc_ref. noReturnCalls , flc_ref. noReturnCallsCount ) ;
644+ let no_return_calls: HashSet < Location > =
645+ raw_no_return_calls. iter ( ) . map ( Location :: from) . collect ( ) ;
646+
647+ let raw_contextual_return_locs: & [ BNArchitectureAndAddress ] = unsafe {
648+ lifter_context_slice (
649+ flc_ref. contextualFunctionReturnLocations ,
650+ flc_ref. contextualFunctionReturnCount ,
651+ )
652+ } ;
653+ let raw_contextual_return_vals: & [ bool ] = unsafe {
654+ lifter_context_slice (
655+ flc_ref. contextualFunctionReturnValues ,
656+ flc_ref. contextualFunctionReturnCount ,
657+ )
658+ } ;
659+ let contextual_returns: HashMap < Location , bool > = raw_contextual_return_locs
660+ . iter ( )
661+ . map ( Location :: from)
662+ . zip ( raw_contextual_return_vals. iter ( ) . copied ( ) )
663+ . collect ( ) ;
664+
665+ let inlined_remapping: HashMap < Location , Location > = {
666+ let raw_inline_remap_locs: & [ BNArchitectureAndAddress ] = lifter_context_slice (
667+ flc_ref. inlinedRemappingKeys ,
668+ flc_ref. inlinedRemappingEntryCount ,
669+ ) ;
670+
671+ let raw_inline_remap_dests: & [ BNArchitectureAndAddress ] = lifter_context_slice (
672+ flc_ref. inlinedRemappingValues ,
673+ flc_ref. inlinedRemappingEntryCount ,
674+ ) ;
675+
676+ raw_inline_remap_locs
677+ . iter ( )
678+ . map ( Location :: from)
679+ . zip ( raw_inline_remap_dests. iter ( ) . map ( Location :: from) )
680+ . collect ( )
681+ } ;
600682
601- FunctionLifterContext { handle }
683+ let mut user_indirect_branches: HashMap < Location , HashSet < Location > > = HashMap :: new ( ) ;
684+ let mut auto_indirect_branches: HashMap < Location , HashSet < Location > > = HashMap :: new ( ) ;
685+ for i in 0 ..flc_ref. indirectBranchesCount {
686+ let entry = unsafe { * flc_ref. indirectBranches . add ( i) } ;
687+ let src = Location :: new (
688+ Some ( CoreArchitecture :: from_raw ( entry. sourceArch ) ) ,
689+ entry. sourceAddr ,
690+ ) ;
691+ let dest = Location :: new (
692+ Some ( CoreArchitecture :: from_raw ( entry. destArch ) ) ,
693+ entry. destAddr ,
694+ ) ;
695+ if entry. autoDefined {
696+ auto_indirect_branches. entry ( src) . or_default ( ) . insert ( dest) ;
697+ } else {
698+ user_indirect_branches. entry ( src) . or_default ( ) . insert ( dest) ;
699+ }
700+ }
701+
702+ FunctionLifterContext {
703+ handle,
704+ function : BNNewLowLevelILFunctionReference ( function) ,
705+ platform,
706+ logger,
707+ blocks,
708+ no_return_calls,
709+ contextual_returns,
710+ inlined_remapping,
711+ user_indirect_branches,
712+ auto_indirect_branches,
713+ }
714+ }
715+
716+ pub fn prepare_block_translation (
717+ & self ,
718+ func : & LowLevelILMutableFunction ,
719+ arch : & CoreArchitecture ,
720+ address : u64 ,
721+ ) {
722+ unsafe {
723+ BNPrepareBlockTranslation ( func. handle , arch. handle , address) ;
724+ }
602725 }
603726
604727 pub fn get_function_arch_context < A : ArchitectureWithFunctionContext > (
@@ -616,6 +739,14 @@ impl FunctionLifterContext {
616739 }
617740}
618741
742+ impl Drop for FunctionLifterContext {
743+ fn drop ( & mut self ) {
744+ if !self . function . is_null ( ) {
745+ unsafe { BNFreeLowLevelILFunction ( self . function ) } ;
746+ }
747+ }
748+ }
749+
619750// TODO: WTF?!?!?!?
620751pub struct CoreArchitectureList ( * mut * mut BNArchitecture , usize ) ;
621752
@@ -1630,12 +1761,12 @@ where
16301761 A : ' static + Architecture < Handle = CustomArchitectureHandle < A > > + Send + Sync ,
16311762 {
16321763 let custom_arch = unsafe { & * ( ctxt as * mut A ) } ;
1633- let function = unsafe {
1764+ let llil = unsafe {
16341765 LowLevelILMutableFunction :: from_raw_with_arch ( function, Some ( * custom_arch. as_ref ( ) ) )
16351766 } ;
1636- let mut context : FunctionLifterContext =
1637- unsafe { FunctionLifterContext :: from_raw ( context) } ;
1638- custom_arch. lift_function ( function , & mut context )
1767+
1768+ let mut ctx = unsafe { FunctionLifterContext :: from_raw ( function , context) } ;
1769+ custom_arch. lift_function ( llil , & mut ctx )
16391770 }
16401771
16411772 extern "C" fn cb_reg_name < A > ( ctxt : * mut c_void , reg : u32 ) -> * mut c_char
@@ -2630,7 +2761,6 @@ where
26302761
26312762 unsafe {
26322763 let res = BNRegisterArchitecture ( name. as_ptr ( ) , & mut custom_arch as * mut _ ) ;
2633-
26342764 assert ! ( !res. is_null( ) ) ;
26352765
26362766 ( * raw) . arch . assume_init_mut ( )
0 commit comments