コード例 #1
0
        private void CreateNodes(ControlFlowGraph <TInstruction> graph, IInstructionTraversalResult <TInstruction> traversalResult)
        {
            ControlFlowNode <TInstruction> currentNode = null;

            foreach (var instruction in traversalResult.GetAllInstructions())
            {
                // Check if we reached a new block header.
                long offset = Architecture.GetOffset(instruction);
                if (currentNode == null || traversalResult.IsBlockHeader(offset))
                {
                    // We arrived at a new basic block header. Create a new node for it.
                    currentNode = new ControlFlowNode <TInstruction>(offset);
                    graph.Nodes.Add(currentNode);
                }

                // Add the current instruction to the current block that we're populating.
                currentNode.Contents.Instructions.Add(instruction);

                // Edge case: Blocks might not come straight after each other. If we see that the next instruction
                // does not exist, or the previous algorithm has decided the next instruction is a block header,
                // we can create a new block in the next iteration.
                long nextOffset = offset + Architecture.GetSize(instruction);
                if (!traversalResult.ContainsInstruction(nextOffset) || traversalResult.IsBlockHeader(nextOffset))
                {
                    currentNode = null;
                }
            }
        }
コード例 #2
0
        private void ConnectNodes(ControlFlowGraph <TInstruction> graph, IInstructionTraversalResult <TInstruction> traversalResult)
        {
            var successorsBufferPool = ArrayPool <SuccessorInfo> .Shared;
            var successorsBuffer     = successorsBufferPool.Rent(2);

            try
            {
                foreach (var node in graph.Nodes)
                {
                    // Get the successors of the last instruction in the current block.
                    var  block        = node.Contents;
                    long footerOffset = Architecture.GetOffset(block.Instructions[block.Instructions.Count - 1]);

                    // Ensure the size of the successors buffer is big enough.
                    int successorCount = traversalResult.GetSuccessorCount(footerOffset);
                    if (successorsBuffer.Length < successorCount)
                    {
                        successorsBufferPool.Return(successorsBuffer);
                        successorsBuffer = successorsBufferPool.Rent(successorCount);
                    }

                    // Read successors.
                    var successorsBufferSlice = new Span <SuccessorInfo>(successorsBuffer, 0, successorCount);
                    int actualCount           = traversalResult.GetSuccessors(footerOffset, successorsBufferSlice);
                    if (actualCount > successorCount)
                    {
                        throw new InvalidOperationException();
                    }

                    // Add edges accordingly.
                    for (int i = 0; i < actualCount; i++)
                    {
                        var successor = successorsBuffer[i];

                        var successorNode = graph.GetNodeByOffset(successor.DestinationAddress);
                        if (successorNode == null)
                        {
                            throw new ArgumentException($"Instruction at address {footerOffset:X8} refers to a non-existing node.");
                        }

                        node.ConnectWith(successorNode, successor.EdgeType);
                    }
                }
            }
            finally
            {
                successorsBufferPool.Return(successorsBuffer);
            }
        }