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))); }
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()); }
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()); }
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()); }
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()); }
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()); }
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); }
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); }
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); }
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()); }
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()); }
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()); }
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()); }
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); }
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()); }
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()); }
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()); }
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()); }
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()); }
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()); }