(self, seq, cmp_lb, jumptable_entries, node_b_addr, addr2nodes)
return cases, node_default, to_remove
Discover all cases for the switch-case structure and build the switch-cases dict.

        :param seq:                 The original Sequence node.
        :param int cmp_lb:          The lower bound of the jump table comparison.
        :param list jumptable_entries:  Addresses of indirect jump targets in the jump table.
        :param int node_b_addr:     Address of node B. Potentially, node B is the default node.
        :param dict addr2nodes:     A dict of addresses to their corresponding nodes in `seq`.
        :return:
Discover all cases for the switch-case structure and build the switch-cases dict.
Discover all cases for the switch - case structure and build the switch - cases dict .
def _switch_build_cases(self, seq, cmp_lb, jumptable_entries, node_b_addr, addr2nodes):
        """
        Discover all cases for the switch-case structure and build the switch-cases dict.

        :param seq:                 The original Sequence node.
        :param int cmp_lb:          The lower bound of the jump table comparison.
        :param list jumptable_entries:  Addresses of indirect jump targets in the jump table.
        :param int node_b_addr:     Address of node B. Potentially, node B is the default node.
        :param dict addr2nodes:     A dict of addresses to their corresponding nodes in `seq`.
        :return:
        """

        cases = { }
        to_remove = set()
        node_default = addr2nodes.get(node_b_addr, None)

        entry_addrs_set = set(jumptable_entries)
        for j, entry_addr in enumerate(jumptable_entries):
            cases_idx = cmp_lb + j
            if entry_addr == node_b_addr:
                # jump to default or end of the switch-case structure - ignore this case
                continue

            entry_node = self._switch_find_jumptable_entry_node(entry_addr, addr2nodes)
            if entry_node is None:
                l.warning("Missing jump table entry %#x for jump table %#x. Please report it to GitHub.",
                          entry_addr,
                          seq.addr,
                          )
                continue
            case_node = SequenceNode(entry_node.addr, nodes=[CodeNode(entry_node.node, claripy.true)])
            to_remove.add(entry_node)
            entry_node_idx = seq.nodes.index(entry_node)

            # find nodes that this entry node dominates
            cond_subexprs = list(get_ast_subexprs(entry_node.reaching_condition))
            guarded_nodes = None
            for subexpr in cond_subexprs:
                guarded_node_candidates = self._nodes_guarded_by_common_subexpr(seq, subexpr, entry_node_idx + 1)
                if guarded_nodes is None:
                    guarded_nodes = set(node_ for _, node_, _ in guarded_node_candidates)
                else:
                    guarded_nodes = guarded_nodes.intersection(set(node_ for _, node_, _ in guarded_node_candidates))

            if guarded_nodes is not None:
                # keep the topological order of nodes in Sequence node
                sorted_guarded_nodes = [node_ for node_ in seq.nodes[entry_node_idx + 1:] if node_ in guarded_nodes]
                for node_ in sorted_guarded_nodes:
                    if node_ is not entry_node and node_.addr not in entry_addrs_set:
                        # fix reaching condition
                        reaching_condition_subexprs = set(ex for ex in get_ast_subexprs(node_.reaching_condition)).difference(set(cond_subexprs))
                        new_reaching_condition = claripy.And(*reaching_condition_subexprs)
                        new_node = CodeNode(node_.node, new_reaching_condition)
                        case_node.add_node(new_node)
                        to_remove.add(node_)

            # do we have a default node?
            case_last_stmt = self.cond_proc.get_last_statement(case_node)
            if isinstance(case_last_stmt, ailment.Stmt.Jump):
                targets = extract_jump_targets(case_last_stmt)
                if len(targets) == 1 and targets[0] == node_b_addr:
                    # jump to the default case is rare - it's more likely that there is no default for this
                    # switch-case struct
                    node_default = None

            self._new_sequences.append(case_node)
            cases[cases_idx] = case_node

        return cases, node_default, to_remove
def _switch_build_cases ( self , seq , cmp_lb , jumptable_entries , node_b_addr , addr2nodes ) : cases = { } to_remove = set ( ) node_default = addr2nodes . get ( node_b_addr , None ) entry_addrs_set = set ( jumptable_entries ) for j , entry_addr in enumerate ( jumptable_entries ) : cases_idx = cmp_lb + j if entry_addr == node_b_addr : # jump to default or end of the switch-case structure - ignore this case continue entry_node = self . _switch_find_jumptable_entry_node ( entry_addr , addr2nodes ) if entry_node is None : l . warning ( "Missing jump table entry %#x for jump table %#x. Please report it to GitHub." , entry_addr , seq . addr , ) continue case_node = SequenceNode ( entry_node . addr , nodes = [ CodeNode ( entry_node . node , claripy . true ) ] ) to_remove . add ( entry_node ) entry_node_idx = seq . nodes . index ( entry_node ) # find nodes that this entry node dominates cond_subexprs = list ( get_ast_subexprs ( entry_node . reaching_condition ) ) guarded_nodes = None for subexpr in cond_subexprs : guarded_node_candidates = self . _nodes_guarded_by_common_subexpr ( seq , subexpr , entry_node_idx + 1 ) if guarded_nodes is None : guarded_nodes = set ( node_ for _ , node_ , _ in guarded_node_candidates ) else : guarded_nodes = guarded_nodes . intersection ( set ( node_ for _ , node_ , _ in guarded_node_candidates ) ) if guarded_nodes is not None : # keep the topological order of nodes in Sequence node sorted_guarded_nodes = [ node_ for node_ in seq . nodes [ entry_node_idx + 1 : ] if node_ in guarded_nodes ] for node_ in sorted_guarded_nodes : if node_ is not entry_node and node_ . addr not in entry_addrs_set : # fix reaching condition reaching_condition_subexprs = set ( ex for ex in get_ast_subexprs ( node_ . reaching_condition ) ) . difference ( set ( cond_subexprs ) ) new_reaching_condition = claripy . And ( * reaching_condition_subexprs ) new_node = CodeNode ( node_ . node , new_reaching_condition ) case_node . add_node ( new_node ) to_remove . add ( node_ ) # do we have a default node? case_last_stmt = self . cond_proc . get_last_statement ( case_node ) if isinstance ( case_last_stmt , ailment . Stmt . Jump ) : targets = extract_jump_targets ( case_last_stmt ) if len ( targets ) == 1 and targets [ 0 ] == node_b_addr : # jump to the default case is rare - it's more likely that there is no default for this # switch-case struct node_default = None self . _new_sequences . append ( case_node ) cases [ cases_idx ] = case_node return cases , node_default , to_remove