(self, b: Blade, stmt_loc: Tuple[int,int])
return ite_stmt, ite_stmt_loc, stmts_to_remove
Find the location of the final ITE statement that loads indirect jump targets into a tmp.

        The slice looks like the following:

               IRSB 0x41d0fc
          00 | ------ IMark(0x41d0fc, 4, 0) ------
        + 01 | t0 = GET:I32(r5)
        + 02 | t2 = Sub32(t0,0x00000022)
          03 | PUT(r3) = t2
          04 | ------ IMark(0x41d100, 4, 0) ------
          05 | PUT(cc_op) = 0x00000002
          06 | PUT(cc_dep1) = t2
          07 | PUT(cc_dep2) = 0x0000001c
          08 | PUT(cc_ndep) = 0x00000000
          09 | ------ IMark(0x41d104, 4, 0) ------
        + 10 | t25 = CmpLE32U(t2,0x0000001c)
          11 | t24 = 1Uto32(t25)
        + 12 | t8 = Shl32(t2,0x02)
        + 13 | t10 = Add32(0x0041d10c,t8)
        + 14 | t26 = ITE(t25,t10,0x0041d104)    <---- this is the statement that we are looking for. Note that
                                                      0x0041d104 *must* be ignored since it is a side effect generated
                                                      by the VEX ARM lifter
          15 | PUT(pc) = t26
          16 | t21 = Xor32(t24,0x00000001)
          17 | t27 = 32to1(t21)
          18 | if (t27) { PUT(offset=68) = 0x41d108; Ijk_Boring }
        + Next: t26

        :param b:           The Blade instance, which comes with the slice.
        :param stmt_loc:    The location of the final statement.
        :return:
Find the location of the final ITE statement that loads indirect jump targets into a tmp.
Find the location of the final ITE statement that loads indirect jump targets into a tmp .
def _find_load_pc_ite_statement(self, b: Blade, stmt_loc: Tuple[int,int]):
        """
        Find the location of the final ITE statement that loads indirect jump targets into a tmp.

        The slice looks like the following:

               IRSB 0x41d0fc
          00 | ------ IMark(0x41d0fc, 4, 0) ------
        + 01 | t0 = GET:I32(r5)
        + 02 | t2 = Sub32(t0,0x00000022)
          03 | PUT(r3) = t2
          04 | ------ IMark(0x41d100, 4, 0) ------
          05 | PUT(cc_op) = 0x00000002
          06 | PUT(cc_dep1) = t2
          07 | PUT(cc_dep2) = 0x0000001c
          08 | PUT(cc_ndep) = 0x00000000
          09 | ------ IMark(0x41d104, 4, 0) ------
        + 10 | t25 = CmpLE32U(t2,0x0000001c)
          11 | t24 = 1Uto32(t25)
        + 12 | t8 = Shl32(t2,0x02)
        + 13 | t10 = Add32(0x0041d10c,t8)
        + 14 | t26 = ITE(t25,t10,0x0041d104)    <---- this is the statement that we are looking for. Note that
                                                      0x0041d104 *must* be ignored since it is a side effect generated
                                                      by the VEX ARM lifter
          15 | PUT(pc) = t26
          16 | t21 = Xor32(t24,0x00000001)
          17 | t27 = 32to1(t21)
          18 | if (t27) { PUT(offset=68) = 0x41d108; Ijk_Boring }
        + Next: t26

        :param b:           The Blade instance, which comes with the slice.
        :param stmt_loc:    The location of the final statement.
        :return:
        """

        project = self.project
        ite_stmt, ite_stmt_loc = None, None
        stmts_to_remove = [stmt_loc]

        while True:
            preds = list(b.slice.predecessors(stmt_loc))
            if len(preds) != 1:
                break
            block_addr, stmt_idx = stmt_loc = preds[0]
            stmts_to_remove.append(stmt_loc)
            block = project.factory.block(block_addr, cross_insn_opt=True).vex
            if stmt_idx == DEFAULT_STATEMENT:
                # we should not reach the default exit (which belongs to a predecessor block)
                break
            if not isinstance(block.next, pyvex.IRExpr.RdTmp):
                # next must be an RdTmp
                break
            stmt = block.statements[stmt_idx]
            if isinstance(stmt, pyvex.IRStmt.WrTmp) and stmt.tmp == block.next.tmp and \
                    isinstance(stmt.data, pyvex.IRExpr.ITE):
                # yes!
                ite_stmt, ite_stmt_loc = stmt, stmt_loc
                break

        return ite_stmt, ite_stmt_loc, stmts_to_remove
def _find_load_pc_ite_statement ( self , b : Blade , stmt_loc : Tuple [ int , int ] ) : project = self . project ite_stmt , ite_stmt_loc = None , None stmts_to_remove = [ stmt_loc ] while True : preds = list ( b . slice . predecessors ( stmt_loc ) ) if len ( preds ) != 1 : break block_addr , stmt_idx = stmt_loc = preds [ 0 ] stmts_to_remove . append ( stmt_loc ) block = project . factory . block ( block_addr , cross_insn_opt = True ) . vex if stmt_idx == DEFAULT_STATEMENT : # we should not reach the default exit (which belongs to a predecessor block) break if not isinstance ( block . next , pyvex . IRExpr . RdTmp ) : # next must be an RdTmp break stmt = block . statements [ stmt_idx ] if isinstance ( stmt , pyvex . IRStmt . WrTmp ) and stmt . tmp == block . next . tmp and isinstance ( stmt . data , pyvex . IRExpr . ITE ) : # yes! ite_stmt , ite_stmt_loc = stmt , stmt_loc break return ite_stmt , ite_stmt_loc , stmts_to_remove