/// <summary> /// Parses the given <see cref="ControlFlowGraph{TInstruction}"/> /// </summary> /// <returns>A <see cref="ControlFlowGraph{TInstruction}"/> representing the Ast</returns> public ControlFlowGraph <Statement <TInstruction> > Parse() { var newGraph = new ControlFlowGraph <Statement <TInstruction> >(AstArchitecture); var blockBuilder = new BlockBuilder <TInstruction>(); var rootScope = blockBuilder.ConstructBlocks(ControlFlowGraph); // Transform and add regions. foreach (var originalRegion in ControlFlowGraph.Regions) { var newRegion = TransformRegion(originalRegion); newGraph.Regions.Add(newRegion); } // Transform and add nodes. foreach (var originalBlock in rootScope.GetAllBlocks()) { var originalNode = ControlFlowGraph.Nodes[originalBlock.Offset]; var transformedBlock = TransformBlock(originalBlock); var newNode = new ControlFlowNode <Statement <TInstruction> >(originalBlock.Offset, transformedBlock); newGraph.Nodes.Add(newNode); // Move node to newly created region. if (originalNode.ParentRegion is BasicControlFlowRegion <TInstruction> basicRegion) { newNode.MoveToRegion(_context.RegionsMapping[basicRegion]); } } // Clone edges. foreach (var originalEdge in ControlFlowGraph.GetEdges()) { var newOrigin = newGraph.Nodes[originalEdge.Origin.Offset]; var newTarget = newGraph.Nodes[originalEdge.Target.Offset]; newOrigin.ConnectWith(newTarget, originalEdge.Type); } // Fix entry point. newGraph.Entrypoint = newGraph.Nodes[_context.ControlFlowGraph.Entrypoint.Offset]; return(newGraph); }
/// <summary> /// Parses the given <see cref="ControlFlowGraph{TInstruction}"/> /// </summary> /// <returns>A <see cref="ControlFlowGraph{TInstruction}"/> representing the Ast</returns> public ControlFlowGraph <Statement <TInstruction> > Parse() { var newGraph = new ControlFlowGraph <Statement <TInstruction> >(_architecture); var rootScope = _controlFlowGraph.ConstructBlocks(); // Transform and add regions. foreach (var originalRegion in _controlFlowGraph.Regions) { var newRegion = TransformRegion(originalRegion); newGraph.Regions.Add(newRegion); } // Transform and add nodes. foreach (var originalBlock in rootScope.GetAllBlocks()) { var originalNode = _controlFlowGraph.Nodes[originalBlock.Offset]; var transformedBlock = _transformer.Transform(originalBlock); var newNode = new ControlFlowNode <Statement <TInstruction> >(originalBlock.Offset, transformedBlock); newGraph.Nodes.Add(newNode); // Move node to newly created region. if (originalNode.ParentRegion is ScopeRegion <TInstruction> basicRegion) { newNode.MoveToRegion(_regionsMapping[basicRegion]); } } // Clone edges. foreach (var originalEdge in _controlFlowGraph.GetEdges()) { var newOrigin = newGraph.Nodes[originalEdge.Origin.Offset]; var newTarget = newGraph.Nodes[originalEdge.Target.Offset]; newOrigin.ConnectWith(newTarget, originalEdge.Type); } // Fix entry point(s). newGraph.Entrypoint = newGraph.Nodes[_controlFlowGraph.Entrypoint.Offset]; FixEntryPoint(_controlFlowGraph); return(newGraph); void FixEntryPoint(IControlFlowRegion <TInstruction> region) { foreach (var child in region.GetSubRegions()) { FixEntryPoint(child); } if (!(region is ScopeRegion <TInstruction> basicControlFlowRegion)) { return; } var entry = basicControlFlowRegion.Entrypoint; if (entry is null) { return; } _regionsMapping[basicControlFlowRegion].Entrypoint = newGraph.Nodes[entry.Offset]; } }