def _scan_irsb(self, cfg_job, current_func_addr):
        """
        Generate a list of successors (generating them each as entries) to IRSB.
        Updates previous CFG nodes with edges.

        :param CFGJob cfg_job: The CFGJob instance.
        :param int current_func_addr: Address of the current function
        :return: a list of successors
        :rtype: list
        """
        addr, function_addr, cfg_node, irsb = self._generate_cfgnode(cfg_job, current_func_addr)

        # Add edges going to this node in function graphs
        cfg_job.apply_function_edges(self, clear=True)

        # function_addr and current_function_addr can be different. e.g. when tracing an optimized tail-call that jumps
        # into another function that has been identified before.

        if cfg_node is None:
            # exceptions occurred, or we cannot get a CFGNode for other reasons
            return [ ]

        self._graph_add_edge(cfg_node, cfg_job.src_node, cfg_job.jumpkind, cfg_job.src_ins_addr,
                             cfg_job.src_stmt_idx
                             )
        self._function_add_node(cfg_node, function_addr)

        if self.functions.get_by_addr(function_addr).returning is not True:
            self._updated_nonreturning_functions.add(function_addr)

        # If we have traced it before, don't trace it anymore
        real_addr = get_real_address_if_arm(self.project.arch, addr)
        if real_addr in self._traced_addresses:
            # the address has been traced before
            return [ ]
        else:
            # Mark the address as traced
            self._traced_addresses.add(real_addr)

        # irsb cannot be None here
        # assert irsb is not None

        # IRSB is only used once per CFGNode. We should be able to clean up the CFGNode here in order to save memory
        cfg_node.irsb = None

        self._process_block_arch_specific(addr, irsb, function_addr)

        # Scan the basic block to collect data references
        if self._collect_data_ref:
            self._collect_data_references(irsb, addr)

        # Get all possible successors
        irsb_next, jumpkind = irsb.next, irsb.jumpkind
        successors = [ ]

        last_ins_addr = None
        ins_addr = addr
        if irsb.statements:
            for i, stmt in enumerate(irsb.statements):
                if isinstance(stmt, pyvex.IRStmt.Exit):
                    successors.append((i,
                                       last_ins_addr if self.project.arch.branch_delay_slot else ins_addr,
                                       stmt.dst,
                                       stmt.jumpkind
                                       )
                                      )
                elif isinstance(stmt, pyvex.IRStmt.IMark):
                    last_ins_addr = ins_addr
                    ins_addr = stmt.addr + stmt.delta
        else:
            for ins_addr, stmt_idx, exit_stmt in irsb.exit_statements:
                successors.append((
                    stmt_idx,
                    last_ins_addr if self.project.arch.branch_delay_slot else ins_addr,
                    exit_stmt.dst,
                    exit_stmt.jumpkind
                ))

        successors.append((DEFAULT_STATEMENT,
                           last_ins_addr if self.project.arch.branch_delay_slot else ins_addr, irsb_next, jumpkind)
                          )

        entries = [ ]

        successors = self._post_process_successors(addr, irsb.size, successors)

        # Process each successor
        for suc in successors:
            stmt_idx, ins_addr, target, jumpkind = suc

            entries += self._create_jobs(target, jumpkind, function_addr, irsb, addr, cfg_node, ins_addr,
                                         stmt_idx
                                         )

        return entries
def _scan_irsb ( self , cfg_job , current_func_addr ) : addr , function_addr , cfg_node , irsb = self . _generate_cfgnode ( cfg_job , current_func_addr ) cfg_job . apply_function_edges ( self , clear = True ) if cfg_node is None : return [ ] self . _graph_add_edge ( cfg_node , cfg_job . src_node , cfg_job . jumpkind , cfg_job . src_ins_addr , cfg_job . src_stmt_idx ) self . _function_add_node ( cfg_node , function_addr ) if self . functions . get_by_addr ( function_addr ) . returning is not True : self . _updated_nonreturning_functions . add ( function_addr ) real_addr = get_real_address_if_arm ( self . project . arch , addr ) if real_addr in self . _traced_addresses : return [ ] else : self . _traced_addresses . add ( real_addr ) cfg_node . irsb = None self . _process_block_arch_specific ( addr , irsb , function_addr ) if self . _collect_data_ref : self . _collect_data_references ( irsb , addr ) irsb_next , jumpkind = irsb . next , irsb . jumpkind successors = [ ] last_ins_addr = None ins_addr = addr if irsb . statements : for i , stmt in enumerate ( irsb . statements ) : if isinstance ( stmt , pyvex . IRStmt . Exit ) : successors . append ( ( i , last_ins_addr if self . project . arch . branch_delay_slot else ins_addr , stmt . dst , stmt . jumpkind ) ) elif isinstance ( stmt , pyvex . IRStmt . IMark ) : last_ins_addr = ins_addr ins_addr = stmt . addr + stmt . delta else : for ins_addr , stmt_idx , exit_stmt in irsb . exit_statements : successors . append ( ( stmt_idx , last_ins_addr if self . project . arch . branch_delay_slot else ins_addr , exit_stmt . dst , exit_stmt . jumpkind ) ) successors . append ( ( DEFAULT_STATEMENT , last_ins_addr if self . project . arch . branch_delay_slot else ins_addr , irsb_next , jumpkind ) ) entries = [ ] successors = self . _post_process_successors ( addr , irsb . size , successors ) for suc in successors : stmt_idx , ins_addr , target , jumpkind = suc entries += self . _create_jobs ( target , jumpkind , function_addr , irsb , addr , cfg_node , ins_addr , stmt_idx ) return entries
Generate a list of successors (generating them each as entries) to IRSB.
        Updates previous CFG nodes with edges.

        :param CFGJob cfg_job: The CFGJob instance.
        :param int current_func_addr: Address of the current function
        :return: a list of successors
        :rtype: list