Пример #1
0
 def _abstract_fp_val(self, ctx, ast, op_name):
     if op_name == 'FPVal':
         # TODO: do better than this
         fp_mantissa = float(z3.Z3_fpa_get_numeral_significand_string(ctx, ast))
         fp_exp = int(z3.Z3_fpa_get_numeral_exponent_string(ctx, ast, False))
         fp_sign_c = ctypes.c_int()
         z3.Z3_fpa_get_numeral_sign(ctx, ast, ctypes.byref(fp_sign_c))
         fp_sign = -1 if fp_sign_c.value != 0 else 1
         value = fp_sign * fp_mantissa * (2 ** fp_exp)
         return value
     elif op_name == 'MinusZero':
         return -0.0
     elif op_name == 'MinusInf':
         return float('-inf')
     elif op_name == 'PlusZero':
         return 0.0
     elif op_name == 'PlusInf':
         return float('inf')
     elif op_name == 'NaN':
         return float('nan')
     else:
         raise BackendError("Called _abstract_fp_val with unknown type")
Пример #2
0
    def _abstract_to_primitive(ctx, ast):
        decl = z3.Z3_get_app_decl(ctx, ast)
        decl_num = z3.Z3_get_decl_kind(ctx, decl)

        if decl_num not in z3_op_nums:
            raise ClaripyError("unknown decl kind %d" % decl_num)
        if z3_op_nums[decl_num] not in op_map:
            raise ClaripyError("unknown decl op %s" % z3_op_nums[decl_num])
        op_name = op_map[z3_op_nums[decl_num]]

        if op_name == 'BitVecVal':
            return long(z3.Z3_get_numeral_string(ctx, ast))
        elif op_name == 'FPVal':
            # this is really imprecise
            fp_mantissa = float(z3.Z3_fpa_get_numeral_significand_string(ctx, ast))
            fp_exp = long(z3.Z3_fpa_get_numeral_exponent_string(ctx, ast))
            return fp_mantissa * (2 ** fp_exp)
        elif op_name == 'True':
            return True
        elif op_name == 'False':
            return False
        else:
            raise BackendError("Unable to abstract Z3 object to primitive")
Пример #3
0
    def _abstract_internal(self, ctx, ast, split_on=None):
        h = self._z3_ast_hash(ctx, ast)
        try:
            return self._ast_cache[h]
        except KeyError:
            pass

        decl = z3.Z3_get_app_decl(ctx, ast)
        decl_num = z3.Z3_get_decl_kind(ctx, decl)
        z3_sort = z3.Z3_get_sort(ctx, ast)

        if decl_num not in z3_op_nums:
            raise ClaripyError("unknown decl kind %d" % decl_num)
        if z3_op_nums[decl_num] not in op_map:
            raise ClaripyError("unknown decl op %s" % z3_op_nums[decl_num])
        op_name = op_map[z3_op_nums[decl_num]]

        num_args = z3.Z3_get_app_num_args(ctx, ast)
        split_on = self._split_on if split_on is None else split_on
        new_split_on = split_on if op_name in split_on else set()
        children = [ self._abstract_internal(ctx, z3.Z3_get_app_arg(ctx, ast, i), new_split_on) for i in range(num_args) ]

        append_children = True

        if op_name == 'True':
            return BoolI(True)
        elif op_name == 'False':
            return BoolI(False)
        elif op_name.startswith('RM_'):
            return RM.from_name(op_name)
        elif op_name == 'BitVecVal':
            bv_num = long(z3.Z3_get_numeral_string(ctx, ast))
            bv_size = z3.Z3_get_bv_sort_size(ctx, z3_sort)
            return BVI(NativeBVV(bv_num, bv_size), length=bv_size)
        elif op_name == 'FPVal':
            # this is really imprecise
            fp_mantissa = float(z3.Z3_fpa_get_numeral_significand_string(ctx, ast))
            fp_exp = long(z3.Z3_fpa_get_numeral_exponent_string(ctx, ast))
            value = fp_mantissa * (2 ** fp_exp)

            ebits = z3.Z3_fpa_get_ebits(ctx, z3_sort)
            sbits = z3.Z3_fpa_get_sbits(ctx, z3_sort)
            sort = FSort.from_params(ebits, sbits)

            return FPI(NativeFPV(value, sort))
        elif op_name in ('MinusZero', 'MinusInf', 'PlusZero', 'PlusInf', 'NaN'):
            ebits = z3.Z3_fpa_get_ebits(ctx, z3_sort)
            sbits = z3.Z3_fpa_get_sbits(ctx, z3_sort)
            sort = FSort.from_params(ebits, sbits)

            if op_name == 'MinusZero':
                return FPI(NativeFPV(-0.0, sort))
            elif op_name == 'MinusInf':
                return FPI(NativeFPV(float('-inf'), sort))
            elif op_name == 'PlusZero':
                return FPI(NativeFPV(0.0, sort))
            elif op_name == 'PlusInf':
                return FPI(NativeFPV(float('inf'), sort))
            elif op_name == 'NaN':
                return FPI(NativeFPV(float('nan'), sort))
        elif op_name == 'UNINTERPRETED': # this *might* be a BitVec ;-)
            bv_name = z3.Z3_get_symbol_string(ctx, z3.Z3_get_decl_name(ctx, decl))
            bv_size = z3.Z3_get_bv_sort_size(ctx, z3_sort)

            #if bv_name.count('_') < 2:
            #      import ipdb; ipdb.set_trace()
            return BV("BitVec", (bv_name, bv_size), length=bv_size, variables={ bv_name }, symbolic=True)
        elif op_name == 'Extract':
            hi = z3.Z3_get_decl_int_parameter(ctx, decl, 0)
            lo = z3.Z3_get_decl_int_parameter(ctx, decl, 1)
            args = [ hi, lo ]
        elif op_name in ('SignExt', 'ZeroExt'):
            num = z3.Z3_get_decl_int_parameter(ctx, decl, 0)
            args = [ num ]
        elif op_name in ('fpToFP', 'fpToFPSigned'):
            exp = z3.Z3_fpa_get_ebits(ctx, z3_sort)
            mantissa = z3.Z3_fpa_get_sbits(ctx, z3_sort)
            sort = FSort.from_params(exp, mantissa)
            args = children + [sort]
            append_children = False
        elif op_name in ('fpToSBV', 'fpToUBV'):
            # uuuuuugggggghhhhhh
            bv_size = z3.Z3_get_bv_sort_size(ctx, z3_sort)
            args = children + [bv_size]
            append_children = False
        else:
            args = [ ]

        if append_children:
            args.extend(children)

        # fix up many-arg __add__
        if op_name in bin_ops and len(args) > 2:
            many_args = args #pylint:disable=unused-variable
            last = args[-1]
            rest = args[:-1]

            a = args[0].make_like(op_name, rest[:2])
            for b in rest[2:]:
                a = args[0].make_like(op_name, [a,b])
            args = [ a, last ]

        # hmm.... honestly not sure what to do here
        result_ty = op_type_map[z3_op_nums[decl_num]]
        ty = type(args[-1])

        if op_name == 'If':
            # If is polymorphic and thus must be handled specially
            ty = type(args[1])

            a = ty('If', tuple(args), length=args[1].length)
        else:
            if hasattr(ty, op_name) or hasattr(_all_operations, op_name):
                op = getattr(ty if hasattr(ty, op_name) else _all_operations, op_name)
                if op.calc_length is not None:
                    length = op.calc_length(*args)
                    a = result_ty(op_name, tuple(args), length=length)
                else:
                    a = result_ty(op_name, tuple(args))
            else:
                a = result_ty(op_name, tuple(args))

        self._ast_cache[h] = a
        return a