@@ -3302,6 +3302,11 @@ def __init__(
33023302 self ._arch = _arch
33033303 self ._source_function = _source_function
33043304
3305+ self ._mlil_to_mlil_expr_map : dict ['MediumLevelILInstruction' , List [Tuple [ExpressionIndex , bool ]]] = {}
3306+ self ._mlil_to_mlil_instr_map : dict ['MediumLevelILInstruction' , List [Tuple [InstructionIndex , bool ]]] = {}
3307+ self ._llil_ssa_to_mlil_expr_map : dict ['lowlevelil.LowLevelILInstruction' , List [Tuple [ExpressionIndex , bool ]]] = {}
3308+ self ._llil_ssa_to_mlil_instr_map : dict ['lowlevelil.LowLevelILInstruction' , List [Tuple [InstructionIndex , bool ]]] = {}
3309+
33053310 def __del__ (self ):
33063311 if core is not None :
33073312 core .BNFreeMediumLevelILFunction (self .handle )
@@ -3548,7 +3553,7 @@ def expr(
35483553 elif isinstance (operation , MediumLevelILOperation ):
35493554 _operation = operation .value
35503555 if source_location is not None :
3551- return ExpressionIndex (core .BNMediumLevelILAddExprWithLocation (
3556+ index = ExpressionIndex (core .BNMediumLevelILAddExprWithLocation (
35523557 self .handle ,
35533558 _operation ,
35543559 source_location .address ,
@@ -3560,6 +3565,17 @@ def expr(
35603565 d ,
35613566 e
35623567 ))
3568+ # Update internal mappings to remember this
3569+ if source_location .source_mlil_instruction is not None :
3570+ if source_location .source_mlil_instruction not in self ._mlil_to_mlil_expr_map :
3571+ self ._mlil_to_mlil_expr_map [source_location .source_mlil_instruction ] = []
3572+ self ._mlil_to_mlil_expr_map [source_location .source_mlil_instruction ].append ((index , source_location .il_direct ))
3573+ if source_location .source_llil_instruction is not None \
3574+ and source_location .source_llil_instruction .function .il_form == FunctionGraphType .LowLevelILSSAFormFunctionGraph :
3575+ if source_location .source_llil_instruction not in self ._llil_ssa_to_mlil_expr_map :
3576+ self ._llil_ssa_to_mlil_expr_map [source_location .source_llil_instruction ] = []
3577+ self ._llil_ssa_to_mlil_expr_map [source_location .source_llil_instruction ].append ((index , source_location .il_direct ))
3578+ return index
35633579 else :
35643580 return ExpressionIndex (core .BNMediumLevelILAddExpr (self .handle , _operation , size , a , b , c , d , e ))
35653581
@@ -3946,7 +3962,7 @@ def translate(
39463962 for instr_index in range (block .start , block .end ):
39473963 instr : MediumLevelILInstruction = self [InstructionIndex (instr_index )]
39483964 propagated_func .set_current_address (instr .address , block .arch )
3949- propagated_func .append (expr_handler (propagated_func , block , instr ))
3965+ propagated_func .append (expr_handler (propagated_func , block , instr ), ILSourceLocation . from_instruction ( instr ) )
39503966
39513967 return propagated_func
39523968
@@ -3970,15 +3986,85 @@ def set_expr_attributes(self, expr: InstructionOrExpression, value: ILInstructio
39703986 result |= flag .value
39713987 core .BNSetMediumLevelILExprAttributes (self .handle , expr , result )
39723988
3973- def append (self , expr : ExpressionIndex ) -> InstructionIndex :
3989+ def append (self , expr : ExpressionIndex , source_location : Optional [ 'ILSourceLocation' ] = None ) -> InstructionIndex :
39743990 """
39753991 ``append`` adds the ExpressionIndex ``expr`` to the current MediumLevelILFunction.
39763992
39773993 :param ExpressionIndex expr: the ExpressionIndex to add to the current MediumLevelILFunction
39783994 :return: Index of added instruction in the current function
39793995 :rtype: int
39803996 """
3981- return InstructionIndex (core .BNMediumLevelILAddInstruction (self .handle , expr ))
3997+ index = InstructionIndex (core .BNMediumLevelILAddInstruction (self .handle , expr ))
3998+
3999+ # Update internal mappings to remember this
4000+ if source_location is not None :
4001+ if source_location .source_mlil_instruction is not None :
4002+ if source_location .source_mlil_instruction not in self ._mlil_to_mlil_instr_map :
4003+ self ._mlil_to_mlil_instr_map [source_location .source_mlil_instruction ] = []
4004+ self ._mlil_to_mlil_instr_map [source_location .source_mlil_instruction ].append ((index , source_location .il_direct ))
4005+ if source_location .source_llil_instruction is not None \
4006+ and source_location .source_llil_instruction .function .il_form == FunctionGraphType .LowLevelILSSAFormFunctionGraph :
4007+ if source_location .source_llil_instruction not in self ._llil_ssa_to_mlil_instr_map :
4008+ self ._llil_ssa_to_mlil_instr_map [source_location .source_llil_instruction ] = []
4009+ self ._llil_ssa_to_mlil_instr_map [source_location .source_llil_instruction ].append ((index , source_location .il_direct ))
4010+ return index
4011+
4012+ def _get_llil_ssa_to_mlil_instr_map (self , from_builders : bool ) -> LLILSSAToMLILInstructionMapping :
4013+ llil_ssa_to_mlil_instr_map = {}
4014+
4015+ if from_builders :
4016+ for (old_instr , new_indices ) in self ._mlil_to_mlil_instr_map .items ():
4017+ old_instr : MediumLevelILInstruction
4018+ new_indices : List [InstructionIndex ]
4019+
4020+ # Look up the LLIL SSA instruction for the old instr in its function
4021+ # And then store that mapping for the new function
4022+
4023+ for (new_index , new_direct ) in new_indices :
4024+ # Instructions are always mapped 1 to 1. If the map is marked indirect
4025+ # then just ignore it
4026+ if new_direct :
4027+ old_llil_ssa_index = old_instr .function .get_low_level_il_instruction_index (old_instr .instr_index )
4028+ llil_ssa_to_mlil_instr_map [old_llil_ssa_index ] = new_index
4029+ else :
4030+ for instr in self .instructions :
4031+ llil_ssa_index = self .get_low_level_il_instruction_index (instr .instr_index )
4032+ llil_ssa_to_mlil_instr_map [llil_ssa_index ] = instr .instr_index
4033+
4034+ return llil_ssa_to_mlil_instr_map
4035+
4036+ def _get_llil_ssa_to_mlil_expr_map (self , from_builders : bool ) -> LLILSSAToMLILExpressionMapping :
4037+ llil_ssa_to_mlil_expr_map = {}
4038+
4039+ if from_builders :
4040+ for (old_expr , new_indices ) in self ._mlil_to_mlil_expr_map .items ():
4041+ old_expr : MediumLevelILInstruction
4042+ new_indices : List [ExpressionIndex ]
4043+
4044+ # Look up the LLIL SSA expression for the old expr in its function
4045+ # And then store that mapping for the new function
4046+
4047+ old_llil_ssa_direct = old_expr .function .get_low_level_il_expr_index (old_expr .expr_index )
4048+ old_llil_ssa_indices = old_expr .function .get_low_level_il_expr_indexes (old_expr .expr_index )
4049+ for old_index in old_llil_ssa_indices :
4050+ if old_index not in llil_ssa_to_mlil_expr_map :
4051+ llil_ssa_to_mlil_expr_map [old_index ] = []
4052+ for (new_index , new_direct ) in new_indices :
4053+ llil_ssa_to_mlil_expr_map [old_index ].append (new_index )
4054+ else :
4055+ for instr in self .instructions :
4056+ for expr in instr .traverse (lambda e : e ):
4057+ llil_ssa_direct = self .get_low_level_il_expr_index (expr .expr_index )
4058+ llil_ssa_indices = self .get_low_level_il_expr_indexes (expr .expr_index )
4059+ for llil_ssa_index in llil_ssa_indices :
4060+ if llil_ssa_index not in llil_ssa_to_mlil_expr_map :
4061+ llil_ssa_to_mlil_expr_map [llil_ssa_index ] = []
4062+ if llil_ssa_index == llil_ssa_direct :
4063+ llil_ssa_to_mlil_expr_map [llil_ssa_index ].insert (0 , expr .expr_index )
4064+ else :
4065+ llil_ssa_to_mlil_expr_map [llil_ssa_index ].append (expr .expr_index )
4066+
4067+ return llil_ssa_to_mlil_expr_map
39824068
39834069 def nop (self , loc : Optional ['ILSourceLocation' ] = None ) -> ExpressionIndex :
39844070 """
0 commit comments