示例#1
0
 public ProcessingEntity(MethodUniqueSignature signature, ICallGraphNode node,
                         bool virtCallRequired = false)
 {
     Signature        = signature;
     Node             = node;
     VirtCallRequired = virtCallRequired;
 }
示例#2
0
        private IEnumerable <ICallGraphNode> TraverseNodes(
            ICallGraphNode rootNode, ICallGraphNode levelOneNode)
        {
            lastTraversalEntryPoints.Clear();
            var nodes = new HashSet <ICallGraphNode>(Nodes.Count);

            nodes.Add(rootNode);
            yield return(rootNode);

            var queue = new Queue <ICallGraphNode>();

            queue.Enqueue(levelOneNode);
            while (queue.Count > 0)
            {
                var node = queue.Dequeue();
                if (!nodes.Add(node))
                {
                    continue;
                }

                yield return(node);

                if (node.InNodes.Count == 0)
                {
                    lastTraversalEntryPoints.Add(node);
                }
                else
                {
                    foreach (var inNode in node.InNodes)
                    {
                        queue.Enqueue(inNode);
                    }
                }
            }
        }
        /// <summary>
        /// Remove redundancies and add in-edge information
        /// </summary>
        private void Optimize(SortedList <ushort, CallGraphNode> nodes)
        {
            // Remove redundant jumps directly to the next block that is not rechable from any other
            for (int i = 0; i < nodes.Count; i++)
            {
                CallGraphNode node = nodes.Values[i];
                if ((node.NodeType == NodeType.OneBranch) && (node.OutEdges.Count == 1) && (node.OutEdges[0].InEdges.Count == 1))
                {
                    ICallGraphNode targetNode = (ICallGraphNode)node.OutEdges[0];

                    // Remove the jump instruction at the end of this node
                    node.Instructions.RemoveAt(node.Instructions.Count - 1);

                    // Add all the instructions in the next node
                    node.EndIP = targetNode.EndIP;
                    foreach (IInstruction instruction in targetNode.Instructions)
                    {
                        node.Instructions.Add(instruction);
                    }

                    // Remove the target node
                    nodes.Remove(targetNode.StartIP);
                    node.OutEdges.Clear();

                    ((List <IGraphNode>)node.OutEdges).AddRange(targetNode.OutEdges);

                    foreach (CallGraphNode n in targetNode.OutEdges)
                    {
                        n.InEdges.Remove(targetNode);
                        n.InEdges.Add(node);
                    }

                    // This node now becomes the type of the target node
                    node.NodeType = targetNode.NodeType;
                }
            }


            // First pass over block list removes redundant jumps of the form
            // (Un)Conditional-> Unconditional jump
            foreach (CallGraphNode node in nodes.Values)
            {
                if ((node.OutEdges.Count == 0) &&
                    ((node.NodeType == NodeType.OneBranch) || (node.NodeType == NodeType.TwoBranch)))
                {
                    for (int i = 0; i < node.OutEdges.Count; i++)
                    {
                        CallGraphNode newTargetNode = RemoveJump((CallGraphNode)node.OutEdges[i]);
                        node.OutEdges[i] = newTargetNode;
                        newTargetNode.InEdges.Add(node);
                    }
                }
            }

            // Next is a depth-first traversal merging any FallThrough node or
            // OneBranch node that fall through to a node with that as their only in-edge.
            MergeFallThrough();

            // Remove redundant nodes created by the optimizations
        }
示例#4
0
        private void GetVertexAttributes(ICallGraphNode node, out string shape, out string style,
                                         out string color, out string fontcolor)
        {
            // https://www.graphviz.org/doc/info/colors.html
            // https://www.graphviz.org/doc/info/shapes.html
            //

            if (!String.IsNullOrEmpty(node.PriorColor))
            {
                shape     = "box";
                style     = "filled";
                color     = node.PriorColor;
                fontcolor = "";
            }
            else if (node.OutNodes.Count == 0)
            {
                shape     = "box";
                style     = "filled";
                color     = "brown1";
                fontcolor = "";
            }
            else if (node.InNodes.Count == 0)
            {
                shape = "box";
                style = "filled, rounded";
                if (node.IsPublic)
                {
                    color     = "darkgreen";
                    fontcolor = "white";
                }
                else
                {
                    color     = "darkgoldenrod1";
                    fontcolor = "";
                }
            }
            else
            {
                shape = "box";
                if (node.IsPublic)
                {
                    style = "filled";
                    color = "green2";
                }
                else
                {
                    style = "";
                    color = "";
                }

                fontcolor = "";
            }
        }
        /// <summary>
        /// Structures if statements
        /// </summary>
        private void StructureIfs()
        {
            List <ICallGraphNode> unresolved = new List <ICallGraphNode>();             // List of unresolved if nodes

            // Linear scan of nodes in reverse depth first search order
            for (int curr = _depthFirstSearchLast.Length - 1; curr >= 0; curr--)
            {
                List <ICallGraphNode> domDesc  = new List <ICallGraphNode>();              // List of nodes dominated by curr
                ICallGraphNode        currNode = _depthFirstSearchLast[curr];

                if (currNode.NodeType == NodeType.TwoBranch)
                {
                    int followInEdges = 0;
                    int follow        = 0;

                    // Find all nodes that have this node as immediate dominator
                    for (int desc = curr + 1; desc < _nodes.Count; desc++)
                    {
                        if (_depthFirstSearchLast[desc].ImmediateDominatorNumber == curr)
                        {
                            domDesc.Add(_depthFirstSearchLast[desc]);
                            ICallGraphNode pbb = _depthFirstSearchLast[desc];
                            if ((pbb.InEdges.Count - pbb.BackEdges.Count) > followInEdges)
                            {
                                follow        = desc;
                                followInEdges = pbb.InEdges.Count - pbb.BackEdges.Count;
                            }
                        }
                    }

                    // Determine follow according to number of descendants
                    // immediately dominated by this node
                    if ((follow != 0) && (followInEdges > 1))
                    {
                        currNode.IfFollow = _depthFirstSearchLast[follow];

                        // Flags all nodes in the list l as having follow node f, and deletes all
                        // nodes from the list.
                        foreach (ICallGraphNode node in unresolved)
                        {
                            node.IfFollow = _depthFirstSearchLast[follow];
                        }

                        unresolved.Clear();
                    }
                    else
                    {
                        unresolved.Add(currNode);
                    }
                }
            }
        }
示例#6
0
        private void RemoveUnavailableNodesFrom(ICallGraphNode node)
        {
            Debug.Assert(node.InNodes.Count == 0);

            Nodes.Remove(node.MethodSignature);
            for (var i = 0; i < node.OutNodes.Count; i++)
            {
                var outNode = node.OutNodes[i];
                outNode.InNodes.Remove(node);
                if (outNode.InNodes.Count == 0)
                {
                    RemoveUnavailableNodesFrom(outNode);
                }
            }
        }
示例#7
0
        private void SaveVertex(ulong id, ICallGraphNode node, TextWriter writer)
        {
            GetVertexAttributes(node, out var shape, out var style, out var color, out var fontcolor);

            writer.Write(id);
            writer.Write(" [");
            var isFirst = true;

            WriteAttribute(writer, "label", node.MethodSignature.ToShortString(), ref isFirst);
            WriteAttribute(writer, "shape", shape, ref isFirst);
            WriteAttribute(writer, "style", style, ref isFirst);
            WriteAttribute(writer, "fillcolor", color, ref isFirst);
            WriteAttribute(writer, "color", color, ref isFirst);
            WriteAttribute(writer, "fontcolor", fontcolor, ref isFirst);
            writer.WriteLine("];");
        }
        /// <summary>
        /// Structures case statements
        /// </summary>
        private void StructureCases()
        {
            // Linear scan of nodes in reverse depth first search last order, searching
            // for case nodes
            for (int i = _depthFirstSearchLast.Length - 1; i >= 0; i--)
            {
                // A case node is a node where the last instruction is a Switch opcode
                ICallGraphNode caseHeader = _depthFirstSearchLast[i];
                if ((caseHeader.Instructions.Count > 0) && (caseHeader.Instructions[caseHeader.Instructions.Count - 1].OpCode != OpCodeTable.Switch))
                {
                    continue;
                }

                // Find descendant node which has as immediate preseccessor
                // the current header node
                ICallGraphNode exitNode = null;
                for (int j = i + 2; j < _depthFirstSearchLast.Length; j++)
                {
                    if (_depthFirstSearchLast[j].ImmediateDominatorNumber == i)
                    {
                        if ((exitNode == null) || (exitNode.InEdges.Count < _depthFirstSearchLast[j].InEdges.Count))
                        {
                            exitNode = _depthFirstSearchLast[j];
                        }
                    }
                }

                caseHeader.CaseTail = exitNode;

                // Tag nodes that belong to the case by recording the header field
                // with caseHeader
                caseHeader.CaseHead = caseHeader;

                List <IGraphNode> caseNodes = new List <IGraphNode>();
                caseNodes.Add(caseHeader);

                foreach (CallGraphNode childNode in caseHeader.OutEdges)
                {
                    TagNodesInCase(childNode, caseNodes, caseHeader, exitNode);
                }

                if (exitNode != null)
                {
                    exitNode.CaseHead = caseHeader;
                }
            }
        }
示例#9
0
        private void RemoveUnavailableNodesTo(ICallGraphNode node)
        {
            Debug.Assert(node.OutNodes.Count == 0);

            Nodes.Remove(node.MethodSignature);
            if (node.InNodes.Count == 0)
            {
                EntryNodes.Remove(node.MethodSignature);
            }

            for (var i = 0; i < node.InNodes.Count; i++)
            {
                var inNode = node.InNodes[i];
                inNode.OutNodes.Remove(node);
                if (inNode.OutNodes.Count == 0)
                {
                    RemoveUnavailableNodesTo(inNode);
                }
            }
        }
        private Box LayoutSubNode(Grid grid, IGraphNode node, Dictionary <IGraphNode, Box> visited)
        {
            Box box;

            if (visited.TryGetValue(node, out box))
            {
                return(box);
            }

            ICallGraphNode callGraphNode = (ICallGraphNode)node;

            box = new Box(String.Format("{0}\r\nDFS# x{1:x4}\r\nDom# x{2:x4}\r\nInt# {3:x4}\r\nIP x{4:x4} - x{5:x4}", callGraphNode.NodeType, node.DepthFirstSearchLastNumber, node.ImmediateDominatorNumber, 0, callGraphNode.StartIP, callGraphNode.EndIP));

            visited.Add(node, box);

            if (node.OutEdges.Count > 0)
            {
                _lines.Add(new Line(box, LayoutSubNode(grid, node.OutEdges[0], visited)));
            }

            for (int i = 1; i < node.OutEdges.Count; i++)
            {
                if (grid[0, 0] != null)
                {
                    grid.InsertColumn(0);
                    grid.InsertRow(0);
                }
                _lines.Add(new Line(box, LayoutSubNode(grid, node.OutEdges[i], visited)));
            }

            if (grid[0, 0] != null)
            {
                grid.InsertRow(0);
            }

            grid[0, 0] = box;
            _boxes.Add(box);

            return(box);
        }
 /// <summary>
 /// Recursive procedure to tag nodes that belong to the case described by
 /// the list l, head and tail (dfsLast index to first and exit node of the
 /// case).
 /// </summary>
 /// <param name="node"></param>
 /// <param name="l"></param>
 /// <param name="head"></param>
 /// <param name="tail"></param>
 private static void TagNodesInCase(CallGraphNode node, ICollection <IGraphNode> l, ICallGraphNode head, IGraphNode tail)
 {
     node.Traversed = true;
     if ((node != tail) && (node.Instructions.Count > 0) && (node.Instructions[node.Instructions.Count - 1].OpCode != OpCodeTable.Switch) && l.Contains(node))
     {
         l.Add(node);
         node.CaseHead = head;
         for (int i = 0; i < node.OutEdges.Count; i++)
         {
             if (!((CallGraphNode)node.OutEdges[i]).Traversed)
             {
                 TagNodesInCase((CallGraphNode)node.OutEdges[i], l, head, tail);
             }
         }
     }
 }
        /// <summary>
        /// Loop structuring
        /// </summary>
        private void StructureLoops()
        {
            int level = 0;               // Derived Sequence Level

            // For all derived sequences of Gi
            foreach (List <IGraphNode> derivedSequence in _derivedSequence)
            {
                level++;

                // For all intervals Ii of Gi
                foreach (IntervalNode interval in derivedSequence)
                {
                    ICallGraphNode latchNode = null;

                    // Find the interval head (original block node in G1) and create
                    // list of nodes of interval Ii.
                    IntervalNode initInt = interval;
                    for (int i = 1; i < level; i++)
                    {
                        initInt = (IntervalNode)initInt.Nodes[0];
                    }

                    ICallGraphNode intervalHead = (ICallGraphNode)initInt.Nodes[0];

                    // Find nodes that belong to the interval (nodes from G1)
                    List <IGraphNode> intervalNodes = FindNodesInInterval(level, interval);

                    // Find the greatest enclosing back edge (if any)
                    for (int i = 0; i < intervalHead.InEdges.Count; i++)
                    {
                        ICallGraphNode pred = (ICallGraphNode)intervalHead.InEdges[i];
                        if (intervalNodes.Contains(pred) && (pred.DepthFirstSearchLastNumber >= intervalHead.DepthFirstSearchLastNumber))
                        {
                            if (latchNode == null)
                            {
                                latchNode = pred;
                            }
                            else
                            {
                                if (pred.DepthFirstSearchLastNumber > latchNode.DepthFirstSearchLastNumber)
                                {
                                    latchNode = pred;
                                }
                            }
                        }
                    }

                    // Find nodes in the loop and the type of loop
                    if (latchNode != null)
                    {
                        // Check latching node is at the same nesting level of case
                        // statements (if any) and that the node doesnt belong to
                        // another loop.
                        if ((latchNode.CaseHead == intervalHead.CaseHead) &&
                            (latchNode.LoopHead == null))
                        {
                            intervalHead.LatchNode = latchNode;
                            FindNodesInLoop(latchNode, intervalHead, intervalNodes);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Flag nodes that belong to the loop determined by (latchNode, head) and determines the type of loop
        /// </summary>
        /// <param name="latchNode"></param>
        /// <param name="intervalHead"></param>
        /// <param name="intervalNodes"></param>
        private void FindNodesInLoop(ICallGraphNode latchNode, ICallGraphNode intervalHead, ICollection <IGraphNode> intervalNodes)
        {
            const int Then = 0;
            const int Else = 1;

            List <int> loopNodes     = new List <int>();
            int        headDfsNumber = intervalHead.DepthFirstSearchLastNumber;

            intervalHead.LoopHead = intervalHead;
            loopNodes.Add(headDfsNumber);

            for (int i = headDfsNumber + 1; i < latchNode.DepthFirstSearchLastNumber; i++)
            {
                int immediateDominator = _depthFirstSearchLast[i].ImmediateDominatorNumber;
                if (loopNodes.Contains(immediateDominator) && intervalNodes.Contains(_depthFirstSearchLast[i]))
                {
                    loopNodes.Add(i);
                    if (_depthFirstSearchLast[i].LoopHead == null)
                    {
                        _depthFirstSearchLast[i].LoopHead = _depthFirstSearchLast[headDfsNumber];
                    }
                }
            }

            latchNode.LoopHead = _depthFirstSearchLast[headDfsNumber];
            if (latchNode != intervalHead)
            {
                loopNodes.Add(latchNode.DepthFirstSearchLastNumber);
            }

            // Determine type of loop and follow node
            NodeType intNodeType = intervalHead.NodeType;

            if (latchNode.NodeType == NodeType.TwoBranch)
            {
                if ((intNodeType == NodeType.TwoBranch) || (latchNode == intervalHead))
                {
                    if ((latchNode == intervalHead) ||
                        loopNodes.Contains(intervalHead.OutEdges[Then].DepthFirstSearchLastNumber) &&
                        loopNodes.Contains(intervalHead.OutEdges[Else].DepthFirstSearchLastNumber))
                    {
                        intervalHead.LoopType = LoopType.Do;
                        if (latchNode.OutEdges[0] == intervalHead)
                        {
                            intervalHead.LoopFollow = (ICallGraphNode)latchNode.OutEdges[Else];
                        }
                        else
                        {
                            intervalHead.LoopFollow = (ICallGraphNode)latchNode.OutEdges[Then];
                        }
                    }
                    else
                    {
                        intervalHead.LoopType = LoopType.While;
                        if (loopNodes.Contains(intervalHead.OutEdges[Then].DepthFirstSearchLastNumber))
                        {
                            intervalHead.LoopFollow = (ICallGraphNode)intervalHead.OutEdges[Else];
                        }
                        else
                        {
                            intervalHead.LoopFollow = (ICallGraphNode)intervalHead.OutEdges[Then];
                        }
                    }
                }
                else
                {
                    intervalHead.LoopType = LoopType.Do;
                    if (loopNodes.Contains(intervalHead.OutEdges[Then].DepthFirstSearchLastNumber))
                    {
                        intervalHead.LoopFollow = (ICallGraphNode)intervalHead.OutEdges[Else];
                    }
                    else
                    {
                        intervalHead.LoopFollow = (ICallGraphNode)intervalHead.OutEdges[Then];
                    }
                }
            }
            else
            if (latchNode.NodeType == NodeType.OneBranch)
            {
                intervalHead.LoopType   = LoopType.Do;
                intervalHead.LoopFollow = (ICallGraphNode)latchNode.OutEdges[0];
            }
            else if (intNodeType == NodeType.TwoBranch)
            {
                intervalHead.LoopType = LoopType.While;
                ICallGraphNode pbb     = latchNode;
                int            thenDfs = intervalHead.OutEdges[Then].DepthFirstSearchLastNumber;
                int            elseDfs = intervalHead.OutEdges[Else].DepthFirstSearchLastNumber;
                while (true)
                {
                    if (pbb.DepthFirstSearchLastNumber == thenDfs)
                    {
                        intervalHead.LoopFollow = _depthFirstSearchLast[elseDfs];
                        break;
                    }

                    if (pbb.DepthFirstSearchLastNumber == elseDfs)
                    {
                        intervalHead.LoopFollow = _depthFirstSearchLast[thenDfs];
                        break;
                    }

                    // Check if couldn't find it, then its a stragenly formed
                    // loop, so it is safer to consider it an endless loop
                    if (pbb.DepthFirstSearchLastNumber <= intervalHead.DepthFirstSearchLastNumber)
                    {
                        intervalHead.LoopType = LoopType.Endless;
                        break;
                    }
                    pbb = _depthFirstSearchLast[pbb.ImmediateDominatorNumber];
                }

                if (pbb.DepthFirstSearchLastNumber > intervalHead.DepthFirstSearchLastNumber)
                {
                    intervalHead.LoopFollow.LoopHead = null;
                }
            }
            else
            {
                intervalHead.LoopType = LoopType.Endless;
            }
        }
示例#14
0
 private void Link(ICallGraphNode from, ICallGraphNode to)
 {
     from.OutNodes.Add(to);
     to.InNodes.Add(from);
 }
示例#15
0
 public ShadowNode(ICallGraphNode node)
 {
     this.node = node;
 }