예제 #1
0
 private ScanResults CreateScanResults(DiGraph <RtlBlock> icfg)
 {
     return(new ScanResults
     {
         ICFG = icfg
     });
 }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
 public void Setup()
 {
     mr          = new MockRepository();
     rd          = null;
     this.graph  = new DiGraph <Address>();
     this.instrs = new SortedList <Address, MachineInstruction>();
 }
예제 #6
0
        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));
        }
예제 #8
0
        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);
        }
예제 #9
0
        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'));
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
                }
            }
        }
예제 #14
0
        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;
        }
예제 #15
0
        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));
        }
예제 #16
0
        public DirectedCycles(DiGraph G)
        {
            var V = G.V();

            marked  = new bool[V];
            edgeTo  = new int[V];
            onStack = new bool[V];
        }
예제 #17
0
 public TransitiveClosure(DiGraph G)
 {
     all = new DirectedDFS[G.V];
     for (int v = 0; v < G.V; v++)
     {
         all[v] = new DirectedDFS(G, v);
     }
 }
예제 #18
0
        public void Test()
        {
            DiGraph dag = GraphGenerator.dag();

            var dfo = new DepthFirstPostOrder(dag);

            console.WriteLine(dfo.PostOrderToString());
        }
예제 #19
0
 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>();
        }
예제 #21
0
 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);
 }
예제 #22
0
        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);
        }
예제 #23
0
            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);
            }
예제 #24
0
        /// <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);
        }
예제 #25
0
        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++; }
        }
예제 #26
0
        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());
        }
예제 #27
0
        /// <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);
        }
예제 #28
0
        /// <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);
        }
예제 #29
0
    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));
                }
            }
        }
예제 #31
0
        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);
         }
     }
 }
예제 #33
0
 /// <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;
 }
예제 #34
0
        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);
                }
            }
        }
예제 #35
0
 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);
            }
        }
예제 #37
0
 /// <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]);
 }
예제 #38
0
        /// <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,
            };
        }
예제 #39
0
        /// <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;
        }
예제 #40
0
 private void AddEdge(DiGraph<Address> g, Address from, Address to)
 {
     g.AddNode(from);
     g.AddNode(to);
     g.AddEdge(from, to);
 }