private ScanResults CreateScanResults(DiGraph <RtlBlock> icfg) { return(new ScanResults { ICFG = icfg }); }
FindStronglyConnectedComponents(DiGraph <T> graph) { var visited = new HashSet <T>(); var finishStack = new Stack <T>(); //step one - create DFS finish visit stack foreach (var vertex in graph.Vertices) { if (!visited.Contains(vertex.Value.Value)) { KosarajuStep1(vertex.Value, visited, finishStack); } } //reverse edges var reverseGraph = ReverseEdges(graph); visited.Clear(); var result = new List <List <T> >(); //now pop finish stack and gather the components while (finishStack.Count > 0) { var currentVertex = reverseGraph.FindVertex(finishStack.Pop()); if (!visited.Contains(currentVertex.Value)) { result.Add(KosarajuStep2(currentVertex, visited, finishStack, new List <T>())); } } return(result); }
public void DFS_Topological_Sort_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'D'); graph.AddEdge('E', 'D'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('F', 'H'); var algorithm = new DepthFirstTopSort <char>(); var result = algorithm.GetTopSort(graph); Assert.AreEqual(result.Count, 8); }
public void CreationOfGraphYieldsCorrectEdges() { var graph = new DiGraph <int, int>(1); graph.AddEdge(1, 2); graph.AddEdge(2, 3); graph.AddEdge(3, 4); graph.AddEdge(4, 5); graph.AddEdge(5, 6); graph.AddEdge(6, 7); var expectedEdges = new List <IEdge <int, int> > { new Edge <int, int>(1, 2, 1), new Edge <int, int>(2, 3, 1), new Edge <int, int>(3, 4, 1), new Edge <int, int>(4, 5, 1), new Edge <int, int>(5, 6, 1), new Edge <int, int>(6, 7, 1), }; CollectionAssert.AreEquivalent(expectedEdges, graph.Edges); var copyGraph = new DiGraph <int, int>(graph); CollectionAssert.AreEquivalent(expectedEdges, copyGraph.Edges); }
public void Setup() { mr = new MockRepository(); rd = null; this.graph = new DiGraph <Address>(); this.instrs = new SortedList <Address, MachineInstruction>(); }
public void HPSC_ResolveBlockConflicts_RemoveDirectlyCalledAddress() { var calledAddr = Address.Ptr32(0x5678); var wrongBlock = Given_Block(0x1234); Given_Instrs(wrongBlock, m => { m.Call(calledAddr, 4); }); var firstBlock = Given_Block(0x1235); Given_Instrs(firstBlock, m => { m.Assign(m.Mem32(m.Word32(0x2222)), 0); }); var lastBlock = Given_Block(0x1240); Given_Instrs(lastBlock, m => { m.Return(4, 0); }); var cfg = new DiGraph <RtlBlock>(); cfg.AddNode(wrongBlock); cfg.AddNode(firstBlock); cfg.AddNode(lastBlock); cfg.AddEdge(firstBlock, lastBlock); var sr = CreateScanResults(cfg); sr.DirectlyCalledAddresses.Add(calledAddr, 1); ResolveBlockConflicts(sr); Assert.AreEqual(0, sr.DirectlyCalledAddresses.Count); }
/// <summary> /// Computes maximum cost in <see cref="graph"/> using topological sort. /// </summary> /// <param name="graph">Graph from which the maximum cost will be calculated. It needs to be acyclic.</param> /// <returns></returns> public double GetMaximumCost(DiGraph <Operation> graph) { // topologically sort the graph => returns topologically sorted operations var topologicallySortedOperations = new DepthFirstTopSort <Operation>().GetTopSort(graph); return(GetMaximumCost(graph, topologicallySortedOperations)); }
public void Top_Sort_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'D'); graph.AddEdge('E', 'D'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('F', 'H'); var algo = new KahnsTopSort <char>(); var result = algo.GetTopSort(graph); Assert.AreEqual(result.Count, 8); }
public static DiGraph dag4StronglyConnectedComponents() { var graph = new DiGraph(13); graph.addEdge(4, 2); graph.addEdge(2, 3); graph.addEdge(3, 2); graph.addEdge(6, 0); graph.addEdge(0, 1); graph.addEdge(2, 0); graph.addEdge(11, 12); graph.addEdge(12, 9); graph.addEdge(9, 10); graph.addEdge(9, 11); graph.addEdge(8, 9); graph.addEdge(10, 12); graph.addEdge(11, 4); graph.addEdge(4, 3); graph.addEdge(3, 5); graph.addEdge(7, 8); graph.addEdge(8, 7); graph.addEdge(5, 4); graph.addEdge(0, 5); graph.addEdge(6, 4); graph.addEdge(6, 9); graph.addEdge(7, 6); return(graph); }
public void BiDirectional_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddVertex('I'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'D'); graph.AddEdge('D', 'E'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('G', 'H'); graph.AddEdge('H', 'I'); var algorithm = new BiDirectional <char>(); Assert.IsTrue(algorithm.PathExists(graph, 'A', 'I')); graph.RemoveEdge('D', 'E'); graph.AddEdge('E', 'D'); Assert.IsFalse(algorithm.PathExists(graph, 'A', 'I')); }
public DiGraph <RtlBlock> BuildIcfg(Dictionary <Address, block> blocks) { var icfg = new DiGraph <RtlBlock>(); var map = new Dictionary <Address, RtlBlock>(); var rtlBlocks = from b in blocks.Values join i in sr.FlatInstructions.Values on b.id equals i.block_id into instrs orderby b.id select new RtlBlock(b.id, b.id.GenerateName("l", "")) { Instructions = instrs.Select(x => x.rtl).ToList() }; foreach (var rtlBlock in rtlBlocks) { map[rtlBlock.Address] = rtlBlock; icfg.AddNode(rtlBlock); } foreach (var edge in sr.FlatEdges) { if (!map.TryGetValue(edge.first, out RtlBlock from) || !map.TryGetValue(edge.second, out RtlBlock to)) { continue; } icfg.AddEdge(from, to); } return(icfg); }
private void RemoveInvalidBlocks(ScanResults sr) { var revGraph = new DiGraph <RtlBlock>(); var invalid = new RtlBlock(null !, "<invalid>"); revGraph.AddNode(invalid); foreach (var b in sr.ICFG.Nodes) { revGraph.AddNode(b); } foreach (var b in sr.ICFG.Nodes) { foreach (var s in sr.ICFG.Successors(b)) { revGraph.AddEdge(s, b); } if (!b.IsValid) { revGraph.AddEdge(invalid, b); } } // Find the transitive closure of invalid nodes. var invalidNodes = new DfsIterator <RtlBlock>(revGraph) .PreOrder(invalid) .ToList(); foreach (var n in invalidNodes.Where(nn => nn != invalid)) { sr.ICFG.RemoveNode(n); sr.DirectlyCalledAddresses.Remove(n.Address); // Debug.Print("Removed invalid node {0}", n.Address); // commented out as this becomes very verbose. } }
private void buildGraph() { //create the nodes foreach (ASystem sys in unsorted) { //create the node DiGraph<ASystem>.Node node = new DiGraph<ASystem>.Node(sys); //add it to the data structures graph.nodes.Add(node); nodeLookup[sys.GetType()] = node; } //create the edges foreach (DiGraph<ASystem>.Node node in graph.nodes) { //for each system that must run after this one foreach (Type childSystem in node.data.GetChildren()) { //create an edge from that system to this one to indicate that dependency DiGraph<ASystem>.Node childNode = nodeLookup[childSystem]; childNode.AddNeighbor(node); } //for each system that must run before this one foreach (Type parentSystem in node.data.GetParents()) { //create an edge from this system to that one to indicate that dependency DiGraph<ASystem>.Node parentNode = nodeLookup[parentSystem]; node.AddNeighbor(parentNode); } } }
private void dfs(DiGraph G, int v) { marked[v] = true; onStack[v] = true; foreach (var w in G.adj(v)) { if (!marked[w]) { edgeTo[w] = v; dfs(G, w); } else if (onStack[w]) { if (circle == null) { return; } else { circle = new StackLinkedList <int>(); for (var x = w; x != v; x = edgeTo[x]) { circle.Push(x); } circle.Push(v); circle.Push(w); } } } onStack[v] = false; }
public void GraphKnowsTheIncomingAndOutgoingEdges() { var graph = new DiGraph <int, int>(1); graph.AddEdge(1, 1); graph.AddEdge(2, 2); graph.AddEdge(3, 3); graph.AddEdge(1, 2); graph.AddEdge(2, 1); graph.AddEdge(2, 3); graph.AddEdge(3, 2); graph.AddEdge(3, 1); graph.AddEdge(1, 3); CollectionAssert.AreEquivalent(new List <IEdge <int, int> > { new Edge <int, int>(1, 1, 1), new Edge <int, int>(2, 1, 1), new Edge <int, int>(3, 1, 1), }, graph.GetIncomingEdges(1)); CollectionAssert.AreEquivalent(new List <IEdge <int, int> > { new Edge <int, int>(1, 1, 1), new Edge <int, int>(1, 2, 1), new Edge <int, int>(1, 3, 1), }, graph.GetOutgoingEdges(1)); CollectionAssert.AreEquivalent(new List <IEdge <int, int> > { new Edge <int, int>(1, 2, 1), new Edge <int, int>(2, 2, 1), new Edge <int, int>(3, 2, 1), }, graph.GetIncomingEdges(2)); CollectionAssert.AreEquivalent(new List <IEdge <int, int> > { new Edge <int, int>(2, 1, 1), new Edge <int, int>(2, 2, 1), new Edge <int, int>(2, 3, 1), }, graph.GetOutgoingEdges(2)); CollectionAssert.AreEquivalent(new List <IEdge <int, int> > { new Edge <int, int>(1, 3, 1), new Edge <int, int>(2, 3, 1), new Edge <int, int>(3, 3, 1), }, graph.GetIncomingEdges(3)); CollectionAssert.AreEquivalent(new List <IEdge <int, int> > { new Edge <int, int>(3, 1, 1), new Edge <int, int>(3, 2, 1), new Edge <int, int>(3, 3, 1), }, graph.GetOutgoingEdges(3)); Assert.IsTrue(graph.HasEdge(3, 1)); Assert.IsFalse(graph.HasEdge(4, 2)); }
public DirectedCycles(DiGraph G) { var V = G.V(); marked = new bool[V]; edgeTo = new int[V]; onStack = new bool[V]; }
public TransitiveClosure(DiGraph G) { all = new DirectedDFS[G.V]; for (int v = 0; v < G.V; v++) { all[v] = new DirectedDFS(G, v); } }
public void Test() { DiGraph dag = GraphGenerator.dag(); var dfo = new DepthFirstPostOrder(dag); console.WriteLine(dfo.PostOrderToString()); }
public RegionGraphBuilder(Procedure proc) { this.proc = proc; this.btor = new Dictionary <Block, Region>(); this.graph = new DiGraph <Region>(); this.regionFactory = new RegionFactory(); this.switchPads = new Dictionary <Block, Dictionary <Block, Region> >(); }
public SystemTopologicalSorter(List<ASystem> toSort) { graph = new DiGraph<ASystem>(); nodeLookup = new Dictionary<Type, DiGraph<ASystem>.Node>(); unsorted = new List<ASystem>(toSort); sorted = new List<ASystem>(); }
private void dfs(DiGraph G, int v) { marked[v] = true; id[v] = count; foreach (int w in G.Adj(v)) if (!marked[w]) dfs(G, w); }
public void DiGraph_Smoke_Test() { var graph = new DiGraph <int>(); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); graph.AddVertex(4); graph.AddVertex(5); graph.AddEdge(1, 2); Assert.IsTrue(graph.HasEdge(1, 2)); Assert.IsFalse(graph.HasEdge(2, 1)); graph.AddEdge(3, 2); Assert.AreEqual(2, graph.InEdges(2).Count()); graph.RemoveEdge(3, 2); graph.AddEdge(2, 3); graph.AddEdge(3, 4); graph.AddEdge(4, 5); graph.AddEdge(4, 1); graph.AddEdge(3, 5); Assert.AreEqual(2, graph.OutEdges(4).Count()); Assert.AreEqual(5, graph.VerticesCount); Assert.IsTrue(graph.HasEdge(1, 2)); graph.RemoveEdge(1, 2); Assert.IsFalse(graph.HasEdge(1, 2)); graph.RemoveEdge(2, 3); graph.RemoveEdge(3, 4); graph.RemoveEdge(4, 5); graph.RemoveEdge(4, 1); Assert.IsTrue(graph.HasEdge(3, 5)); graph.RemoveEdge(3, 5); Assert.IsFalse(graph.HasEdge(3, 5)); graph.RemoveVertex(1); graph.RemoveVertex(2); graph.RemoveVertex(3); graph.AddEdge(4, 5); graph.RemoveVertex(4); graph.AddEdge(5, 5); graph.RemoveEdge(5, 5); graph.RemoveVertex(5); Assert.AreEqual(0, graph.VerticesCount); }
private IEnumerable <IDiGraph <T, TWeight> > StrongConnect(T vertex) { var metadata = _metadataLookup[vertex]; metadata.Index = _index; metadata.LowLink = _index; _index += 1; _stack.Push(vertex); metadata.OnStack = true; foreach (var outEdge in _graph.GetOutgoingEdges(vertex)) { var targetVertex = outEdge.TargetVertex; var outMetadata = _metadataLookup[targetVertex]; if (outMetadata.Index == -1) { foreach (var result in StrongConnect(targetVertex)) { yield return(result); } } if (outMetadata.OnStack) { metadata.LowLink = Math.Min(metadata.LowLink, outMetadata.LowLink); } } if (metadata.LowLink != metadata.Index) { yield break; } IDiGraph <T, TWeight> componentGraph = new DiGraph <T, TWeight>(_graph.DefaultEdgeWeight); T wVertex; do { wVertex = _stack.Pop(); var stackNodeMetadata = _metadataLookup[wVertex]; stackNodeMetadata.OnStack = false; componentGraph.AddVertex(wVertex); } while (!EqualityComparer <T> .Default.Equals(vertex, wVertex)); var filteredEdges = componentGraph.Vertices .SelectMany(v => _graph.GetOutgoingEdges(v)) .Where(e => componentGraph.Vertices.Contains(e.SourceVertex)) .Where(e => componentGraph.Vertices.Contains(e.TargetVertex)); foreach (var edge in filteredEdges) { componentGraph.AddEdge(edge.SourceVertex, edge.TargetVertex, edge.Weight); } yield return(componentGraph); }
/// <summary> /// Returns the vertices in Topologically Sorted Order /// </summary> /// <param name="graph"></param> /// <returns></returns> public List <T> GetTopSort(DiGraph <T> graph) { var inEdgeMap = new Dictionary <T, int>(); var kahnQueue = new Queue <T>(); foreach (var vertex in graph.Vertices) { inEdgeMap.Add(vertex.Key, vertex.Value.InEdges.Count); //init queue with vertices having not in edges if (vertex.Value.InEdges.Count == 0) { kahnQueue.Enqueue(vertex.Value.Value); } } //no vertices with zero number of in edges if (kahnQueue.Count == 0) { throw new Exception("Graph has a cycle."); } var result = new List <T>(); int visitCount = 0; //until queue is empty while (kahnQueue.Count > 0) { //cannot exceed vertex number of iterations if (visitCount > graph.Vertices.Count) { throw new Exception("Graph has a cycle."); } //pick a neighbour var nextPick = graph.Vertices[kahnQueue.Dequeue()]; //if in edge count is 0 then ready for result if (inEdgeMap[nextPick.Value] == 0) { result.Add(nextPick.Value); } //decrement in edge count for neighbours foreach (var edge in nextPick.OutEdges) { inEdgeMap[edge.Value]--; kahnQueue.Enqueue(edge.Value); } visitCount++; } return(result); }
private bool[] marked; // reached vertices #endregion Fields #region Constructors public KosarajuSCC(DiGraph G) { marked = new bool[G.V]; id = new int[G.V]; DepthFirstOrder order = new DepthFirstOrder(G.reverse()); foreach (int s in order.ReversePost()) if (!marked[s]) { dfs(G, s); count++; } }
private void CheckCycle() { var diGraph = DiGraph <string> .GetDiGraph(Model.NodesSource.Cast <NodeModel>(), Model.LinksSource.Cast <LinkModel>()); var algorithm = new CycleDetector <string>(); var HasCycle = algorithm.HasCycle(diGraph); MessageBox.Show(HasCycle.ToString()); }
/// <summary> /// Breaks cycles, returning list of edges whose orientation was reversed during the process. /// </summary> /// <param name="graph"></param> /// <returns></returns> public List <(Operation Operation1, Operation Operation2)> BreakCycles(DiGraph <Operation> graph) { // break cycles var edgesThatChangedOrientation = new GraphCycleBreaker( Global.Config.BackEdgeSwitchOrientationProbability, Global.Config.ForwardEdgeSwitchOrientationProbability, Global.Config.SameLevelEdgeSwitchOrientationProbability) .BreakCycles(graph); return(edgesThatChangedOrientation); }
/// <summary> /// Build Shingle blocks from the graph. An instruction can only be /// in one block at a time, so at each point in the graph where the /// successors > 1 or the predecessors > 1, we create a new node. /// </summary> /// <param name="g"></param> /// <param name="instructions"></param> /// <returns></returns> public SortedList <Address, ShingleBlock> BuildBlocks( DiGraph <Address> g, SortedList <Address, MachineInstruction> instructions) { // Remember, the graph is backwards! var activeBlocks = new List <ShingleBlock>(); var allBlocks = new SortedList <Address, ShingleBlock>(); var wl = instructions.Keys.ToSortedSet(); while (wl.Count > 0) { var addr = wl.First(); wl.Remove(addr); var instr = instructions[addr]; var block = new ShingleBlock { BaseAddress = addr }; allBlocks.Add(addr, block); bool terminateNow = false; bool terminateDeferred = false; for (;;) { var addrInstrEnd = instr.Address + instr.Length; if ((instr.InstructionClass & InstructionClass.Transfer) != 0) { if ((instr.InstructionClass & DT) == DT) { terminateDeferred = true; } else { terminateNow = true; } } else { terminateNow = terminateDeferred; } if (terminateNow || !wl.Contains(addrInstrEnd) || !g.Nodes.Contains(addrInstrEnd) || g.Successors(addrInstrEnd).Count != 1) { block.EndAddress = addrInstrEnd; break; } wl.Remove(addrInstrEnd); instr = instructions[addrInstrEnd]; terminateNow = terminateDeferred; } } return(allBlocks); }
public int FindJudge(int N, int[][] trust) { DiGraph di = new DiGraph(N); for (int i = 0; i < trust.Length; i++) { di.AddEdge(trust[i][0] - 1, trust[i][1] - 1); } int ansCandidate = -1; for (int i = 0; i < di.Count(); i++) { if (di.OutDeg(i) == 0) { if (ansCandidate == -1) { ansCandidate = i; } else { return(-1); } } } if (ansCandidate == -1) { return(-1); } for (int i = 0; i < di.Count(); i++) { bool isTrust = false; if (i != ansCandidate) { foreach (var j in di.Adj(i)) { if (j == ansCandidate) { isTrust = true; break; } } if (!isTrust) { return(-1); } } } return(ansCandidate + 1); }
public void KosarajuStronglyConnected_Smoke_Test() { var graph = new DiGraph <char>(); graph.AddVertex('A'); graph.AddVertex('B'); graph.AddVertex('C'); graph.AddVertex('D'); graph.AddVertex('E'); graph.AddVertex('F'); graph.AddVertex('G'); graph.AddVertex('H'); graph.AddEdge('A', 'B'); graph.AddEdge('B', 'C'); graph.AddEdge('C', 'A'); graph.AddEdge('C', 'D'); graph.AddEdge('D', 'E'); graph.AddEdge('E', 'F'); graph.AddEdge('F', 'G'); graph.AddEdge('G', 'E'); graph.AddEdge('F', 'H'); var algorithm = new KosarajuStronglyConnected <char>(); var result = algorithm.FindStronglyConnectedComponents(graph); Assert.AreEqual(4, result.Count); var expectedResult = new List <List <char> >() { new char[] { 'A', 'B', 'C' }.ToList(), new char[] { 'D' }.ToList(), new char[] { 'E', 'F', 'G' }.ToList(), new char[] { 'H' }.ToList() }; for (int i = 0; i < expectedResult.Count; i++) { var expectation = expectedResult[i]; var actual = result[i]; Assert.IsTrue(expectation.Count == actual.Count); foreach (var vertex in expectation) { Assert.IsTrue(actual.Contains(vertex)); } } }
private string DumpBlocks(DiGraph <RtlBlock> blocks) { var sb = new StringBuilder(); foreach (var block in blocks.Nodes.OrderBy(b => b.Address)) { sb.AppendFormat("{0} - {1}", block.Address, block.GetEndAddress()); sb.AppendLine(); } return(sb.ToString()); }
private void dfs(DiGraph G, int v) { marked[v] = true; id[v] = count; foreach (var w in G.adj(v)) { if (!marked[w]) { dfs(G, w); } } }
/// <summary> /// Disassemble every byte of the image, marking those addresses that likely /// are code as MaybeCode, everything else as data. /// </summary> /// <param name="segment"></param> /// <returns>An array of bytes classifying each byte as code or data. /// </returns> public byte[] ScanSegment(ImageMapSegment segment) { var G = new DiGraph<Address>(); G.AddNode(bad); var y = new byte[segment.ContentSize]; var step = program.Architecture.InstructionBitSize / 8; bool inDelaySlot = false; for (var a = 0; a < y.Length; a += step) { y[a] = MaybeCode; var i = Dasm(segment, a); if (i == null || i.InstructionClass == InstructionClass.Invalid) { AddEdge(G, bad, i.Address); inDelaySlot = false; } else { if (MayFallThrough(i)) { if (!inDelaySlot) { if (a + i.Length < y.Length) AddEdge(G, i.Address + i.Length, i.Address); else AddEdge(G, bad, i.Address); } } if ((i.InstructionClass & InstructionClass.Transfer) != 0) { var dest = Destination(i); if (dest != null) { if (IsExecutable(dest)) AddEdge(G, dest, i.Address); else AddEdge(G, bad, i.Address); } } // If this is a delayed unconditional branch... inDelaySlot = i.InstructionClass == DT; } } foreach (var a in new DfsIterator<Address>(G).PreOrder(bad)) { if (a != bad) { y[a - segment.Address] = Data; } } return y; }
private IEnumerable <Operation> GetNeighborComponentOperations(DiGraph <Operation> graph, Operation operation1, HashSet <Operation> componentOperations) { var vertex = graph.FindVertex(operation1); foreach (var vertexOutEdge in vertex.OutEdges) { if (componentOperations.Contains(vertexOutEdge.Value)) { yield return(vertexOutEdge.Value); } } }
public HeuristicProcedureScanner( Program program, ScanResults sr, Func <Address, bool> isAddressValid, IRewriterHost host) { this.program = program; this.host = host; this.sr = sr; this.blocks = sr.ICFG; this.isAddressValid = isAddressValid; this.conflicts = BuildConflictGraph(blocks.Nodes); }
private void DFS(DiGraph<ASystem>.Node cur, HashSet<DiGraph<ASystem>.Node> visited, HashSet<DiGraph<ASystem>.Node> visitedThisTime) { if (visitedThisTime.Contains(cur)) { throw new ArgumentException("A cycle exists in the set of systems!"); } if (!visited.Contains(cur)) { visited.Add(cur); //visit every ancestor of cur (every system that must be executed first) foreach (DiGraph<ASystem>.Node neighbor in cur.neighbors) { DFS(neighbor, visited, visitedThisTime); } //Since every preceding system has been added to the execution ordering, this one can be safely added now sorted.Add(cur.data); } }
/// <summary> /// Builds a graph of regions based on the basic blocks of the code. /// </summary> /// <param name="proc"></param> /// <returns></returns> public Tuple<DirectedGraph<Region>, Region> BuildRegionGraph(Procedure proc) { var btor = new Dictionary<Block, Region>(); var regs = new DiGraph<Region>(); var regionFactory = new RegionFactory(); foreach (var b in proc.ControlGraph.Blocks) { var reg = regionFactory.Create(b); btor.Add(b, reg); regs.AddNode(reg); } foreach (var b in proc.ControlGraph.Blocks) { foreach (var s in b.Succ) { var from = btor[b]; var to = btor[s]; regs.AddEdge(from, to); } } return new Tuple<DirectedGraph<Region>, Region>(regs, btor[proc.EntryBlock]); }
/// <summary> /// Disassemble every byte of the segment, marking those addresses /// that likely are code as MaybeCode, everything else as data. /// </summary> /// <remarks> /// The plan is to disassemble every location of the segment, building /// a reverse control graph. Any jump to an illegal address or any /// invalid instruction will result in an edge from "bad" to that /// instruction. /// </remarks> /// <param name="segment"></param> /// <returns>An array of bytes classifying each byte as code or data. /// </returns> public ScannedSegment ScanSegment(ImageSegment segment, ulong workToDo) { var G = new DiGraph<Address>(); G.AddNode(bad); var cbAlloc = Math.Min( segment.Size, segment.MemoryArea.EndAddress - segment.Address); var y = new byte[cbAlloc]; // Advance by the instruction granularity. var step = program.Architecture.InstructionBitSize / 8; var delaySlot = InstructionClass.None; for (var a = 0; a < y.Length; a += step) { y[a] = MaybeCode; var i = Dasm(segment, a); if (i == null) { AddEdge(G, bad, segment.Address + a); break; } if (IsInvalid(segment.MemoryArea, i)) { AddEdge(G, bad, i.Address); delaySlot = InstructionClass.None; y[a] = Data; } else { if (MayFallThrough(i)) { if (delaySlot != DT) { if (a + i.Length < y.Length) { // Still inside the segment. AddEdge(G, i.Address + i.Length, i.Address); } else { // Fell off segment, i must be a bad instruction. AddEdge(G, bad, i.Address); y[a] = Data; } } } if ((i.InstructionClass & InstructionClass.Transfer) != 0) { var addrDest = DestinationAddress(i); if (addrDest != null) { if (IsExecutable(addrDest)) { // call / jump destination is executable AddEdge(G, addrDest, i.Address); if ((i.InstructionClass & InstructionClass.Call) != 0) { int callTally; if (!this.possibleCallDestinationTallies.TryGetValue(addrDest, out callTally)) callTally = 0; this.possibleCallDestinationTallies[addrDest] = callTally + 1; } } else { // Jump to data / hyperspace. AddEdge(G, bad, i.Address); y[a] = Data; } } } // If this is a delayed unconditional branch... delaySlot = i.InstructionClass; } if (y[a] == MaybeCode) instructions.Add(i.Address, i); eventListener.ShowProgress("Shingle scanning", instructions.Count, (int)workToDo); } // Find all places that are reachable from "bad" addresses. // By transitivity, they must also be be bad. foreach (var a in new DfsIterator<Address>(G).PreOrder(bad)) { if (a != bad) { y[a - segment.Address] = Data; instructions.Remove(a); // Destination can't be a call destination. possibleCallDestinationTallies.Remove(a); } } // Build blocks out of sequences of instructions. var blocks = BuildBlocks(G, instructions); return new ScannedSegment { Blocks = blocks, CodeFlags = y, }; }
/// <summary> /// Build Shingle blocks from the graph. An instruction can only be /// in one block at a time, so at each point in the graph where the /// successors > 1 or the predecessors > 1, we create a new node. /// </summary> /// <param name="g"></param> /// <param name="instructions"></param> /// <returns></returns> public SortedList<Address,ShingleBlock> BuildBlocks( DiGraph<Address> g, SortedList<Address,MachineInstruction> instructions) { // Remember, the graph is backwards! var activeBlocks = new List<ShingleBlock>(); var allBlocks = new SortedList<Address, ShingleBlock>(); var wl = instructions.Keys.ToSortedSet(); while (wl.Count > 0) { var addr = wl.First(); wl.Remove(addr); var instr = instructions[addr]; var block = new ShingleBlock { BaseAddress = addr }; allBlocks.Add(addr, block); bool terminateNow = false; bool terminateDeferred = false; for (;;) { var addrInstrEnd = instr.Address + instr.Length; if ((instr.InstructionClass & InstructionClass.Transfer) != 0) { if ((instr.InstructionClass & DT) == DT) { terminateDeferred = true; } else { terminateNow = true; } } else { terminateNow = terminateDeferred; } if (terminateNow || !wl.Contains(addrInstrEnd) || !g.Nodes.Contains(addrInstrEnd) || g.Successors(addrInstrEnd).Count != 1) { block.EndAddress = addrInstrEnd; break; } wl.Remove(addrInstrEnd); instr = instructions[addrInstrEnd]; terminateNow = terminateDeferred; } } return allBlocks; }
private void AddEdge(DiGraph<Address> g, Address from, Address to) { g.AddNode(from); g.AddNode(to); g.AddEdge(from, to); }