예제 #1
0
        public void Bwslc_BranchTaken()
        {
            var r1 = Reg("r1");
            var r2 = Reg("r2");
            var cz = Cc("CZ");

            var b = Given_Block(0x100);

            Given_Instrs(b, m => { m.Branch(m.Test(ConditionCode.ULE, cz), Address.Ptr32(0x200), InstrClass.ConditionalTransfer); });

            var b2 = Given_Block(0x200);

            Given_Instrs(b2, m => { m.Assign(r1, m.Shl(r2, 2)); });
            Given_Instrs(b2, m => { m.Goto(m.IAdd(r1, 0x00123400)); });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, 0, Target(b2)));  // indirect jump
            Assert.IsTrue(bwslc.Step());                    // shift left
            Assert.IsTrue(bwslc.Step());                    // branch

            Assert.AreEqual("CZ,r2",
                            string.Join(",", bwslc.Live.Select(l => l.Key.ToString()).OrderBy(n => n)));
        }
예제 #2
0
        public void Bwslc_RangeCheck()
        {
            var r1 = Reg("r1");
            var r2 = Reg("r2");
            var cz = Cc("CZ");

            var b = Given_Block(0x100);

            Given_Instrs(b, m => { m.Assign(cz, m.Cond(m.ISub(r2, 4))); });
            Given_Instrs(b, m => { m.Branch(m.Test(ConditionCode.ULE, cz), Address.Ptr32(0x200), InstrClass.ConditionalTransfer); });

            var b2 = Given_Block(0x200);

            Given_Instrs(b2, m => { m.Assign(r1, m.Shl(r2, 2)); });
            Given_Instrs(b2, m => { m.Goto(m.IAdd(r1, 0x00123400)); });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, 0, Target(b2))); // indirect jump
            Assert.IsTrue(bwslc.Step());                   // shift left
            Assert.IsTrue(bwslc.Step());                   // branch
            Assert.IsFalse(bwslc.Step());                  // test
            Assert.AreEqual("r2",
                            string.Join(",", bwslc.Live.Select(l => l.Key.ToString()).OrderBy(n => n)));
            Assert.AreEqual("(r2 << 2<8>) + 0x123400<32>", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("1[0,4]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #3
0
        public void Bwslc_x86_RegisterHack()
        {
            // In old x86 binaries we see this mechanism
            // for zero extending a register.
            arch = new Reko.Arch.X86.X86ArchitectureReal(sc, "x86-real-16", new Dictionary <string, object>());
            var bl   = binder.EnsureRegister(arch.GetRegister("bl"));
            var bh   = binder.EnsureRegister(arch.GetRegister("bh"));
            var bx   = binder.EnsureRegister(arch.GetRegister("bx"));
            var si   = binder.EnsureRegister(arch.GetRegister("si"));
            var SCZO = binder.EnsureFlagGroup(arch.GetFlagGroup("SCZO"));
            var SZO  = binder.EnsureFlagGroup(arch.GetFlagGroup("SZO"));
            var c    = binder.EnsureFlagGroup(arch.GetFlagGroup("C"));

            var b = Given_Block(0x0100);

            Given_Instrs(b, m =>
            {
                m.Assign(bl, m.Mem8(si));
            });
            Given_Instrs(b, m =>
            {
                m.Assign(SCZO, m.Cond(m.ISub(bl, 2)));
            });
            Given_Instrs(b, m => {
                m.Branch(new TestCondition(ConditionCode.UGT, SCZO), Address.Ptr16(0x120), InstrClass.ConditionalTransfer);
            });

            var b2 = Given_Block(0x200);

            Given_Instrs(b2, m =>
            {
                m.Assign(bh, m.Xor(bh, bh));
                m.Assign(SCZO, new ConditionOf(bh));
            });
            Given_Instrs(b2, m =>
            {
                m.Assign(bx, m.IAdd(bx, bx));
                m.Assign(SCZO, new ConditionOf(bx));
            });
            Given_Instrs(b2, m => {
                m.Goto(m.Mem16(m.IAdd(bx, 0x8400)));
            });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsTrue(bwslc.Start(b2, 3, Target(b2))); // indirect jump
            Assert.IsTrue(bwslc.Step());                   // assign flags
            Assert.IsTrue(bwslc.Step());                   // add bx,bx
            Assert.IsTrue(bwslc.Step());                   // assign flags
            Assert.IsTrue(bwslc.Step());                   // xor high-byte of bx
            Assert.IsTrue(bwslc.Step());                   // branch.
            Assert.IsFalse(bwslc.Step());                  // cmp.

            Assert.AreEqual("Mem0[CONVERT(SLICE(bx, byte, 0), byte, word16) * 2<16> + 0x8400<16>:word16]", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("1[0,2]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #4
0
        public void Bwslc_AcrossJump()
        {
            var r1 = Reg("r1");
            var r2 = Reg("r2");

            var b = Given_Block(0x100);

            Given_Instrs(b, m => { m.Assign(r1, m.Shl(r2, 2)); });
            Given_Instrs(b, m => { m.Goto(Address.Ptr32(0x200)); });

            var b2 = Given_Block(0x200);

            Given_Instrs(b2, m => { m.Goto(m.IAdd(r1, 0x00123400)); });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, -1, Target(b2))); // indirect jump
            Assert.IsTrue(bwslc.Step());                    // direct jump
            Assert.IsTrue(bwslc.Step());                    // shift left
            Assert.AreEqual(1, bwslc.Live.Count);
            Assert.AreEqual("r2", bwslc.Live.First().Key.ToString());
        }
예제 #5
0
        public void Bwslc_Issue_691()
        {
            arch = new Reko.Arch.M68k.M68kArchitecture(sc, "m68k", new Dictionary <string, object>());
            var d0   = Reg("d0");
            var CVZN = Cc("CVZN");
            var C    = Cc("C");
            var v3   = binder.CreateTemporary(PrimitiveType.Word16);
            var v16  = binder.CreateTemporary(PrimitiveType.Word16);
            var v17  = binder.CreateTemporary(PrimitiveType.Word16);
            var b1   = Given_Block(0xA860);

            Given_Instrs(b1, m =>
            {
                m.Assign(v3, m.ISub(m.Slice(PrimitiveType.Word16, d0, 0), m.Word16(0x20)));
                m.Assign(d0, m.Dpb(d0, v3, 0));
                m.Assign(CVZN, m.Cond(v3));
                m.Branch(m.Test(ConditionCode.UGE, C), Address.Ptr32(0xA900), InstrClass.ConditionalTransfer);
            });

            var bRet = Given_Block(0xA870);

            Given_Instrs(bRet, m =>
            {
                m.Return(0, 0);
            });

            var b2 = Given_Block(0xA900);

            Given_Instrs(b2, m =>
            {
                m.Assign(v16, m.IAdd(m.Slice(PrimitiveType.Word16, d0, 0), m.Slice(PrimitiveType.Word16, d0, 0)));
                m.Assign(d0, m.Dpb(d0, v16, 0));
                m.Assign(CVZN, m.Cond(v16));
                m.Assign(v17, m.IAdd(m.Slice(PrimitiveType.Word16, d0, 0), m.Slice(PrimitiveType.Word16, d0, 0)));
                m.Assign(CVZN, m.Cond(v17));
                m.Assign(d0, m.Dpb(d0, v17, 0));
                m.Goto(m.IAdd(m.Word32(0x0000A8B4), m.Convert(
                                  m.Slice(PrimitiveType.Int16, d0, 0),
                                  PrimitiveType.Int16, PrimitiveType.Int32)));
            });

            graph.Nodes.Add(b1);
            graph.Nodes.Add(bRet);
            graph.Nodes.Add(b2);
            graph.AddEdge(b1, bRet);
            graph.AddEdge(b1, b2);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, 6, Target(b2)));
            while (bwslc.Step())
            {
                ;
            }
            Assert.AreEqual("CONVERT(v3 * 4<16>, word16, int32) + 0xA8B4<32>", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("v3", bwslc.JumpTableIndex.ToString());
            Assert.AreEqual("v3", bwslc.JumpTableIndexToUse.ToString(), "Expression to use when indexing");
            Assert.AreEqual("1[20,7FFFFFFFFFFFFFFF]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #6
0
        public void Bwslc_SignExtension()
        {
            var CVZNX = Cc("CVZNX");
            var CVZN  = Cc("CVZN");
            var VZN   = Cc("VZN");
            var r1    = Reg("r1");
            var v80   = binder.CreateTemporary("v80", PrimitiveType.Word32);
            var v82   = binder.CreateTemporary("v82", PrimitiveType.Word32);

            var b1 = Given_Block(0x1000);

            Given_Instrs(b1, m =>
            {
                m.Assign(v80, m.ISub(r1, 0x28));
                m.Assign(CVZN, m.Cond(v80));
                m.Branch(m.Test(ConditionCode.GT, VZN), Address.Ptr16(0x1020), InstrClass.ConditionalTransfer);
            });

            var b2 = Given_Block(0x1010);

            Given_Instrs(b2, m =>
            {
                m.Assign(r1, m.IAdd(r1, r1));
                m.Assign(CVZNX, m.Cond(r1));
                m.Assign(v82, m.Mem16(m.IAdd(m.Word32(0x001066A4), r1)));
                m.Assign(r1, m.Dpb(r1, v82, 0));
                m.Assign(CVZN, m.Cond(v82));
                m.Goto(
                    m.IAdd(
                        m.Word32(0x001066A2),
                        m.Convert(m.Slice(PrimitiveType.Int16, r1, 0), PrimitiveType.Int16, PrimitiveType.Int32)),
                    InstrClass.Transfer);
            });

            //m.Label("default_case");
            //m.Return();

            graph.Nodes.Add(b1);
            graph.Nodes.Add(b2);
            graph.AddEdge(b1, b2);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, 5, Target(b2)));
            while (bwslc.Step())
            {
                ;
            }

            Assert.AreEqual(2, bwslc.Live.Count);
            Assert.AreEqual("(int32) (int16) DPB(r1 * 0x00000002<32>, Mem0[r1 * 0x00000002<32> + 0x001066A4<32>:word16], 0) + 0x001066A2<32>", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("v80", bwslc.JumpTableIndex.ToString());
            Assert.AreEqual("v80", bwslc.JumpTableIndexToUse.ToString(), "Expression to use when indexing");
            Assert.AreEqual("1[0,17]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #7
0
        public void Bwslc_DetectRegister()
        {
            var r1 = Reg("r1");
            var b  = Given_Block(0x10);

            Given_Instrs(b, m => m.Goto(r1));

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsTrue(bwslc.Start(b, 0, Target(b)));
            Assert.AreEqual(new BitRange(0, 32), bwslc.Live[r1].BitRange);
        }
예제 #8
0
        public void Bwslc_SeedSlicer()
        {
            var r1 = Reg("r1");
            var b  = Given_Block(0x10);

            Given_Instrs(b, m => m.Goto(r1));

            var bwslc  = new BackwardSlicer(host, b, processorState);
            var result = bwslc.Start(b, 0, Target(b));

            Assert.IsTrue(result);
        }
예제 #9
0
        public void Bwslc_DetectNoRegister()
        {
            var r1 = Reg("r1");
            var b  = Given_Block(0x10);

            Given_Instrs(b, m => m.Goto(Address.Ptr32(0x00123400)));

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsFalse(bwslc.Start(b, 0, Target(b)));
            Assert.AreEqual(0, bwslc.Live.Count);
        }
예제 #10
0
        public void Bwslc_DetectAddition()
        {
            var r1 = Reg("r1");
            var b  = Given_Block(0x100);

            Given_Instrs(b, m => m.Goto(m.IAdd(r1, 0x00123400)));

            var bwslc = new BackwardSlicer(host, b, processorState);
            var start = bwslc.Start(b, 0, Target(b));

            Assert.IsTrue(start);
            Assert.AreEqual(1, bwslc.Live.Count);
            Assert.AreEqual("r1", bwslc.Live.First().Key.ToString());
        }
예제 #11
0
        public void Bwslc_KillLiveness()
        {
            var r1 = Reg("r1");
            var r2 = Reg("r2");
            var b  = Given_Block(0x100);

            Given_Instrs(b, m => { m.Assign(r1, m.Shl(r2, 2)); });
            Given_Instrs(b, m => { m.Goto(m.IAdd(r1, 0x00123400)); });

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsTrue(bwslc.Start(b, 0, Target(b)));
            Assert.IsTrue(bwslc.Step());
            Assert.AreEqual(1, bwslc.Live.Count);
            Assert.AreEqual("r2", bwslc.Live.First().Key.ToString());
        }
예제 #12
0
        public void Bwslc_SimplifySum()
        {
            var r1 = Reg("r1");
            var b  = Given_Block(0x100);

            Given_Instrs(b, m => m.Assign(r1, m.IAdd(r1, r1)));
            Given_Instrs(b, m => m.Goto(m.IAdd(r1, 0x00123400)));

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsTrue(bwslc.Start(b, 0, Target(b)));
            Assert.IsTrue(bwslc.Step());
            Assert.AreEqual(1, bwslc.Live.Count);
            Assert.AreEqual("r1", bwslc.Live.First().Key.ToString());
            Assert.AreEqual("r1 * 2<32> + 0x123400<32>", bwslc.JumpTableFormat.ToString());
        }
예제 #13
0
        public void Bwslc_SimplifySumAndProduct()
        {
            var r1 = Reg(1);
            var b  = Given_Block(0x100);

            Given_Instrs(b, m => m.Assign(r1, m.IAdd(r1, r1)));
            Given_Instrs(b, m => m.Assign(r1, m.IAdd(r1, r1)));
            Given_Instrs(b, m => m.Goto(m.IAdd(r1, 0x00123400)));

            var bwslc = new BackwardSlicer(host);

            Assert.IsTrue(bwslc.Start(b, 1, Target(b)));
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.AreEqual(1, bwslc.Live.Count);
            Assert.AreEqual("r1", bwslc.Live.First().Key.ToString());
            Assert.AreEqual("r1 * 0x00000004 + 0x00123400", bwslc.JumpTableFormat.ToString());
        }
예제 #14
0
        public void Bwslc_DetectUsingExpression()
        {
            var r1 = Reg("r1");
            var r2 = Reg("r2");
            var b  = Given_Block(0x10);

            Given_Instrs(b, m => m.Assign(r1, m.Mem32(m.IAdd(r2, 8))));
            Given_Instrs(b, m => m.Goto(r1));

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsTrue(bwslc.Start(b, 0, Target(b)));
            Assert.AreEqual(new BitRange(0, 32), bwslc.Live[r1].BitRange);
            Assert.IsTrue(bwslc.Step());
            Assert.AreEqual(2, bwslc.Live.Count);
            Assert.AreEqual("r2", bwslc.Live.First().Key.ToString());
            Assert.AreEqual(new BitRange(0, 32), bwslc.Live.First().Value.BitRange);
        }
예제 #15
0
        public void Bwslc_Issue_826()
        {
            var A     = binder.EnsureRegister(new RegisterStorage("A", 0, 0, PrimitiveType.Byte));
            var R7    = binder.EnsureRegister(new RegisterStorage("R7", 7, 0, PrimitiveType.Byte));
            var DPTR  = binder.EnsureRegister(new RegisterStorage("DPTR", 8, 0, PrimitiveType.Word16));
            var C     = Cc("C");
            var b0082 = Given_Block(0x0082);

            Given_Instrs(b0082, m =>
            {
                m.Assign(A, m.Mem(A.DataType, DPTR));
                m.Assign(R7, A);
                m.Assign(A, m.IAdd(A, 0xFC));   // A >= 4 will cause a carry.
                m.Assign(C, m.Cond(A));
                m.Branch(m.Test(ConditionCode.ULT, C), Address.Ptr16(0x00C0));
            });

            var b0088 = Given_Block(0x0088);

            Given_Instrs(b0088, m =>
            {
                m.Assign(A, R7);
                m.Assign(A, m.IAdd(A, R7));
                m.Assign(DPTR, m.Word16(0x008E));
                m.Goto(m.IAdd(DPTR, m.Slice(PrimitiveType.UInt16, A, 0)));
            });
            graph.Nodes.Add(b0082);
            graph.Nodes.Add(b0088);
            graph.AddEdge(b0082, b0088);

            var bwslc = new BackwardSlicer(host, b0088, processorState);

            Assert.IsTrue(bwslc.Start(b0088, 3, Target(b0088)));
            while (bwslc.Step())
            {
                ;
            }
            Assert.AreEqual("SLICE(R7 * 2<8>, uint16, 0) + 0x8E<16>", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("A", bwslc.JumpTableIndex.ToString());
            Assert.AreEqual("A", bwslc.JumpTableIndexToUse.ToString(), "Expression to use when indexing");
            Assert.AreEqual("1[0,3]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #16
0
        public void Bwslc_BoundIndexWithAnd()
        {
            var r1 = Reg("r1");
            var r2 = Reg("r2");
            var cz = Cc("CZ");

            var b = Given_Block(0x100);

            Given_Instrs(b, m => { m.Assign(r1, m.And(r1, 7)); m.Assign(cz, m.Cond(r1)); });
            Given_Instrs(b, m => { m.Goto(m.Mem32(m.IAdd(m.Word32(0x00123400), m.IMul(r1, 4)))); });

            graph.Nodes.Add(b);

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsTrue(bwslc.Start(b, 1, Target(b))); // indirect jump
            Assert.IsTrue(bwslc.Step());                 // assign flags
            Assert.IsFalse(bwslc.Step());                // and
            Assert.AreEqual("Mem0[(r1 & 7<32>) * 4<32> + 0x123400<32>:word32]", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("1[0,7]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #17
0
        public void Bwslc_ClearingBits()
        {
            arch = new Reko.Arch.X86.X86ArchitectureReal(sc, "x86-real-16", new Dictionary <string, object>());
            var eax  = binder.EnsureRegister(arch.GetRegister("eax"));
            var edx  = binder.EnsureRegister(arch.GetRegister("edx"));
            var dl   = binder.EnsureRegister(arch.GetRegister("dl"));
            var C    = binder.EnsureFlagGroup(arch.GetFlagGroup("C"));
            var SZO  = binder.EnsureFlagGroup(arch.GetFlagGroup("SZO"));
            var SCZO = binder.EnsureFlagGroup(arch.GetFlagGroup("SCZO"));

            var b = Given_Block(0x001000000);

            Given_Instrs(b, m => { m.Assign(SCZO, m.Cond(m.ISub(eax, 3))); });
            Given_Instrs(b, m => { m.Branch(m.Test(ConditionCode.UGT, C), Address.Ptr32(0x00100010), InstrClass.ConditionalTransfer); });

            var b2 = Given_Block(0x001000008);

            Given_Instrs(b2, m => { m.Assign(edx, m.Xor(edx, edx)); m.Assign(SZO, m.Cond(edx)); m.Assign(C, Constant.False()); });
            Given_Instrs(b2, m => { m.Assign(dl, m.Mem8(m.IAdd(eax, 0x00123500))); });
            Given_Instrs(b2, m => { m.Goto(m.Mem32(m.IAdd(m.IMul(edx, 4), 0x00123400))); });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            graph.Nodes.Add(b);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, 3, Target(b2)));  // indirect jump
            Assert.IsTrue(bwslc.Step());                    // dl = ...
            Assert.IsTrue(bwslc.Step());                    // edx = 0
            Assert.IsTrue(bwslc.Step());                    // branch ...
            Assert.IsTrue(bwslc.Step());                    // SZCO = cond(eax - 3)
            Assert.IsTrue(bwslc.Step());
            Assert.IsFalse(bwslc.Step());

            Assert.AreEqual("Mem0[Mem0[eax + 0x123500<32>:byte] *32 4<32> + 0x123400<32>:word32]", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("1[0,3]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #18
0
        public void Bwslc_SegmentedLoad()
        {
            arch = new Reko.Arch.X86.X86ArchitectureReal(sc, "x86-real-16", new Dictionary <string, object>());
            var cx   = binder.EnsureRegister(arch.GetRegister("cx"));
            var bx   = binder.EnsureRegister(arch.GetRegister("bx"));
            var ds   = binder.EnsureRegister(arch.GetRegister("ds"));
            var C    = binder.EnsureFlagGroup(arch.GetFlagGroup("C"));
            var SZO  = binder.EnsureFlagGroup(arch.GetFlagGroup("SZO"));
            var SCZO = binder.EnsureFlagGroup(arch.GetFlagGroup("SCZO"));

            var b = Given_Block(0x0C00, 0x0100);

            Given_Instrs(b, m => { m.Assign(SCZO, m.Cond(m.ISub(bx, 15))); });
            Given_Instrs(b, m => { m.Branch(m.Test(ConditionCode.UGT, C), Address.SegPtr(0xC00, 0x200), InstrClass.ConditionalTransfer); });

            var b2 = Given_Block(0x0C00, 0x0108);

            Given_Instrs(b2, m => { m.Assign(bx, m.IAdd(bx, bx)); m.Assign(SCZO, m.Cond(bx)); });
            Given_Instrs(b2, m => { m.Goto(m.SegMem(PrimitiveType.Ptr32, ds, m.IAdd(bx, 34))); });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            graph.Nodes.Add(b);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, 0, Target(b2)));   // indirect jump
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsFalse(bwslc.Step());

            Assert.AreEqual("Mem0[ds:bx * 2<16> + 0x22<16>:ptr32]", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("1[0,F]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #19
0
        public void Bwslc_RepMovsd()
        {
            // Original i386 code:
            // shr ecx,02
            // and edx,03
            // cmp ecx,08
            // jc 00002000
            // rep movsd
            // jmp dword ptr[007862E8 + edx * 4]

            arch = new Reko.Arch.X86.X86ArchitectureReal(sc, "x86-real-16", new Dictionary <string, object>());
            var ecx  = binder.EnsureRegister(arch.GetRegister("ecx"));
            var edx  = binder.EnsureRegister(arch.GetRegister("edx"));
            var esi  = binder.EnsureRegister(arch.GetRegister("esi"));
            var edi  = binder.EnsureRegister(arch.GetRegister("edi"));
            var C    = binder.EnsureFlagGroup(arch.GetFlagGroup("C"));
            var SZO  = binder.EnsureFlagGroup(arch.GetFlagGroup("SZO"));
            var SCZO = binder.EnsureFlagGroup(arch.GetFlagGroup("SCZO"));
            var tmp  = binder.CreateTemporary(ecx.DataType);

            var b = Given_Block(0x1000);

            Given_Instrs(b, m => { m.Assign(ecx, m.Shr(ecx, 2)); m.Assign(SCZO, m.Cond(ecx)); });
            Given_Instrs(b, m => { m.Assign(edx, m.And(edx, 3)); m.Assign(SZO, m.Cond(edx)); m.Assign(C, Constant.False()); });
            Given_Instrs(b, m => { m.Assign(SCZO, m.Cond(m.ISub(ecx, 8))); });
            Given_Instrs(b, m => { m.Branch(m.Test(ConditionCode.ULT, C), Address.Ptr32(0x2000), InstrClass.ConditionalTransfer); });

            var b2 = Given_Block(0x1008);

            Given_Instrs(b2, m => {
                m.BranchInMiddleOfInstruction(m.Eq0(ecx), Address.Ptr32(0x1010), InstrClass.ConditionalTransfer);
                m.Assign(tmp, m.Mem32(esi));
                m.Assign(m.Mem32(edi), tmp);
                m.Assign(esi, m.IAdd(esi, 4));
                m.Assign(edi, m.IAdd(edi, 4));
                m.Assign(ecx, m.ISub(ecx, 1));
                m.Goto(Address.Ptr32(0x1008));
            });

            var b3 = Given_Block(0x1010);

            Given_Instrs(b3, m => {
                m.Goto(m.Mem32(m.IAdd(m.IMul(edx, 4), 0x00123400)));
            });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.Nodes.Add(b3);
            graph.AddEdge(b, b2);
            graph.AddEdge(b2, b3);
            graph.AddEdge(b2, b2);

            var bwslc = new BackwardSlicer(host, b3, processorState);

            Assert.IsTrue(bwslc.Start(b3, -1, Target(b3)));   // indirect jump
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.IsTrue(bwslc.Step());
            Assert.False(bwslc.Step());     // edx &= 3
            Assert.AreEqual("Mem0[(edx & 3<32>) * 4<32> + 0x123400<32>:word32]", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("1[0,3]", bwslc.JumpTableIndexInterval.ToString());
        }
예제 #20
0
        public void Bwslc_Slices()
        {
            // This test is derived from a m68k binary which originally looked like this:

            //  cmpi.b #$17,d0
            //  bhi $0010F010
            //
            //  moveq #$00,d1
            //  move.b d0,d1
            //  add.w d1,d1
            //  move.w (06,pc,d1),d1
            //  jmp.l (pc,d1)

            // The code introduces a lot of SLICEs, which must be dealt with appropriately.

            var W8  = PrimitiveType.Byte;
            var W16 = PrimitiveType.Word16;
            var W32 = PrimitiveType.Word32;
            var I16 = PrimitiveType.Int16;
            var I32 = PrimitiveType.Int32;

            arch = new Reko.Arch.M68k.M68kArchitecture(sc, "m68k", new Dictionary <string, object>());
            var d0    = Reg("d0");
            var d1    = Reg("d1");
            var v2    = binder.CreateTemporary("v2", W8);
            var v3    = binder.CreateTemporary("v3", W8);
            var v4    = binder.CreateTemporary("v4", W16);
            var v5    = binder.CreateTemporary("v5", PrimitiveType.Word16);
            var CVZNX = Cc("CVZNX");
            var CVZN  = Cc("CVZN");
            var CZ    = Cc("CZ");

            var b = Given_Block(0x00100000);

            Given_Instrs(b, m =>
            {
                m.Assign(v2, m.ISub(m.Slice(PrimitiveType.Byte, d0, 0), 0x17));
                m.Assign(CVZN, m.Cond(v2));
            });
            Given_Instrs(b, m =>
            {
                m.Branch(m.Test(ConditionCode.UGT, CZ), Address.Ptr32(0x00100040), InstrClass.ConditionalTransfer);
            });

            var b2 = Given_Block(0x00100008);

            Given_Instrs(b2, m => {
                m.Assign(d1, m.Word32(0));
                m.Assign(CVZN, m.Cond(d1));
            });
            Given_Instrs(b2, m =>
            {
                m.Assign(v3, m.Slice(v3.DataType, d0, 0));
                m.Assign(d1, m.Dpb(d1, v3, 0));
                m.Assign(CVZN, m.Cond(v3));
            });
            Given_Instrs(b2, m =>
            {
                m.Assign(v4, m.IAdd(m.Slice(v4.DataType, d1, 0), m.Slice(v4.DataType, d1, 0)));
                m.Assign(d1, m.Dpb(d1, v4, 0));
                m.Assign(CVZNX, m.Cond(v4));
            });
            Given_Instrs(b2, m =>
            {
                m.Assign(v5, m.Mem16(m.IAdd(m.Word32(0x0010EC32), m.Convert(m.Slice(W16, d1, 0), W16, W32))));
                m.Assign(d1, m.Dpb(d1, v5, 0));
                m.Assign(CVZN, m.Cond(v5));
            });
            Given_Instrs(b2, m => {
                m.Goto(m.IAdd(m.Word32(0x0010EC30), m.Convert(m.Slice(I16, d1, 0), I16, I32)));
            });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            var bwslc = new BackwardSlicer(host, b2, processorState);

            Assert.IsTrue(bwslc.Start(b2, 10, Target(b2)));
            while (bwslc.Step())
            {
                ;
            }
            Assert.AreEqual(2, bwslc.Live.Count);
            Assert.AreEqual("CONVERT(Mem0[CONVERT(SLICE(d0, word16, 0) * 2<16>, word16, word32) + 0x10EC32<32>:word16], word16, int32) + 0x10EC30<32>", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("d0", bwslc.JumpTableIndex.ToString());
            Assert.AreEqual("SLICE(d0, byte, 0)", bwslc.JumpTableIndexToUse.ToString(), "Expression to use when indexing");
            Assert.AreEqual("1[0,17]", bwslc.JumpTableIndexInterval.ToString());
        }