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); }
//[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, null, gr, new HashSet<RegisterStorage>()); SsaState ssa = sst.SsaState; ValueNumbering vn = new ValueNumbering(ssa.Identifiers); DumpProc(proc, ssa, fut.TextWriter); vn.Write(fut.TextWriter); fut.AssertFilesEqual(); } }
protected override void RunTest(Program program, TextWriter writer) { var importResolver = MockRepository.GenerateStub<IImportResolver>(); importResolver.Replay(); var dfa = new DataFlowAnalysis(program, importResolver, 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, importResolver, proc.CreateBlockDominatorGraph(), new HashSet<RegisterStorage>()); 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); } } }
private void PerformTest(FileUnitTester fut) { DataFlowAnalysis dfa = new DataFlowAnalysis(program, null, 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, null, proc.CreateBlockDominatorGraph(), program.Platform.CreateImplicitArgumentRegisters()); 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("===================="); } }
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(); } }
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()); }
//[Test] public void VnLoop() { Program program = 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 = program.Procedures.Values[0]; var gr = proc.CreateBlockDominatorGraph(); Aliases alias = new Aliases(proc, program.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(); } }
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; }
/// <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; }
private Procedure RunTest(string sExp, IProcessorArchitecture arch, Func<Procedure> mkProc) { var proc = mkProc(); progBuilder.ResolveUnresolved(); var importResolver = MockRepository.GenerateStub<IImportResolver>(); importResolver.Replay(); var sst = new SsaTransform( pf, proc, importResolver, proc.CreateBlockDominatorGraph(), new HashSet<RegisterStorage>()); var vp = new ValuePropagator(arch, sst.SsaState); vp.Transform(); sst.RenameFrameAccesses = true; sst.AddUseInstructions = true; sst.Transform(); vp.Transform(); var trf = new TrashedRegisterFinder2( arch, pf, proc, sst.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); Debug.WriteLine(sActual); Assert.AreEqual(sExp, sActual); } pf.ProcedureFlows2.Add(proc, flow); return proc; }
private void Build(Procedure proc) { this.proc = proc; this.doms = proc.CreateBlockDominatorGraph(); SsaTransform sst = new SsaTransform( new ProgramDataFlow(), proc, null, doms, new HashSet<RegisterStorage>()); this.ssaIds = sst.SsaState.Identifiers; }
private void Build(Program prog) { var eventListener = new FakeDecompilerEventListener(); DataFlowAnalysis dfa = new DataFlowAnalysis(prog, null, eventListener); 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, null, gr, new HashSet<RegisterStorage>()); SsaState ssa = sst.SsaState; ConditionCodeEliminator cce = new ConditionCodeEliminator(ssa, prog.Platform); cce.Transform(); DeadCode.Eliminate(proc, ssa); var vp = new ValuePropagator(prog.Architecture, ssa); 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); } }
public void Cdiv_3() { /* eax = ~0x33333332 edx_eax = esi *u eax edx = edx >>u 0x03 */ var c = Constant.UInt32(0x55555555); var r1 = m.Reg32("r1"); var r2 = m.Reg32("r2"); var r2_r1 = m.Frame.EnsureSequence(r2, r1, PrimitiveType.Word64); var ass = m.Assign(r2_r1, m.UMul(r1, c)); var proc = m.Procedure; var ssa = new SsaTransform(null, proc, proc.CreateBlockDominatorGraph()).Transform(); var ctx = new SsaEvaluationContext(null, ssa.Identifiers); var rule = new ConstDivisionImplementedByMultiplication(ctx); //ctx.Statement = proc.EntryBlock.Succ[0].Statements[0]; //Assert.IsTrue(rule.Match((BinaryExpression) ass.Src)); //ass.Src = rule.Transform(); Assert.AreEqual("x = id /u 3", ass.ToString()); }
//[Test] public void VnRedundantStore() { Program program = 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 = program.Procedures.Values[0]; var gr = proc.CreateBlockDominatorGraph(); Aliases alias = new Aliases(proc, program.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(); } }
//[Test] public void VnMemoryTest() { Program program = 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 = program.Procedures.Values[0]; var gr = proc.CreateBlockDominatorGraph(); Aliases alias = new Aliases(proc, program.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(); } }
/// <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(program.Architecture, 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 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(program.Architecture, 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(); } //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 { throw new NotImplementedException(); } }
private SsaState RunTest(ProcedureBuilder m) { var proc = m.Procedure; var gr = proc.CreateBlockDominatorGraph(); var sst = new SsaTransform(new ProgramDataFlow(), proc, importResolver, gr, new HashSet<RegisterStorage>()); var ssa = sst.SsaState; var vp = new ValuePropagator(arch, ssa); vp.Transform(); return ssa; }
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(); } }
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(); } }
protected override void RunTest(Program prog, TextWriter writer) { var dfa = new DataFlowAnalysis(prog, importResolver, 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, importResolver, gr, new HashSet<RegisterStorage>()); SsaState ssa = sst.SsaState; var cce = new ConditionCodeEliminator(ssa, prog.Platform); cce.Transform(); ssa.Write(writer); proc.Write(false, writer); writer.WriteLine(); ValuePropagator vp = new ValuePropagator(prog.Architecture, ssa); vp.Transform(); ssa.Write(writer); proc.Write(false, writer); } }
private void UntangleProcedureScc(IList <Procedure> procs) { if (procs.Count == 1) { var proc = procs[0]; Aliases alias = new Aliases(proc, 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, importResolver, doms, program.Platform.CreateImplicitArgumentRegisters()); 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, program.Platform); cce.Transform(); var vp = new ValuePropagator(program.SegmentMap, ssa, program.CallGraph, importResolver, eventListener); 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(proc.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(); } //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(program, proc, ssa.Identifiers, program.InductionVariables, eventListener); web.Transform(); ssa.ConvertBack(false); } else { throw new NotImplementedException(); } }
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(arch, 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(); }
//[Test] public void VnLoopTest() { Program program = 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 = program.Procedures.Values[0]; var gr = proc.CreateBlockDominatorGraph(); Aliases alias = new Aliases(proc, program.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(); } }
protected override void RunTest(Program program, TextWriter writer) { var progFlow = new ProgramDataFlow(); foreach (Procedure proc in program.Procedures.Values) { var gr = proc.CreateBlockDominatorGraph(); Aliases alias = new Aliases(proc, program.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(); } }
public void VpDbp() { Procedure proc = new DpbMock().Procedure; var gr = proc.CreateBlockDominatorGraph(); SsaTransform sst = new SsaTransform(new ProgramDataFlow(), proc, null, gr, new HashSet<RegisterStorage>()); SsaState ssa = sst.SsaState; ValuePropagator vp = new ValuePropagator(arch, ssa); vp.Transform(); using (FileUnitTester fut = new FileUnitTester("Analysis/VpDbp.txt")) { proc.Write(false, fut.TextWriter); fut.TextWriter.WriteLine(); fut.AssertFilesEqual(); } }
protected override void RunTest(Program program, TextWriter writer) { var importResolver = MockRepository.GenerateStub<IImportResolver>(); DataFlowAnalysis dfa = new DataFlowAnalysis(program, importResolver, new FakeDecompilerEventListener()); dfa.UntangleProcedures(); foreach (Procedure proc in program.Procedures.Values) { var larw = new LongAddRewriter(proc, program.Architecture); larw.Transform(); Aliases alias = new Aliases(proc, program.Architecture, dfa.ProgramDataFlow); alias.Transform(); var sst = new SsaTransform(dfa.ProgramDataFlow, proc, importResolver, proc.CreateBlockDominatorGraph(), new HashSet<RegisterStorage>()); SsaState ssa = sst.SsaState; var cce = new ConditionCodeEliminator(ssa, program.Platform); cce.Transform(); var vp = new ValuePropagator(program.Architecture, ssa); vp.Transform(); DeadCode.Eliminate(proc, ssa); ssa.Write(writer); proc.Write(false, writer); writer.WriteLine(); } }
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(arch, ssa.Identifiers, proc); vp.Transform(); using (FileUnitTester fut = new FileUnitTester("Analysis/VpDbp.txt")) { proc.Write(false, fut.TextWriter); fut.TextWriter.WriteLine(); fut.AssertFilesEqual(); } }
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; ConditionCodeEliminator cce = new ConditionCodeEliminator(ssa.Identifiers, prog.Platform); cce.Transform(); DeadCode.Eliminate(proc, ssa); ssa.Write(writer); proc.Write(false, writer); } }
/// <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(); }
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>(); }
public SequenceIdentifierGenerator(SsaTransform sst) { this.sst = sst; this.ssa = sst.SsaState; }