docs: def _try_resolving_indirect_jumps(self, sim_successors, cfg_node, func_addr, successors, exception_info, artifacts):
          """
          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
          """
  
          # Try to resolve indirect jumps with advanced backward slicing (if enabled)
          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)
  
              # We need input states to perform backward slicing
              if self._advanced_backward_slicing and self._keep_state:
  
                  # Optimization: make sure we only try to resolve an indirect jump if any of the following criteria holds
                  # - It's a jump (Ijk_Boring), and its target is either fully symbolic, or its resolved target is within
                  #   the current binary
                  # - It's a call (Ijk_Call), and its target is fully symbolic
                  # TODO: This is very hackish, please refactor this part of code later
                  should_resolve = True
                  legit_successors = [suc for suc in successors if suc.history.jumpkind in ('Ijk_Boring', 'Ijk_InvalICache', '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
                      else:
                          if legit_successor.history.jumpkind == 'Ijk_Call':
                              should_resolve = False
                          else:
                              concrete_target = legit_successor.solver.eval(legit_successor.ip)
                              if not self.project.loader.find_object_containing(
                                      concrete_target) is self.project.loader.main_object:
                                  should_resolve = False
  
                  else:
                      # No interesting successors... skip
                      should_resolve = False
  
                  # TODO: Handle those successors
                  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._backward_slice_indirect(cfg_node, sim_successors, func_addr)
  
                      if more_successors:
                          # Remove the symbolic successor
                          # TODO: Now we are removing all symbolic successors. Is it possible
                          # TODO: that there is more than one symbolic successor?
                          all_successors = [suc for suc in successors if not suc.solver.symbolic(suc.ip)]
                          # Insert new successors
                          # We insert new successors in the beginning of all_successors list so that we don't break the
                          # assumption that Ijk_FakeRet is always the last element in the list
                          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)
  
              else:
                  if not successors:
                      l.debug('Cannot resolve the indirect jump without advanced backward slicing enabled: %s',
                              cfg_node)
  
          # Try to find more successors if we failed to resolve the indirect jump before
          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.solver.symbolic(
                                             suc_state.ip)]
              else:
                  concrete_successors = [suc_state for suc_state in successors if
                                         not suc_state.solver.symbolic(suc_state.ip)]
              symbolic_successors = [suc_state for suc_state in successors if suc_state.solver.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.solver.eval_upto(suc.ip, 32)
                          if len(targets) < 32:
                              all_successors = []
                              resolved = True
                              for t in targets:
                                  new_ex = suc.copy()
                                  new_ex.ip = suc.solver.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']:
                      # Skip those SimProcedures that don't create new SimExits
                      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)
                          # mark jump as resolved if we got successors
                          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)
                          # keep fake_rets
                          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]):
                      # We cannot properly handle Return as that requires us start execution from the caller...
                      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)
  
                          # Remove successors whose IP doesn't make sense
                          successors = [suc for suc in successors
                                            if self._is_address_executable(suc.solver.eval_one(suc.ip))]
  
                          # mark jump as resolved if we got successors
                          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