#NEWLINE# def _merge_paths( self , base_path , merge_info_list ) : #NEWLINE# #INDENT# def find_real_ref( ref , ref_list ) : #NEWLINE# #INDENT# '\n            Returns the last element r in ref_list that satisfies r == ref\n            ' #NEWLINE# for r in reversed ( ref_list ) : #NEWLINE# #INDENT# if ( r == ref ) : #NEWLINE# #INDENT# return r #NEWLINE# #UNINDENT# #UNINDENT# return None #NEWLINE# #UNINDENT# all_outputs = [ ] #NEWLINE# for ( _ , _ , outputs ) in merge_info_list : #NEWLINE# #INDENT# for ref in reversed ( outputs ) : #NEWLINE# #INDENT# if ( ref not in all_outputs ) : #NEWLINE# #INDENT# all_outputs . append ( ref ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# all_outputs = reversed ( all_outputs ) #NEWLINE# merged_path = base_path . copy ( ) #NEWLINE# merged_path . trim_history ( ) #NEWLINE# merged_path . history . _events = ( ) #NEWLINE# merged_state = merged_path . state #NEWLINE# merged_path . info [ 'actionqueue_list' ] . append ( self . _new_actionqueue ( ( merged_path . addr , self . _get_last_actionqueue ( merged_path ) . id ) ) ) #NEWLINE# for ref in all_outputs : #NEWLINE# #INDENT# last_ip = None #NEWLINE# all_values = [ ] #NEWLINE# all_guards = [ ] #NEWLINE# for ( _ , merge_info ) in enumerate ( merge_info_list ) : #NEWLINE# #INDENT# ( final_path , _ , outputs ) = merge_info #NEWLINE# if ( ref in outputs ) : #NEWLINE# #INDENT# real_ref = find_real_ref ( ref , outputs ) #NEWLINE# if ( real_ref . type == 'mem' ) : #NEWLINE# #INDENT# v = real_ref . value #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( real_ref . type == 'reg' ) : #NEWLINE# #INDENT# v = real_ref . value #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if real_ref . type . startswith ( 'file' ) : #NEWLINE# #INDENT# v = real_ref . value #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# raise VeritestingError ( 'FINISH ME' ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if ( ( real_ref . type == 'reg' ) and ( real_ref . offset == self . project . arch . ip_offset ) ) : #NEWLINE# #INDENT# if ( last_ip is None ) : #NEWLINE# #INDENT# last_ip = v #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if merged_state . se . is_true ( ( last_ip != v ) , exact = False ) : #NEWLINE# #INDENT# raise VeritestingError ( "We don't want to merge IP - something is seriously wrong" ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# guards = final_path . info [ 'guards' ] #NEWLINE# guard = ( merged_state . se . And ( * guards ) if guards else merged_state . se . true ) #NEWLINE# all_values . append ( v ) #NEWLINE# all_guards . append ( guard ) #NEWLINE# #UNINDENT# #UNINDENT# max_value_size = max ( [ v . size ( ) for v in all_values ] ) #NEWLINE# merged_actions = [ ] #NEWLINE# if ( real_ref . type == 'mem' ) : #NEWLINE# #INDENT# for actual_addr in real_ref . actual_addrs : #NEWLINE# #INDENT# merged_action = SimActionData ( merged_state , 'mem' , 'write' , addr = merged_state . se . BVV ( actual_addr , self . project . arch . bits ) , size = max_value_size ) #NEWLINE# merged_state . memory . store_cases ( actual_addr , all_values , all_guards , endness = 'Iend_BE' , action = merged_action ) #NEWLINE# merged_actions . append ( merged_action ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( real_ref . type == 'reg' ) : #NEWLINE# #INDENT# if ( real_ref . offset != self . project . arch . ip_offset ) : #NEWLINE# #INDENT# merged_action = SimActionData ( merged_state , 'reg' , 'write' , addr = real_ref . offset , size = max_value_size ) #NEWLINE# merged_state . registers . store_cases ( real_ref . offset , all_values , all_guards , endness = 'Iend_BE' , action = merged_action ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# merged_action = SimActionData ( merged_state , 'reg' , 'write' , addr = real_ref . offset , size = max_value_size ) #NEWLINE# merged_state . registers . store ( real_ref . offset , last_ip , action = merged_action ) #NEWLINE# #UNINDENT# merged_actions . append ( merged_action ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if real_ref . type . startswith ( 'file' ) : #NEWLINE# #INDENT# for actual_addr in real_ref . actual_addrs : #NEWLINE# #INDENT# file_id = real_ref . type [ ( real_ref . type . index ( '_' ) + 1 ) : ] #NEWLINE# file_id = merged_state . posix . filename_to_fd ( file_id [ : file_id . index ( '_' ) ] ) #NEWLINE# merged_action = SimActionData ( merged_state , real_ref . type , real_ref . action , addr = actual_addr , size = max_value_size ) #NEWLINE# merged_state . posix . files [ file_id ] . content . store_cases ( actual_addr , all_values , all_guards , endness = 'Iend_BE' , action = merged_action ) #NEWLINE# merged_actions . append ( merged_action ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# l . error ( 'Unsupported Ref type %s in path merging' , real_ref . type ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if merged_actions : #NEWLINE# #INDENT# for merged_action in merged_actions : #NEWLINE# #INDENT# merged_path . history . _events += ( merged_action , ) #NEWLINE# self . _get_last_actionqueue ( merged_path ) . actions . append ( merged_action ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# "\n        for i, merge_info in enumerate(merge_info_list):\n            final_path, _, _ = merge_info\n\n            guards = final_path.info['guards']\n            guard = merged_state.se.And(*guards) if guards else None\n\n            for action in final_path.actions:\n                if action.type == 'tmp':\n                    continue\n                # Encode the constraint into action.condition\n                action = action.copy()\n                if guard is not None:\n                    if action.condition is None:\n                        action.condition = action._make_object(guard)\n                    else:\n                        action.condition.ast = merged_state.se.And(action.condition.ast, guard)\n                if 'actions' not in merged_path.info:\n                    merged_path.info['actions'] = [ ]\n\n                merged_path.info['actions'].append(action)\n        " #NEWLINE# merged_path . history . addr = ( - 1 ) #NEWLINE# merged_path . history . _runstr = 'Veritesting' #NEWLINE# all_constraints = [ ] #NEWLINE# for ( final_path , _ , _ ) in merge_info_list : #NEWLINE# #INDENT# if final_path . info [ 'guards' ] : #NEWLINE# #INDENT# se = final_path . state . se #NEWLINE# guards = final_path . info [ 'guards' ] #NEWLINE# constraints = [ ( a . constraint if ( a . condition is None ) else se . And ( a . constraint , a . condition ) ) for a in final_path . actions if ( a . type == 'constraint' ) ] #NEWLINE# all_constraints . append ( se . And ( * ( guards + constraints ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# if all_constraints : #NEWLINE# #INDENT# merged_state . add_constraints ( merged_state . se . Or ( * all_constraints ) ) #NEWLINE# #UNINDENT# merged_path . callstack = merge_info_list [ 0 ] [ 0 ] . callstack #NEWLINE# new_loop_ctrs = defaultdict ( int ) #NEWLINE# for ( final_path , _ , _ ) in merge_info_list : #NEWLINE# #INDENT# for ( loop_head_addr , looping_times ) in final_path . info [ 'loop_ctrs' ] . iteritems ( ) : #NEWLINE# #INDENT# if ( looping_times > new_loop_ctrs [ loop_head_addr ] ) : #NEWLINE# #INDENT# new_loop_ctrs [ loop_head_addr ] = looping_times #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# merged_path . info [ 'loop_ctrs' ] = new_loop_ctrs #NEWLINE# if ( 'guards' in merged_path . info ) : #NEWLINE# #INDENT# del merged_path . info [ 'guards' ] #NEWLINE# #UNINDENT# merged_path . _run = None #NEWLINE# return merged_path