Ejemplo n.º 1
0
def prepare(val, signext=False, size=SIZE) -> z3.BitVecRef:
    if z3.is_bv(val):
        szdiff = size - val.size()

        if szdiff > 0:
            if signext:
                result = z3.SignExt(szdiff, val)
            else:
                result = z3.ZeroExt(szdiff, val)
        elif szdiff < 0:
            result = z3.Extract(size - 1, 0, val)
        else:
            result = val
    elif type(val) == int:
        result = z3.BitVecVal(val, size)
    elif z3.is_int(val):
        result = z3.Int2BV(val, size)
    elif z3.is_fp(val):
        # changing up this logic to align with r2ghidra impl
        result = z3.fpToIEEEBV(val)
        #result = val
    else:
        result = z3.BitVecVal(val, size)

    #return z3.simplify(result)
    return result
Ejemplo n.º 2
0
def prepare(val, signext=False, size=SIZE) -> z3.BitVecRef:
    if z3.is_bv(val):
        szdiff = size-val.size()
        if szdiff == 0:
            result = val
        elif szdiff > 0:
            if signext:
                result = z3.SignExt(szdiff, val)
            else:
                result = z3.ZeroExt(szdiff, val)
        elif szdiff < 0:
            result = z3.Extract(size-1, 0, val)

    elif isinstance(val, int):
        result = z3.BitVecVal(val, size)
    elif z3.is_int(val):
        result = z3.Int2BV(val, size)
    elif z3.is_fp(val):
        result = z3.fpToIEEEBV(val)
    else:
        result = z3.BitVecVal(val, size)

    if not z3.is_bv_value(result):
        return z3.simplify(result)
    else:
        return result
Ejemplo n.º 3
0
def _(src, tgt, v):
  w = z3.fpToIEEEBV(v)
  i = z3.If(z3.Or(z3.fpIsZero(v), z3.fpIsSubnormal(v)),
    z3.BitVecVal(0,1),
    z3.BitVecVal(1,1))

  return z3.Concat(z3.Extract(78,63,w), i, z3.Extract(62,0,w))
Ejemplo n.º 4
0
def _(src, tgt, v):
  w = z3.fpToIEEEBV(v)
  i = z3.If(z3.Or(z3.fpIsZero(v), z3.fpIsSubnormal(v)),
    z3.BitVecVal(0,1),
    z3.BitVecVal(1,1))

  return z3.Concat(z3.Extract(78,63,w), i, z3.Extract(62,0,w))
Ejemplo n.º 5
0
 def get_bv_str(self):
     bv_str = bin(int(str(z3.simplify(z3.fpToIEEEBV(self.z3_ds)))))
     assert bv_str[0:2] == '0b', bv_str[0:2] + ' vs ' + '0b'
     bv_str = bv_str[2:]
     while len(bv_str) < self.ne + self.ns:
         bv_str = '0' + bv_str
     return bv_str
Ejemplo n.º 6
0
 def pack_f32(n: f32):
     if utils.is_all_real(n):
         float_bytes = struct.pack('<f', n)
         return [float_bytes for float_byte in float_bytes]
     f32_bv = z3.fpToIEEEBV(n)
     return [
         z3.Extract(7, 0, f32_bv),
         z3.Extract(15, 8, f32_bv),
         z3.Extract(23, 16, f32_bv),
         z3.Extract(31, 24, f32_bv)
     ]
Ejemplo n.º 7
0
 def pack_f64(n: f64):
     if utils.is_all_real(n):
         double_bytes = struct.pack('<d', n)
         return [double_byte for double_byte in double_bytes]
     f64_bv = z3.fpToIEEEBV(n)
     return [
         z3.Extract(7, 0, f64_bv),
         z3.Extract(15, 8, f64_bv),
         z3.Extract(23, 16, f64_bv),
         z3.Extract(31, 24, f64_bv),
         z3.Extract(39, 32, f64_bv),
         z3.Extract(47, 40, f64_bv),
         z3.Extract(55, 48, f64_bv),
         z3.Extract(63, 56, f64_bv)
     ]
Ejemplo n.º 8
0
 def _op_raw_fpToIEEEBV(self, x):
     return z3.fpToIEEEBV(x, ctx=self._context)
import z3

# We do float16 because it lets the solver run much faster.  These results
# should generalize to fp32 and fp64, and you can verify this by changing the
# value of FLOAT_TY (and then waiting a while).
FLOAT_TY = z3.Float16

a = z3.FP("a", FLOAT_TY())
b = z3.FP("b", FLOAT_TY())
c = z3.FP("c", FLOAT_TY())

s = z3.Solver()

# C must be a power of 2, i.e. significand bits must all be 0.
s.add(z3.Extract(FLOAT_TY().sbits() - 1, 0, z3.fpToIEEEBV(c)) == 0)

for rm in [z3.RTZ(), z3.RNE()]:
    z3.set_default_rounding_mode(rm)
    before = a * c + b * c
    after = (a + b) * c

    # Check that before == after, allowing that 0 == -0.
    s.add(
        z3.Not(
            z3.Or(
                before == after,  #
                z3.And(z3.fpIsZero(before), z3.fpIsZero(after)))))

    for x in [
        (a * c),
Ejemplo n.º 10
0
def _(src, tgt, v):
  return z3.fpToIEEEBV(v)
Ejemplo n.º 11
0
def f642i64(f: f64) -> i64:
    if utils.is_all_real(f):
        return struct.unpack('<q', struct.pack('<d', f))[0]
    return z3.fpToIEEEBV(f, z3.Float64())
Ejemplo n.º 12
0
def f322i32(f: f32) -> i32:
    if utils.is_all_real(f):
        return struct.unpack('<i', struct.pack('<f', f))[0]
    return z3.fpToIEEEBV(f, z3.Float32())
Ejemplo n.º 13
0
 def _op_raw_fpToIEEEBV(self, x):
     return z3.fpToIEEEBV(x, ctx=self._context)
Ejemplo n.º 14
0
def _(src, tgt, v):
    return z3.fpToIEEEBV(v)
Ejemplo n.º 15
0
def do_F2I(op, stack, state):
    val, = pop_values(stack, state)
    stack.append(z3.fpToIEEEBV(val))
from __future__ import print_function
import z3

# We do float16 because it lets the solver run much faster.  These results
# should generalize to fp32 and fp64, and you can verify this by changing the
# value of FLOAT_TY (and then waiting a while).
FLOAT_TY = z3.Float16

a = z3.FP("a", FLOAT_TY())
b = z3.FP("b", FLOAT_TY())
c = z3.FP("c", FLOAT_TY())

s = z3.Solver()

# C must be a power of 2, i.e. significand bits must all be 0.
s.add(z3.Extract(FLOAT_TY().sbits() - 1, 0, z3.fpToIEEEBV(c)) == 0)

for rm in [z3.RTZ(), z3.RNE()]:
  z3.set_default_rounding_mode(rm)
  before = a * c + b * c
  after = (a + b) * c

  # Check that before == after, allowing that 0 == -0.
  s.add(
      z3.Not(
          z3.Or(
              before == after,  #
              z3.And(z3.fpIsZero(before), z3.fpIsZero(after)))))

  for x in [
      (a * c),
Ejemplo n.º 17
0
def interp(tree, lookup, z3_mode):
    """Evaluate the arithmetic expression.

    Pass a tree as a Lark `Tree` object for the parsed expression. For
    `lookup`, provide a function for mapping variable names to values.
    """

    op = tree.data
    if op in ('add', 'sub', 'mul', 'div', 'shl', 'shr'):  # Binary operators.
        lhs = interp(tree.children[0], lookup, z3_mode)
        rhs = interp(tree.children[1], lookup, z3_mode)
        if op == 'add':
            return lhs + rhs
        elif op == 'sub':
            return lhs - rhs
        elif op == 'mul':
            return lhs * rhs
        elif op == 'div':
            return lhs / rhs
        elif op == 'shl':
            return lhs << rhs
        elif op == 'shr':
            return lhs >> rhs
    elif op == 'neg':  # Negation.
        sub = interp(tree.children[0], lookup, z3_mode)
        return -sub
    elif op == 'int':  # Literal number.
        if z3_mode:
            return z3.BitVecVal(int(tree.children[0]), 32)
        else:
            return int(tree.children[0])
    elif op == 'float':  # Literal number.
        if z3_mode:
            return z3.BitVecVal(float(tree.children[0]), 32)
        else:
            return float(tree.children[0])
    elif op == 'var':  # Variable lookup.
        return lookup(tree.children[0])
    elif op == 'if':  # Conditional.
        cond = interp(tree.children[0], lookup, z3_mode)
        true = interp(tree.children[1], lookup, z3_mode)
        false = interp(tree.children[2], lookup, z3_mode)
        return (cond != 0) * true + (cond == 0) * false
    elif op == "intcast":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.BV2Int(child)
        else:
            return int(child)
    elif op == "floatcast":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.fpBVToFP(child, z3.Float32())
        else:
            return float(child)
    elif op == "int2bv":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.Int2BV(child, 32)
        else:
            return child
    elif op == "float2bv":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.fpToIEEEBV(child)
        else:
            return child