private ISatExpressionWrapper /*?*/ GetSolverExpressionFor(List <Instruction> listOfExpressions) { Contract.Requires(listOfExpressions != null); var n = listOfExpressions.Count; if (n == 0) { return(null); } ISatExpressionWrapper /*?*/ conjunct = null; for (int i = 0; i < n; i++) { if (listOfExpressions[i] == null) { return(null); } var expression = this.GetSolverExpressionFor(listOfExpressions[i]); if (conjunct == null) { conjunct = expression; } else { conjunct = this.satSolver.MakeExpression(this.andOp, conjunct.Type, conjunct, expression); } } return(conjunct); }
internal ISatExpressionWrapper /*?*/ GetSolverExpressionFor(List <List <Instruction> > listOfConjunctions) { Contract.Requires(listOfConjunctions != null); var n = listOfConjunctions.Count; if (n == 0) { return(null); } ISatExpressionWrapper /*?*/ disjunct = null; for (int i = 0; i < n; i++) { if (listOfConjunctions[i] == null) { return(null); } var conjunct = this.GetSolverExpressionFor(listOfConjunctions[i]); if (conjunct == null) { return(null); } if (disjunct == null) { disjunct = conjunct; } else { disjunct = this.satSolver.MakeExpression(this.orOp, disjunct.Type, disjunct, conjunct); } } return(disjunct); }
public void AddInverse(ISatExpressionWrapper expression) { if (expression.Type.TypeCode != PrimitiveTypeCode.Boolean) { this.isDummy = true; } else { this.solverContext.Assert(this.solver.MkNot(expression.Unwrap <BoolExpr>())); } }
private BoolExpr ConvertToBool(ISatExpressionWrapper expr) { if (expr.Type.TypeCode == PrimitiveTypeCode.Boolean) { return(expr.Unwrap <BoolExpr>()); } if (HasBitVectorSort(expr.Type)) { var bv = expr.Unwrap <BitVecExpr>(); return(this.solver.MkNot(this.solver.MkEq(bv, this.solver.MkBV(0, bv.SortSize)))); } return(this.solver.MkBoolConst("bool" + expr.GetHashCode().ToString())); }
private BitVecExpr ConvertToBitVector(ISatExpressionWrapper expr, uint size) { if (HasBitVectorSort(expr.Type)) { return(expr.Unwrap <BitVecExpr>()); } BitVecExpr result = null; if (expr.Type.TypeCode == PrimitiveTypeCode.Boolean) { result = this.solver.MkITE(expr.Unwrap <BoolExpr>(), this.solver.MkBV(1, 32), this.solver.MkBV(0, 32)) as BitVecExpr; //TODO: this cast might never work } if (result != null) { return(result); } return(this.solver.MkInt2BV(size, this.solver.MkIntConst("int" + expr.GetHashCode().ToString()))); }
public ISatExpressionWrapper MakeImplication(ISatExpressionWrapper operand1, ISatExpressionWrapper operand2) { return(new ExpressionWrapper(this.solver.MkImplies(operand1.Unwrap <BoolExpr>(), operand2.Unwrap <BoolExpr>()), operand1.Type)); }
public ISatExpressionWrapper MakeExpression(IOperation operation, ITypeReference expressionType, ISatExpressionWrapper operand1, ISatExpressionWrapper operand2) { Expr expr; var operationSize = Math.Max(Math.Max(TypeHelper.SizeOfType(expressionType), TypeHelper.SizeOfType(operand1.Type)), TypeHelper.SizeOfType(operand2.Type)) <= 4 ? 32u : 64u; switch (operation.OperationCode) { //Instructions that are side-effect free and cacheable and that could result in compile time values. //We attempt to compute the compile time values. case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: expr = this.solver.MkBVAdd(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.And: if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean) { expr = this.solver.MkAnd(operand1.Unwrap <BoolExpr>(), this.ConvertToBool(operand2)); } else { expr = this.solver.MkBVAND(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); } break; case OperationCode.Div: expr = this.solver.MkBVSDiv(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Div_Un: expr = this.solver.MkBVUDiv(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: expr = this.solver.MkBVMul(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Or: if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean) { expr = this.solver.MkOr(operand1.Unwrap <BoolExpr>(), this.ConvertToBool(operand2)); } else { expr = this.solver.MkBVOR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); } break; case OperationCode.Rem: expr = this.solver.MkBVSRem(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Rem_Un: expr = this.solver.MkBVURem(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Shl: expr = this.solver.MkBVURem(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Shr: expr = this.solver.MkBVASHR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Shr_Un: expr = this.solver.MkBVLSHR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Sub: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: expr = this.solver.MkBVSub(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Xor: if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean) { expr = this.solver.MkXor(operand1.Unwrap <BoolExpr>(), this.ConvertToBool(operand2)); } else { expr = this.solver.MkBVXOR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); } break; //Boolean expression case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Ceq: expr = this.solver.MkEq(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Bge: case OperationCode.Bge_S: expr = this.solver.MkBVSGE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: expr = this.solver.MkBVUGE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Cgt: expr = this.solver.MkBVSGT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Cgt_Un: expr = this.solver.MkBVUGT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Ble: case OperationCode.Ble_S: expr = this.solver.MkBVSLE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: expr = this.solver.MkBVULE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Clt: expr = this.solver.MkBVSLT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Clt_Un: expr = this.solver.MkBVULT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)); break; case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: expr = this.solver.MkNot(this.solver.MkEq(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize))); break; //Instructions that cause side-effect that we do not currently track. case OperationCode.Call: case OperationCode.Calli: case OperationCode.Callvirt: case OperationCode.Cpblk: case OperationCode.Cpobj: case OperationCode.Initblk: case OperationCode.Newobj: case OperationCode.Stfld: case OperationCode.Stind_I: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Stind_Ref: case OperationCode.Stobj: goto default; //Instructions that are side-effect free and cacheable and that could result in compile time values. //We do NOT attempt to compute the compile time values at this time. case OperationCode.Ldelem_I: case OperationCode.Ldelem_I1: case OperationCode.Ldelem_I2: case OperationCode.Ldelem_I4: case OperationCode.Ldelem_I8: case OperationCode.Ldelem_R4: case OperationCode.Ldelem_R8: case OperationCode.Ldelem_Ref: case OperationCode.Ldelem_U1: case OperationCode.Ldelem_U2: case OperationCode.Ldelem_U4: case OperationCode.Ldelema: goto default; case OperationCode.Nop: var v = operation.Value as INamedEntity; if (v != null && !(v.Name is Dummy)) //phi node { expr = this.GetVariableFor(v, expressionType); break; } goto default; default: var hashCode = operation.GetHashCode(); if (operation is Dummy) { hashCode = new object().GetHashCode(); } expr = this.solver.MkConst("binary" + hashCode, this.GetSortFor(expressionType)); break; } return(new ExpressionWrapper(expr, expressionType)); }
public ISatExpressionWrapper /*?*/ MakeExpression(IOperation operation, ITypeReference expressionType, ISatExpressionWrapper operand1) { Expr expr; ExpressionWrapper wrapper1 = operand1 as ExpressionWrapper; var operationSize = Math.Max(TypeHelper.SizeOfType(expressionType), TypeHelper.SizeOfType(operand1.Type)) <= 4 ? 32u : 64u; switch (operation.OperationCode) { case OperationCode.Conv_I1: case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_I1_Un: expr = this.solver.MkSignExt(24, this.solver.MkExtract(7, 0, this.ConvertToBitVector(operand1, operationSize))); break; case OperationCode.Conv_I2: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_I2_Un: expr = this.solver.MkSignExt(16, this.solver.MkExtract(16, 0, this.ConvertToBitVector(operand1, operationSize))); break; case OperationCode.Conv_I4: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_I4_Un: expr = this.solver.MkExtract(32, 0, this.ConvertToBitVector(operand1, operationSize)); break; case OperationCode.Conv_I8: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_I8_Un: if (TypeHelper.SizeOfType(operand1.Type) == 8) { expr = this.ConvertToBitVector(operand1, 64); } else { expr = this.solver.MkSignExt(32, this.ConvertToBitVector(operand1, operationSize)); } break; case OperationCode.Conv_R4: goto default; case OperationCode.Conv_R8: goto default; case OperationCode.Conv_U1: case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_U1_Un: expr = this.solver.MkZeroExt(24, this.solver.MkExtract(7, 0, this.ConvertToBitVector(operand1, operationSize))); break; case OperationCode.Conv_U2: case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_U2_Un: expr = this.solver.MkZeroExt(16, this.solver.MkExtract(16, 0, this.ConvertToBitVector(operand1, operationSize))); break; case OperationCode.Conv_U4: case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_U4_Un: expr = this.solver.MkExtract(32, 0, this.ConvertToBitVector(operand1, operationSize)); break; case OperationCode.Conv_U8: case OperationCode.Conv_Ovf_U8: case OperationCode.Conv_Ovf_U8_Un: if (TypeHelper.SizeOfType(operand1.Type) == 8) { expr = this.ConvertToBitVector(operand1, 64); } else { expr = this.solver.MkZeroExt(32, this.ConvertToBitVector(operand1, 32)); } break; case OperationCode.Conv_I: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_I_Un: if (expressionType.PlatformType.PointerSize == 8) { goto case OperationCode.Conv_I8; } else { goto case OperationCode.Conv_I4; } case OperationCode.Conv_U: case OperationCode.Conv_Ovf_U: case OperationCode.Conv_Ovf_U_Un: if (expressionType.PlatformType.PointerSize == 8) { goto case OperationCode.Conv_U8; } else { goto case OperationCode.Conv_U4; } case OperationCode.Conv_R_Un: goto default; case OperationCode.Dup: return(operand1); case OperationCode.Neg: expr = this.solver.MkBVNeg(this.ConvertToBitVector(operand1, operationSize)); break; case OperationCode.Nop: var v = operation.Value as INamedEntity; if (v != null && !(v.Name is Dummy)) //phi node { expr = this.GetVariableFor(v, expressionType); break; } goto default; case OperationCode.Not: if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean) { expr = this.solver.MkNot(operand1.Unwrap <BoolExpr>()); } else { expr = this.solver.MkBVNot(this.ConvertToBitVector(operand1, operationSize)); } break; default: var hashCode = operation.GetHashCode(); if (operation is Dummy) { hashCode = new object().GetHashCode(); } expr = this.solver.MkConst("unary" + hashCode, this.GetSortFor(expressionType)); break; } return(new ExpressionWrapper(expr, expressionType)); }