/// <summary> /// Mutually recursive functions that jump into each other's bodies. /// </summary> /// <returns></returns> public static Program BuildProgram() { var prog = new ProgramBuilder(); var m = new ProcedureBuilder("even"); var r1 = m.Register(1); m.BranchIf(m.Eq0(r1), "done"); m.Assign(r1, m.ISub(r1, 1)); m.Call("odd", 4); m.Assign(r1, m.Not(r1)); m.Return(); m.Label("done"); m.Assign(r1, true); m.Return(); prog.Add(m); m = new ProcedureBuilder("odd"); r1 = m.Register(1); m.BranchIf(m.Eq(r1, 1), "done"); m.Assign(r1, m.ISub(r1, 1)); m.Call("event", 4); m.Assign(r1, m.Not(r1)); m.Return(); m.Label("done"); m.Assign(r1, true); m.Return(); prog.Add(m); return prog.BuildProgram(); }
public void VpIndirectCall() { var callee = CreateExternalProcedure("foo", RegArg(1, "r1"), StackArg(4), StackArg(8)); var pc = new ProcedureConstant(PrimitiveType.Pointer32, callee); var m = new ProcedureBuilder(); var r1 = m.Reg32("r1", 1); var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister); m.Assign(r1, pc); m.Assign(sp, m.ISub(sp, 4)); m.Store(sp, 3); m.Assign(sp, m.ISub(sp, 4)); m.Store(sp, m.LoadW(m.Word32(0x1231230))); m.Call(r1, 4); m.Return(); arch.Stub(a => a.CreateStackAccess(null, 0, null)) .IgnoreArguments() .Do(new Func<Frame, int, DataType, Expression>((f, off, dt) => m.Load(dt, m.IAdd(sp, off)))); mr.ReplayAll(); var ssa = RunTest(m); var sExp = #region Expected @"r1_0: orig: r1 def: r1_0 = foo r63:r63 def: def r63 uses: r63_2 = r63 - 0x00000004 Mem3[r63 - 0x00000004:word32] = 0x00000003 r63_4 = r63 - 0x00000008 Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16] r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32]) r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32]) r63_2: orig: r63 def: r63_2 = r63 - 0x00000004 Mem3: orig: Mem0 def: Mem3[r63 - 0x00000004:word32] = 0x00000003 uses: Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16] r63_4: orig: r63 def: r63_4 = r63 - 0x00000008 Mem5: orig: Mem0 def: Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16] r1_6: orig: r1 def: r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32]) r63_7: orig: r63 Mem8: orig: Mem0 uses: r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32]) Mem9: orig: Mem0 uses: r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32]) // ProcedureBuilder // Return size: 0 void ProcedureBuilder() ProcedureBuilder_entry: def r63 // succ: l1 l1: r1_0 = foo r63_2 = r63 - 0x00000004 Mem3[r63 - 0x00000004:word32] = 0x00000003 r63_4 = r63 - 0x00000008 Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16] r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32]) return // succ: ProcedureBuilder_exit ProcedureBuilder_exit: "; #endregion AssertStringsEqual(sExp, ssa); }
public void VpPhiLoops() { var m = new ProcedureBuilder(); var ssa = new SsaState(m.Procedure, null); ssaIds = ssa.Identifiers; var fp = Reg16("fp"); var a = Reg16("a"); var b = Reg16("b"); var c = Reg16("c"); var d = Reg16("d"); var x = Reg16("x"); var y = Reg16("y"); var z = Reg16("z"); m.Emit(m.Assign(y, m.IAdd(x, 4))); m.Emit(m.Assign(z, m.ISub(x, 8))); m.Emit(m.Assign(a, m.ISub(fp, 12))); m.Emit(m.Assign(b, m.ISub(fp, 12))); m.Emit(m.Assign(c, m.ISub(y, 4))); m.Emit(m.Assign(d, m.IAdd(z, 8))); var phiStm = m.Phi(x, a, b, c, d); var stms = m.Procedure.EntryBlock.Succ[0].Statements; stms.ForEach(stm => { var ass = stm.Instruction as Assignment; if (ass != null) ssaIds[ass.Dst].DefStatement = stm; var phiAss = stm.Instruction as PhiAssignment; if (phiAss != null) ssaIds[phiAss.Dst].DefStatement = stm; }); var vp = new ValuePropagator(arch, ssa); vp.Transform(); Assert.AreEqual("x = fp - 0x000C", phiStm.Instruction.ToString()); }
public void VpShiftSum() { ProcedureBuilder m = new ProcedureBuilder(); Expression e = m.Shl(1, m.ISub(Constant.Byte(32), 1)); var vp = new ExpressionSimplifier(new SsaEvaluationContext(arch, ssaIds)); e = e.Accept(vp); Assert.AreEqual("0x80000000", e.ToString()); }
public void VpEquality2() { // Makes sure that // y = x - 2 // if (y == 0) ... // doesn't get munged into // y = x - 2 // if (x == 2) ProcedureBuilder m = new ProcedureBuilder(); var ssa = new SsaState(m.Procedure, null); this.ssaIds = ssa.Identifiers; Identifier x = Reg32("x"); Identifier y = Reg32("y"); var stmX = m.Assign(x, m.LoadDw(Constant.Word32(0x1000300))); ssaIds[x].DefStatement = m.Block.Statements.Last; var stmY = m.Assign(y, m.ISub(x, 2)); ssaIds[y].DefStatement = m.Block.Statements.Last; var stm = m.BranchIf(m.Eq(y, 0), "test"); Assert.AreEqual("x = Mem0[0x01000300:word32]", stmX.ToString()); Assert.AreEqual("y = x - 0x00000002", stmY.ToString()); Assert.AreEqual("branch y == 0x00000000 test", stm.ToString()); var vp = new ValuePropagator(arch, ssa); vp.Transform(stm); Assert.AreEqual("branch x == 0x00000002 test", stm.Instruction.ToString()); }
public void SsaPushAndPop() { // Mirrors the pattern of stack accesses used by x86 compilers. var m = new ProcedureBuilder("SsaPushAndPop"); var esp = EnsureRegister32(m, "esp"); var ebp = EnsureRegister32(m, "ebp"); var eax = EnsureRegister32(m, "eax"); m.Assign(esp, m.ISub(esp, 4)); m.Store(esp, ebp); m.Assign(ebp, esp); m.Assign(eax, m.LoadDw(m.IAdd(ebp, 8))); // dwArg04 m.Assign(ebp, m.LoadDw(esp)); m.Assign(esp, m.IAdd(esp,4)); m.Return(); RunUnitTest(m, "Analysis/SsaPushAndPop.txt"); }