Exemplo n.º 1
0
def _(term, smt):
  x = smt.eval(term.x)

  with smt.local_nonpoison() as ny:
    y = smt.eval(term.y)

  smt.add_defs(y != 0, *ny)

  if 'exact' in term.flags:
    smt.add_nonpoison(z3.UDiv(x,y)*y == x)

  return z3.UDiv(x,y)
Exemplo n.º 2
0
Arquivo: z3eval.py Projeto: ekiwi/irpy
 def udiv(self, ctx, return_type, a, atype, b, btype, nuw=False, nsw=False, exact=False):
     assert atype == return_type
     assert atype == btype
     assert not nuw and not nsw and not exact
     assert util.path_condition_implies(
         ctx, b != z3.BitVecVal(0, btype.size()), print_model=True), "udiv by zero"
     return z3.UDiv(a, b)
Exemplo n.º 3
0
 def UDiv(self, other):
     if isinstance(other, int):
         other = BVV(other, self.size)
     else:
         assert isinstance(other, BV)
         assert self.size == other.size
     return BVExpr(self.size, z3.UDiv(self.z3obj, other.z3obj), self.interval.UDiv(other.interval))
Exemplo n.º 4
0
def sys_map_pcipage(old, pt, index, pcipn, perm):
    cond = z3.And(
        # pt is a valid PT page
        is_pn_valid(pt),
        old.pages[pt].type == dt.page_type.PAGE_TYPE_X86_PT,
        old.pages[pt].owner == old.current,
        z3.ULT(index, 512),

        # pcipn is a valid pci page owned by current
        is_pcipn_valid(pcipn),
        old.pcipages[pcipn].valid,
        old.pci[old.pcipages[pcipn].owner].owner == old.current,

        # perm has no unsafe bits on it and it is present
        perm & (dt.MAX_INT64 ^ dt.PTE_PERM_MASK) == 0,
        perm & dt.PTE_P != 0,

        # slot should be empty
        old.pages[pt].data(index) & dt.PTE_P == 0,
    )

    new = old.copy()

    new.pages[pt].data[index] = ((z3.UDiv(
        dt.PCI_START, util.i64(dt.PAGE_SIZE)) + pcipn) << dt.PTE_PFN_SHIFT) | perm

    # maintain the "shadow" pgtable
    new.pages[pt].pgtable_pn[index] = pcipn
    new.pages[pt].pgtable_perm[index] = perm
    new.pages[pt].pgtable_type[index] = dt.PGTYPE_PCIPAGE

    new.flush_tlb(old.current)

    return cond, util.If(cond, new, old)
Exemplo n.º 5
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = self._idivC(res, arg)
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res - (arg * (self._idivC(res, arg)))
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        elif expr.op == "cnttrailzeros":
            size = expr.size
            src = res
            res = z3.If(src == 0, size, src)
            for i in xrange(size - 1, -1, -1):
                res = z3.If((src & (1 << i)) != 0, i, res)
        elif expr.op == "cntleadzeros":
            size = expr.size
            src = res
            res = z3.If(src == 0, size, src)
            for i in xrange(size, 0, -1):
                index = -i % size
                out = size - (index + 1)
                res = z3.If((src & (1 << index)) != 0, out, res)
        elif expr.op.startswith("zeroExt"):
            arg, = expr.args
            res = z3.ZeroExt(expr.size - arg.size, self.from_expr(arg))
        elif expr.op.startswith("signExt"):
            arg, = expr.args
            res = z3.SignExt(expr.size - arg.size, self.from_expr(arg))
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemplo n.º 6
0
def UDiv(a: BitVec, b: BitVec) -> BitVec:
    """Create an unsigned division expression.

    :param a:
    :param b:
    :return:
    """
    union = a.annotations + b.annotations
    return BitVec(z3.UDiv(a.raw, b.raw), annotations=union)
Exemplo n.º 7
0
 def DIV(self, gstate, a, b):
     a, b = map(svm_utils.convert_to_bitvec, (a, b))
     if self.svm.abs_div and not svm_utils.is_bv_concrete(a) and not svm_utils.is_bv_concrete(b):
         abs_bv = self.svm.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.DIV,
                                                           gstate.wstate.gen,
                                                           unique=True)
         gstate.mstate.stack.append(abs_bv)
     else:
         gstate.mstate.stack.append(z3.UDiv(a, b))
Exemplo n.º 8
0
 def UDiv(self, other):
     if isinstance(other, int):
         other = BVV(other, self.size)
     else:
         assert isinstance(other, BV)
         assert self.size == other.size
     if isinstance(other, BVV):
         return BVV((self.value // other.value) & self._mask, self.size)
     return BVExpr(self.size, z3.UDiv(self.z3obj, other.z3obj), self.interval.UDiv(other.interval))
Exemplo n.º 9
0
 def _idivC(self, num, den):
     """Divide (signed) @num by @den (z3 values) as C would
     See modint.__div__ for implementation choice
     """
     result_sign = z3.If(num * den >= 0,
                         z3.BitVecVal(1, num.size()),
                         z3.BitVecVal(-1, num.size()),
     )
     return z3.UDiv(self._abs(num), self._abs(den)) * result_sign
Exemplo n.º 10
0
def alloc_page_table(old, pid, frm, index, to, perm, from_type, to_type):
    cond = z3.And(
        # The to argument is a valid page and is marked as free
        is_pn_valid(to),
        old.pages[to].type == dt.page_type.PAGE_TYPE_FREE,

        # The pid is valid and is either current running process or child embryo
        is_pid_valid(pid),
        z3.Or(pid == old.current,
              z3.And(
                  old.procs[pid].ppid == old.current,
                  old.procs[pid].state == dt.proc_state.PROC_EMBRYO)),

        # The from parameter is valid and of type PML4 and owned by pid
        is_pn_valid(frm),
        old.pages[frm].owner == pid,
        old.pages[frm].type == from_type,

        # Index is a valid page index
        z3.ULT(index, 512),

        # perm has no unsafe bits on it and it is present
        perm & (dt.MAX_INT64 ^ dt.PTE_PERM_MASK) == 0,
        perm & dt.PTE_P != 0,

        # index does not have the P bit in PML4
        old.pages[frm].data(index) & dt.PTE_P == 0,
    )

    new = old.copy()

    new.pages[to].owner = pid
    new.pages[to].type = to_type

    new.pages[frm].data[index] = (
        (z3.UDiv(new.pages_ptr_to_int, util.i64(dt.PAGE_SIZE)) + to) << dt.PTE_PFN_SHIFT) | perm

    # Zero out the new page
    new.pages[to].data = util.i64(0)

    # Maintain the "shadow" pgtable
    new.pages[frm].pgtable_pn[index] = to
    new.pages[to].pgtable_reverse_pn = frm
    new.pages[to].pgtable_reverse_idx = index

    new.pages[frm].pgtable_perm[index] = perm
    new.pages[frm].pgtable_type[index] = dt.PGTYPE_PAGE

    new.pages[to].pgtable_pn = util.i64(0)
    new.pages[to].pgtable_perm = util.i64(0)
    new.pages[to].pgtable_type = dt.PGTYPE_NONE

    new.procs[pid].nr_pages[to] += 1

    new.flush_tlb(pid)

    return cond, util.If(cond, new, old)
Exemplo n.º 11
0
def ast_to_z3_expression(ast: Union[AstNode, AstLeaf], use_bitvecval=False):
    if not Z3_INSTALLED:
        raise D810Z3Exception("Z3 is not installed")
    if isinstance(ast, AstLeaf):
        if ast.is_constant():
            return z3.BitVecVal(ast.value, 32)
        return ast.z3_var
    if ast.opcode == m_neg:
        return -(ast_to_z3_expression(ast.left, use_bitvecval))
    elif ast.opcode == m_lnot:
        return not (ast_to_z3_expression(ast.left, use_bitvecval))
    elif ast.opcode == m_bnot:
        return ~(ast_to_z3_expression(ast.left, use_bitvecval))
    elif ast.opcode == m_add:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) + (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_sub:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) - (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_mul:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) * (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_udiv:
        return z3.UDiv(ast_to_z3_expression(ast.left, use_bitvecval=True),
                       ast_to_z3_expression(ast.right, use_bitvecval=True))
    elif ast.opcode == m_sdiv:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) / (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_umod:
        return z3.URem(ast_to_z3_expression(ast.left, use_bitvecval),
                       ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_smod:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) % (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_or:
        return (ast_to_z3_expression(ast.left,
                                     use_bitvecval)) | (ast_to_z3_expression(
                                         ast.right, use_bitvecval))
    elif ast.opcode == m_and:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) & (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_xor:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) ^ (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_shl:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) << (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_shr:
        return z3.LShR(ast_to_z3_expression(ast.left, use_bitvecval),
                       ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_sar:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) >> (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode in [m_xdu, m_xds, m_low, m_high]:
        return ast_to_z3_expression(ast.left, use_bitvecval)
    raise D810Z3Exception("Z3 evaluation: Unknown opcode {0} for {1}".format(
        opcode_to_string(ast.opcode), ast))
def sys_map_page(old, pid, frm, index, pa, perm, from_type):
    pfn = z3.UDiv(pa, util.i64(dt.PAGE_SIZE))
    n = pfn - z3.UDiv(old.page_desc_table_ptr_to_int, util.i64(dt.PAGE_SIZE))

    cond = z3.And(
        is_pid_valid(pid),

        # the pid is either current or an embryo belonging to current
        z3.Or(pid == old.current,
              z3.And(
                  old.procs[pid].ppid == old.current,
                  old.procs[pid].state == dt.proc_state.PROC_EMBRYO)),

        # frm is a valid pn of type PT whose owner is pid
        is_pn_valid(frm),
        old.pages[frm].type == from_type,
        old.pages[frm].owner == pid,

        # Index is a valid page index
        z3.ULT(index, 512),

        # perm has no unsafe bits on it and it is present and non-writable
        perm & (dt.MAX_INT64 ^ dt.PTE_PERM_MASK) == 0,
        perm & dt.PTE_P != 0,

        # index does not have the P bit in the from page
        old.pages[frm].data(index) & dt.PTE_P == 0,
    )

    new = old.copy()

    new.pages[frm].data[index] = ((z3.UDiv(
        new.page_desc_table_ptr_to_int, util.i64(dt.PAGE_SIZE)) + n) << dt.PTE_PFN_SHIFT) | perm

    # maintain the "shadow" pgtable
    new.pages[frm].pgtable_pn[index] = n
    new.pages[frm].pgtable_perm[index] = perm
    new.pages[frm].pgtable_type[index] = dt.PGTYPE_PAGE_DESC

    new.flush_tlb(pid)

    return cond, util.If(cond, new, old)
def pgentry2pfn(ks, off, perm, type):
    res = util.i64(0)
    res = util.If(type == dt.PGTYPE_PCIPAGE, util.i64(dt.PCI_START), res)
    res = util.If(type == dt.PGTYPE_IOMMU_FRAME, ks.dmapages_ptr_to_int, res)
    res = util.If(type == dt.PGTYPE_DEVICES, ks.devices_ptr_to_int, res)
    res = util.If(type == dt.PGTYPE_FILE_TABLE, ks.file_table_ptr_to_int, res)
    res = util.If(type == dt.PGTYPE_PAGE_DESC, ks.page_desc_table_ptr_to_int,
                  res)
    res = util.If(type == dt.PGTYPE_PROC, ks.proc_table_ptr_to_int, res)
    res = util.If(type == dt.PGTYPE_PAGE, ks.pages_ptr_to_int, res)
    return ((z3.UDiv(res, util.i64(dt.PAGE_SIZE)) + off) <<
            dt.PTE_PFN_SHIFT) | perm
Exemplo n.º 14
0
def sys_ack_intr(old, vector):
    cond = z3.BoolVal(True)

    new = old.copy()

    vector = z3.ZeroExt(64 - vector.size(), vector)
    idx = z3.UDiv(vector, 64)
    mask = 1 << (vector % 64)

    new.procs[new.current].intr[idx] = new.procs[new.current].intr(idx) & ~mask

    return cond, new
Exemplo n.º 15
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "a<<":
                    res = res << arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = res / arg
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res % arg
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        elif expr.op == "bsf":
            size = expr.size
            src = res
            res = z3.If((src & (1 << (size - 1))) != 0, size - 1, src)
            for i in xrange(size - 2, -1, -1):
                res = z3.If((src & (1 << i)) != 0, i, res)
        elif expr.op == "bsr":
            size = expr.size
            src = res
            res = z3.If((src & 1) != 0, 0, src)
            for i in xrange(size - 1, 0, -1):
                index = -i % size
                res = z3.If((src & (1 << index)) != 0, index, res)
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemplo n.º 16
0
def sys_protect_frame(old, pt, index, frame, perm):
    cond = z3.And(
        is_pn_valid(pt),
        old.pages[pt].type == dt.page_type.PAGE_TYPE_X86_PT,
        old.pages[pt].owner == old.current,

        # Index is a valid page index
        z3.ULT(index, 512),

        is_pn_valid(frame),
        old.pages[frame].type == dt.page_type.PAGE_TYPE_FRAME,
        old.pages[frame].owner == old.current,

        # index must be preset
        old.pages[pt].data(index) & dt.PTE_P != 0,

        # the entry in the pt must be the frame
        z3.Extract(63, 40, z3.UDiv(old.pages_ptr_to_int,
                                   util.i64(dt.PAGE_SIZE)) + frame) == z3.BitVecVal(0, 24),
        z3.Extract(39, 0, z3.UDiv(old.pages_ptr_to_int, util.i64(
            dt.PAGE_SIZE)) + frame) == z3.Extract(51, 12, old.pages[pt].data(index)),

        # no unsafe bits in perm is set
        perm & (dt.MAX_INT64 ^ dt.PTE_PERM_MASK) == 0,

        # P bit is set in perm
        perm & dt.PTE_P != 0
    )

    new = old.copy()

    new.pages[pt].data[index] = (
        (z3.UDiv(new.pages_ptr_to_int, util.i64(dt.PAGE_SIZE)) + frame) << dt.PTE_PFN_SHIFT) | perm

    # The only thing that changed is the permission.
    new.pages[pt].pgtable_perm[index] = perm

    new.flush_tlb(old.current)

    return cond, util.If(cond, new, old)
Exemplo n.º 17
0
 def _sdivC(self, num_expr, den_expr):
     """Divide (signed) @num by @den (Expr) as C would
     See modint.__div__ for implementation choice
     """
     num, den = self.from_expr(num_expr), self.from_expr(den_expr)
     num_s = self.from_expr(num_expr.signExtend(num_expr.size * 2))
     den_s = self.from_expr(den_expr.signExtend(den_expr.size * 2))
     result_sign = z3.If(
         num_s * den_s >= 0,
         z3.BitVecVal(1, num.size()),
         z3.BitVecVal(-1, num.size()),
     )
     return z3.UDiv(self._abs(num), self._abs(den)) * result_sign
Exemplo n.º 18
0
def free_page_table_page(old, frm, index, to, from_type, to_type):
    cond = z3.And(
        # The frm pn has the correct type and owned by current
        is_pn_valid(frm),
        old.pages[frm].type == from_type,
        old.pages[frm].owner == old.current,

        # Index is a valid page index
        z3.ULT(index, 512),

        # The to pn has the correct type and owned by current
        is_pn_valid(to),
        old.pages[to].type == to_type,
        old.pages[to].owner == old.current,

        # index does have the P bit in the from page
        old.pages[frm].data(index) & dt.PTE_P != 0,

        # The current pgtable entry matches to...
        z3.Extract(63, 40, z3.UDiv(old.pages_ptr_to_int,
                                   util.i64(dt.PAGE_SIZE)) + to) == z3.BitVecVal(0, 24),
        z3.Extract(39, 0, z3.UDiv(old.pages_ptr_to_int, util.i64(
            dt.PAGE_SIZE)) + to) == z3.Extract(51, 12, old.pages[frm].data(index)),
    )

    new = old.copy()

    new.pages[frm].data[index] = util.i64(0)

    new.pages[to].owner = z3.BitVecVal(0, dt.pid_t)
    new.pages[to].type = dt.page_type.PAGE_TYPE_FREE

    new.procs[old.current].nr_pages[to] -= 1

    new.flush_tlb(old.current)

    return cond, util.If(cond, new, old)
Exemplo n.º 19
0
    def initial(self, instance):
        def trim(var, type):
            if var.size() == type.size():
                return var
            return z3.Extract(type.size() - 1, 0, var)
        def extend(var):
            if var.size() < self.get_types()[-1].size():
                v = z3.ZeroExt(self.get_types()[2].size() - var.size(), var)
                return v
            return var

        ref = instance._fields[self._name][0]
        perm1 = lambda fn, idx: trim(z3.UDiv(idx, 16) + 1 , type=self.get_types()[1][0])
        perm2 = lambda fn, idx: trim(z3.URem(idx, 16), type=self.get_types()[1][1])
        perm_inv = lambda fn, owned1, owned2: extend(owned1 - 1) * 16 + extend(owned2 % 16)
        instance._fields[self._name] = (ref, perm1, perm2, perm_inv)
Exemplo n.º 20
0
def extintr(old, vector):
    pid = old.vectors[vector].owner
    cond = is_pid_valid(pid)
    cond2 = z3.And(cond, old.procs[pid].state == dt.proc_state.PROC_SLEEPING)

    vector = z3.ZeroExt(64 - vector.size(), vector)
    idx = z3.UDiv(vector, 64)
    mask = 1 << (vector % 64)

    new = old.copy()
    new.procs[pid].intr[idx] = new.procs[pid].intr(idx) | mask

    new2 = new.copy()
    new2.procs[pid].state = dt.proc_state.PROC_RUNNABLE
    new2.procs[pid].ipc_from = z3.BitVecVal(0, dt.pid_t)
    new2.procs[pid].ipc_val = vector
    new2.procs[pid].ipc_size = z3.BitVecVal(0, dt.size_t)

    return cond, util.If(cond, util.If(cond2, new2, new), old)
Exemplo n.º 21
0
def sys_map_pml4(old, pid, index, perm):

    cond = z3.And(
        is_pid_valid(pid),

        # the pid is either current or an embryo belonging to current
        z3.Or(pid == old.current,
              z3.And(
                  old.procs[pid].ppid == old.current,
                  old.procs[pid].state == dt.proc_state.PROC_EMBRYO)),

        # Index is a valid page index
        z3.ULT(index, 512),

        # perm has no unsafe bits on it and it is present and non-writable
        perm & (dt.MAX_INT64 ^ dt.PTE_PERM_MASK) == 0,
        perm & dt.PTE_P != 0,
        perm & dt.PTE_W == 0,

        # index does not have the P bit in the page table root at that index
        old.pages[old.procs[pid].page_table_root].data(
            index) & dt.PTE_P == 0,
    )

    new = old.copy()

    frm = old.procs[pid].page_table_root

    new.pages[frm].data[index] = (
        (z3.UDiv(new.pages_ptr_to_int, util.i64(dt.PAGE_SIZE)) + frm) << dt.PTE_PFN_SHIFT) | perm

    # maintain the "shadow" pgtable
    new.pages[frm].pgtable_pn[index] = frm
    new.pages[frm].pgtable_perm[index] = perm
    new.pages[frm].pgtable_type[index] = dt.PGTYPE_PAGE

    new.pages[frm].pgtable_reverse_pn = frm
    new.pages[frm].pgtable_reverse_idx = index

    new.flush_tlb(pid)

    return cond, util.If(cond, new, old)
Exemplo n.º 22
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "a<<":
                    res = res << arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = res / arg
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res % arg
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemplo n.º 23
0
def sys_alloc_port(old, port):
    cond = z3.And(
        old.io[port].owner == 0,
        old.procs[old.current].use_io_bitmap,
    )

    new = old.copy()

    new.io[port].owner = old.current
    new.procs[old.current].nr_ports[port] += 1

    page = util.If(z3.ULT(port, 0x8000),
            new.procs[new.current].io_bitmap_a,
            new.procs[new.current].io_bitmap_b)

    port = z3.ZeroExt(64 - port.size(), util.If(z3.ULT(port, 0x8000), port, port - 0x8000))

    idx = z3.UDiv(port, 64)
    mask = 1 << (port % 64)

    new.pages[page].data[idx] = new.pages[page].data(idx) & ~mask

    return cond, util.If(cond, new, old)
Exemplo n.º 24
0
def sys_map_iommu_frame(old, pt, index, to, perm):
    cond = z3.And(
        # to is a valid IOMMU_FRAME owned by current
        is_dmapn_valid(to),
        old.dmapages[to].type == dt.page_type.PAGE_TYPE_IOMMU_FRAME,
        old.dmapages[to].owner == old.current,

        # pt is a valid X86_PT page owned by current
        is_pn_valid(pt),
        old.pages[pt].type == dt.page_type.PAGE_TYPE_X86_PT,
        old.pages[pt].owner == old.current,

        # Index valid
        z3.ULT(index, 512),

        # permissions contain no unsafe bits
        perm & (dt.MAX_INT64 ^ dt.PTE_PERM_MASK) == 0,
        perm & dt.PTE_P != 0,


        # index slot is unused in pt
        old.pages[pt].data(index) & dt.PTE_P == 0,
    )

    new = old.copy()

    new.pages[pt].data[index] = (
        (z3.UDiv(new.dmapages_ptr_to_int, util.i64(dt.PAGE_SIZE)) + to) << dt.PTE_PFN_SHIFT) | perm

    new.pages[pt].pgtable_pn[index] = to
    new.pages[pt].pgtable_perm[index] = perm
    new.pages[pt].pgtable_type[index] = dt.PGTYPE_IOMMU_FRAME

    new.flush_tlb(old.current)

    return cond, util.If(cond, new, old)
Exemplo n.º 25
0
b = z3.BitVec('b', 32)

## Compute the average of a and b.  The initial computation we provided
## naively adds them and divides by two, but that is not correct.  Modify
## these lines to implement your solution for both unsigned (u_avg) and
## signed (s_avg) division.
##
## Watch out for the difference between signed and unsigned integer
## operations.  For example, the Z3 expression (x/2) performs signed
## division, meaning it treats the 32-bit value as a signed integer.
## Similarly, (x>>16) shifts x by 16 bits to the right, treating it
## as a signed integer.
##
## Use z3.UDiv(x, y) for unsigned division of x by y.
## Use z3.LShR(x, y) for unsigned (logical) right shift of x by y bits.
u_avg = z3.UDiv(a + b, 2)
s_avg = (a + b) / 2

## Do not change the code below.
# u_avg = a|b-(z3.LShR(a^b, 1)) failed!

# first div each integer,also with remainder,finally plus them
u_avg = z3.UDiv(a, 2) + z3.UDiv(b, 2) + (a % 2 + b % 2) / 2
# approach2: from hack's delight
u_avg = (a & b) + z3.LShR((a ^ b), 1)

#failed!
#s_avg = a/2 + b/2 + (((-1)*(a%2) if (a>>31==1) else (a%2))+((-1)*(b%2) if (b>>31==1) else (b%2)))/2
#s_avg = a/2 + b/2 + (a>>31+b>>31)/2

# from hack's delight again
Exemplo n.º 26
0
 def walk_bv_udiv(self, formula, args, **kwargs):
     return z3.UDiv(args[0], args[1])
b = z3.BitVec('b', 32)

## Compute the average of a and b.  The initial computation we provided
## naively adds them and divides by two, but that is not correct.  Modify
## these lines to implement your solution for both unsigned (u_avg) and
## signed (s_avg) division.
##
## Watch out for the difference between signed and unsigned integer
## operations.  For example, the Z3 expression (x/2) performs signed
## division, meaning it treats the 32-bit value as a signed integer.
## Similarly, (x>>16) shifts x by 16 bits to the right, treating it
## as a signed integer.
##
## Use z3.UDiv(x, y) for unsigned division of x by y.
## Use z3.LShR(x, y) for unsigned (logical) right shift of x by y bits.
u_avg = z3.UDiv(a + b, 2)
s_avg = (a + b) / 2

## Do not change the code below.

## To compute the reference answers, we extend both a and b by one
## more bit (to 33 bits), add them, divide by two, and shrink back
## down to 32 bits.  You are not allowed to "cheat" in this way in
## your answer.
az33 = z3.ZeroExt(1, a)
bz33 = z3.ZeroExt(1, b)
real_u_avg = z3.Extract(31, 0, z3.UDiv(az33 + bz33, 2))

as33 = z3.SignExt(1, a)
bs33 = z3.SignExt(1, b)
real_s_avg = z3.Extract(31, 0, (as33 + bs33) / 2)
Exemplo n.º 28
0
b = z3.BitVec('b', 32)

## Compute the average of a and b.  The initial computation we provided
## naively adds them and divides by two, but that is not correct.  Modify
## these lines to implement your solution for both unsigned (u_avg) and
## signed (s_avg) division.
##
## Watch out for the difference between signed and unsigned integer
## operations.  For example, the Z3 expression (x/2) performs signed
## division, meaning it treats the 32-bit value as a signed integer.
## Similarly, (x>>16) shifts x by 16 bits to the right, treating it
## as a signed integer.
##
## Use z3.UDiv(x, y) for unsigned division of x by y.
## Use z3.LShR(x, y) for unsigned (logical) right shift of x by y bits.
u_avg = z3.UDiv(a, 2) + z3.UDiv(b, 2) + (a & b & 1)
s_avg = (a + b) / 2

## Do not change the code below.

## To compute the reference answers, we extend both a and b by one
## more bit (to 33 bits), add them, divide by two, and shrink back
## down to 32 bits.  You are not allowed to "cheat" in this way in
## your answer.
az33 = z3.ZeroExt(1, a)
bz33 = z3.ZeroExt(1, b)
real_u_avg = z3.Extract(31, 0, z3.UDiv(az33 + bz33, 2))

as33 = z3.SignExt(1, a)
bs33 = z3.SignExt(1, b)
real_s_avg = z3.Extract(31, 0, (as33 + bs33) / 2)
Exemplo n.º 29
0
 def _op_div(a, b):
     return z3.UDiv(a, b)
Exemplo n.º 30
0
 def bvudiv(self, other):
     return type(self)(z3.UDiv(self.value, other.value))