Пример #1
0
        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;
        }
Пример #2
0
		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));
		}
Пример #3
0
		/// <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;
		}
Пример #4
0
        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);
        }
Пример #5
0
        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();
			}
		}
Пример #6
0
 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());
 }
Пример #7
0
		public void TrcoSegmentedAccess()
		{
			ProcedureBuilder m = new ProcedureBuilder();
			Identifier ds = m.Local16("ds");
			Identifier bx = m.Local16("bx");
			Identifier ax = m.Local16("ax");
			Expression e = m.SegMem(PrimitiveType.Word16, ds, m.IAdd(bx, 4));

            coll = CreateCollector();
			e = e.Accept(en);
			e.Accept(eqb);
			e.Accept(coll);
			Verify(null, "Typing/TrcoSegmentedAccess.txt");
		}
Пример #8
0
        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);
        }
Пример #9
0
		public void TrcoArrayExpression()
		{
			var b = new Identifier("base", PrimitiveType.Word32, null);
			var i = new Identifier("idx", PrimitiveType.Word32, null);
			var s = Constant.Word32(4);

			ProcedureBuilder m = new ProcedureBuilder();

			// e ::= Mem[(b+0x1003000)+(i*s):word16]
			Expression e = m.Load(
				PrimitiveType.Word16,
				m.IAdd(m.IAdd(b, Constant.Word32(0x10030000)),
				m.SMul(i, s)));
            coll = CreateCollector();
			e = e.Accept(en);
			e.Accept(eqb);
			e.Accept(coll);
			Verify(null, "Typing/TrcoArrayExpression.txt");
		}
Пример #10
0
        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();
            }
        }
Пример #11
0
        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");
        }
Пример #12
0
        public void DtbSegmentedAccess()
        {
            ProcedureBuilder m = new ProcedureBuilder();

            Identifier ds = m.Local16("ds");
            Identifier bx = m.Local16("bx");
            Expression e = m.SegMem(bx.DataType, ds, m.IAdd(bx, 4));
            var arch = new Reko.Arch.X86.X86ArchitectureReal();
            Program prog = new Program
            {
                Architecture = arch,
                Platform = new DefaultPlatform(null, arch),
            };
            TraitCollector trco = new TraitCollector(factory, store, dtb, prog);
            e = e.Accept(aen);
            e.Accept(eqb);
            e.Accept(trco);
            dtb.BuildEquivalenceClassDataTypes();
            Verify("Typing/DtbSegmentedAccess.txt");
        }
		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());

		}
Пример #14
0
        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);
        }
Пример #15
0
		public void TrcoGlobalArray()
		{
            Program prog = CreateProgram();
            ProcedureBuilder m = new ProcedureBuilder();
            Identifier i = m.Local32("i");
            Expression ea = m.IAdd(prog.Globals, m.IAdd(m.Shl(i, 2), 0x3000));
            Expression e = m.Load(PrimitiveType.Int32, ea);

            coll = CreateCollector(prog);
			e = e.Accept(en);
			e.Accept(eqb);
			e.Accept(coll);
			Verify(null, "Typing/TrcoGlobalArray.txt");
		}
Пример #16
0
        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);
        }
Пример #17
0
		public void TrcoMemberPointer()
		{
			ProcedureBuilder m = new ProcedureBuilder();
			Identifier ds = m.Local16("ds");
			Identifier bx = m.Local16("bx");
			Identifier ax = m.Local16("ax");
			MemberPointerSelector mps = m.MembPtrW(ds, m.IAdd(bx, 4));
			Expression e = m.Load(PrimitiveType.Byte, mps);

            coll = CreateCollector();
			e = e.Accept(en);
			e.Accept(eqb);
			e.Accept(coll);
			Assert.IsNotNull(mps.BasePointer.TypeVariable, "Base pointer should have type variable");
			Verify(null, "Typing/TrcoMemberPointer.txt");
		}
Пример #18
0
        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");
        }
Пример #19
0
 public static void MemStore(ProcedureBuilder m)
 {
     m.Store(m.Word32(0x3120), 0);
     m.Store(m.Word32(0x3120), m.IAdd(m.LoadDw(m.Word32(0x3120)), 1));
     m.Return();
 }