예제 #1
0
 def visit_float_is_infinite(self, e):
     arg = e.arg(0)
     self._check_fp_sort(arg)
     arg_sort = arg.sort()
     pos_inf = None
     neg_inf = None
     if self._is_float32_sort(arg_sort):
         pos_inf = z3.fpPlusInfinity(z3.Float32())
         neg_inf = z3.fpMinusInfinity(z3.Float32())
     elif self._is_float64_sort(arg_sort):
         pos_inf = z3.fpPlusInfinity(z3.Float64())
         neg_inf = z3.fpMinusInfinity(z3.Float64())
     else:
         raise CoralPrinterException('Unhandled fp.isInfinite op case')
     temp = z3.Or(z3.fpEQ(arg, pos_inf), z3.fpEQ(arg, neg_inf))
     self.visit(temp)
예제 #2
0
    def _float_binary_operator(self, term, op):
        logger.debug('_fbo: %s\n%s', term, self.attrs[term])
        x = self.eval(term.x)
        y = self.eval(term.y)
        z = op(x, y)

        conds = []
        if 'nnan' in self.attrs[term]:
            df = z3.And(z3.Not(z3.fpIsNaN(x)), z3.Not(z3.fpIsNaN(y)),
                        z3.Not(z3.fpIsNaN(z)))
            conds.append(z3.Implies(self.attrs[term]['nnan'], df))

        elif 'nnan' in term.flags:
            conds += [
                z3.Not(z3.fpIsNaN(x)),
                z3.Not(z3.fpIsNaN(y)),
                z3.Not(z3.fpIsNaN(z))
            ]

        if 'ninf' in self.attrs[term]:
            df = z3.And(z3.Not(z3.fpIsInf(x)), z3.Not(z3.fpIsInf(y)),
                        z3.Not(z3.fpIsInf(z)))
            conds.append(z3.Implies(self.attrs[term]['ninf'], df))

        elif 'ninf' in term.flags:
            conds += [
                z3.Not(z3.fpIsInf(x)),
                z3.Not(z3.fpIsInf(y)),
                z3.Not(z3.fpIsInf(z))
            ]

        if 'nsz' in self.attrs[term] or 'nsz' in term.flags:
            # NOTE: this will return a different qvar for each (in)direct reference
            # to this term. Is this desirable?
            b = self.fresh_bool()
            self.add_qvar(b)
            z = op(x, y)

            c = z3.fpIsZero(z)
            if 'nsz' in self.attrs[term]:
                c = z3.And(self.attrs[term]['nsz'], c)

            s = _ty_sort(self.type(term))
            z = z3.If(c, z3.If(b, 0, z3.fpMinusZero(s)), z)

            if isinstance(term, FDivInst):
                c = [z3.Not(z3.fpIsZero(x)), z3.fpIsZero(y)]
                if 'nsz' in self.attrs[term]:
                    c.append(self.attrs[term]['nsz'])

                z = z3.If(
                    z3.And(c),
                    z3.If(b, z3.fpPlusInfinity(s), z3.fpMinusInfinity(s)), z)

        return self._conditional_value(conds, z, term.name)
예제 #3
0
 def visit_float_is_normal(self, e):
     arg = e.arg(0)
     self._check_fp_sort(arg)
     arg_sort = e.arg(0).sort()
     smallest_positive_normal = self._get_smallest_positive_normal_for(
         arg_sort)
     largest_negative_normal = self._get_largest_negative_normal_for(
         arg_sort)
     temp = z3.Or(
         z3.And(z3.fpGEQ(arg, smallest_positive_normal),
                z3.fpLT(arg, z3.fpPlusInfinity(arg_sort))),
         z3.And(z3.fpLEQ(arg, largest_negative_normal),
                z3.fpGT(arg, z3.fpMinusInfinity(arg_sort))))
     self.visit(temp)
예제 #4
0
  def _float_binary_operator(self, term, op):
    logger.debug('_fbo: %s\n%s', term, self.attrs[term])
    x = self.eval(term.x)
    y = self.eval(term.y)
    z = op(x,y)

    conds = []
    if 'nnan' in self.attrs[term]:
      df = z3.And(z3.Not(z3.fpIsNaN(x)), z3.Not(z3.fpIsNaN(y)),
        z3.Not(z3.fpIsNaN(z)))
      conds.append(z3.Implies(self.attrs[term]['nnan'], df))

    elif 'nnan' in term.flags:
      conds += [z3.Not(z3.fpIsNaN(x)), z3.Not(z3.fpIsNaN(y)),
        z3.Not(z3.fpIsNaN(z))]

    if 'ninf' in self.attrs[term]:
      df = z3.And(z3.Not(z3.fpIsInf(x)), z3.Not(z3.fpIsInf(y)),
        z3.Not(z3.fpIsInf(z)))
      conds.append(z3.Implies(self.attrs[term]['ninf'], df))

    elif 'ninf' in term.flags:
      conds += [z3.Not(z3.fpIsInf(x)), z3.Not(z3.fpIsInf(y)),
        z3.Not(z3.fpIsInf(z))]

    if 'nsz' in self.attrs[term] or 'nsz' in term.flags:
      # NOTE: this will return a different qvar for each (in)direct reference
      # to this term. Is this desirable?
      b = self.fresh_bool()
      self.add_qvar(b)
      z = op(x,y)

      c = z3.fpIsZero(z)
      if 'nsz' in self.attrs[term]:
        c = z3.And(self.attrs[term]['nsz'], c)

      s = _ty_sort(self.type(term))
      z = z3.If(c, z3.If(b, 0, z3.fpMinusZero(s)), z)

      if isinstance(term, FDivInst):
        c = [z3.Not(z3.fpIsZero(x)), z3.fpIsZero(y)]
        if 'nsz' in self.attrs[term]:
          c.append(self.attrs[term]['nsz'])

        z = z3.If(z3.And(c),
          z3.If(b, z3.fpPlusInfinity(s), z3.fpMinusInfinity(s)),
          z)

    return self._conditional_value(conds, z, term.name)
예제 #5
0
 def FPV(self, ast):  #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)
예제 #6
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)
예제 #7
0
파일: backend_z3.py 프로젝트: avain/claripy
 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))
예제 #8
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))
예제 #9
0
@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)
def _undef(term, smt):
  ty = smt.type(term)
  x = smt.fresh_var(ty)
  smt.add_qvar(x)
  return x

@eval.register(PoisonValue, BaseSMTTranslator)
예제 #10
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)


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)
def _undef(term, smt):
    ty = smt.type(term)
    x = smt.fresh_var(ty)
    smt.add_qvar(x)
    return x