public void PrintDot() { string name = method.DeclaringType.Name + "." + method.Name + ".dot"; FileMode mode = FileMode.Create; StreamWriter writer = new StreamWriter(new FileStream(name, mode)); writer.WriteLine("digraph {0} (", method.Name); foreach (Node node in Nodes) { BasicBlock bb = (BasicBlock)node; writer.WriteLine(" \"{0}\" [ label = \"{1}\" ];", bb, bb); } foreach (Edge edge in Edges) { CFGEdge ce = (CFGEdge)edge; writer.Write(" \"{0}\" -> \"{1}\"", ce.Start, ce.End); if (ce.Type == CFGEdgeType.Branch) { writer.WriteLine(" [ label = \"branch\" ];"); } else if (ce.Type == CFGEdgeType.Forward) { writer.WriteLine(" [ label = \"forward\" ];"); } else if (ce.Type == CFGEdgeType.Return) { writer.WriteLine(" [ label = \"return\" ];"); } else if (ce.Type == CFGEdgeType.Exception) { writer.WriteLine(" [ label = \"exception\" ];"); } else { writer.WriteLine(" [ label = \"unknown\" ];"); } } writer.WriteLine(")"); writer.Close(); }
private void BuildGraph() { BasicBlock tail = null; Instruction prevInsn = null; BasicBlock prevBB = null; int currentInsnNum = 0; Hashtable insnBB = new Hashtable(); BasicBlock exit = new BasicBlock(instructions); exit.first = exit.last = 0; exit.isExit = true; AddNode(exit); foreach (Instruction insn in instructions) { if (printer.IsLeader(insn, prevInsn)) { tail = new BasicBlock(instructions); tail.first = currentInsnNum; AddNode(tail); if (prevBB != null) { prevBB.last = currentInsnNum - 1; if (HasNext(instructions[currentInsnNum - 1])) { CFGEdge edge = new CFGEdge(prevBB, tail, CFGEdgeType.Forward); AddEdge(edge); } } } insnBB.Add(insn.Offset, tail); prevInsn = insn; prevBB = tail; currentInsnNum++; } if (prevBB != null) { prevBB.last = currentInsnNum - 1; } foreach (Instruction insn in instructions) { if ((printer.EndsTryRegion(insn) != null) || (printer.EndsHandlerRegion(insn) != null)) { BasicBlock finallyBB = GetNearestFinally(insn, insnBB); if (finallyBB != null) { AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], finallyBB, CFGEdgeType.Forward)); } } if (insn.OpCode.FlowControl == FlowControl.Return) { if (insn.OpCode.Code == Code.Endfinally && insn.Next != null) { AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], (BasicBlock)insnBB[insn.Next.Offset], CFGEdgeType.Forward)); } else { AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], exit, CFGEdgeType.Return)); } } /* * if((insn.OpCode.Value != OpCodeConstants.Leave) && * (insn.OpCode.Value != OpCodeConstants.Endfinally)) { */ int[] targets = MethodPrinter.BranchTargets(insn); if (targets == null) { continue; } foreach (int target in targets) { AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], (BasicBlock)insnBB[target], CFGEdgeType.Branch)); } /*} */ } entryPoint = (BasicBlock)insnBB[0]; }
private void BuildGraph() { BasicBlock tail = null; Instruction prevInsn = null; BasicBlock prevBB = null; int currentInsnNum = 0; Hashtable insnBB = new Hashtable(); BasicBlock exit = new BasicBlock(instructions); exit.first = exit.last = 0; exit.isExit = true; AddNode(exit); foreach(Instruction insn in instructions) { if (printer.IsLeader (insn, prevInsn)) { tail = new BasicBlock(instructions); tail.first = currentInsnNum; AddNode(tail); if(prevBB != null) { prevBB.last = currentInsnNum - 1; if(HasNext(instructions[currentInsnNum - 1])) { CFGEdge edge = new CFGEdge(prevBB, tail, CFGEdgeType.Forward); AddEdge(edge); } } } insnBB.Add(insn.Offset, tail); prevInsn = insn; prevBB = tail; currentInsnNum++; } if(prevBB != null) { prevBB.last = currentInsnNum - 1; } foreach(Instruction insn in instructions) { if ((printer.EndsTryRegion (insn) != null) || (printer.EndsHandlerRegion (insn) != null)) { BasicBlock finallyBB = GetNearestFinally(insn, insnBB); if(finallyBB != null) AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], finallyBB, CFGEdgeType.Forward)); } if(insn.OpCode.FlowControl == FlowControl.Return) { if(insn.OpCode.Code == Code.Endfinally && insn.Next != null) { AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], (BasicBlock)insnBB[insn.Next.Offset], CFGEdgeType.Forward)); } else { AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], exit, CFGEdgeType.Return)); } } /* if((insn.OpCode.Value != OpCodeConstants.Leave) && (insn.OpCode.Value != OpCodeConstants.Endfinally)) { */ int[] targets = MethodPrinter.BranchTargets (insn); if(targets == null) continue; foreach(int target in targets) { AddEdge(new CFGEdge((BasicBlock)insnBB[insn.Offset], (BasicBlock)insnBB[target], CFGEdgeType.Branch)); } /*} */ } entryPoint = (BasicBlock)insnBB[0]; }