public void SrtSimpleLoop()
        {
            Procedure proc = BuildSimpleLoop();

            var dom = proc.CreateBlockDominatorGraph();
            SsaTransform ssa = new SsaTransform(new ProgramDataFlow(), proc, dom);
            proc.Write(false, Console.Out);
            LinearInductionVariableFinder lif = new LinearInductionVariableFinder(proc, ssa.SsaState.Identifiers, dom);
            lif.Find();

            Assert.AreEqual(1, lif.InductionVariables.Count, "Should have found one induction variable");
            Assert.AreEqual(1, lif.Contexts.Count);
            LinearInductionVariableContext ctx = lif.Contexts[lif.InductionVariables[0]];

            StrengthReduction str = new StrengthReduction(ssa.SsaState,lif.InductionVariables[0], ctx);
            str.ClassifyUses();
            Assert.AreEqual(1, str.IncrementedUses.Count);
            str.ModifyUses();
            Assert.AreEqual("(0x00003000 0x00000004 0x00007000)", lif.InductionVariables[0].ToString());
            using (FileUnitTester fut = new FileUnitTester("Analysis/SrtSimpleLoop.txt"))
            {
                proc.Write(false, fut.TextWriter);
                fut.AssertFilesEqual();
            }
        }
示例#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);

            // 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);
        }
示例#3
0
		//[Test]
		public void VnSumTest()
		{
			Program prog = RewriteCodeFragment(
				@".i86
	push bp
	mov	 bp,sp
	mov	dx,3
	add dx,dx

	mov bx,3
	lea dx,[bx+3]
	mov sp,bp
	pop	bp
	ret
	");
			using (FileUnitTester fut = new FileUnitTester("Analysis/VnSumTest.txt"))
			{
				Procedure proc = prog.Procedures.Values[0];
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				var gr = proc.CreateBlockDominatorGraph();
                SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr);
				SsaState ssa = sst.SsaState;
				ValueNumbering vn = new ValueNumbering(ssa.Identifiers);
				DumpProc(proc, ssa, fut.TextWriter);
				vn.Write(fut.TextWriter);
				fut.AssertFilesEqual();
			}
		}
		private void Build(Procedure proc)
		{
			this.proc = proc;
			this.doms = proc.CreateBlockDominatorGraph();
			SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, doms);
			
			this.ssaIds = sst.SsaState.Identifiers;
            sst.SsaState.DebugDump(true);//$DEBUG
		}
		/// <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;
		}
        private Procedure RunTest(string sExp, IProcessorArchitecture arch, Func<Procedure> mkProc)
        {
            var proc = mkProc();
            progBuilder.ResolveUnresolved();

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

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

            vp.Transform();

            var trf = new TrashedRegisterFinder2(
                arch, 
                pf,
                proc, 
                ssa.SsaState.Identifiers,
                NullDecompilerEventListener.Instance);
            var flow = trf.Compute();
            var sw = new StringWriter();
            sw.Write("Preserved: ");
            sw.WriteLine(string.Join(",", flow.Preserved.OrderBy(p => p.ToString())));
            sw.Write("Trashed: ");
            sw.WriteLine(string.Join(",", flow.Trashed.OrderBy(p => p.ToString())));
            if (flow.Constants.Count > 0)
            {
                sw.Write("Constants: ");
                sw.WriteLine(string.Join(
                    ",",
                    flow.Constants
                        .OrderBy(kv => kv.Key.ToString())
                        .Select(kv => string.Format(
                            "{0}:{1}", kv.Key, kv.Value))));
            }
            var sActual = sw.ToString();
            if (sActual != sExp)
            {
                proc.Dump(true, false);
                Debug.WriteLine(sActual);
                Assert.AreEqual(sExp, sActual);
            }
            pf.ProcedureFlows2.Add(proc, flow);
            return proc;
        }
		private void PerformTest(FileUnitTester fut)
		{
			DataFlowAnalysis dfa = new DataFlowAnalysis(program, new FakeDecompilerEventListener());
			dfa.UntangleProcedures();
			foreach (Procedure proc in program.Procedures.Values)
			{
				Aliases alias = new Aliases(proc, program.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(dfa.ProgramDataFlow, proc, proc.CreateBlockDominatorGraph());
				SsaState ssa = sst.SsaState;

				proc.Write(false, fut.TextWriter);
				fut.TextWriter.WriteLine();

				OutParameterTransformer opt = new OutParameterTransformer(proc, ssa.Identifiers);
				opt.Transform();

				DeadCode.Eliminate(proc, ssa);

				proc.Write(false, fut.TextWriter);
				fut.TextWriter.WriteLine("====================");
			}
		}
		protected override void RunTest(Program prog, TextWriter writer)
		{
            DataFlowAnalysis dfa = new DataFlowAnalysis(prog, new FakeDecompilerEventListener());
			dfa.UntangleProcedures();
			foreach (Procedure proc in prog.Procedures.Values)
			{
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(dfa.ProgramDataFlow, proc, proc.CreateBlockDominatorGraph());
				SsaState ssa = sst.SsaState;
				GrfDefinitionFinder grfd = new GrfDefinitionFinder(ssa.Identifiers);
				foreach (SsaIdentifier sid in ssa.Identifiers)
				{
                    var id = sid.OriginalIdentifier as Identifier;
					if (id == null || !(id.Storage is FlagGroupStorage) || sid.Uses.Count == 0)
						continue;
					writer.Write("{0}: ", sid.DefStatement.Instruction);
					grfd.FindDefiningExpression(sid);
					string fmt = grfd.IsNegated ? "!{0};" : "{0}";
					writer.WriteLine(fmt, grfd.DefiningExpression);
				}
			}
		}
示例#9
0
		private void Build(Program prog)
		{
			DataFlowAnalysis dfa = new DataFlowAnalysis(prog, new FakeDecompilerEventListener());
			dfa.UntangleProcedures();
			foreach (Procedure proc in prog.Procedures.Values)
			{
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				var gr = proc.CreateBlockDominatorGraph();
				SsaTransform sst = new SsaTransform(dfa.ProgramDataFlow, proc, gr);
				SsaState ssa = sst.SsaState;

				ConditionCodeEliminator cce = new ConditionCodeEliminator(ssa.Identifiers, prog.Platform);
				cce.Transform();

				DeadCode.Eliminate(proc, ssa);

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

				DeadCode.Eliminate(proc, ssa);

				Coalescer coa = new Coalescer(proc, ssa);
				coa.Transform();

				DeadCode.Eliminate(proc, ssa);

				LiveCopyInserter lci = new LiveCopyInserter(proc, ssa.Identifiers);
				lci.Transform();

				WebBuilder web = new WebBuilder(proc, ssa.Identifiers, new Dictionary<Identifier,LinearInductionVariable>());
				web.Transform();

				ssa.ConvertBack(false);
			}

		}
示例#10
0
		protected override void RunTest(Program prog, TextWriter writer)
		{
            var progFlow = new ProgramDataFlow();
			foreach (Procedure proc in prog.Procedures.Values)
			{
				var gr = proc.CreateBlockDominatorGraph();
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(progFlow, proc, gr);
				SsaState ssa = sst.SsaState;
				DumpProc(proc, ssa, writer);
				ValueNumbering vn = new ValueNumbering(ssa.Identifiers);
				vn.Write(writer);
				writer.WriteLine();

			}
		}
示例#11
0
		//[Test]
		public void VnLoop()
		{
			Program prog = RewriteCodeFragment(@".i86
	push ax
	jmp looptest
again:
    mov si,[0x302]
	mov ax,[si+04]
	add [si+06],ax
looptest:
    cmp	ax,bx
	jl again

	pop ax
	ret
");
			using (FileUnitTester fut = new FileUnitTester("Analysis/VnLoop.txt"))
			{
				Procedure proc = prog.Procedures.Values[0];
				var gr = proc.CreateBlockDominatorGraph();
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr);
				SsaState ssa = sst.SsaState;
				DumpProc(proc, ssa, fut.TextWriter);
				ValueNumbering vn = new ValueNumbering(ssa.Identifiers);
				vn.Write(fut.TextWriter);

				fut.AssertFilesEqual();
			}
		}
示例#12
0
		//[Test]
		public void VnRedundantStore()
		{
			Program prog = RewriteCodeFragment(
				@".i86
	mov	ax,2
isdone:
	cmp	bx,10
	jz  yay
boo: mov ax,3
	jmp done
yay:
	mov ax,3
done:
	ret
");
			using (FileUnitTester fut = new FileUnitTester("Analysis/VnRedundantStore.txt"))
			{
				Procedure proc = prog.Procedures.Values[0];
				var gr = proc.CreateBlockDominatorGraph();
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr);
				SsaState ssa = sst.SsaState;
				DumpProc(proc, ssa, fut.TextWriter);
				ValueNumbering vn = new ValueNumbering(ssa.Identifiers);
				vn.Write(fut.TextWriter);

				fut.AssertFilesEqual();
			}
		}
示例#13
0
		protected override void RunTest(Program prog, TextWriter writer)
		{
            var flow = new ProgramDataFlow(prog);
            var eventListener = new FakeDecompilerEventListener();
            var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, flow, eventListener);
            trf.Compute();
            trf.RewriteBasicBlocks();
            Dump(prog.CallGraph);
            var rl = RegisterLiveness.Compute(prog, flow, eventListener);
            GlobalCallRewriter.Rewrite(prog, flow);

			foreach (Procedure proc in prog.Procedures.Values)
			{
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				var gr = proc.CreateBlockDominatorGraph();
				SsaTransform sst = new SsaTransform(flow, proc, gr);
				ssa = sst.SsaState;
				ssa.Write(writer);
				proc.Write(false, true, writer);
				writer.WriteLine();
			}
		}
示例#14
0
 private void RunUnitTest(ProcedureBuilder m, string outfile)
 {
     var proc = m.Procedure;
     var sst = new SsaTransform(new ProgramDataFlow(), proc, proc.CreateBlockDominatorGraph());
     ssa = sst.SsaState;
     using (var fut = new FileUnitTester(outfile))
     {
         ssa.Write(fut.TextWriter);
         proc.Write(false, fut.TextWriter);
         fut.AssertFilesEqual();
     }
 }
示例#15
0
			/// <summary>
			/// Walks the dominator tree, renaming the different definitions of variables
			/// (including phi-functions). 
			/// </summary>
			/// <param name="ssa">SSA identifiers</param>
			/// <param name="p">procedure to rename</param>
			public VariableRenamer(SsaTransform ssaXform)
			{
                this.programFlow = ssaXform.programFlow;
				this.ssa = ssaXform.SsaState;
                this.renameFrameAccess = ssaXform.RenameFrameAccesses;
                this.addUseInstructions = ssaXform.AddUseInstructions;
                this.proc = ssaXform.proc;
				this.rename = new Dictionary<Identifier, Identifier>();
				this.stmCur = null;
                this.existingDefs = proc.EntryBlock.Statements
                    .Select(s => s.Instruction as DefInstruction)
                    .Where(d => d != null)
                    .Select(d => d.Expression)
                    .ToHashSet();
			}
		private void Prepare(Procedure proc)
		{
			this.proc = proc;
            doms = proc.CreateBlockDominatorGraph();
			SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, doms);
			SsaState ssa = sst.SsaState;
			ssaIds = ssa.Identifiers;

			var cce = new ConditionCodeEliminator(ssaIds, new DefaultPlatform(null,new FakeArchitecture()));
			cce.Transform();

			DeadCode.Eliminate(proc, ssa);

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

			DeadCode.Eliminate(proc, ssa);
            proc.Dump(true, false); //$DEBUG
		}
示例#17
0
        private void UntangleProcedureScc(IList<Procedure> procs)
        {
            if (procs.Count == 1)
            {
                var proc = procs[0];
                Aliases alias = new Aliases(proc, program.Architecture, flow);
                alias.Transform();
                
                // Transform the procedure to SSA state. When encountering 'call' instructions,
                // they can be to functions already visited. If so, they have a "ProcedureFlow" 
                // associated with them. If they have not been visited, or are computed destinations
                // (e.g. vtables) they will have no "ProcedureFlow" associated with them yet, in
                // which case the the SSA treats the call as a "hell node".
                var doms = proc.CreateBlockDominatorGraph();
                var sst = new SsaTransform(flow, proc, doms);
                var ssa = sst.SsaState;

                // Propagate condition codes and registers. At the end, the hope is that 
                // all statements like (x86) mem[esp_42+4] will have been converted to
                // mem[fp - 30]. We also hope that procedure constants kept in registers
                // are propagated to the corresponding call sites.
                var cce = new ConditionCodeEliminator(ssa.Identifiers, program.Platform);
                cce.Transform();
                var vp = new ValuePropagator(ssa.Identifiers, proc);
                vp.Transform();

                // Now compute SSA for the stack-based variables as well. That is:
                // mem[fp - 30] becomes wLoc30, while 
                // mem[fp + 30] becomes wArg30.
                // This allows us to compute the dataflow of this procedure.
                sst.RenameFrameAccesses = true;
                sst.AddUseInstructions = true;
                sst.Transform();

                // Propagate those newly discovered identifiers.
                vp.Transform();

                // At this point, the computation of _actual_ ProcedureFlow should be possible.
                var tid = new TrashedRegisterFinder2(program.Architecture, flow, proc, ssa.Identifiers, this.eventListener);
                tid.Compute();
                DeadCode.Eliminate(proc, ssa);

                // Build expressions. A definition with a single use can be subsumed
                // into the using expression. 

                var coa = new Coalescer(proc, ssa);
                coa.Transform();
                DeadCode.Eliminate(proc, ssa);

                var liv = new LinearInductionVariableFinder(
                    proc,
                    ssa.Identifiers,
                    new BlockDominatorGraph(proc.ControlGraph, proc.EntryBlock));
                liv.Find();

                foreach (var de in liv.Contexts)
                {
                    var str = new StrengthReduction(ssa, de.Key, de.Value);
                    str.ClassifyUses();
                    str.ModifyUses();
                }
                proc.Dump(true, false);
                //var opt = new OutParameterTransformer(proc, ssa.Identifiers);
                //opt.Transform();
                DeadCode.Eliminate(proc, ssa);

                // Definitions with multiple uses and variables joined by PHI functions become webs.
                var web = new WebBuilder(proc, ssa.Identifiers, program.InductionVariables);
                web.Transform();
                ssa.ConvertBack(false);
            }
            else
            {

            }
        }
示例#18
0
		//[Test]
		public void VnLoopTest()
		{
			Program prog = this.RewriteCodeFragment(
				@".i86
	mov	ax,1
	mov	bx,1
isdone:
	cmp	ax,10
	jz  done

	inc ax
	inc bx
	jmp isdone
done:
	mov [0002],ax
	mov	[0004],bx
	ret
");
			using (FileUnitTester fut = new FileUnitTester("Analysis/VnLoopTest.txt"))
			{
				Procedure proc = prog.Procedures.Values[0];
				var gr = proc.CreateBlockDominatorGraph();
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr);
				SsaState ssa = sst.SsaState;
				DumpProc(proc, ssa, fut.TextWriter);

				DeadCode.Eliminate(proc, ssa);

				DumpProc(proc, ssa, fut.TextWriter);

				ValueNumbering vn = new ValueNumbering(ssa.Identifiers);
				vn.Write(fut.TextWriter);

				fut.AssertFilesEqual();
			}
		}
示例#19
0
		public void VpDbp()
		{
			Procedure proc = new DpbMock().Procedure;
			var gr = proc.CreateBlockDominatorGraph();
			SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr);
			SsaState ssa = sst.SsaState;

            ssa.DebugDump(true);

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

			using (FileUnitTester fut = new FileUnitTester("Analysis/VpDbp.txt"))
			{
				proc.Write(false, fut.TextWriter);
				fut.TextWriter.WriteLine();
				fut.AssertFilesEqual();
			}
		}
示例#20
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(ssa.Identifiers, proc);
			vp.Transform();

			using (FileUnitTester fut = new FileUnitTester("Analysis/VpDpbDpb.txt"))
			{
				proc.Write(false, fut.TextWriter);
				fut.TextWriter.WriteLine();
				fut.AssertFilesEqual();
			}
		}
示例#21
0
		private void Build(Procedure proc, IProcessorArchitecture arch)
		{
            var platform = new DefaultPlatform(null, arch);
			this.proc = proc;
			Aliases alias = new Aliases(proc, arch);
			alias.Transform();
			SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, proc.CreateBlockDominatorGraph());
			ssa = sst.SsaState;
			ConditionCodeEliminator cce = new ConditionCodeEliminator(ssa.Identifiers, platform);
			cce.Transform();
			ValuePropagator vp = new ValuePropagator(ssa.Identifiers, proc);
			vp.Transform();
			DeadCode.Eliminate(proc, ssa);
			Coalescer coa = new Coalescer(proc, ssa);
			coa.Transform();
			DeadCode.Eliminate(proc, ssa);

			sla = new SsaLivenessAnalysis(proc, ssa.Identifiers);
			sla2 = new SsaLivenessAnalysis2(proc, ssa.Identifiers);
			sla2.Analyze();
		}
示例#22
0
		//[Test]
		public void VnMemoryTest()
		{
			Program prog = RewriteCodeFragment(
				@".i86
	mov word ptr [bx+2],0
	mov si,[bx+4]
	mov ax,[bx+2]
	mov cx,[bx+2]
	mov dx,[bx+4]
	ret
");
			using (FileUnitTester fut = new FileUnitTester("Analysis/VnMemoryTest.txt"))
			{
				Procedure proc = prog.Procedures.Values[0];
				var gr = proc.CreateBlockDominatorGraph();
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr);
				SsaState ssa = sst.SsaState;
				ValueNumbering vn = new ValueNumbering(ssa.Identifiers);
				DumpProc(proc, ssa, fut.TextWriter);
				vn.Write(fut.TextWriter);
				fut.AssertFilesEqual();
			}
		}
示例#23
0
		protected override void RunTest(Program prog, TextWriter writer)
		{
			var dfa = new DataFlowAnalysis(prog, new FakeDecompilerEventListener());
			dfa.UntangleProcedures();
			foreach (Procedure proc in prog.Procedures.Values)
			{
				writer.WriteLine("= {0} ========================", proc.Name);
				var gr = proc.CreateBlockDominatorGraph();
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(dfa.ProgramDataFlow, proc, gr);
				SsaState ssa = sst.SsaState;
                var cce = new ConditionCodeEliminator(ssa.Identifiers, prog.Platform);
                cce.Transform();
				ssa.Write(writer);
				proc.Write(false, writer);
				writer.WriteLine();

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

				ssa.Write(writer);
				proc.Write(false, writer);
			}
		}
        protected override void RunTest(Program prog, TextWriter writer)
        {
            DataFlowAnalysis dfa = new DataFlowAnalysis(prog, new FakeDecompilerEventListener());
            dfa.UntangleProcedures();
            foreach (Procedure proc in prog.Procedures.Values)
            {
                var larw = new LongAddRewriter(proc, prog.Architecture);
                larw.Transform();

                Aliases alias = new Aliases(proc, prog.Architecture, dfa.ProgramDataFlow);
                alias.Transform();
                var sst = new SsaTransform(dfa.ProgramDataFlow, proc, proc.CreateBlockDominatorGraph());
                SsaState ssa = sst.SsaState;

                proc.Dump(true, false);

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

                var cce = new ConditionCodeEliminator(ssa.Identifiers, prog.Platform);
                cce.Transform();
                DeadCode.Eliminate(proc, ssa);

                ssa.Write(writer);
                proc.Write(false, writer);
                writer.WriteLine();
            }
        }
示例#25
0
		private void Build(Procedure proc, IProcessorArchitecture arch)
		{
            var platform = new DefaultPlatform(null, arch);
			this.proc = proc;
			Aliases alias = new Aliases(proc, arch);
			alias.Transform();
			var gr = proc.CreateBlockDominatorGraph();
			SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, gr);
			SsaState ssa = sst.SsaState;
			this.ssaIds = ssa.Identifiers;

			ConditionCodeEliminator cce = new ConditionCodeEliminator(ssa.Identifiers, platform);
			cce.Transform();
			DeadCode.Eliminate(proc, ssa);

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

			Coalescer coa = new Coalescer(proc, ssa);
			coa.Transform();

			DeadCode.Eliminate(proc, ssa);
            proc.Dump(true, false); //$DEBUG
		}
示例#26
0
		protected override void RunTest(Program prog, TextWriter fut)
		{
			DataFlowAnalysis dfa = new DataFlowAnalysis(prog, new FakeDecompilerEventListener());
			dfa.UntangleProcedures();
			
			foreach (Procedure proc in prog.Procedures.Values)
			{
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				SsaTransform sst = new SsaTransform(dfa.ProgramDataFlow, proc, proc.CreateBlockDominatorGraph());
				SsaState ssa = sst.SsaState;
				
                ConditionCodeEliminator cce = new ConditionCodeEliminator(ssa.Identifiers, prog.Platform);
				cce.Transform();
				DeadCode.Eliminate(proc, ssa);

				ValuePropagator vp = new ValuePropagator(ssa.Identifiers, proc);
				vp.Transform();
				DeadCode.Eliminate(proc, ssa);
				Coalescer co = new Coalescer(proc, ssa);
				co.Transform();

				ssa.Write(fut);
				proc.Write(false, fut);
				fut.WriteLine();
			}
		}
示例#27
0
			public LocateDefinedVariables(SsaTransform ssaXform, Dictionary<Expression, byte>[] defOrig)
			{
                this.programFlow = ssaXform.programFlow;
				this.proc = ssaXform.proc;
                this.ssa = ssaXform.SsaState;
                this.frameVariables = ssaXform.RenameFrameAccesses;
                this.defVars = defOrig;
                this.definitions = new List<Identifier>();
                this.inDefinitions = new HashSet<Identifier>();
			}
示例#28
0
        /// <summary>
        /// Processes procedures individually, building complex expression trees out
        /// of the simple, close-to-the-machine code generated by the disassembly.
        /// </summary>
        /// <param name="rl"></param>
		public void BuildExpressionTrees()
		{
            int i = 0;
			foreach (Procedure proc in program.Procedures.Values)
			{
                eventListener.ShowProgress("Building complex expressions.", i, program.Procedures.Values.Count);
                ++i;

                try
                {
                    var larw = new LongAddRewriter(proc, program.Architecture);
                    larw.Transform();

                    Aliases alias = new Aliases(proc, program.Architecture, flow);
                    alias.Transform();

                    var doms = new DominatorGraph<Block>(proc.ControlGraph, proc.EntryBlock);
                    var sst = new SsaTransform(flow, proc, doms);
                    var ssa = sst.SsaState;

                    var cce = new ConditionCodeEliminator(ssa.Identifiers, program.Platform);
                    cce.Transform();
                    DeadCode.Eliminate(proc, ssa);

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

                    // Build expressions. A definition with a single use can be subsumed
                    // into the using expression. 

                    var coa = new Coalescer(proc, ssa);
                    coa.Transform();
                    DeadCode.Eliminate(proc, ssa);

                    var liv = new LinearInductionVariableFinder(
                        proc,
                        ssa.Identifiers,
                        new BlockDominatorGraph(proc.ControlGraph, proc.EntryBlock));
                    liv.Find();

                    foreach (KeyValuePair<LinearInductionVariable, LinearInductionVariableContext> de in liv.Contexts)
                    {
                        var str = new StrengthReduction(ssa, de.Key, de.Value);
                        str.ClassifyUses();
                        str.ModifyUses();
                    }
                    var opt = new OutParameterTransformer(proc, ssa.Identifiers);
                    opt.Transform();
                    DeadCode.Eliminate(proc, ssa);

                    // Definitions with multiple uses and variables joined by PHI functions become webs.
                    var web = new WebBuilder(proc, ssa.Identifiers, program.InductionVariables);
                    web.Transform();
                    ssa.ConvertBack(false);
                }
                catch (Exception ex)
                {
                    eventListener.Error(new NullCodeLocation(proc.Name), ex, "An error occurred during data flow analysis.");
                }
			} 
		}
		private void Prepare(ProcedureBuilder mock)
		{
			proc = mock.Procedure;
			SsaTransform tr = new SsaTransform(new ProgramDataFlow(), proc, proc.CreateBlockDominatorGraph());
			ssaIds = tr.SsaState.Identifiers;
		}