show definefunctions in separate clusters in graphs

This commit is contained in:
Jindra Petřík
2018-04-01 21:34:06 +02:00
parent 7810a84ad2
commit db5750a8f7
4 changed files with 84 additions and 2 deletions

View File

@@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.action;
import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.FinalProcessLocalData;
import com.jpexs.decompiler.flash.SWF;
import static com.jpexs.decompiler.flash.action.Action.adr2ip;
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
import com.jpexs.decompiler.flash.action.model.EnumerateActionItem;
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
@@ -35,14 +37,17 @@ import com.jpexs.decompiler.flash.action.swf4.ActionJump;
import com.jpexs.decompiler.flash.action.swf4.ActionNot;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals;
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.Loop;
import com.jpexs.decompiler.graph.TranslateStack;
@@ -52,8 +57,10 @@ import com.jpexs.decompiler.graph.model.DefaultItem;
import com.jpexs.decompiler.graph.model.IfItem;
import com.jpexs.decompiler.graph.model.SwitchItem;
import com.jpexs.decompiler.graph.model.WhileItem;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -71,6 +78,37 @@ public class ActionGraph extends Graph {
this.insideDoInitAction = insideDoInitAction;
}
@Override
public LinkedHashMap<String, Graph> getSubGraphs() {
LinkedHashMap<String, Graph> subgraphs = new LinkedHashMap<>();
List<Action> alist = ((ActionGraphSource) code).getActions();
int ip = 0;
for (Action action : alist) {
if ((action instanceof GraphSourceItemContainer) && ((action instanceof ActionDefineFunction) || (action instanceof ActionDefineFunction2))) {
GraphSourceItemContainer cnt = (GraphSourceItemContainer) action;
String functionName = (action instanceof ActionDefineFunction) ? ((ActionDefineFunction) action).functionName : ((ActionDefineFunction2) action).functionName;
long endAddr = action.getAddress() + cnt.getHeaderSize();
List<ActionList> outs = new ArrayList<>();
for (long size : cnt.getContainerSizes()) {
if (size == 0) {
outs.add(new ActionList());
continue;
}
outs.add(new ActionList(alist.subList(adr2ip(alist, endAddr), adr2ip(alist, endAddr + size))));
endAddr += size;
}
for (ActionList al : outs) {
subgraphs.put("loc" + Helper.formatAddress(code.pos2adr(ip)) + ": function " + functionName,
new ActionGraph("", false, al, new HashMap<>(), new HashMap<>(), new HashMap<>(), SWF.DEFAULT_VERSION)
);
}
}
ip++;
}
return subgraphs;
}
public boolean isInsideDoInitAction() {
return insideDoInitAction;
}

View File

@@ -16,15 +16,21 @@
*/
package com.jpexs.decompiler.flash.exporters.script;
import com.jpexs.decompiler.flash.AppResources;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.action.Action;
import static com.jpexs.decompiler.flash.action.Action.adr2ip;
import com.jpexs.decompiler.flash.action.ActionGraph;
import com.jpexs.decompiler.flash.action.ActionGraphSource;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
import com.jpexs.decompiler.flash.action.swf5.ActionWith;
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
import com.jpexs.decompiler.flash.action.swf7.ActionTry;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.StringBuilderTextWriter;
@@ -32,13 +38,20 @@ import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.ScopeStack;
import com.jpexs.decompiler.graph.TranslateException;
import com.jpexs.decompiler.graph.model.CommentItem;
import com.jpexs.graphs.graphviz.dot.parser.DotId;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
/**
*
@@ -83,7 +96,7 @@ public class PcodeGraphVizExporter {
export(gr, writer);
}
public void export(Graph graph, GraphTextWriter writer) throws InterruptedException {
private void exportGraph(Graph graph, GraphTextWriter writer) throws InterruptedException {
graph.init(null);
GraphSource graphSource = graph.getGraphCode();
Set<GraphPart> allBlocks = new HashSet<>();
@@ -92,7 +105,6 @@ public class PcodeGraphVizExporter {
populateParts(h, allBlocks);
}
writer.append("digraph pcode {\r\n");
Set<Long> knownAddresses = graphSource.getImportantAddresses();
int h = 0;
for (GraphPart head : heads) {
@@ -141,6 +153,20 @@ public class PcodeGraphVizExporter {
writer.append(partBlockName + orientation + " -> " + nextBlockName + ":n;\r\n");
}
}
}
public void export(Graph graph, GraphTextWriter writer) throws InterruptedException {
writer.append("digraph pcode {\r\n");
exportGraph(graph, writer);
int pos = 0;
Map<String, Graph> subgraphs = graph.getSubGraphs();
for (String name : subgraphs.keySet()) {
writer.append("subgraph cluster_" + pos + " {");
writer.append("label=" + new DotId(name, false) + ";\r\n");
pos++;
exportGraph(subgraphs.get(name), writer);
writer.append("}");
}
writer.append("}\r\n");
}
}

View File

@@ -20,6 +20,8 @@ import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.FinalProcessLocalData;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.model.AndItem;
import com.jpexs.decompiler.graph.model.BreakItem;
@@ -51,6 +53,7 @@ import com.jpexs.decompiler.graph.model.WhileItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -84,6 +87,10 @@ public class Graph {
return code;
}
public LinkedHashMap<String, Graph> getSubGraphs() {
return new LinkedHashMap<>();
}
/**
* Identify loop exits
*
@@ -2348,7 +2355,18 @@ public class Graph {
endAddr += size;
}
ip = code.adr2pos(endAddr);
if ((ins instanceof ActionDefineFunction) || (ins instanceof ActionDefineFunction2)) {
part.end = lastIp;
allBlocks.add(part);
GraphPart gp = new GraphPart(ip, -1);
gp.path = path;
part.nextParts.add(gp);
gp.refs.add(part);
part = gp;
}
}
continue;
} else if (ins.isExit()) {
part.end = ip;