Esempio n. 1
0
        public void Test_FlagTools_Create_OF_Add()
        {
            Context ctx = this.CreateContext();
            {
                uint  nBits = 8;
                ulong a     = 10;
                ulong b     = 20;

                BitVecExpr aExpr = ctx.MkBV(a, nBits);
                BitVecExpr bExpr = ctx.MkBV(b, nBits);

                BoolExpr resultExpr = ToolsFlags.Create_OF_Add(aExpr, bExpr, nBits, ctx).Simplify() as BoolExpr;
                Assert.IsTrue(AsmTestTools.Calc_OF_Add(nBits, a, b) ? resultExpr.IsTrue : resultExpr.IsFalse);
            }
        }
Esempio n. 2
0
        public void Test_BitTricks_Min_Signed()
        {
            Tools tools = this.CreateTools();

            tools.StateConfig.Set_All_Reg_Off();
            tools.StateConfig.RAX = true;
            tools.StateConfig.RBX = true;
            tools.StateConfig.RDX = true;

            return;                        // this trick does not seem to be correct?!

            string line1 = "sub rax, rbx"; // Will not work if overflow here!
            string line2 = "cqo";          // rdx1 = (rax0 > rbx0) ? -1 : 0
            string line3 = "and rdx, rax"; // rdx2 = (rax0 > rbx0) ? 0 : (rax0 - rbx0)
            string line4 = "add rbx, rdx"; // rbx1 = (rax0 > rbx0) ? (rbx0 + 0) : (rbx0 + rax0 - rbx0)

            {                              // forward
                State   state = this.CreateState(tools);
                Context ctx   = state.Ctx;

                if (true)
                {
                    ulong       rax_value   = 0x61a4292198602827;
                    ulong       rbx_value   = 0x8739140220c24080;
                    StateUpdate updateState = new StateUpdate("!PREVKEY", "!NEXTKEY", state.Tools);
                    updateState.Set(Rn.RAX, rax_value);
                    updateState.Set(Rn.RBX, rbx_value);
                    state.Update_Forward(updateState);
                    if (LogToDisplay)
                    {
                        Console.WriteLine("Initially, we know:\n" + state);
                    }
                }

                BitVecExpr rax0 = state.Create(Rn.RAX);
                BitVecExpr rbx0 = state.Create(Rn.RBX);

                {
                    state.Solver.Assert(state.Ctx.MkNot(ToolsFlags.Create_OF_Sub(rax0, rbx0, rax0.SortSize, ctx))); // this code only works when there is no overflow in line1
                }
                {                                                                                                   // line 1
                    state = Runner.SimpleStep_Forward(line1, state);
                    // retrieve the overflow after line 1, OF has to be zero for the code to work
                    state.Solver.AssertAndTrack(ctx.MkNot(state.Create(Flags.OF)), ctx.MkBoolConst("OF-ZERO"));
                    Assert.AreEqual(Status.SATISFIABLE, state.Solver.Check());
                    if (LogToDisplay)
                    {
                        Console.WriteLine("After \"" + line1 + "\", we know:\n" + state);
                    }
                }
                { // line 2
                    state = Runner.SimpleStep_Forward(line2, state);
                    // if (logToDisplay) Console.WriteLine("After \"" + line2 + "\", we know:\n" + state);
                    BoolExpr t2 = ctx.MkEq(state.Create(Rn.RDX), ctx.MkITE(ctx.MkBVSGT(rax0, rbx0), ctx.MkBV(0xFFFF_FFFF_FFFF_FFFF, 64), ctx.MkBV(0, 64)));
                    // Assert.AreEqual(Tv5.ONE, ToolsZ3.GetTv5(t2, state.Solver, state.Ctx));
                }
                {
                    state = Runner.SimpleStep_Forward(line3, state);
                    // if (logToDisplay) Console.WriteLine("After \"" + line3 + "\", we know:\n" + state);
                    // BoolExpr t2 = ctx.MkEq(state.Get(Rn.RDX), ctx.MkITE(ctx.MkBVSGT(rax0, rbx0), ctx.MkBV(0, 64), ctx.MkBVSub(rax0, rbx0)));
                    // Assert.AreEqual(Tv5.ONE, ToolsZ3.GetTv5(t2, state.Solver, state.Ctx));
                }
                {
                    state = Runner.SimpleStep_Forward(line4, state);
                    if (LogToDisplay)
                    {
                        Console.WriteLine("After \"" + line4 + "\", we know:\n" + state);
                    }
                }

                // ebx is minimum of ebx and eax
                BitVecExpr rbx1 = state.Create(Rn.RBX);
                BoolExpr   t    = ctx.MkEq(rbx1, ctx.MkITE(ctx.MkBVSGT(rax0, rbx0), rbx0, rax0));

                if (false)
                {
                    state.Solver.Push();
                    state.Solver.AssertAndTrack(t, ctx.MkBoolConst("MIN_RAX_RBX"));
                    Status s = state.Solver.Check();
                    if (LogToDisplay)
                    {
                        Console.WriteLine("Status A = " + s + "; expected " + Status.SATISFIABLE);
                    }

                    if (s == Status.UNSATISFIABLE)
                    {
                        if (LogToDisplay)
                        {
                            Console.WriteLine("UnsatCore has " + state.Solver.UnsatCore.Length + " elements");
                        }

                        foreach (BoolExpr b in state.Solver.UnsatCore)
                        {
                            if (LogToDisplay)
                            {
                                Console.WriteLine("UnsatCore=" + b);
                            }
                        }

                        if (LogToDisplay)
                        {
                            Console.WriteLine(state.Solver);
                        }

                        Assert.Fail();
                    }
                    state.Solver.Pop();
                }
                if (true)
                {
                    state.Solver.Push();
                    state.Solver.Assert(ctx.MkNot(t), ctx.MkBoolConst("NOT_MIN_RAX_RBX"));
                    Status s = state.Solver.Check();
                    if (LogToDisplay)
                    {
                        Console.WriteLine("Status B = " + s + "; expected " + Status.UNSATISFIABLE);
                    }

                    if (s == Status.SATISFIABLE)
                    {
                        if (LogToDisplay)
                        {
                            Console.WriteLine("Model=" + state.Solver.Model);
                        }

                        Assert.Fail();
                    }
                    state.Solver.Pop();
                }
                Assert.AreEqual(Tv.ONE, ToolsZ3.GetTv(t, state.Solver, state.Ctx));
            }
        }