'Try to resolve an indirect jump by slicing backwards'

def _resolve_indirect_jump(self, cfgnode, sim_successors, current_function_addr):

    irsb = sim_successors.artifacts['irsb']
    l.debug('Resolving    indirect    jump    at    IRSB    %s', irsb)
    next_tmp = irsb.next.tmp
    stmt_id = [i for (i, s) in enumerate(irsb.statements) if (isinstance(s, pyvex.IRStmt.WrTmp) and (s.tmp == next_tmp))][0]
    cdg = self.project.analyses.CDG(cfg=self)
    ddg = self.project.analyses.DDG(cfg=self, start=current_function_addr, call_depth=0)
    bc = self.project.analyses.BackwardSlice(self, cdg, ddg, targets=[(cfgnode, stmt_id)], same_function=True)
    taint_graph = bc.taint_graph
    next_nodes = [cl for cl in taint_graph.nodes() if (cl.block_addr == sim_successors.addr)]
    if (not next_nodes):
        l.error('The    target    exit    is    not    included    in    the    slice.    Something    is    wrong')
        return []
    next_node = next_nodes[0]
    all_subgraphs = networkx.weakly_connected_component_subgraphs(taint_graph)
    starts = set()
    for subgraph in all_subgraphs:
        if (next_node in subgraph):
            nodes = [n for n in subgraph.nodes() if (subgraph.in_degree(n) == 0)]
            for n in nodes:
                starts.add(n.block_addr)
    successing_addresses = set()
    annotated_cfg = bc.annotated_cfg()
    for start in starts:
        l.debug('Start    symbolic    execution    at    0x%x    on    program    slice.', start)
        node = self.get_any_node(start)
        if (node is None):
            p = self.project.factory.path(self.project.factory.blank_state(addr=start))
        else:
            base_state = node.input_state.copy()
            base_state.set_mode('symbolic')
            base_state.ip = start
            initial_nodes = [n for n in bc.taint_graph.nodes() if (bc.taint_graph.in_degree(n) == 0)]
            for cl in initial_nodes:
                cfg_nodes = self.get_all_nodes(cl.block_addr)
                for n in cfg_nodes:
                    if (not n.final_states):
                        continue
                    actions = [ac for ac in n.final_states[0].history.recent_actions if ((ac.bbl_addr == cl.block_addr) and (ac.stmt_idx == cl.stmt_idx))]
                    for ac in actions:
                        if (not hasattr(ac, 'action')):
                            continue
                        if (ac.action == 'read'):
                            if (ac.type == 'mem'):
                                unconstrained_value = base_state.se.Unconstrained('unconstrained', (ac.size.ast * 8))
                                base_state.memory.store(ac.addr, unconstrained_value, endness=self.project.arch.memory_endness)
                            elif (ac.type == 'reg'):
                                unconstrained_value = base_state.se.Unconstrained('unconstrained', (ac.size.ast * 8))
                                base_state.registers.store(ac.offset, unconstrained_value, endness=self.project.arch.register_endness)
            base_state.release_plugin('solver_engine')
            p = self.project.factory.path(base_state)
        old_timeout = p.state.se._solver.timeout
        p.state.se._solver.timeout = 5000
        sc = self.project.surveyors.Slicecutor(annotated_cfg, start=p, max_loop_iterations=1).run()
        p.state.se._solver.timeout = old_timeout
        if (sc.cut or sc.deadended):
            all_deadended_paths = (sc.cut + sc.deadended)
            for p in all_deadended_paths:
                if (p.addr == sim_successors.addr):
                    successing_paths = p.step()
                    for sp in successing_paths:
                        successing_addresses.add(sp.addr)
        else:
            l.debug('Cannot    determine    the    exit.    You    need    some    better    ways    to    recover    the    exits    :-(')
    l.debug('Resolution    is    done,    and    we    have    %d    new    successors.', len(successing_addresses))
    return list(successing_addresses)
