示例#1
0
 def FPV(self, ast, result=None):  #pylint:disable=unused-argument
     val = str(ast.args[0])
     sort = self._convert(ast.args[1])
     if val == 'inf':
         return z3.fpPlusInfinity(sort)
     elif val == '-inf':
         return z3.fpMinusInfinity(sort)
     elif val == '0.0':
         return z3.fpPlusZero(sort)
     elif val == '-0.0':
         return z3.fpMinusZero(sort)
     elif val == 'nan':
         return z3.fpNaN(sort)
     else:
         better_val = str(Decimal(ast.args[0]))
         return z3.FPVal(better_val, sort, ctx=self._context)
示例#2
0
 def FPV(self, ast):
     val = str(ast.args[0])
     sort = self._convert(ast.args[1])
     if val == 'inf':
         return z3.fpPlusInfinity(sort)
     elif val == '-inf':
         return z3.fpMinusInfinity(sort)
     elif val == '0.0':
         return z3.fpPlusZero(sort)
     elif val == '-0.0':
         return z3.fpMinusZero(sort)
     elif val == 'nan':
         return z3.fpNaN(sort)
     else:
         better_val = str(Decimal(ast.args[0]))
         return z3.FPVal(better_val, sort, ctx=self._context)
示例#3
0
 def _convert(self, obj, result=None):
     if type(obj) is NativeBVV:
         return z3.BitVecVal(obj.value, obj.bits)
     elif isinstance(obj, FSort):
         return z3.FPSort(obj.exp, obj.mantissa)
     elif isinstance(obj, RM):
         if obj == RM_RNE:
             return z3.RNE()
         elif obj == RM_RNA:
             return z3.RNA()
         elif obj == RM_RTP:
             return z3.RTP()
         elif obj == RM_RTN:
             return z3.RTN()
         elif obj == RM_RTZ:
             return z3.RTZ()
         else:
             raise BackendError("unrecognized rounding mode")
     elif isinstance(obj, NativeFPV):
         val = str(obj.value)
         sort = self._convert(obj.sort)
         if val == 'inf':
             return z3.fpPlusInfinity(sort)
         elif val == '-inf':
             return z3.fpMinusInfinity(sort)
         elif val == '0.0':
             return z3.fpPlusZero(sort)
         elif val == '-0.0':
             return z3.fpMinusZero(sort)
         elif val == 'nan':
             return z3.fpNaN(sort)
         else:
             better_val = str(Decimal(obj.value))
             return z3.FPVal(better_val, sort)
     elif obj is True:
         return z3.BoolVal(True)
     elif obj is False:
         return z3.BoolVal(False)
     elif type(obj) in (int, long, float, str):
         return obj
     elif hasattr(obj, '__module__') and obj.__module__ == 'z3':
         return obj
     else:
         l.debug("BackendZ3 encountered unexpected type %s", type(obj))
         raise BackendError("unexpected type %s encountered in BackendZ3" %
                            type(obj))
示例#4
0
def prepare_float(val, signext=False, size=SIZE) -> z3.FPRef:
    if z3.is_fp(val):
        return val

    size_class = z3.Float64()
    if size == 32:
        size_class = z3.Float32()
    elif size == 128:
        size_class = z3.Float128()

    if type(val) in (int, float):
        result = z3.FPVal(val)
    else:
        bv_val = prepare(val, signext, size)
        result = z3.fpBVToFP(bv_val, size_class)

    return result
示例#5
0
def prepare_float(val, signext=False, size=SIZE) -> z3.FPRef:

    size_class = fp_size_to_sort(size)

    if z3.is_fp(val):
        result = val
    elif type(val) in (int, float):
        result = z3.FPVal(float(val), size_class)
    else:
        bv_val = z3.simplify(prepare(val, signext, size))
        if bv_val.decl().name() == "fp.to_ieee_bv":
            result = bv_val.arg(0)
        else:
            result = z3.fpToFP(bv_val, size_class)

    if result.sort() != size_class:
        result = z3.fpFPToFP(result, size_class)

    return result
示例#6
0
    def cast(self, value, is_type, to_type):
        if is_type is Types.STRING and isinstance(to_type,
                                                  z3.z3.DatatypeSortRef):
            # the value is a string and it should be cast to a datatyperef
            # (i.e. an enum-type), just return the value because we can deal with it
            return value

        value_is_int = isinstance(value, int)
        value_is_float = isinstance(value, float)

        if is_type is to_type:  # already correct type, just return the value
            return value
            """ INT <---> INTEGER """
        elif is_type is Types.INT and to_type is Types.INTEGER:
            if value_is_int or value_is_float:
                return value  # this happens if it is an int numeral (e.g. 2)
            else:
                return z3.BV2Int(value)
        elif is_type is Types.INTEGER and to_type is Types.INT:
            if value_is_int or value_is_float:
                return value
            else:
                return z3.Int2BV(value, 32)
            """ INT <---> FLOAT """
        elif is_type is Types.FLOAT and to_type is Types.INT:
            if value_is_float:
                return value  # this happens if it is a float numeral (e.g. 3.14)
            else:
                return z3.fpToSBV(z3.RNE(), value, z3.BitVecSort(32))
        elif is_type is Types.INT and to_type is Types.FLOAT:
            if value_is_int:
                return value
            else:
                return z3.fpSignedToFP(z3.RNE(), value, z3.Float32())
            """ INTEGER <---> FLOAT """
        elif is_type is Types.FLOAT and to_type is Types.INTEGER:
            if value_is_float:
                return value  # this happens if it is a float numeral (e.g. 3.14)
            else:
                return self.cast(self.cast(value, Types.FLOAT, Types.INT),
                                 Types.INT, Types.INTEGER)
        elif is_type is Types.INTEGER and to_type is Types.FLOAT:
            if value_is_int:
                return value
            else:
                return self.cast(self.cast(value, Types.INTEGER, Types.INT),
                                 Types.INT, Types.FLOAT)
            """ from REAL """
        elif is_type is Types.REAL and to_type is Types.INTEGER:
            if value_is_float:
                return value
            else:
                return z3.ToInt(value)
        elif is_type is Types.REAL and to_type is Types.INT:
            return self.cast(self.cast(value, Types.REAL, Types.INTEGER),
                             Types.INTEGER, Types.INT)
        elif is_type is Types.REAL and to_type is Types.FLOAT:
            """
            Rounding modes: probably should make these parameterizable!
            roundNearestTiesToEven ... RNE() = default
            roundNearestTiesToAway ... RNA()
            roundTowardPositive ...... RTP()
            roundTowardNegative ...... RTN()
            roundTowardZero .......... RTZ()
            """
            if value_is_int or value_is_float:  # int numeral
                return value
            else:
                return z3.fpRealToFP(z3.RNE(), value, z3.Float32())
            """ to REAL """
        elif is_type is Types.INT and to_type is Types.REAL:
            if value_is_int or value_is_float:  # int numeral
                return value
            else:
                return z3.ToReal(self.cast(value, Types.INT, Types.INTEGER))
        elif is_type is Types.INTEGER and to_type is Types.REAL:
            if value_is_int or value_is_float:  # int numeral
                return value
            else:
                return z3.ToReal(value)
        elif is_type is Types.FLOAT and to_type is Types.REAL:
            if value_is_int or value_is_float:
                return value  # this happens if it is a float numeral (e.g. 3.14)
            else:
                return z3.fpToReal(value)
            """ FROM BOOL conversions """
        elif is_type is Types.BOOL and to_type is Types.INT:
            return z3.If(value, z3.BitVecVal(1, 32), z3.BitVecVal(0, 32))
        elif is_type is Types.BOOL and to_type is Types.INTEGER:
            return z3.If(value, 1, 0)
        elif is_type is Types.BOOL and to_type is Types.REAL:
            return z3.If(value, 1.0, 0.0)
        elif is_type is Types.BOOL and to_type is Types.FLOAT:
            return z3.If(value, z3.FPVal(1.0, z3.Float32()),
                         z3.FPVal(0.0, z3.Float32()))
            """ TO BOOL conversions """
        elif is_type is Types.INT and to_type is Types.BOOL:
            return value == 1
        elif is_type is Types.INTEGER and to_type is Types.BOOL:
            return value == 1
        elif is_type is Types.REAL and to_type is Types.BOOL:
            return value == 1
        elif is_type is Types.FLOAT and to_type is Types.BOOL:
            return value == 1

        raise TypeError(f"Don't know how to cast from {is_type} to {to_type}!")
示例#7
0
from .esilclasses import *
import z3

SIZE = 64
FSIZE = z3.Float64()

ONE = z3.BitVecVal(1, SIZE)
ZERO = z3.BitVecVal(0, SIZE)
NEGONE = z3.BitVecVal(-1, SIZE)

FONE = z3.FPVal(1.0, FSIZE)
FZERO = z3.FPVal(0.0, FSIZE)
FNEGONE = z3.FPVal(-1.0, FSIZE)

INT = 1
FLOAT = 2

FPM = z3.RTZ()


def pop_values(stack,
               state,
               num: int = 1,
               signext=False) -> List[z3.BitVecRef]:
    size = state.esil["size"]
    val_type = state.esil["type"]
    return [
        get_value(stack.pop(), state, signext, size, val_type)
        for i in range(num)
    ]
示例#8
0
def _literal(term, smt):
    ty = smt.type(term)
    if isinstance(ty, FloatType):
        return z3.FPVal(term.val, _ty_sort(ty))

    return z3.BitVecVal(term.val, ty.width)
示例#9
0
# Constants
# ---------


@eval.register(Literal, BaseSMTTranslator)
def _literal(term, smt):
    ty = smt.type(term)
    if isinstance(ty, FloatType):
        return z3.FPVal(term.val, _ty_sort(ty))

    return z3.BitVecVal(term.val, ty.width)


eval.register(FLiteralVal, BaseSMTTranslator,
              lambda term, smt: z3.FPVal(term.val, _ty_sort(smt.type(term))))

eval.register(FLiteralNaN, BaseSMTTranslator,
              lambda term, smt: z3.fpNaN(_ty_sort(smt.type(term))))

eval.register(FLiteralPlusInf, BaseSMTTranslator,
              lambda term, smt: z3.fpPlusInfinity(_ty_sort(smt.type(term))))

eval.register(FLiteralMinusInf, BaseSMTTranslator,
              lambda term, smt: z3.fpMinusInfinity(_ty_sort(smt.type(term))))

eval.register(FLiteralMinusZero, BaseSMTTranslator,
              lambda term, smt: z3.fpMinusZero(_ty_sort(smt.type(term))))


@eval.register(UndefValue, BaseSMTTranslator)
示例#10
0
 def as_z3(self) -> z3.ExprRef:
     return z3.FPVal(self.number)