예제 #1
0
        /// <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();
        }
예제 #2
0
        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&nbsp;proc()<br />
            {<br />
            proc_entry:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">goto</span>&nbsp;l1<br />
            greaterthan:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">return</span>&nbsp;r1<br />
            l1:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">branch</span>&nbsp;r1&nbsp;&gt;&nbsp;r2&nbsp;greaterthan<br />
            l2:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;r3&nbsp;=&nbsp;r2<br />
            &nbsp;&nbsp;&nbsp;&nbsp;r2&nbsp;=&nbsp;r1<br />
            &nbsp;&nbsp;&nbsp;&nbsp;r1&nbsp;=&nbsp;r3<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">goto</span>&nbsp;greaterthan<br />
            proc_exit:<br />
            }<br />
            ";
            Debug.Write(sb.ToString());
            Assert.AreEqual(sExp, sb.ToString());
        }
 private void Given_Procedure(uint address)
 {
     var m = new ProcedureBuilder("fnTest");
     m.Return();
     this.proc = m.Procedure;
     this.program.Procedures[Address.Ptr32(address)] = this.proc;
 }
예제 #4
0
		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");
		}
예제 #5
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;
		}
예제 #6
0
파일: SsaTests.cs 프로젝트: nemerle/reko
        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 BlockTerminates()
        {
            var m = new ProcedureBuilder();
            m.Call(exit, 4);
            var b = m.CurrentBlock;
            m.Return();

            var a = new TerminationAnalysis(flow);
            flow[b] = CreateBlockFlow(b, m.Frame);
            a.Analyze(b);
            Assert.IsTrue(flow[b].TerminatesProcess);
        }
예제 #8
0
        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);
        }
예제 #9
0
        public void FindNoLoopInInterval()
        {
            ProcedureBuilder m = new ProcedureBuilder();
            m.Return();

            StructureNode node = new StructureNode(m.Procedure.ControlGraph.Blocks[1], 3);
            node.Order = 0;
            Interval interval = new Interval(1, node);

            var nodesInInterval = interval.FindIntervalNodes(0);
            SccLoopFinder finder = new SccLoopFinder(interval, nodesInInterval);
            var loopNodes = finder.FindLoop();
            Assert.AreEqual(0, loopNodes.Count);
        }
예제 #10
0
 public void BlockDoesntTerminate()
 {
     var m = new ProcedureBuilder();
     m.Store(m.Word32(0x1231), m.Byte(0));
     var b = m.Block;
     m.Return();
     var a = new TerminationAnalysis(flow);
     program = new Program
     {
         Architecture = new FakeArchitecture()
     };
     flow[b] = CreateBlockFlow(b, m.Frame);
     a.Analyze(b);
     Assert.IsFalse(flow[b].TerminatesProcess);
 }
예제 #11
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;
        }
예제 #12
0
        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);
        }
예제 #13
0
        public void Cvp_SetProcedure()
        {
            codeViewer.CreateControl();
            var m = new ProcedureBuilder();
            m.Return();

            using (mr.Record())
            {
                var project = new Project { Programs = { new Program() } };
                decompiler.Stub(d => d.Project).Return(project);
            }

            codeViewer.DisplayProcedure(m.Procedure);

            string sExp =
                "void ProcedureBuilder()" + nl +
                "{" + nl +
                "ProcedureBuilder_entry:" + nl +
                "l1:" + nl +
                "    'return'" + nl +
                "ProcedureBuilder_exit:" + nl +
                "}" + nl;
            Assert.AreEqual(sExp, Flatten(codeViewer.TextView.Model));
        }
예제 #14
0
        public void VpCastCast()
        {
            var m = new ProcedureBuilder();
            m.Store(
                m.Word32(0x1234000),
                m.Cast(
                    PrimitiveType.Real32,
                    m.Cast(
                        PrimitiveType.Real64, 
                        m.Load(PrimitiveType.Real32, m.Word32(0x123400)))));
            m.Return();
            mr.ReplayAll();

            RunFileTest(m, "Analysis/VpCastCast.txt");
        }
예제 #15
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);
        }
예제 #16
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();
 }
예제 #17
0
        public void Pdg_LoopWithIfElse()
        {
            var m = new ProcedureBuilder();
            var c = m.Declare(PrimitiveType.Word32, "c");
            var f = m.Declare(PrimitiveType.Bool, "f");
            m.Label("loopHead");
            m.BranchIf(m.Eq(c, 0), "done");
            m.BranchIf(f, "then");
            m.Label("else");
            m.SideEffect(m.Fn("CallElse"));
            m.Jump("loopHead");
            m.Label("then");
            m.SideEffect(m.Fn("CallThen"));
            m.Jump("loopHead");
            m.Label("done");
            m.Return();

            FindPostDominators(m);

            string sExp =
                "done (6): idom ProcedureBuilder_exit (7)" + nl +
                "else (4): idom loopHead (2)" + nl +
                "l1 (3): idom loopHead (2)" + nl +
                "loopHead (2): idom done (6)" + nl +
                "ProcedureBuilder_entry (1): idom loopHead (2)" + nl +
                "ProcedureBuilder_exit (7): idom " + nl +
                "then (5): idom loopHead (2)" + nl;
            Assert.AreEqual(sExp, sw.ToString());
        }
        public void Usb_ParseFunctionDeclaration_WithRegisterArgs()
        {
            var arch = new FakeArchitecture();
            var m = new ProcedureBuilder(arch, "test");
            var r1 = m.Reg32("r1", 1);
            var r2 = m.Reg32("r2", 2);
            m.Store(m.Word32(0x123400), m.Cast(PrimitiveType.Byte, r1));
            m.Store(m.Word32(0x123404), m.Cast(PrimitiveType.Real32, r2));
            m.Return();

            var usb = new UserSignatureBuilder(program);
            usb.ApplySignatureToProcedure(
                Address.Create(PrimitiveType.Pointer32, 0x1000),
                new ProcedureSignature(
                    null,
                    new Identifier("r2", PrimitiveType.Char, r1.Storage),  // perverse but legal.
                    new Identifier("r1", PrimitiveType.Real32, r2.Storage)),
                m.Procedure);
            var sExp = @"// test
// Return size: 0
void test(char r2, real32 r1)
test_entry:
	// succ:  l1
l1:
	r1 = r2
	r2 = r1
	Mem0[0x00123400:byte] = (byte) r1
	Mem0[0x00123404:real32] = (real32) r2
	return
	// succ:  test_exit
test_exit:
";
            var sb = new StringWriter();
            m.Procedure.Write(false, sb);
            Assert.AreEqual(sExp, sb.ToString());
        }
        private void Given_StubProcedure(uint addr, uint size)
        {
            var address = Address32.Ptr32(addr);
            var m = new ProcedureBuilder("fnTest");
            m.Return();
            this.proc = m.Procedure;
            this.program.Procedures[address] = proc;

            var item = new ImageMapBlock
            {
                Address = address,
                Size = size,
                Block = new Block(proc, "fakeBlock")
            };
            program.ImageMap.AddItemWithSize(address, item);
        }
예제 #20
0
        public void Scanner_IsLinearReturn_EndsWithReturn()
        {
            var scanner = CreateScanner(0x1000, 0x1000);
            var m = new ProcedureBuilder(arch, "fn1000");
            m.Return();

            var block = m.Procedure.ControlGraph.Blocks[2];
            Assert.IsTrue(scanner.IsLinearReturning(block));
        }
예제 #21
0
파일: SsaTests.cs 프로젝트: relaxar/reko
        public void SsaOutParamters()
        {
            ProcedureBuilder m = new ProcedureBuilder("foo");
            Identifier r4 = m.Register(4);
            m.Store(m.Int32(0x400), m.Fn("foo", m.Out(PrimitiveType.Pointer32, r4)));
            m.Return();

            RunFileTest(m, "Analysis/SsaOutParameters.txt");
        }
예제 #22
0
        public void Pdg_PostdominateLoop()
        {
            ProcedureBuilder m = new ProcedureBuilder();
            m.Jump("test");
            m.Label("test");
            m.BranchIf(m.LocalBool("f"), "done");
            m.Label("body");
            m.Store(m.Int32(30), m.Int32(0));
            m.Jump("test");
            m.Label("done");
            m.Return();

            FindPostDominators(m);
            string sExp = 
                "body (4): idom test (3)" + nl +
                "done (5): idom ProcedureBuilder_exit (6)" + nl +
                "l1 (2): idom test (3)" + nl +
                "ProcedureBuilder_entry (1): idom l1 (2)" + nl +
                "ProcedureBuilder_exit (6): idom " + nl +
                "test (3): idom done (5)" + nl;
            Console.WriteLine(sw.ToString());
            Assert.AreEqual(sExp, sw.ToString());
        }
예제 #23
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");
        }
예제 #24
0
        public void DfaUnsignedDiv()
        {
            var m = new ProcedureBuilder();
            var r1 = m.Register(1);
            var r2 = m.Register(2);
            var r2_r1 = m.Frame.EnsureSequence(r2.Storage, r1.Storage, PrimitiveType.Word64);
            var tmp = m.Frame.CreateTemporary(r2_r1.DataType);
            m.Assign(r1, m.LoadDw(m.Word32(0x123400)));
            m.Assign(r2_r1, m.Seq(m.Word32(0), r1));
            m.Assign(tmp, r2_r1);
            m.Assign(r1, m.UDiv(tmp, m.Word32(42)));
            m.Store(m.Word32(0x123404), r1);
            m.Return();

            RunFileTest(m, "Analysis/DfaUnsignedDiv.txt");
        }
예제 #25
0
파일: SsaTests.cs 프로젝트: relaxar/reko
        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");
        }
예제 #26
0
        public void Pdg_InfiniteLoop()
        {
            ProcedureBuilder m = new ProcedureBuilder();
            m.Label("Infinity");
            m.BranchIf(m.Eq(m.LoadW(m.Word16(0x1234)), 0), "hop");
            m.SideEffect(m.Fn("foo"));
            m.Label("hop");
            m.BranchIf(m.Eq(m.LoadW(m.Word16(0x5123)), 1), "Infinity");
            m.SideEffect(m.Fn("bar"));
            m.Jump("Infinity");
            m.Return();

            FindPostDominators(m);
            string sExp = 
                "hop (4): idom ProcedureBuilder_exit (6)" + nl +
                "Infinity (2): idom hop (4)" + nl +
                "l1 (3): idom hop (4)" + nl +
                "l2 (5): idom ProcedureBuilder_exit (6)" + nl +
                "ProcedureBuilder_entry (1): idom Infinity (2)" + nl +
                "ProcedureBuilder_exit (6): idom " + nl;
            Assert.AreEqual(sExp, sw.ToString());
        }
예제 #27
0
 private void Given_StubProcedure()
 {
     var m = new ProcedureBuilder("fnTest");
     m.Return();
     this.proc = m.Procedure;
     this.program.Procedures[Address.Ptr32(0x1234)] = proc;
 }
예제 #28
0
파일: SsaTests.cs 프로젝트: relaxar/reko
        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");
        }