예제 #1
0
        private void RunTest(string sExp, Action<ProcedureBuilder> builder)
        {
            var pb = new ProcedureBuilder(this.pb.Program.Architecture);
            builder(pb);
            var proc = pb.Procedure;
            var dg = new DominatorGraph<Block>(proc.ControlGraph, proc.EntryBlock);

            // Perform the initial transformation
            var ssa = new SsaTransform(programFlow, proc, dg);

            // Propagate values and simplify the results.
            // We hope the the sequence
            //   esp = fp - 4
            //   mov [esp-4],eax
            // will become
            //   esp_2 = fp - 4
            //   mov [fp - 8],eax

            var vp = new ValuePropagator(ssa.SsaState.Identifiers, proc);
            vp.Transform();

            ssa.RenameFrameAccesses = true;
            ssa.AddUseInstructions = true;
            ssa.Transform();

            var writer = new StringWriter();
            proc.Write(false, writer);
            var sActual = writer.ToString();
            if (sActual != sExp)
                Debug.Print(sActual);
            Assert.AreEqual(sExp, sActual);
        }
예제 #2
0
        private void RunTest(string sExp, Action<ProcedureBuilder> builder)
        {
            var pb = new ProcedureBuilder(this.pb.Program.Architecture);
            builder(pb);
            var proc = pb.Procedure;
            var dg = new DominatorGraph<Block>(proc.ControlGraph, proc.EntryBlock);
            var project = new Project
            {
                Programs = { this.pb.Program }
            };
            var importResolver = new ImportResolver(
                project,
                this.pb.Program,
                new FakeDecompilerEventListener());
            var arch = new FakeArchitecture();
            
            var platform = new FakePlatform(null, arch);

            // Register r1 is assumed to always be implicit when calling
            // another procedure.
            var implicitRegs = new HashSet<RegisterStorage>
            {
                arch.GetRegister(1)
            };
            Debug.Print("GetRegister(1) {0}", arch.GetRegister(1));
            this.pb.Program.Platform = platform;
            this.pb.Program.Platform = new FakePlatform(null, new FakeArchitecture());
            this.pb.Program.SegmentMap = new SegmentMap(
                Address.Ptr32(0x0000),
                new ImageSegment(
                    ".text",
                    Address.Ptr32(0), 
                    0x40000,
                    AccessMode.ReadWriteExecute));

            // Perform the initial transformation
            var ssa = new SsaTransform(programFlow, proc, importResolver, dg, implicitRegs);

            // Propagate values and simplify the results.
            // We hope the the sequence
            //   esp = fp - 4
            //   mov [esp-4],eax
            // will become
            //   esp_2 = fp - 4
            //   mov [fp - 8],eax

            var vp = new ValuePropagator(this.pb.Program.Architecture, ssa.SsaState);
            vp.Transform();

            ssa.RenameFrameAccesses = true;
            ssa.AddUseInstructions = true;
            ssa.Transform();

            var writer = new StringWriter();
            proc.Write(false, writer);
            var sActual = writer.ToString();
            if (sActual != sExp)
                Debug.Print(sActual);
            Assert.AreEqual(sExp, sActual);
        }
예제 #3
0
        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());
        }
예제 #4
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));
		}
예제 #5
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());
        }
예제 #6
0
		public void Setup()
		{
            m = new ProcedureBuilder();
            ssaState = new SsaState(m.Procedure, null);
            ssaIds = ssaState.Identifiers;
            freg = new FlagRegister("flags", 32, PrimitiveType.Word32);
		}
예제 #7
0
 private void FindPostDominators(ProcedureBuilder m)
 {
     ProcedureStructureBuilder graphs = new ProcedureStructureBuilder(m.Procedure);
     h = graphs.Build();
     sw = new StringWriter();
     graphs.AnalyzeGraph().Write(sw);
 }
예제 #8
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();
        }
예제 #9
0
 public void Setup()
 {
     this.sc = new ServiceContainer();
     this.x86 = new X86ArchitectureFlat32();
     this.ppc = new PowerPcArchitecture32();
     this.m = new ProcedureBuilder();
     this.printfChr = new ProcedureCharacteristics()
     {
         VarargsParserClass =
             "Reko.Libraries.Libc.PrintfFormatParser,Reko.Libraries.Libc"
     };
     this.x86PrintfSig = new FunctionType(
         null,
         StackId(null,   4, CStringType()),
         StackId("...",  8, new UnknownType()));
     this.x86SprintfSig = new FunctionType(
         null,
         StackId(null,   4, CStringType()),
         StackId(null,   8, CStringType()),
         StackId("...", 12, new UnknownType()));
     this.ppcPrintfSig = new FunctionType(
         null,
         RegId(null,  ppc, "r3", CStringType()),
         RegId("...", ppc, "r4", new UnknownType()));
     this.addrInstr = Address.Ptr32(0x123400);
 }
 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;
 }
        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());
        }
예제 #12
0
 protected virtual void RunTest(ProcedureBuilder pm)
 {
     ProcedureStructureBuilder g = new ProcedureStructureBuilder(pm.Procedure);
     g.BuildNodes();
     g.DefineEdges();
     proc = g.CreateProcedureStructure();
     g.SetTimeStamps();
 }
예제 #13
0
 private void CompileTest(ProcedureBuilder mock)
 {
     proc = mock.Procedure;
     StructureAnalysis sa = new StructureAnalysis(mock.Procedure);
     sa.BuildProcedureStructure();
     sa.FindStructures();
     curProc = sa.ProcedureStructure;
 }
예제 #14
0
 public void Fstsw_Setup()
 {
     arch = new X86ArchitectureFlat32();
     asm = new X86Assembler(null, new DefaultPlatform(null, new X86ArchitectureFlat32()), Address.Ptr32(0x10000), new List<ImageSymbol>());
     Procedure proc = new Procedure("test", arch.CreateFrame());
     orw = new OperandRewriter32(arch, proc.Frame, null);
     emitter = new ProcedureBuilder();
 }
예제 #15
0
 public void Fstsw_Setup()
 {
     arch = new IntelArchitecture(ProcessorMode.Protected32);
     asm = new X86Assembler(arch, Address.Ptr32(0x10000), new List<EntryPoint>());
     Procedure proc = new Procedure("test", arch.CreateFrame());
     orw = new OperandRewriter32(arch, proc.Frame, null);
     emitter = new ProcedureBuilder();
 }
예제 #16
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");
		}
예제 #17
0
 private void RunBlockTest(Action<ProcedureBuilder> testBuilder)
 {
     var builder = new ProcedureBuilder(); 
     testBuilder(builder);
     var proc = builder.Procedure;
     CreateSymbolicEvaluator(proc.Frame);
     proc.ControlGraph.Successors(proc.EntryBlock).First().Statements.ForEach(x => se.Evaluate(x.Instruction));
 }
예제 #18
0
 private void RunTest(ProcedureBuilder mock, string outputFile)
 {
     using (FileUnitTester fut = new FileUnitTester(outputFile))
     {
         mock.Procedure.Write(true, fut.TextWriter);
         fut.AssertFilesEqual();
     }
 }
예제 #19
0
 protected Program CompileTest(Action<ProcedureBuilder> m)
 {
     var mock = new ProcedureBuilder();
     m(mock);
     var pmock = new ProgramBuilder();
     pmock.Add(mock);
     return pmock.BuildProgram();
 }
		public void Setup()
		{
			m = new ProcedureBuilder();
			i = m.Local32("i");
			c = m.Int32(16);
			off = m.Int32(42);
			r = m.Local32("r");
			aem = new ArrayExpressionMatcher(PrimitiveType.Pointer32);
		}
예제 #21
0
 public void PprMemberVars()
 {
     ProgramBuilder mock = new ProgramBuilder();
     ProcedureBuilder p = new ProcedureBuilder();
     Identifier cs = p.Frame.EnsureRegister(Registers.cs);
     p.Store(p.SegMemW(cs, p.Word32(0x0001)), Constant.Create(PrimitiveType.SegmentSelector, 0x0800));
     mock.Add(p);
     RunTest(mock.BuildProgram(), "Typing/PprMemberVars.txt");
 }
예제 #22
0
 public void PprMemberPointers()
 {
     ProgramBuilder mock = new ProgramBuilder();
     ProcedureBuilder m = new ProcedureBuilder();
     Identifier ds = m.Local(PrimitiveType.SegmentSelector, "ds");
     m.SegStore(ds, m.Word32(7000), m.SegMemW(ds, m.SegMemW(ds, m.Word32(0x5321))));
     mock.Add(m);
     RunTest(mock.BuildProgram(), "Typing/PprMemberPointers.txt");
 }
예제 #23
0
 public void Setup()
 {
     arch = new IntelArchitecture(ProcessorMode.Protected32);
     m = new ProcedureBuilder();
     state = arch.CreateProcessorState();
     expSimp = new ExpressionSimplifier(
             new IntelArchitecture(ProcessorMode.Protected32).CreateProcessorState());
     SCZO = m.Frame.EnsureFlagGroup((uint)(FlagM.SF | FlagM.CF | FlagM.ZF | FlagM.OF), "SCZO", PrimitiveType.Byte);
     host = new BackwalkerHost();
 }
예제 #24
0
 public void Setup()
 {
     arch = new X86ArchitectureFlat32();
     m = new ProcedureBuilder(arch);
     program = new Program();
     program.Architecture = arch;
     exit = new Procedure("exit", new Frame(PrimitiveType.Word32));
     flow = new ProgramDataFlow();
     p = new ProgramBuilder();
 }
예제 #25
0
 public Procedure Add(string procName, Action<ProcedureBuilder> testCodeBuilder)
 {
     var mock = new ProcedureBuilder(Program.Architecture, procName, null);
     mock.ProgramMock = this;
     mock.LinearAddress = (uint)((procCount + 1) * 0x1000);
     testCodeBuilder(mock);
     Add(mock.Procedure);
     unresolvedProcedures.AddRange(mock.UnresolvedProcedures);
     return mock.Procedure;
 }
예제 #26
0
 public void Setup()
 {
     arch = new IntelArchitecture(ProcessorMode.Protected32);
     m = new ProcedureBuilder(arch);
     prog = new Program();
     prog.Architecture = arch;
     exit = new Procedure("exit", new Frame(PrimitiveType.Word32));
     flow = new ProgramDataFlow();
     p = new ProgramBuilder();
 }
 private Procedure RunTest(string sExp, string fnName, Action<ProcedureBuilder> builder)
 {
     var pb = new ProcedureBuilder(fnName);
     return RunTest(sExp, pb.Architecture, () =>
     {
         builder(pb);
         progBuilder.Add(pb);
         return pb.Procedure;
     });
 }
예제 #28
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;
		}
예제 #29
0
        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");
        }
예제 #30
0
		public void SetUp()
		{
			m = new ProcedureBuilder();
			id = m.Local32("id");
			x = m.Local32("x");
			ssaIds = new SsaIdentifierCollection();
			foreach (Identifier i in m.Procedure.Frame.Identifiers)
			{
				ssaIds.Add(i, null, null, false);
			}
		}
        public void CEB_SegmentedArray()
        {
            var m   = new Reko.UnitTests.Mocks.ProcedureBuilder("CEB_SegmentedArray");
            var aw  = new ArrayType(PrimitiveType.Int16, 0);
            var ds  = m.Temp(PrimitiveType.SegmentSelector, "ds");
            var bx  = m.Temp(PrimitiveType.Word16, "bx");
            var acc =
                m.Array(
                    PrimitiveType.Word16,
                    m.Seq(
                        ds,
                        m.Word16(0x5388)),
                    m.IMul(bx, 2));

            CreateTv(globals, Ptr32(factory.CreateStructureType()), Ptr32(factory.CreateStructureType()));
            CreateTv(ds, Ptr16(factory.CreateStructureType()), Ptr16(factory.CreateStructureType()));
        }
예제 #32
0
 public void Add(ProcedureBuilder mock)
 {
     mock.ProgramMock = this;
     Add(mock.Procedure, null);
     unresolvedProcedures.AddRange(mock.UnresolvedProcedures);
 }