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> /// 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, dom); /* 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 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)); }
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.Jump("loop"); m.Label("done"); m.Return(); return m.Procedure; }
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 OutpReplaceSimple() { var m = new ProcedureBuilder(); var block = 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 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 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 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 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"); }
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 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 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(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 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 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 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 CreateNoincInitialValue() { ProcedureBuilder m = new ProcedureBuilder(); ssaIds = new SsaIdentifierCollection(); SsaId(new Identifier("id0", PrimitiveType.Word32, new TemporaryStorage("id0", 0, PrimitiveType.Word32)), null, null, false); SsaId(new Identifier("id1", PrimitiveType.Word32, new TemporaryStorage("id1", 1, PrimitiveType.Word32)), null, null, false); LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, ssaIds, null); liv.Context.InitialValue = Constant.Word32(0); Identifier id2 = m.Local32("id_2"); SsaId(id2, new Statement(0, null, null), null, false); Assert.AreEqual(3, ssaIds.Count); Identifier id3 = m.Local32("id_3"); Identifier id4 = m.Local32("id_4"); liv.Context.PhiStatement = m.Phi(id3, id2, id4); liv.Context.PhiIdentifier = id3; SsaId(id3, liv.Context.PhiStatement, ((PhiAssignment)liv.Context.PhiStatement.Instruction).Src, false); Assert.AreEqual(4, ssaIds.Count); Statement use = new Statement(0, null, null); ssaIds[id3].Uses.Add(use); liv.Context.DeltaValue = m.Int32(1); m.Assign(id4, m.IAdd(id3, liv.Context.DeltaValue)); liv.Context.DeltaStatement = m.Block.Statements.Last; ssaIds[id3].Uses.Add(liv.Context.DeltaStatement); LinearInductionVariable iv = liv.CreateInductionVariable(); Assert.AreEqual("(0x00000000 0x00000001 ?)", iv.ToString()); }
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 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, 8)); 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, 8) : word32)" + nl + "\ttrait_primitive(word32)" + nl; Assert.AreEqual(exp, sb.ToString()); }
public void DtbSignedCompare() { ProcedureBuilder m = new ProcedureBuilder(); Identifier p = m.Local32("p"); Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier ds2 = m.Local16("ds2"); ds.DataType = PrimitiveType.SegmentSelector; m.Assign(ds2, ds); m.Store( m.SegMem(PrimitiveType.Bool, ds, m.Word16(0x5400)), m.Lt(m.SegMemW(ds, m.Word16(0x5404)), m.Word16(20))); m.Store(m.SegMemW(ds2, m.Word16(0x5404)), m.Word16(0)); ProgramBuilder prog = new ProgramBuilder(); prog.Add(m); RunTest(prog.BuildProgram(), "Typing/DtbSignedCompare.txt"); }
public void VpEquality2() { // Makes sure that // y = x - 2 // if (y == 0) ... // doesn't get munged into // y = x - 2 // if (x == 2) Identifier x = Reg32("x"); Identifier y = Reg32("y"); ProcedureBuilder m = new ProcedureBuilder(); 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(ssaIds, null); vp.Transform(stm); Assert.AreEqual("branch x == 0x00000002 test", stm.Instruction.ToString()); }