diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 13ff08d..8ff633f 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,7 +2,15 @@ + + + + + + + + @@ -67,30 +75,19 @@ - + - - - - - - - - - - - - + - + - + @@ -99,34 +96,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -146,14 +116,12 @@ @@ -217,6 +187,7 @@ + @@ -235,326 +206,27 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + - - + + @@ -574,6 +246,24 @@ - + @@ -734,11 +406,11 @@ - + - + - + @@ -782,11 +454,6 @@ - - - - - @@ -812,69 +479,64 @@ - + - + - + - + - + - - - + - + - - - + - + - - - + - + - - - + - + - - - + - + - + - + - + - + - - - - + + + + + + + + + diff --git a/cjbe.bat b/cjbe.bat index 2a037c6..eabbb9a 100644 --- a/cjbe.bat +++ b/cjbe.bat @@ -4,5 +4,5 @@ echo Code Maintained by Contra cd out cd production cd cjbe -java net.rec.contra.cjbe.editor.BrowserApplication +java -cp ".;soot.jar" net.rec.contra.cjbe.editor.BrowserApplication pause \ No newline at end of file diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.class index 70e61af..86930ce 100644 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.class and b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.class differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.class index 8f1ca03..cd18576 100644 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.class and b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.class differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.class index 83e9008..aa856dd 100644 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.class and b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.class differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/DirectedGraph.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/DirectedGraph.class deleted file mode 100644 index 6ae3b0a..0000000 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/DirectedGraph.class and /dev/null differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/HashMutableDirectedGraph.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/HashMutableDirectedGraph.class deleted file mode 100644 index b5ee06b..0000000 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/HashMutableDirectedGraph.class and /dev/null differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/MutableDirectedGraph.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/MutableDirectedGraph.class deleted file mode 100644 index 8dc6aa1..0000000 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/MutableDirectedGraph.class and /dev/null differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/Block.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/Block.class deleted file mode 100644 index 1656397..0000000 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/Block.class and /dev/null differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/BlockGraph.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/BlockGraph.class deleted file mode 100644 index f7c6866..0000000 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/BlockGraph.class and /dev/null differ diff --git a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/InstructionGraph.class b/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/InstructionGraph.class deleted file mode 100644 index 5ba3a7a..0000000 Binary files a/out/production/CJBE/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/InstructionGraph.class and /dev/null differ diff --git a/out/production/CJBE/soot.jar b/out/production/CJBE/soot.jar new file mode 100644 index 0000000..6f8dd30 Binary files /dev/null and b/out/production/CJBE/soot.jar differ diff --git a/soot.jar b/soot.jar new file mode 100644 index 0000000..6f8dd30 Binary files /dev/null and b/soot.jar differ diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.java index dc535b8..acaa6f4 100644 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.java +++ b/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisDisplay.java @@ -3,6 +3,8 @@ import net.rec.contra.cjbe.editor.BrowserInternalFrame; import org.gjt.jclasslib.structures.ClassFile; import soot.*; +import soot.dava.DavaBody; +import soot.dava.DavaUnitPrinter; import soot.grimp.Grimp; import soot.grimp.GrimpBody; import soot.javaToJimple.AbstractJimpleBodyBuilder; @@ -11,8 +13,10 @@ import soot.jimple.JimpleMethodSource; import soot.jimple.parser.JimpleAST; import soot.toolkits.graph.CompleteUnitGraph; +import soot.toolkits.graph.ExceptionalUnitGraph; import javax.swing.*; +import javax.swing.text.html.HTMLEditorKit; import java.awt.*; import java.util.Iterator; @@ -24,35 +28,43 @@ public class AnalysisDisplay extends JEditorPane { SootMethod thisMethod; Body mBody; - CompleteUnitGraph cGraph; - + ExceptionalUnitGraph cGraph; AnalysisDisplay(int methodIndex, ClassFile classFile, BrowserInternalFrame internalFrame) { this.internalFrame = internalFrame; + setEditorKitForContentType("text/html", new HTMLEditorKit()); + setContentType("text/html"); try { setEditable(false); - Scene tz = Scene.v(); - tz.setSootClassPath(System.getProperty("java.class.path") + ";" + internalFrame.getClassPathString()); - tz.setPhantomRefs(true); - this.klass = tz.loadClassAndSupport(classFile.getThisClassName()); - this.thisMethod = (SootMethod) klass.getMethods().toArray()[methodIndex]; - this.mBody = thisMethod.retrieveActiveBody(); - //soot.grimp.Grimp gb = new soot.grimp.Grimp.v(); - this.cGraph = new CompleteUnitGraph(mBody); + Scene.v().setSootClassPath(System.getProperty("java.class.path") + ";" + internalFrame.getClassPathString()); + Scene.v().setPhantomRefs(true); + klass = Scene.v().loadClassAndSupport(classFile.getThisClassName()); + thisMethod = (SootMethod) klass.getMethods().toArray()[methodIndex]; + mBody = thisMethod.retrieveActiveBody(); + cGraph = new CompleteUnitGraph(mBody); } catch (Exception e) { e.printStackTrace(); - setText("Error: " + e + "\nControl Flow Analysis Unavailable.\nMake sure your classpath has all necessary dependencies."); + setText("Error: " + e + "
\nControl Flow Analysis Unavailable.
\nMake sure your classpath has all necessary dependencies."); return; } - Iterator it = cGraph.iterator(); String pageText = ""; + Iterator it = cGraph.iterator(); while (it.hasNext()) { - pageText += it.next().toString(); - if (it.hasNext()) pageText += "\n"; + Unit u = it.next(); + pageText += u.toString(); + if (u.branches()) + { + pageText += " (Jumps)"; + } + if (u.getBoxesPointingToThis().size() > 1){ + pageText += " (Jump Point)"; + } + if (it.hasNext()) pageText += "
\n"; } - setFont(new Font("monospaced", Font.PLAIN, 12)); - setCaretPosition(0); if (!pageText.equals("")) { + setCaretPosition(0); + pageText = pageText.replaceAll("virutalinvoke", "virtualinvoke"); + pageText = "\n\n\n" + pageText + "\n\n\n"; setText(pageText); } else { setText("Control Flow Analysis Unavailable."); diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.java index 29b3ad5..0d27cbf 100644 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.java +++ b/src/net/rec/contra/cjbe/editor/detail/attributes/code/AnalysisPane.java @@ -7,6 +7,7 @@ import net.rec.contra.cjbe.editor.BrowserInternalFrame; import net.rec.contra.cjbe.editor.BrowserServices; import net.rec.contra.cjbe.editor.BrowserTreeNode; +import org.apache.bcel.classfile.LineNumber; import org.gjt.jclasslib.structures.ClassFile; import org.gjt.jclasslib.structures.MethodInfo; import org.gjt.jclasslib.structures.attributes.CodeAttribute; @@ -50,7 +51,8 @@ private void addEditPane(String methodIndex, ClassFile classFile) { //System.out.println(methodIndex); //Scrollbar JScrollPane scroll = new JScrollPane(editArea); - scroll.setRowHeaderView(new LineNumberView(editArea)); + //LineNumberView view = new LineNumberView(editArea); + //scroll.setRowHeaderView(view); scroll.getVerticalScrollBar().setValue(10); this.add(scroll, methodIndex); diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.java index c750943..26dbed0 100644 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.java +++ b/src/net/rec/contra/cjbe/editor/detail/attributes/code/DiagramDisplay.java @@ -1,17 +1,21 @@ package net.rec.contra.cjbe.editor.detail.attributes.code; import net.rec.contra.cjbe.editor.BrowserInternalFrame; -import net.rec.contra.cjbe.editor.detail.attributes.code.graph.cfg.Block; -import net.rec.contra.cjbe.editor.detail.attributes.code.graph.cfg.BlockGraph; -import net.rec.contra.cjbe.editor.detail.attributes.code.graph.cfg.InstructionGraph; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.MethodGen; +import soot.CoffiClassSource; +import soot.G; +import soot.dava.Dava; +import soot.dava.DavaBody; +import soot.tools.CFGViewer; +import soot.util.cfgcmd.CFGIntermediateRep; import javax.swing.*; import java.io.IOException; +import java.io.InputStream; import java.util.Iterator; @@ -27,44 +31,15 @@ public class DiagramDisplay extends JEditorPane { try { javaClass = new ClassParser(internalFrame.getFileName()).parse(); } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + e.printStackTrace(); System.out.println("Failed to analyze control flow. Skipping..."); return; } ClassGen cg = new ClassGen(javaClass); MethodGen mg = new MethodGen(cg.getMethods()[methodIndex], cg.getClassName(), cg.getConstantPool()); - InstructionGraph ig = new InstructionGraph(mg, true); - BlockGraph blockGraph = new BlockGraph(ig); - String pageText = ""; - Iterator it = blockGraph.iterator(); - while(it.hasNext()){ - Block bk = it.next(); - pageText += "Block " + bk.getIndex() + ":\n"; - if(bk.getSuccs() != null){ - pageText += " Hops to"; - for (Block bz : bk.getSuccs()){ - pageText += "\n - Block " + bz.getIndex(); - } - pageText += "\n"; - } - InstructionHandle[] handles = bk.getMethod().getInstructionList().getInstructionHandles(); - for(int i = bk.getHead().getPosition(); i <= bk.getTail().getPosition(); i++){ - if(i < handles.length){ - pageText += handles[i].toString() + "\n"; - } else { - pageText += " INVALID\n"; - } - /* - if(bk.getTail().getPosition() > mg.getInstructionList().getInstructionHandles().length){ - System.out.println(mg.getName() + " had invalid unit data."); - pageText += "INVALID UNIT DATA\n"; - break; - } else { - pageText += handles[i].toString() + "\n"; - } */ - } - } - setText(pageText); + soot.tools.CFGViewer cfg = new CFGViewer(); + + //soot.dava.Dava d = new Dava(G.); } } \ No newline at end of file diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/DirectedGraph.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/DirectedGraph.java deleted file mode 100644 index a5543fc..0000000 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/DirectedGraph.java +++ /dev/null @@ -1,20 +0,0 @@ - -package net.rec.contra.cjbe.editor.detail.attributes.code.graph; - -import java.util.Iterator; -import java.util.List; - -public interface DirectedGraph { - - public List getHeads(); - - public List getTails(); - - public List getPreds(N node); - - public List getSuccs(N node); - - public int size(); - - public Iterator iterator(); -} diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/HashMutableDirectedGraph.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/HashMutableDirectedGraph.java deleted file mode 100644 index 5050028..0000000 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/HashMutableDirectedGraph.java +++ /dev/null @@ -1,191 +0,0 @@ - -package net.rec.contra.cjbe.editor.detail.attributes.code.graph; - -import java.util.*; - -public class HashMutableDirectedGraph implements MutableDirectedGraph { - - protected HashMap> nodeToPreds = new HashMap>(); - protected HashMap> nodeToSuccs = new HashMap>(); - - protected HashSet heads = new HashSet(); - protected HashSet tails = new HashSet(); - - public HashMutableDirectedGraph() { } - - public void clearAll() { - nodeToPreds = new HashMap>(); - nodeToSuccs = new HashMap>(); - heads = new HashSet(); - tails = new HashSet(); - } - - public List getHeads() { - ArrayList list = new ArrayList(); - list.addAll(heads); - return Collections.unmodifiableList(list); - } - - public List getTails() { - ArrayList list = new ArrayList(); - list.addAll(tails); - return Collections.unmodifiableList(list); - } - - public List getPreds(N node) { - - List list = nodeToPreds.get(node); - - if (list != null) { - return Collections.unmodifiableList(list); - } else { - throw new RuntimeException(node + " is not in graph"); - } - } - - public List getSuccs(N node) { - List list = nodeToSuccs.get(node); - - if (list != null) { - return Collections.unmodifiableList(list); - } else { - throw new RuntimeException(node + " is not in graph"); - } - } - - public int size() { - return nodeToPreds.keySet().size(); - } - - public Iterator iterator() { - return nodeToPreds.keySet().iterator(); - } - - public void addEdge(N start, N dest) { - - if (start == null || dest == null) { - throw new RuntimeException("edge cannot contain null beginning or end"); - } - - if (containsEdge(start, dest)) { - return; - } - List succsList = nodeToSuccs.get(start); - - if (succsList == null) { - throw new RuntimeException(start + " not in graph"); - } - List predsList = nodeToPreds.get(dest); - - if (predsList == null) { - throw new RuntimeException(dest + " not in graph"); - } - - if (heads.contains(dest)) { - heads.remove(dest); - } - - if (tails.contains(start)) { - tails.remove(start); - } - succsList.add(dest); - predsList.add(start); - } - - public void removeEdge(N start, N dest) { - - if (!containsEdge(start, dest)) { - return; - } - List succsList = nodeToSuccs.get(start); - - if (succsList == null) { - throw new RuntimeException(start + " not in graph"); - } - List predsList = nodeToPreds.get(dest); - - if (predsList == null) { - throw new RuntimeException(dest + " not in graph"); - } - succsList.remove(dest); - predsList.remove(start); - - if (succsList.isEmpty()) { - tails.add(start); - } - - if (predsList.isEmpty()) { - heads.add(dest); - } - nodeToSuccs.put(start, succsList); - nodeToPreds.put(dest, predsList); - } - - public boolean containsEdge(N start, N dest) { - List succs = nodeToSuccs.get(start); - - return succs != null && succs.contains(dest); - } - - public boolean containsNode(N node) { - return nodeToPreds.keySet().contains(node); - } - - public List getNodes() { - return Arrays.asList((N[]) nodeToPreds.keySet().toArray()); - } - - public void addNode(N node) { - - if (containsNode(node)) { - throw new RuntimeException("node " + node + "already in graph"); - } - nodeToSuccs.put(node, new ArrayList()); - nodeToPreds.put(node, new ArrayList()); - heads.add(node); - tails.add(node); - } - - public void removeNode(N node) { - List succs = nodeToSuccs.get(node); - - for (N succNode: succs) { - removeEdge(node, succNode); - } - nodeToSuccs.remove(node); - List preds = nodeToPreds.get(node); - - for (N predNode: preds) { - removeEdge(predNode, node); - } - nodeToPreds.remove(node); - - if (heads.contains(node)) { - heads.remove(node); - } - - if (tails.contains(node)) { - tails.remove(node); - } - } - - public void printGraph() { - - for (N node: nodeToPreds.keySet()) { - System.out.println("Node = " + node); - System.out.println("Preds:"); - - for (N predNode: getPreds(node)) { - System.out.print(" "); - System.out.println(predNode); - } - System.out.println("Succs:"); - - for (N succNode: getSuccs(node)) { - System.out.print(" "); - System.out.println(succNode); - } - } - } -} - diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/MutableDirectedGraph.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/MutableDirectedGraph.java deleted file mode 100644 index ea4b684..0000000 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/MutableDirectedGraph.java +++ /dev/null @@ -1,17 +0,0 @@ - -package net.rec.contra.cjbe.editor.detail.attributes.code.graph; - -public interface MutableDirectedGraph extends DirectedGraph { - - public void addEdge(N start, N dest); - - public void removeEdge(N start, N dest); - - public boolean containsEdge(N start, N dest); - - public void addNode(N node); - - public void removeNode(N node); - - public boolean containsNode(N node); -} \ No newline at end of file diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/Block.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/Block.java deleted file mode 100644 index 5151056..0000000 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/Block.java +++ /dev/null @@ -1,124 +0,0 @@ - -package net.rec.contra.cjbe.editor.detail.attributes.code.graph.cfg; - -import java.util.*; -import org.apache.bcel.generic.*; - -public class Block { - private InstructionHandle head; - private InstructionHandle tail; - private MethodGen mg; - private List preds; - private List succs; - private int len = 0; - private int idx = 0; - private BlockGraph graph; - - public Block(InstructionHandle head, InstructionHandle tail, MethodGen mg, - int idx, int len, BlockGraph graph) { - this.head = head; - this.tail = tail; - this.mg = mg; - this.idx = idx; - this.len = len; - this.graph = graph; - } - - public MethodGen getMethod() { - return mg; - } - - public Iterator iterator() { - return mg.getInstructionList().iterator(); - } - - public void setIndex(int idx) { - this.idx = idx; - } - - public int getIndex() { - return idx; - } - - public InstructionHandle getHead() { - return head; - } - - public InstructionHandle getTail() { - return tail; - } - - public void setPreds(List preds) { - this.preds = preds; - } - - public List getPreds() { - return preds; - } - - public void setSuccs(List succs) { - this.succs = succs; - } - - public List getSuccs() { - return succs; - } - - public String toString() { - return "block #" + idx; - } - - public String toString(boolean verbose) { - - if(!verbose) { - return toString(); - } else { - StringBuilder sb = new StringBuilder("block " + idx + ":\n"); - sb.append("[preds: "); - Iterator it; - - if(preds != null) { - it = preds.iterator(); - - while(it.hasNext()) { - sb.append(it.next().getIndex()).append(" "); - } - } - sb.append("] [succs: "); - - if(succs != null) { - it = succs.iterator(); - - while(it.hasNext()) { - sb.append(it.next().getIndex()).append(" "); - } - } - sb.append("]\n"); - Iterator it2 = iterator(); - - if(it2.hasNext()) { - InstructionHandle ih = it2.next(); - sb.append(ih.toString()).append(";\n"); - - while(it2.hasNext()){ - ih = it2.next(); - - if(ih == tail) { - break; - } - sb.append(ih.toString()).append(";\n"); - } - ih = tail; - - if(tail == null) { - sb.append("null tail; block length: ").append(len).append("\n"); - } else if(head != tail) { - sb.append(ih.toString()).append(";\n"); - } - } else { - System.out.println("no basic blocks found, must be interface or abstract class"); - } - return sb.toString(); - } - } -} \ No newline at end of file diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/BlockGraph.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/BlockGraph.java deleted file mode 100644 index 4ee8cfa..0000000 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/BlockGraph.java +++ /dev/null @@ -1,225 +0,0 @@ - -package net.rec.contra.cjbe.editor.detail.attributes.code.graph.cfg; - -import java.util.*; - -import net.rec.contra.cjbe.editor.detail.attributes.code.graph.DirectedGraph; -import org.apache.bcel.generic.*; - -public class BlockGraph implements DirectedGraph { - MethodGen method; - InstructionList instList; - List blocks; - List heads = new ArrayList(); - List tails = new ArrayList(); - - public BlockGraph(MethodGen mg, boolean exceptEdges) { - new BlockGraph(new InstructionGraph(mg, exceptEdges)); - } - - public BlockGraph(InstructionGraph instGraph) { - method = instGraph.getMethod(); - instList = method.getInstructionList(); - Set leaders = getLeaders(instGraph); - buildBlocks(leaders, instGraph); - } - - private Set getLeaders(InstructionGraph instGraph) { - - if(instGraph.getMethod() != method) { - throw new RuntimeException("BlockGraph: instGraph.getMethod() != method"); - } - Set leaders = new HashSet(); - CodeExceptionGen[] exceptions = method.getExceptionHandlers(); - - for (CodeExceptionGen exception : exceptions) { - leaders.add(exception.getHandlerPC()); - } - - for(Iterator instIt = instList.iterator(); instIt.hasNext(); ) { - InstructionHandle ih = instIt.next(); - List predecessors = instGraph.getPreds(ih); - int predCount = predecessors.size(); - List successors = instGraph.getSuccs(ih); - int succCount = successors.size(); - - if(predCount != 1) { - leaders.add(ih); - } - - if(succCount > 1 || ih.getInstruction() instanceof BranchInstruction) { - - for (InstructionHandle successor : successors) { - leaders.add(successor); - } - } - } - return leaders; - } - - private Map buildBlocks(Set leaders, - InstructionGraph instGraph) { - List blockList = new ArrayList(leaders.size()); - Map instToBlock = new HashMap(); - InstructionHandle head = null; - int len = 0; - Iterator it = instList.iterator(); - - if(it.hasNext()) { - head = it.next(); - - if(!leaders.contains(head)) { - throw new RuntimeException("BlockGraph: first instruction is not a leader"); - } - len++; - } - InstructionHandle tail = head; - int idx = 0; - - while(it.hasNext()) { - InstructionHandle ih = it.next(); - - if(leaders.contains(ih)) { - addBlock(head, tail, idx, len, blockList, instToBlock); - idx++; - head = ih; - len = 0; - } - tail = ih; - len++; - } - if(len > 0) { - addBlock(head, tail, idx, len, blockList, instToBlock); - } - - for(it = instGraph.getHeads().iterator(); it.hasNext(); ) { - head = it.next(); - Block headBlock = instToBlock.get(head); - - if(headBlock.getHead() == head) { - heads.add(headBlock); - } else { - throw new RuntimeException("BlockGraph(): head instruction " + - "is not the first instruction in block"); - } - } - - for(it = instGraph.getTails().iterator(); it.hasNext(); ) { - tail = it.next(); - Block tailBlock = instToBlock.get(tail); - - if(tailBlock.getTail() == tail) { - tails.add(tailBlock); - } else { - throw new RuntimeException("BlockGraph(): tail instruction " + - "is not the last instruction in block"); - } - } - - for (Block block : blockList) { - List preds = instGraph.getPreds(block.getHead()); - List predBlocks = new ArrayList(preds.size()); - - for (InstructionHandle predIh : preds) { - Block predBlock = instToBlock.get(predIh); - - if (predBlock == null) { - throw new RuntimeException("BlockGraph(): block head mapped to null block"); - } - predBlocks.add(predBlock); - } - - if (predBlocks.size() == 0) { - block.setPreds(Collections.EMPTY_LIST); - } else { - block.setPreds(Collections.unmodifiableList(predBlocks)); - - if (block.getHead() == instList.getStart()) { - heads.add(block); - } - } - List succs = instGraph.getSuccs(block.getTail()); - List succBlocks = new ArrayList(succs.size()); - - for (InstructionHandle succIh : succs) { - Block succBlock = instToBlock.get(succIh); - - if (succBlock == null) { - throw new RuntimeException("BlockGraph(): block tail mapped to null block"); - } - succBlocks.add(succBlock); - } - - if (succBlocks.size() == 0) { - block.setSuccs(Collections.EMPTY_LIST); - - if (!tails.contains(block)) { - throw new RuntimeException("BlockGraph(): block with no successors " + - "is not a tail: " + block.toString()); - } - } else { - block.setSuccs(Collections.unmodifiableList(succBlocks)); - } - } - blocks = Collections.unmodifiableList(blockList); - heads = Collections.unmodifiableList(heads); - - if (tails.size() == 0) { - tails = Collections.EMPTY_LIST; - } else { - tails = Collections.unmodifiableList(tails); - } - return instToBlock; - } - - private void addBlock(InstructionHandle head, InstructionHandle tail, int idx, - int len, List blockList, Map instToBlock) { - Block block = new Block(head, tail, method, idx, len, this); - blockList.add(block); - instToBlock.put(tail, block); - instToBlock.put(head, block); - } - - public MethodGen getMethod() { - return method; - } - - public List getBlocks() { - return blocks; - } - - public String toString() { - Iterator it = blocks.iterator(); - StringBuilder sb = new StringBuilder(); - - while(it.hasNext()) { - Block block = it.next(); - sb.append(block.toString(true)).append("\n"); - } - return sb.toString(); - } - - public List getHeads() { - return heads; - } - - public List getTails() { - return tails; - } - - public List getPreds(Block b) { - return b.getPreds(); - } - - public List getSuccs(Block b) { - return b.getSuccs(); - } - - public int size() { - return blocks.size(); - } - - public Iterator iterator() { - return blocks.iterator(); - } -} diff --git a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/InstructionGraph.java b/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/InstructionGraph.java deleted file mode 100644 index 830d3a7..0000000 --- a/src/net/rec/contra/cjbe/editor/detail/attributes/code/graph/cfg/InstructionGraph.java +++ /dev/null @@ -1,213 +0,0 @@ - -package net.rec.contra.cjbe.editor.detail.attributes.code.graph.cfg; - -import java.util.*; - -import net.rec.contra.cjbe.editor.detail.attributes.code.graph.DirectedGraph; -import org.apache.bcel.generic.*; - -public class InstructionGraph implements DirectedGraph { - private List heads; - private List tails; - private Map> instToSuccs; - private Map> instToPreds; - private MethodGen method; - private InstructionList instList; - - public InstructionGraph(MethodGen method, boolean exceptEdges) { - this.method = method; - instList = method.getInstructionList(); - instToSuccs = new HashMap>(); - instToPreds = new HashMap>(); - buildUnexceptionalEdges(instToSuccs, instToPreds); - - if(exceptEdges) { - buildExceptionalEdges(instToSuccs, instToPreds); - } - buildHeadsAndTails(); - } - - - private void buildUnexceptionalEdges( - Map> instToSuccs, - Map> instToPreds) { - Iterator instIt = instList.iterator(); - - while(instIt.hasNext()) { - instToPreds.put(instIt.next(), new ArrayList()); - } - instIt = instList.iterator(); - InstructionHandle currentIh; - InstructionHandle nextIh = instIt.hasNext() ? instIt.next() : null; - - while(nextIh != null) { - currentIh = nextIh; - nextIh = instIt.hasNext() ? instIt.next() : null; - List successors = new ArrayList(); - - if(fallsThrough(currentIh)) { - - if(nextIh != null) { - successors.add(nextIh); - instToPreds.get(nextIh).add(currentIh); - } - } - - if(branches(currentIh)) { - InstructionHandle target = ((BranchHandle) currentIh).getTarget(); - - if(!successors.contains(target)) { - successors.add(target); - instToPreds.get(target).add(currentIh); - } - } - instToSuccs.put(currentIh, successors); - } - } - - private void buildExceptionalEdges( - Map> instToSuccs, - Map> instToPreds) { - CodeExceptionGen[] exceptions = method.getExceptionHandlers(); - - for (CodeExceptionGen e : exceptions) { - InstructionHandle first = e.getStartPC(); - InstructionHandle last = e.getEndPC().getPrev(); - InstructionHandle handler = e.getHandlerPC(); - //Iterator it = instList.iterator(); - for(InstructionHandle ih : instList.getInstructionHandles()){ - if(first.getPosition() >= ih.getPosition() && ih.getPosition() >= last.getPosition()){ - addEdge(instToSuccs, instToPreds, ih, handler); - } - } - /* - while (it.hasNext()) { - InstructionHandle trapped = it.next(); - addEdge(instToSuccs, instToPreds, trapped, handler); - } */ - } - } - - private boolean branches(InstructionHandle ih) { - Instruction inst = ih.getInstruction(); - - return inst instanceof BranchInstruction; - } - - private boolean fallsThrough(InstructionHandle ih) { - Instruction inst = ih.getInstruction(); - - return !(inst instanceof GotoInstruction || inst instanceof ReturnInstruction); - } - - private void buildHeadsAndTails() { - List tailList = new ArrayList(); - List headList = new ArrayList(); - - for(Iterator it = instList.iterator(); it.hasNext(); ) { - InstructionHandle ih = it.next(); - List succs = instToSuccs.get(ih); - - if(succs.size() == 0) { - tailList.add(ih); - } - List preds = instToPreds.get(ih); - - if(preds.size() == 0) { - headList.add(ih); - } - } - InstructionHandle entry = instList.getStart(); - - if(!headList.contains(entry)) { - headList.add(entry); - } - tails = Collections.unmodifiableList(tailList); - heads = Collections.unmodifiableList(headList); - } - - private static void makeMappedListsUnmodifiable(Map> map) { - - for (Map.Entry> instructionHandleListEntry : map.entrySet()) { - List value = instructionHandleListEntry.getValue(); - - if (value.size() == 0) { - instructionHandleListEntry.setValue(Collections.EMPTY_LIST); - } else { - instructionHandleListEntry.setValue(Collections.unmodifiableList(value)); - } - } - } - - private void addEdge( - Map> instToSuccs, - Map> instToPreds, - InstructionHandle head, InstructionHandle tail) { - List headSuccs = instToSuccs.get(head); - - if(headSuccs == null) { - headSuccs = new ArrayList(); - instToSuccs.put(head, headSuccs); - } - - if(!headSuccs.contains(tail)) { - headSuccs.add(tail); - List tailPreds = instToPreds.get(tail); - - if (tailPreds == null) { - tailPreds = new ArrayList(); - instToPreds.put(tail, tailPreds); - } - tailPreds.add(head); - } - } - - public MethodGen getMethod() { - return method; - } - - public List getHeads() { - return heads; - } - - public List getTails() { - return tails; - } - - public List getPreds(InstructionHandle ih) { - - if(!instToSuccs.containsKey(ih)) { - throw new RuntimeException("graph does not contain " + ih); - } - return instToPreds.get(ih); - } - - public List getSuccs(InstructionHandle ih) { - - if(!instToSuccs.containsKey(ih)) { - throw new RuntimeException("graph does not contain " + ih); - } - return instToSuccs.get(ih); - } - - public int size() { - return instList.size(); - } - - public Iterator iterator() { - return instList.iterator(); - } - - public String toString() { - Iterator it = instList.iterator(); - StringBuilder sb = new StringBuilder(); - - while(it.hasNext()) { - InstructionHandle ih = it.next(); - sb.append("// preds: ").append(getPreds(ih)).append("\n"); - sb.append(ih.toString()).append("\n"); - sb.append("// succs ").append(getSuccs(ih)).append("\n"); - } - return sb.toString(); - } -} \ No newline at end of file