'Resolve indirect jumps specified by sim_successors.addr.
:param SimSuccessors sim_successors: The SimSuccessors instance.
:param CFGNode cfg_node:                     The CFGNode instance.
:param int func_addr:                        Current function address.
:param list successors:                      A list of successors.
:param tuple exception_info:                 The sys.exc_info() of the exception or None if none occured.
:param artifacts:                            A container of collected information.
:return:                                     Resolved successors
:rtype:                                      list'

def _resolve_indirect_jumps(self, sim_successors, cfg_node, func_addr, successors, exception_info, artifacts):

    if ((sim_successors.sort == 'IRSB') and self._is_indirect_jump(cfg_node, sim_successors)):
        l.debug('IRSB    %#x    has    an    indirect    jump    as    its    default    exit', cfg_node.addr)
        old_successors = successors[::None]
        successors = []
        for (i, suc) in enumerate(old_successors):
            if suc.se.symbolic(suc.ip):
                successors.append(suc)
            else:
                ip_int = suc.se.exactly_int(suc.ip)
                if (self._is_address_executable(ip_int) or self.project.is_hooked(ip_int)):
                    successors.append(suc)
                else:
                    l.info('%s:    an    obviously    incorrect    successor    %d/%d    (%#x)    is    ditched', cfg_node, (i + 1), len(old_successors), ip_int)
        if (self._advanced_backward_slicing and self._keep_state):
            should_resolve = True
            legit_successors = [suc for suc in successors if (suc.history.jumpkind in ('Ijk_Boring', 'Ijk_Call'))]
            if legit_successors:
                legit_successor = legit_successors[0]
                if legit_successor.ip.symbolic:
                    if (not (legit_successor.history.jumpkind == 'Ijk_Call')):
                        should_resolve = False
                elif (legit_successor.history.jumpkind == 'Ijk_Call'):
                    should_resolve = False
                else:
                    concrete_target = legit_successor.se.any_int(legit_successor.ip)
                    if (not (self.project.loader.find_object_containing(concrete_target) is self.project.loader.main_object)):
                        should_resolve = False
            else:
                should_resolve = False
            if (not should_resolve):
                l.debug('This    might    not    be    an    indirect    jump    that    has    multiple    targets.    Skipped.')
                self.kb._unresolved_indirect_jumps.add(cfg_node.addr)
            else:
                more_successors = self._resolve_indirect_jump(cfg_node, sim_successors, func_addr)
                if more_successors:
                    all_successors = [suc for suc in successors if (not suc.se.symbolic(suc.ip))]
                    for suc_addr in more_successors:
                        a = sim_successors.all_successors[0].copy()
                        a.ip = suc_addr
                        all_successors.insert(0, a)
                    l.debug('The    indirect    jump    is    successfully    resolved.')
                    self.kb._resolved_indirect_jumps.add(cfg_node.addr)
                else:
                    l.debug('Failed    to    resolve    the    indirect    jump.')
                    self.kb._unresolved_indirect_jumps.add(cfg_node.addr)
        elif (not successors):
            l.debug('Cannot    resolve    the    indirect    jump    without    advanced    backward    slicing    enabled:    %s', cfg_node)
    if ((exception_info is None) and (cfg_node.is_simprocedure or self._is_indirect_jump(cfg_node, sim_successors))):
        has_call_jumps = any(((suc_state.history.jumpkind == 'Ijk_Call') for suc_state in successors))
        if has_call_jumps:
            concrete_successors = [suc_state for suc_state in successors if ((suc_state.history.jumpkind != 'Ijk_FakeRet') and (not suc_state.se.symbolic(suc_state.ip)))]
        else:
            concrete_successors = [suc_state for suc_state in successors if (not suc_state.se.symbolic(suc_state.ip))]
        symbolic_successors = [suc_state for suc_state in successors if suc_state.se.symbolic(suc_state.ip)]
        resolved = (True if (not symbolic_successors) else False)
        if symbolic_successors:
            for suc in symbolic_successors:
                if (o.SYMBOLIC in suc.options):
                    targets = suc.se.any_n_int(suc.ip, 32)
                    if (len(targets) < 32):
                        all_successors = []
                        resolved = True
                        for t in targets:
                            new_ex = suc.copy()
                            new_ex.ip = suc.se.BVV(t, suc.ip.size())
                            all_successors.append(new_ex)
                    else:
                        break
        if ((not resolved) and ((symbolic_successors and (not concrete_successors)) or ((not cfg_node.is_simprocedure) and self._is_indirect_jump(cfg_node, sim_successors)))):
            l.debug('%s    has    an    indirect    jump.    See    what    we    can    do    about    it.', cfg_node)
            if ((sim_successors.sort == 'SimProcedure') and sim_successors.artifacts['adds_exits']):
                l.debug('We    got    a    SimProcedure    %s    in    fastpath    mode    that    creates    new    exits.', sim_successors.description)
                if self._enable_symbolic_back_traversal:
                    successors = self._symbolically_back_traverse(sim_successors, artifacts, cfg_node)
                    if successors:
                        self.kb._resolved_indirect_jumps.add(cfg_node.addr)
                    else:
                        self.kb._unresolved_indirect_jumps.add(cfg_node.addr)
                    l.debug('Got    %d    concrete    exits    in    symbolic    mode.', len(successors))
                else:
                    self.kb._unresolved_indirect_jumps.add(cfg_node.addr)
                    successors = [s for s in successors if (s.history.jumpkind == 'Ijk_FakeRet')]
            elif ((sim_successors.sort == 'IRSB') and any([(ex.history.jumpkind != 'Ijk_Ret') for ex in successors])):
                l.debug('Try    traversal    backwards    in    symbolic    mode    on    %s.', cfg_node)
                if self._enable_symbolic_back_traversal:
                    successors = self._symbolically_back_traverse(sim_successors, artifacts, cfg_node)
                    successors = [suc for suc in successors if self._is_address_executable(suc.se.exactly_int(suc.ip))]
                    if successors:
                        self.kb._resolved_indirect_jumps.add(cfg_node.addr)
                    else:
                        self.kb._unresolved_indirect_jumps.add(cfg_node.addr)
                    l.debug('Got    %d    concrete    exits    in    symbolic    mode', len(successors))
                else:
                    self.kb._unresolved_indirect_jumps.add(cfg_node.addr)
                    successors = []
            elif (successors and all([(ex.history.jumpkind == 'Ijk_Ret') for ex in successors])):
                l.debug('All    exits    are    returns    (Ijk_Ret).    It    will    be    handled    by    pending    exits.')
            else:
                l.debug('Cannot    resolve    this    indirect    jump:    %s', cfg_node)
                self.kb._unresolved_indirect_jumps.add(cfg_node.addr)
    return successors
