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")
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")
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