'Resolve indirect jumps found in previous scanning.
Currently we support resolving the following types of indirect jumps:
- Ijk_Call (disabled now): indirect calls where the function address is passed in from a proceeding basic block
- Ijk_Boring: jump tables
:return: a set of 2-tuples: (resolved indirect jump target, function address)
:rtype: set'

def _process_indirect_jumps(self):

    all_targets = set()
    jumps_resolved = {}
    l.info('%d    indirect    jumps    to    resolve.', len(self._indirect_jumps_to_resolve))
    for jump in self._indirect_jumps_to_resolve:
        jumps_resolved[jump] = False
        resolved = False
        targets = None
        for resolver in self.indirect_jump_resolvers:
            block = self.project.factory.block(jump.addr)
            if (not resolver.filter(self, jump.addr, jump.func_addr, block, jump.jumpkind)):
                continue
            (resolved, targets) = resolver.resolve(self, jump.addr, jump.func_addr, block, jump.jumpkind)
            if resolved:
                break
        if resolved:
            jumps_resolved[jump] = True
            targets = [t for t in targets if any(iter(((a <= t < b) for (a, b) in self._exec_mem_regions)))]
            '\n                                                                if    jump.addr    in    self.indirect_jumps:\n                                                                                ij    =    self.indirect_jumps[jump.addr]\n                                                                                ij.jumptable    =    True\n                                                                                ij.resolved    =    True\n                                                                                #    Fill    the    IndirectJump    object\n                                                                                ij.resolved_targets    |=    set(targets)\n                                                                '
            all_targets |= set([(t, jump.func_addr, jump.addr) for t in targets])
    for (jump, resolved) in jumps_resolved.iteritems():
        self._indirect_jumps_to_resolve.remove(jump)
        self._deregister_analysis_job(jump.func_addr, jump)
        if (not resolved):
            src_node = self._nodes[jump.addr]
            dst_node = CFGNode(self._unresolvable_target_addr, 0, self, function_address=self._unresolvable_target_addr, simprocedure_name='UnresolvableTarget')
            if (self._unresolvable_target_addr not in self._nodes):
                self._nodes[self._unresolvable_target_addr] = dst_node
                self._nodes_by_addr[self._unresolvable_target_addr].append(dst_node)
            self._graph_add_edge(dst_node, src_node, jump.jumpkind, jump.ins_addr, jump.stmt_idx)
            self._function_add_transition_edge(self._unresolvable_target_addr, src_node, jump.func_addr, to_outside=True, to_function_addr=self._unresolvable_target_addr, ins_addr=jump.ins_addr, stmt_idx=jump.stmt_idx)
            self.kb._unresolved_indirect_jumps.add(jump.addr)
    return all_targets
