private static void InlineBlock(SequenceStatement seq, int index) { Statement first = seq.GetStats()[index]; Statement pre = seq.GetStats()[index - 1]; pre.RemoveSuccessor(pre.GetAllSuccessorEdges()[0]); // single regular edge StatEdge edge = first.GetPredecessorEdges(StatEdge.Type_Break)[0]; Statement source = edge.GetSource(); Statement parent = source.GetParent(); source.RemoveSuccessor(edge); List <Statement> lst = new List <Statement>(); for (int i = seq.GetStats().Count - 1; i >= index; i--) { lst.Add(0, seq.GetStats().RemoveAtReturningValue(i)); } if (parent.type == Statement.Type_If && ((IfStatement)parent).iftype == IfStatement .Iftype_If && source == parent.GetFirst()) { IfStatement ifparent = (IfStatement)parent; SequenceStatement block = new SequenceStatement(lst); block.SetAllParent(); StatEdge newedge = new StatEdge(StatEdge.Type_Regular, source, block); source.AddSuccessor(newedge); ifparent.SetIfEdge(newedge); ifparent.SetIfstat(block); ifparent.GetStats().AddWithKey(block, block.id); block.SetParent(ifparent); } else { lst.Add(0, source); SequenceStatement block = new SequenceStatement(lst); block.SetAllParent(); parent.ReplaceStatement(source, block); // LabelHelper.lowContinueLabels not applicable because of forward continue edges // LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>()); // do it by hand foreach (StatEdge prededge in block.GetPredecessorEdges(StatEdge.Type_Continue)) { block.RemovePredecessor(prededge); prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, source ); source.AddPredecessor(prededge); source.AddLabeledEdge(prededge); } if (parent.type == Statement.Type_Switch) { ((SwitchStatement)parent).SortEdgesAndNodes(); } source.AddSuccessor(new StatEdge(StatEdge.Type_Regular, source, first)); } }
private static Statement CopyStatement(Statement from, Statement to, Dictionary <Statement , Statement> mapAltToCopies) { if (to == null) { // first outer invocation to = from.GetSimpleCopy(); Sharpen.Collections.Put(mapAltToCopies, from, to); } // copy statements foreach (Statement st in from.GetStats()) { Statement stcopy = st.GetSimpleCopy(); to.GetStats().AddWithKey(stcopy, stcopy.id); Sharpen.Collections.Put(mapAltToCopies, st, stcopy); } // copy edges for (int i = 0; i < from.GetStats().Count; i++) { Statement stold = from.GetStats()[i]; Statement stnew = to.GetStats()[i]; foreach (StatEdge edgeold in stold.GetSuccessorEdges(Statement.Statedge_Direct_All )) { // type cannot be TYPE_EXCEPTION (checked in isIrreducibleTriangle) StatEdge edgenew = new StatEdge(edgeold.GetType(), stnew, mapAltToCopies.ContainsKey (edgeold.GetDestination()) ? mapAltToCopies.GetOrNull(edgeold.GetDestination()) : edgeold.GetDestination(), mapAltToCopies.ContainsKey(edgeold.closure) ? mapAltToCopies .GetOrNull(edgeold.closure) : edgeold.closure); stnew.AddSuccessor(edgenew); } } // recurse statements for (int i = 0; i < from.GetStats().Count; i++) { Statement stold = from.GetStats()[i]; Statement stnew = to.GetStats()[i]; CopyStatement(stold, stnew, mapAltToCopies); } return(to); }
public static bool SplitIrreducibleNode(Statement statement) { Statement splitnode = GetCandidateForSplitting(statement); if (splitnode == null) { return(false); } StatEdge enteredge = splitnode.GetPredecessorEdges(StatEdge.Type_Regular).GetEnumerator ().Current; // copy the smallest statement Statement splitcopy = CopyStatement(splitnode, null, new Dictionary <Statement, Statement >()); InitCopiedStatement(splitcopy); // insert the copy splitcopy.SetParent(statement); statement.GetStats().AddWithKey(splitcopy, splitcopy.id); // switch input edges foreach (StatEdge prededge in splitnode.GetPredecessorEdges(Statement.Statedge_Direct_All )) { if (prededge.GetSource() == enteredge.GetSource() || prededge.closure == enteredge .GetSource()) { splitnode.RemovePredecessor(prededge); prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, splitcopy ); splitcopy.AddPredecessor(prededge); } } // connect successors foreach (StatEdge succ in splitnode.GetSuccessorEdges(Statement.Statedge_Direct_All )) { splitcopy.AddSuccessor(new StatEdge(succ.GetType(), splitcopy, succ.GetDestination (), succ.closure)); } return(true); }
private static void BuildSynchronized(Statement stat) { foreach (Statement st in stat.GetStats()) { BuildSynchronized(st); } if (stat.type == Statement.Type_Sequence) { while (true) { bool found = false; List <Statement> lst = stat.GetStats(); for (int i = 0; i < lst.Count - 1; i++) { Statement current = lst[i]; // basic block if (current.IsMonitorEnter()) { Statement next = lst[i + 1]; Statement nextDirect = next; while (next.type == Statement.Type_Sequence) { next = next.GetFirst(); } if (next.type == Statement.Type_Catchall) { CatchAllStatement ca = (CatchAllStatement)next; if (ca.GetFirst().IsContainsMonitorExit() && ca.GetHandler().IsContainsMonitorExit ()) { // remove the head block from sequence current.RemoveSuccessor(current.GetSuccessorEdges(Statement.Statedge_Direct_All)[ 0]); foreach (StatEdge edge in current.GetPredecessorEdges(Statement.Statedge_Direct_All )) { current.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, nextDirect); nextDirect.AddPredecessor(edge); } stat.GetStats().RemoveWithKey(current.id); stat.SetFirst(stat.GetStats()[0]); // new statement SynchronizedStatement sync = new SynchronizedStatement(current, ca.GetFirst(), ca .GetHandler()); sync.SetAllParent(); foreach (StatEdge edge in new HashSet <StatEdge>(ca.GetLabelEdges())) { sync.AddLabeledEdge(edge); } current.AddSuccessor(new StatEdge(StatEdge.Type_Regular, current, ca.GetFirst())); ca.GetParent().ReplaceStatement(ca, sync); found = true; break; } } } } if (!found) { break; } } } }
private static RootStatement GraphToStatement(ControlFlowGraph graph) { VBStyleCollection <Statement, int> stats = new VBStyleCollection <Statement, int>(); VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks(); foreach (BasicBlock block in blocks) { stats.AddWithKey(new BasicBlockStatement(block), block.id); } BasicBlock firstblock = graph.GetFirst(); // head statement Statement firstst = stats.GetWithKey(firstblock.id); // dummy exit statement DummyExitStatement dummyexit = new DummyExitStatement(); Statement general; if (stats.Count > 1 || firstblock.IsSuccessor(firstblock)) { // multiple basic blocks or an infinite loop of one block general = new GeneralStatement(firstst, stats, null); } else { // one straightforward basic block RootStatement root = new RootStatement(firstst, dummyexit); firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root)); return(root); } foreach (BasicBlock block in blocks) { Statement stat = stats.GetWithKey(block.id); foreach (BasicBlock succ in block.GetSuccs()) { Statement stsucc = stats.GetWithKey(succ.id); int type; if (stsucc == firstst) { type = StatEdge.Type_Continue; } else if (graph.GetFinallyExits().Contains(block)) { type = StatEdge.Type_Finallyexit; stsucc = dummyexit; } else if (succ.id == graph.GetLast().id) { type = StatEdge.Type_Break; stsucc = dummyexit; } else { type = StatEdge.Type_Regular; } stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general : stsucc, (type == StatEdge.Type_Regular) ? null : general)); } // exceptions edges foreach (BasicBlock succex in block.GetSuccExceptions()) { Statement stsuccex = stats.GetWithKey(succex.id); ExceptionRangeCFG range = graph.GetExceptionRange(succex, block); if (!range.IsCircular()) { stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes())); } } } general.BuildContinueSet(); general.BuildMonitorFlags(); return(new RootStatement(general, dummyexit)); }
private static void ProcessEdgesWithNext(Statement stat, Dictionary <Statement, List <StatEdge> > mapEdges, Statement next) { StatEdge statedge = null; List <StatEdge> lstSuccs = stat.GetAllSuccessorEdges(); if (!(lstSuccs.Count == 0)) { statedge = lstSuccs[0]; if (statedge.GetDestination() == next) { statedge.@explicit = false; statedge = null; } else { next = statedge.GetDestination(); } } // no next for a do statement if (stat.type == Statement.Type_Do && ((DoStatement)stat).GetLooptype() == DoStatement .Loop_Do) { next = null; } if (next == null) { if (mapEdges.Count == 1) { List <StatEdge> lstEdges = new Sharpen.EnumeratorAdapter <List <StatEdge> >(mapEdges.Values.GetEnumerator()).Next(); if (lstEdges.Count > 1 && new Sharpen.EnumeratorAdapter <Statement>(mapEdges.Keys.GetEnumerator()).Next().type != Statement .Type_Dummyexit) { StatEdge edge_example = lstEdges[0]; Statement closure = stat.GetParent(); if (!closure.ContainsStatementStrict(edge_example.closure)) { closure = edge_example.closure; } StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination (), closure); stat.AddSuccessor(newedge); foreach (StatEdge edge in lstEdges) { edge.@explicit = false; } Sharpen.Collections.Put(mapEdges, newedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] { newedge }))); } } } else { bool implfound = false; foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges) { if (entr.Key == next) { foreach (StatEdge edge in entr.Value) { edge.@explicit = false; } implfound = true; break; } } if ((stat.GetAllSuccessorEdges().Count == 0) && !implfound) { List <StatEdge> lstEdges = null; foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges) { if (entr.Key.type != Statement.Type_Dummyexit && (lstEdges == null || entr.Value. Count > lstEdges.Count)) { lstEdges = entr.Value; } } if (lstEdges != null && lstEdges.Count > 1) { StatEdge edge_example = lstEdges[0]; Statement closure = stat.GetParent(); if (!closure.ContainsStatementStrict(edge_example.closure)) { closure = edge_example.closure; } StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination (), closure); stat.AddSuccessor(newedge); foreach (StatEdge edge in lstEdges) { edge.@explicit = false; } } } mapEdges.Clear(); } if (statedge != null) { Sharpen.Collections.Put(mapEdges, statedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] { statedge }))); } }
private static void CondenseSequencesRec(Statement stat) { if (stat.type == Statement.Type_Sequence) { List <Statement> lst = new List <Statement>(stat.GetStats()); bool unfolded = false; // unfold blocks for (int i = 0; i < lst.Count; i++) { Statement st = lst[i]; if (st.type == Statement.Type_Sequence) { RemoveEmptyStatements((SequenceStatement)st); if (i == lst.Count - 1 || IsSequenceDisbandable(st, lst[i + 1])) { // move predecessors Statement first = st.GetFirst(); foreach (StatEdge edge in st.GetAllPredecessorEdges()) { st.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, first); first.AddPredecessor(edge); } // move successors Statement last = st.GetStats().GetLast(); if ((last.GetAllSuccessorEdges().Count == 0) && i < lst.Count - 1) { last.AddSuccessor(new StatEdge(StatEdge.Type_Regular, last, lst[i + 1])); } else { foreach (StatEdge edge in last.GetAllSuccessorEdges()) { if (i == lst.Count - 1) { if (edge.closure == st) { stat.AddLabeledEdge(edge); } } else { edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, StatEdge.Type_Regular ); edge.closure.GetLabelEdges().Remove(edge); edge.closure = null; } } } foreach (StatEdge edge in st.GetAllSuccessorEdges()) { st.RemoveSuccessor(edge); } foreach (StatEdge edge in new HashSet <StatEdge>(st.GetLabelEdges())) { if (edge.GetSource() != last) { last.AddLabeledEdge(edge); } } lst.RemoveAtReturningValue(i); lst.InsertRange(i, st.GetStats()); i--; unfolded = true; } } } if (unfolded) { SequenceStatement sequence = new SequenceStatement(lst); sequence.SetAllParent(); stat.GetParent().ReplaceStatement(stat, sequence); stat = sequence; } } // sequence consisting of one statement -> disband if (stat.type == Statement.Type_Sequence) { RemoveEmptyStatements((SequenceStatement)stat); if (stat.GetStats().Count == 1) { Statement st = stat.GetFirst(); bool ok = (st.GetAllSuccessorEdges().Count == 0); if (!ok) { StatEdge edge = st.GetAllSuccessorEdges()[0]; ok = (stat.GetAllSuccessorEdges().Count == 0); if (!ok) { StatEdge statedge = stat.GetAllSuccessorEdges()[0]; ok = (edge.GetDestination() == statedge.GetDestination()); if (ok) { st.RemoveSuccessor(edge); } } } if (ok) { stat.GetParent().ReplaceStatement(stat, st); stat = st; } } } // replace flat statements with synthetic basic blocks while (true) { foreach (Statement st in stat.GetStats()) { if (((st.GetStats().Count == 0) || st.GetExprents() != null) && st.type != Statement .Type_Basicblock) { DestroyAndFlattenStatement(st); goto outer_continue; } } break; outer_continue :; } outer_break :; // recursion for (int i = 0; i < stat.GetStats().Count; i++) { CondenseSequencesRec(stat.GetStats()[i]); } }
private static bool CollapseElse(IfHelper.IfNode rtnode) { if (rtnode.edgetypes[1] == 0) { IfHelper.IfNode elsebranch = rtnode.succs[1]; if (elsebranch.succs.Count == 2) { // else-if or else-else branch int path = elsebranch.succs[1].value == rtnode.succs[0].value ? 2 : (elsebranch.succs [0].value == rtnode.succs[0].value ? 1 : 0); if (path > 0) { IfStatement firstif = (IfStatement)rtnode.value; IfStatement secondif = (IfStatement)elsebranch.value; Statement parent = firstif.GetParent(); if ((secondif.GetFirst().GetExprents().Count == 0)) { firstif.GetFirst().RemoveSuccessor(firstif.GetIfEdge()); // remove first if firstif.RemoveAllSuccessors(secondif); foreach (StatEdge edge in firstif.GetAllPredecessorEdges()) { if (!firstif.ContainsStatementStrict(edge.GetSource())) { firstif.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, secondif); secondif.AddPredecessor(edge); } } parent.GetStats().RemoveWithKey(firstif.id); if (parent.GetFirst() == firstif) { parent.SetFirst(secondif); } // merge if conditions IfExprent statexpr = secondif.GetHeadexprent(); List <Exprent> lstOperands = new List <Exprent>(); lstOperands.Add(firstif.GetHeadexprent().GetCondition()); if (path == 2) { lstOperands[0] = new FunctionExprent(FunctionExprent.Function_Bool_Not, lstOperands [0], null); } lstOperands.Add(statexpr.GetCondition()); statexpr.SetCondition(new FunctionExprent(path == 1 ? FunctionExprent.Function_Cor : FunctionExprent.Function_Cadd, lstOperands, null)); if ((secondif.GetFirst().GetExprents().Count == 0) && !(firstif.GetFirst().GetExprents ().Count == 0)) { secondif.ReplaceStatement(secondif.GetFirst(), firstif.GetFirst()); } return(true); } } } else if (elsebranch.succs.Count == 1) { if (elsebranch.succs[0].value == rtnode.succs[0].value) { IfStatement firstif = (IfStatement)rtnode.value; Statement second = elsebranch.value; firstif.RemoveAllSuccessors(second); foreach (StatEdge edge in second.GetAllSuccessorEdges()) { second.RemoveSuccessor(edge); edge.SetSource(firstif); firstif.AddSuccessor(edge); } StatEdge ifedge = firstif.GetIfEdge(); firstif.GetFirst().RemoveSuccessor(ifedge); second.AddSuccessor(new StatEdge(ifedge.GetType(), second, ifedge.GetDestination( ), ifedge.closure)); StatEdge newifedge = new StatEdge(StatEdge.Type_Regular, firstif.GetFirst(), second ); firstif.GetFirst().AddSuccessor(newifedge); firstif.SetIfstat(second); firstif.GetStats().AddWithKey(second, second.id); second.SetParent(firstif); firstif.GetParent().GetStats().RemoveWithKey(second.id); // negate the if condition IfExprent statexpr = firstif.GetHeadexprent(); statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Bool_Not, statexpr .GetCondition(), null)); return(true); } } } return(false); }
private static int IntegrateExits(Statement stat) { int ret = 0; Statement dest; if (stat.GetExprents() == null) { while (true) { int changed = 0; foreach (Statement st in stat.GetStats()) { changed = IntegrateExits(st); if (changed > 0) { ret = 1; break; } } if (changed == 0) { break; } } if (stat.type == Statement.Type_If) { IfStatement ifst = (IfStatement)stat; if (ifst.GetIfstat() == null) { StatEdge ifedge = ifst.GetIfEdge(); dest = IsExitEdge(ifedge); if (dest != null) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents())); ifst.GetFirst().RemoveSuccessor(ifedge); StatEdge newedge = new StatEdge(StatEdge.Type_Regular, ifst.GetFirst(), bstat); ifst.GetFirst().AddSuccessor(newedge); ifst.SetIfEdge(newedge); ifst.SetIfstat(bstat); ifst.GetStats().AddWithKey(bstat, bstat.id); bstat.SetParent(ifst); StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0]; StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination ()); bstat.AddSuccessor(newexitedge); oldexitedge.closure.AddLabeledEdge(newexitedge); ret = 1; } } } } if (stat.GetAllSuccessorEdges().Count == 1 && stat.GetAllSuccessorEdges()[0].GetType () == StatEdge.Type_Break && (stat.GetLabelEdges().Count == 0)) { Statement parent = stat.GetParent(); if (stat != parent.GetFirst() || (parent.type != Statement.Type_If && parent.type != Statement.Type_Switch)) { StatEdge destedge = stat.GetAllSuccessorEdges()[0]; dest = IsExitEdge(destedge); if (dest != null) { stat.RemoveSuccessor(destedge); BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents())); StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0]; StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination ()); bstat.AddSuccessor(newexitedge); oldexitedge.closure.AddLabeledEdge(newexitedge); SequenceStatement block = new SequenceStatement(Sharpen.Arrays.AsList(stat, bstat )); block.SetAllParent(); parent.ReplaceStatement(stat, block); // LabelHelper.lowContinueLabels not applicable because of forward continue edges // LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>()); // do it by hand foreach (StatEdge prededge in block.GetPredecessorEdges(StatEdge.Type_Continue)) { block.RemovePredecessor(prededge); prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, stat); stat.AddPredecessor(prededge); stat.AddLabeledEdge(prededge); } stat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, stat, bstat)); foreach (StatEdge edge in dest.GetAllPredecessorEdges()) { if (!edge.@explicit && stat.ContainsStatementStrict(edge.GetSource()) && MergeHelper .IsDirectPath(edge.GetSource().GetParent(), bstat)) { dest.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, bstat); bstat.AddPredecessor(edge); if (!stat.ContainsStatementStrict(edge.closure)) { stat.AddLabeledEdge(edge); } } } ret = 2; } } } return(ret); }