@@ -75,34 +75,36 @@ pub fn user_signature_dir() -> PathBuf {
7575
7676pub fn build_variables ( func : & BNFunction ) -> Vec < FunctionVariable > {
7777 let func_start = func. start ( ) ;
78- let mut variables = vec ! [ ] ;
79- if let Ok ( mlil) = func. medium_level_il ( ) {
80- let bn_vars = func. variables ( ) ;
81- for bn_var in & bn_vars {
82- if mlil. is_var_user_defined ( & bn_var. variable ) {
83- // TODO: live_instruction_for_variable only works for register types.
84- if let Some ( first_instr) = mlil
85- . live_instruction_for_variable ( & bn_var. variable , true )
86- . iter ( )
87- . sorted_by_key ( |i| i. instr_index )
88- . next ( )
89- {
90- if let Some ( var_loc) = bn_var_to_location ( bn_var. variable ) {
91- let var_name = bn_var. name ;
92- let var_type =
93- from_bn_type ( & func. view ( ) , & bn_var. ty . contents , bn_var. ty . confidence ) ;
94- variables. push ( FunctionVariable {
95- offset : ( first_instr. address as i64 ) - ( func_start as i64 ) ,
96- location : var_loc,
97- name : Some ( var_name) ,
98- ty : Some ( var_type) ,
99- } )
100- }
101- }
102- }
103- }
104- }
105- variables
78+ // It is important that we only retrieve the medium-level IL if the function has
79+ // any user-defined variables, otherwise, we will possibly be generating MLIL for no reason.
80+ // For the above reason, we do a filter on user-defined variables first.
81+ func. variables ( )
82+ . iter ( )
83+ . filter ( |var| func. is_variable_user_defined ( & var. variable ) )
84+ . filter_map ( |var| {
85+ // Get the first instruction that uses the variable, this is the "placement" location we store.
86+ // TODO: live_instruction_for_variable only works for register types.
87+ let first_instr = func
88+ . medium_level_il ( )
89+ . ok ( ) ?
90+ . live_instruction_for_variable ( & var. variable , true )
91+ . iter ( )
92+ . sorted_by_key ( |i| i. instr_index )
93+ . next ( ) ?;
94+ Some ( ( var, first_instr) )
95+ } )
96+ . filter_map ( |( var, instr) | {
97+ // Build the WARP function variable using the placement location, and the variable itself.
98+ let var_loc = bn_var_to_location ( var. variable ) ?;
99+ let var_type = from_bn_type ( & func. view ( ) , & var. ty . contents , var. ty . confidence ) ;
100+ Some ( FunctionVariable {
101+ offset : ( instr. address as i64 ) - ( func_start as i64 ) ,
102+ location : var_loc,
103+ name : Some ( var. name ) ,
104+ ty : Some ( var_type) ,
105+ } )
106+ } )
107+ . collect ( )
106108}
107109
108110// TODO: Get rid of the minimal bool.
0 commit comments