private void AssertSmallConst(string sExp, int shift, uint mult) { var m = new ProcedureBuilder(); var c = Constant.Int32((int)mult); var r1 = m.Reg32("r1", 1); var r2 = m.Reg32("r2", 2); var r2_r1 = m.Frame.EnsureSequence(r2.Storage, r1.Storage, PrimitiveType.Word64); var ass = m.Assign(r2_r1, m.SMul(r1, c)); m.Emit(new AliasAssignment(r2, m.Slice(PrimitiveType.Word32, r2_r1, 32))); if (shift != 0) m.Assign(r2, m.Sar(r2, shift)); var proc = m.Procedure; var ssa = new SsaTransform( null, proc, null, proc.CreateBlockDominatorGraph(), new HashSet<RegisterStorage>()).Transform(); var ctx = new SsaEvaluationContext(null, ssa.Identifiers); var rule = new ConstDivisionImplementedByMultiplication(ssa); ctx.Statement = proc.EntryBlock.Succ[0].Statements[0]; Assert.IsTrue(rule.Match(ass)); ass = rule.TransformInstruction(); Assert.AreEqual(sExp, ass.Src.ToString()); }
public void WriteProcedure_Max() { var m = new ProcedureBuilder("proc"); var r1 = m.Register("r1"); var r2 = m.Register("r2"); var r3 = m.Register("r3"); m.BranchIf(m.Gt(r1, r2), "greaterthan"); m.Assign(r3,r2); m.Assign(r2, r1); m.Assign(r1, r3); m.Label("greaterthan"); m.Return(r1); hcf.Write(m.Procedure); var sExp = @"void proc()<br /> {<br /> proc_entry:<br /> <span class=""kw"">goto</span> l1<br /> greaterthan:<br /> <span class=""kw"">return</span> r1<br /> l1:<br /> <span class=""kw"">branch</span> r1 > r2 greaterthan<br /> l2:<br /> r3 = r2<br /> r2 = r1<br /> r1 = r3<br /> <span class=""kw"">goto</span> greaterthan<br /> proc_exit:<br /> }<br /> "; Debug.Write(sb.ToString()); Assert.AreEqual(sExp, sb.ToString()); }
/// <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(); }
/// <summary> /// Builds a strongly connected component corresponding to: /// a1 = 0 /// a2 = phi(a1, a3) /// while (a2 != 10) /// { /// a3 = a2 + 4 /// } /// </summary> private List<SsaIdentifier> BuildScc() { var m = new ProcedureBuilder("test"); Identifier a = new Identifier("a", PrimitiveType.Word32, null); m.Label("b1"); m.Assign(a, Constant.Word32(0)); m.Label("b2"); m.Assign(a, m.IAdd(a, 4)); m.BranchIf(m.Ne(a, 10), "b2"); m.Label("b3"); m.Return(); this.dom = m.Procedure.CreateBlockDominatorGraph(); var ssa = new SsaTransform( new ProgramDataFlow(), m.Procedure, null, dom, new HashSet<RegisterStorage>()); /* proc = new Procedure("test", new Frame(PrimitiveType.Word32)); Block b1 = proc.AddBlock("b1"); Block b2 = proc.AddBlock("b2"); Identifier a2 = new Identifier("a2", PrimitiveType.Word32, null); Identifier a3 = new Identifier("a3", PrimitiveType.Word32, null); PhiFunction phi = new PhiFunction(a1.DataType, new Expression [] { a1, a3 }); Statement stm_a1 = new Statement(0, new Assignment(a1, Constant.Word32(0)), null); Statement stm_a2 = new Statement(0, new PhiAssignment(a2, new PhiFunction(a1.DataType, a1, a3 )), null); Statement stm_ex = new Statement(0, new Branch(new BinaryExpression(Operator.Ne, PrimitiveType.Bool, a2, Constant.Word32(10)), b2), null); Statement stm_a3 = new Statement(0, new Assignment(a3, new BinaryExpression(Operator.IAdd, a3.DataType, a2, Constant.Word32(4))), null); b1.Statements.Add(stm_a1); b2.Statements.Add(stm_a2); b2.Statements.Add(stm_a3); SsaIdentifier sid_a1 = new SsaIdentifier(a1, a1, stm_a1, ((Assignment)stm_a1.Instruction).Src, false); SsaIdentifier sid_a2 = new SsaIdentifier(a2, a2, stm_a2, ((PhiAssignment) stm_a2.Instruction).Src, false); SsaIdentifier sid_a3 = new SsaIdentifier(a3, a3, stm_a3, ((Assignment) stm_a3.Instruction).Src, false); sid_a1.Uses.Add(stm_a2); ssaIds = new SsaIdentifierCollection(); ssaIds.Add(a1, sid_a1); ssaIds.Add(a2, sid_a2); ssaIds.Add(a3, sid_a3); */ ssaIds = ssa.SsaState.Identifiers; List<SsaIdentifier> list = new List<SsaIdentifier> { ssaIds.Where(i => i.Identifier.Name == "a_0").Single(), ssaIds.Where(i => i.Identifier.Name == "a_1").Single(), ssaIds.Where(i => i.Identifier.Name == "a_2").Single(), }; return list; }
public void Pdg_PostDominateIfElse() { ProcedureBuilder m = new ProcedureBuilder(); m.BranchIf(m.Local32("a"), "then"); m.Assign(m.Local32("b"), m.Int32(0)); m.Jump("join"); m.Label("then"); m.Assign(m.Local32("c"), m.Int32(0)); m.Label("join"); m.Return(); FindPostDominators(m); }
private Procedure BuildSimpleLoop() { ProcedureBuilder m = new ProcedureBuilder(); Identifier p = m.Local32("p"); m.Assign(p, 0); m.Label("loop"); m.BranchIf(m.Eq(p, 0x4000), "done"); m.Store(m.IAdd(p, 0x3000), m.Int32(0)); m.Assign(p, m.IAdd(p, 4)); m.Goto("loop"); m.Label("done"); m.Return(); return m.Procedure; }
public void Test1() { var m = new ProcedureBuilder(); var id = m.Local32("id"); var x = m.Local32("x"); var stm = m.Assign(x, m.IAdd(m.SMul(id, 4), id)); }
public void DeadFnReturn() { ProcedureBuilder m = new ProcedureBuilder("foo"); Identifier unused = m.Local32("unused"); m.Assign(unused, m.Fn("foo", Constant.Word32(1))); m.Return(); RunTest(m, "Analysis/DeadFnReturn.txt"); }
public void SsaCallIndirect() { var m = new ProcedureBuilder("SsaCallIndirect"); var r1 = m.Reg32("r1"); var r2 = m.Reg32("r2"); m.Assign(r1, m.LoadDw(r2)); m.Call(r1, 4); m.Return(); RunUnitTest(m, "Analysis/SsaCallIndirect.txt"); }
public void DpaConstantPointer() { ProgramBuilder prog = new ProgramBuilder(); ProcedureBuilder m = new ProcedureBuilder(); Identifier r1 = m.Register(1); m.Assign(r1, 0x123130); m.Store(r1, m.Int32(0x42)); prog.Add(m); RunTest(prog.BuildProgram(), "Typing/DpaConstantPointer.txt"); }
public void DpaConstantMemberPointer() { ProgramBuilder prog = new ProgramBuilder(); ProcedureBuilder m = new ProcedureBuilder(); Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier bx = m.Local16("bx"); m.Assign(bx, 0x1234); m.Store(m.SegMemW(ds, bx), m.Int16(0x0042)); prog.Add(m); RunTest(prog.BuildProgram(), "Typing/DpaConstantMemberPointer.txt"); }
public void OutpReplaceSimple() { var m = new ProcedureBuilder(); m.Label("block"); var foo = new Identifier("foo", PrimitiveType.Word32, null); var pfoo = new Identifier("pfoo", PrimitiveType.Pointer32, null); m.Assign(foo, 3); var sid = new SsaIdentifier(foo, foo, m.Block.Statements.Last, null, false); var ssaIds = new SsaIdentifierCollection { { foo, sid } }; var opt = new OutParameterTransformer(null, ssaIds); opt.ReplaceDefinitionsWithOutParameter(foo, pfoo); Assert.AreEqual("*pfoo = 0x00000003", m.Block.Statements[0].ToString()); }
public void BlockCloner_CloneBlock() { var m = new ProcedureBuilder(arch, "fn1000"); var r1 = m.Register("r1"); var r2 = m.Register("r2"); var ass = m.Assign(r1, r2); m.Return(); var block = m.Procedure.ControlGraph.Blocks[2]; m = new ProcedureBuilder(arch, "procCalling"); var blockCloner = new BlockCloner(block, m.Procedure, callgraph); var blockNew = blockCloner.Execute(); var assNew = (Assignment) blockNew.Statements[0].Instruction; Assert.AreNotSame(ass.Dst, assNew.Dst); Assert.AreNotSame(ass.Src, assNew.Src); }
public void TrcoCallFunctionWithArraySize() { var m = new ProcedureBuilder(); var sig = new ProcedureSignature(null, m.Frame.EnsureStackArgument(0, PrimitiveType.Word32)); var ex = new ExternalProcedure("malloc", sig, new ProcedureCharacteristics { Allocator = true, ArraySize = new ArraySizeCharacteristic { Argument = "r", Factors = new ArraySizeFactor[] { new ArraySizeFactor { Constant = "1" } } } }); Identifier eax = m.Local32("eax"); var call = m.Assign(eax, m.Fn(new ProcedureConstant(PrimitiveType.Word32, ex), m.Word32(3))); coll = CreateCollector(); call.Accept(eqb); call.Accept(coll); StringWriter sw = new StringWriter(); handler.Traits.Write(sw); string sExp = "T_1 (in malloc : word32)" + nl + "\ttrait_func(T_4 -> T_5)" + nl + "T_3 (in dwArg00 : word32)" + nl + "\ttrait_primitive(word32)" + nl + "T_4 (in 0x00000003 : word32)" + nl + "\ttrait_primitive(word32)" + nl + "\ttrait_equal(T_3)" + nl + "T_5 (in malloc(0x00000003) : word32)" + nl + "\ttrait_primitive(word32)"; Console.WriteLine(sw.ToString()); Assert.AreEqual(sExp, sw.ToString()); }
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 VpUndoUnnecessarySlicingOfSegmentPointer() { var m = new ProcedureBuilder(); var es = m.Reg16("es", 1); var bx = m.Reg16("bx", 3); var es_bx = m.Frame.EnsureSequence(es.Storage, bx.Storage, PrimitiveType.Word32); m.Assign(es_bx, m.SegMem(PrimitiveType.Word32, es, bx)); m.Assign(es, m.Slice(PrimitiveType.Word16, es_bx, 16)); m.Assign(bx, m.Cast(PrimitiveType.Word16, es_bx)); m.SegStore(es, m.IAdd(bx, 4), m.Byte(3)); var ssa = RunTest(m); var sExp = #region Expected @"es:es def: def es uses: es_bx_3 = Mem0[es:bx:word32] bx:bx def: def bx uses: es_bx_3 = Mem0[es:bx:word32] Mem0:Global memory def: def Mem0 uses: es_bx_3 = Mem0[es:bx:word32] es_bx_3: orig: es_bx def: es_bx_3 = Mem0[es:bx:word32] uses: es_4 = SLICE(es_bx_3, word16, 16) bx_5 = (word16) es_bx_3 Mem0[es_bx_3 + 0x0004:byte] = 0x03 es_4: orig: es def: es_4 = SLICE(es_bx_3, word16, 16) bx_5: orig: bx def: bx_5 = (word16) es_bx_3 Mem6: orig: Mem0 def: Mem0[es_bx_3 + 0x0004:byte] = 0x03 // ProcedureBuilder // Return size: 0 void ProcedureBuilder() ProcedureBuilder_entry: def es def bx def Mem0 // succ: l1 l1: es_bx_3 = Mem0[es:bx:word32] es_4 = SLICE(es_bx_3, word16, 16) bx_5 = (word16) es_bx_3 Mem0[es_bx_3 + 0x0004:byte] = 0x03 ProcedureBuilder_exit: "; #endregion AssertStringsEqual(sExp, ssa); }
public void VpLoadDpbSmallerCast() { var m = new ProcedureBuilder(); var a2 = m.Reg32("a2", 10); var d3 = m.Reg32("d3", 3); var tmp = m.Temp(PrimitiveType.Word16, "tmp"); m.Assign(tmp, m.LoadW(a2)); m.Assign(d3, m.Dpb(d3, tmp, 0)); m.Store(m.IAdd(a2, 4), m.Cast(PrimitiveType.Byte, d3)); SsaState ssa = RunTest(m); var sExp = #region Expected @"a2:a2 def: def a2 uses: tmp_2 = Mem0[a2:word16] Mem5[a2 + 0x00000004:byte] = (byte) tmp_2 Mem0:Global memory def: def Mem0 uses: tmp_2 = Mem0[a2:word16] tmp_2: orig: tmp def: tmp_2 = Mem0[a2:word16] uses: d3_4 = DPB(d3, tmp_2, 0) Mem5[a2 + 0x00000004:byte] = (byte) tmp_2 d3:d3 def: def d3 uses: d3_4 = DPB(d3, tmp_2, 0) d3_4: orig: d3 def: d3_4 = DPB(d3, tmp_2, 0) Mem5: orig: Mem0 def: Mem5[a2 + 0x00000004:byte] = (byte) tmp_2 // ProcedureBuilder // Return size: 0 void ProcedureBuilder() ProcedureBuilder_entry: def a2 def Mem0 def d3 // succ: l1 l1: tmp_2 = Mem0[a2:word16] d3_4 = DPB(d3, tmp_2, 0) Mem5[a2 + 0x00000004:byte] = (byte) tmp_2 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 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 SsaStackReference_Load() { var m = new ProcedureBuilder("SsaStackReference"); var wRef = m.Frame.EnsureStackArgument(4, PrimitiveType.Word16); var ax = EnsureRegister16(m, "ax"); m.Assign(ax, wRef); m.Return(); RunUnitTest(m, "Analysis/SsaStackReference.txt"); }
public void VpDbpDbp() { var m = new ProcedureBuilder(); var d1 = m.Reg32("d32",0); var a1 = m.Reg32("a32",1); m.Assign(d1, m.Dpb(d1, m.LoadW(a1), 0)); m.Assign(d1, m.Dpb(d1, m.LoadW(m.IAdd(a1, 4)), 0)); Procedure proc = m.Procedure; var gr = proc.CreateBlockDominatorGraph(); var importResolver = MockRepository.GenerateStub<IImportResolver>(); importResolver.Replay(); var sst = new SsaTransform(new ProgramDataFlow(), proc, importResolver, gr, new HashSet<RegisterStorage>()); var ssa = sst.SsaState; var vp = new ValuePropagator(arch, ssa); vp.Transform(); using (FileUnitTester fut = new FileUnitTester("Analysis/VpDpbDpb.txt")) { proc.Write(false, fut.TextWriter); fut.TextWriter.WriteLine(); fut.AssertFilesEqual(); } }
public void OutpReplacePhi() { var m = new ProcedureBuilder(); var foo = new Identifier("foo", PrimitiveType.Word32, null); var foo1 = new Identifier("foo1", PrimitiveType.Word32, null); var foo2 = new Identifier("foo2", PrimitiveType.Word32, null); var foo3 = new Identifier("foo3", PrimitiveType.Word32, null); var pfoo = new Identifier("pfoo", PrimitiveType.Pointer32, null); Block block1 = m.Label("block1"); m.Assign(foo1, Constant.Word32(1)); Statement stmFoo1 = m.Block.Statements.Last; Block block2 = m.Label("block2"); m.Assign(foo2, Constant.Word32(2)); Statement stmFoo2 = m.Block.Statements.Last; Block block3 = m.Label("block3"); Statement stmFoo3 = m.Phi(foo3, foo1, foo2); SsaIdentifierCollection ssaIds = new SsaIdentifierCollection(); ssaIds.Add(foo1, new SsaIdentifier(foo1, foo, stmFoo1, null, false)); ssaIds.Add(foo2, new SsaIdentifier(foo2, foo, stmFoo2, null, false)); ssaIds.Add(foo3, new SsaIdentifier(foo3, foo, stmFoo3, null, false)); OutParameterTransformer opt = new OutParameterTransformer(null, ssaIds); opt.ReplaceDefinitionsWithOutParameter(foo3, pfoo); Assert.AreEqual("*pfoo = 0x00000001", stmFoo1.Instruction.ToString()); Assert.AreEqual("*pfoo = 0x00000002", stmFoo2.Instruction.ToString()); Assert.AreEqual("foo3 = PHI(foo1, foo2)", stmFoo3.Instruction.ToString()); }
public void VpCastRealConstant() { var m = new ProcedureBuilder(); var r1 = m.Reg32("r1", 1); m.Assign(r1, m.Cast(PrimitiveType.Real32, ConstantReal.Real64(1))); var ssa = RunTest(m); var sExp = #region Expected @"r1_0: orig: r1 def: r1_0 = 1.0F // ProcedureBuilder // Return size: 0 void ProcedureBuilder() ProcedureBuilder_entry: // succ: l1 l1: r1_0 = 1.0F ProcedureBuilder_exit: "; #endregion AssertStringsEqual(sExp, ssa); }
public void OutpReplaceManyUses() { ProcedureBuilder m = new ProcedureBuilder(); Identifier foo = new Identifier("foo", PrimitiveType.Word32, null); Identifier bar = new Identifier("bar", PrimitiveType.Word32, null); Identifier pfoo = new Identifier("pfoo", PrimitiveType.Pointer32, null); Block block = m.Label("block"); m.Assign(foo, 1); Statement stmFoo = m.Block.Statements.Last; m.Assign(bar, foo); Statement stmBar = m.Block.Statements.Last; SsaIdentifier ssaFoo = new SsaIdentifier(foo, foo, stmFoo, ((Assignment) stmFoo.Instruction).Src, false); ssaFoo.Uses.Add(stmBar); SsaIdentifier ssaBar = new SsaIdentifier(bar, bar, stmBar, ((Assignment) stmBar.Instruction).Src, false); SsaIdentifierCollection ssaIds = new SsaIdentifierCollection(); ssaIds.Add(foo, ssaFoo); ssaIds.Add(bar, ssaBar); OutParameterTransformer opt = new OutParameterTransformer(m.Procedure, ssaIds); opt.ReplaceDefinitionsWithOutParameter(foo, pfoo); Assert.AreEqual(3, block.Statements.Count); Assert.AreEqual("foo = 0x00000001", block.Statements[0].Instruction.ToString()); Assert.AreEqual("*pfoo = foo", block.Statements[1].Instruction.ToString()); Assert.AreEqual("bar = foo", block.Statements[2].Instruction.ToString()); }
public void VpMulBy6() { var m = new ProcedureBuilder(); var r1 = m.Reg16("r1", 1); var r2 = m.Reg16("r1", 2); m.Assign(r2, r1); // r1 m.Assign(r1, m.Shl(r1, 1)); // r1 * 2 m.Assign(r1, m.IAdd(r1, r2)); // r1 * 3 m.Assign(r1, m.Shl(r1, 1)); // r1 * 6 var ssa = RunTest(m); var sExp = #region Expected @"r1:r1 def: def r1 uses: r1_1 = r1 r1_2 = r1 << 0x01 r1_3 = r1 * 0x0003 r1_4 = r1 * 0x0006 r1_1: orig: r1 def: r1_1 = r1 r1_2: orig: r1 def: r1_2 = r1 << 0x01 r1_3: orig: r1 def: r1_3 = r1 * 0x0003 r1_4: orig: r1 def: r1_4 = r1 * 0x0006 // ProcedureBuilder // Return size: 0 void ProcedureBuilder() ProcedureBuilder_entry: def r1 // succ: l1 l1: r1_1 = r1 r1_2 = r1 << 0x01 r1_3 = r1 * 0x0003 r1_4 = r1 * 0x0006 ProcedureBuilder_exit: "; #endregion AssertStringsEqual(sExp, ssa); }
public void VpDbpDbp() { var m = new ProcedureBuilder(); var d1 = m.Reg32("d32"); var a1 = m.Reg32("a32"); var tmp = m.Frame.CreateTemporary(PrimitiveType.Word16); m.Assign(d1, m.Dpb(d1, m.LoadW(a1), 0, 16)); m.Assign(d1, m.Dpb(d1, m.LoadW(m.IAdd(a1, 4)), 0, 16)); Procedure proc = m.Procedure; var gr = proc.CreateBlockDominatorGraph(); SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr); SsaState ssa = sst.SsaState; ssa.DebugDump(true); var vp = new ValuePropagator(arch, ssa.Identifiers, proc); vp.Transform(); using (FileUnitTester fut = new FileUnitTester("Analysis/VpDpbDpb.txt")) { proc.Write(false, fut.TextWriter); fut.TextWriter.WriteLine(); fut.AssertFilesEqual(); } }
public void VpAddress32Const() { var m = new ProcedureBuilder("VpAddress32Const"); var r1 = m.Reg32("r1", 1); m.Assign(r1, Address.Ptr32(0x00123400)); m.Assign(r1, m.Load(r1.DataType, m.IAdd(r1, 0x56))); m.Return(); mr.ReplayAll(); RunFileTest(m, "Analysis/VpAddress32Const.txt"); }
public void CceEqId() { Identifier r = Reg32("r"); Identifier z = FlagGroup("z"); // is a condition code. Identifier y = FlagGroup("y"); // is a condition code. ProcedureBuilder m = new ProcedureBuilder(); m.Assign(z, new ConditionOf(r)); ssaIds[z].DefStatement = m.Block.Statements.Last; m.Assign(y, z); ssaIds[y].DefStatement = m.Block.Statements.Last; ssaIds[z].Uses.Add(m.Block.Statements.Last); var stmBr = m.BranchIf(m.Test(ConditionCode.EQ, y), "foo"); ssaIds[y].Uses.Add(stmBr); var arch = new FakeArchitecture(); var cce = new ConditionCodeEliminator(ssaIds, new DefaultPlatform(null, arch)); cce.Transform(); Assert.AreEqual("branch r == 0x00000000 foo", stmBr.Instruction.ToString()); }
public void Scanner_IsLinearReturn_DoesntEndWithReturn() { var scanner = CreateScanner(0x1000, 0x1000); var m = new ProcedureBuilder(arch, "fn1000"); m.Assign(m.Register("ax"), m.Register("bx")); var block = m.Block; Assert.IsFalse(scanner.IsLinearReturning(block)); }
public void TrcoDbp() { ProcedureBuilder m = new ProcedureBuilder(); Identifier a = m.Local32("a"); Identifier b = m.LocalByte("b"); var s = m.Assign(a, m.Dpb(a, b, 0)); coll = CreateCollector(); s.Accept(eqb); s.Accept(coll); StringWriter sb = new StringWriter(); handler.Traits.Write(sb); Console.WriteLine(sb); string exp = "T_1 (in a : word32)" + nl + "\ttrait_primitive(word32)" + nl + "\ttrait_primitive(word32)" + nl + "\ttrait_primitive(word32)" + nl + "\ttrait_equal(T_3)" + nl + "T_2 (in b : byte)" + nl + "\ttrait_primitive(byte)" + nl + "T_3 (in DPB(a, b, 0) : word32)" + nl + "\ttrait_primitive(word32)" + nl; Assert.AreEqual(exp, sb.ToString()); }