mirror of
https://github.com/Colton1skees/Dna
synced 2026-06-21 13:42:09 +00:00
98 lines
3.1 KiB
C#
98 lines
3.1 KiB
C#
using Dna.Extensions;
|
|
using Rivers;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Dna.ControlFlow
|
|
{
|
|
public class ControlFlowGraph<T> : Graph
|
|
{
|
|
public ulong StartAddress { get; }
|
|
|
|
public ControlFlowGraph(ulong startAddress)
|
|
{
|
|
Name = startAddress.ToString("X");
|
|
StartAddress = startAddress;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new basic block and adds it to the control flow graph.
|
|
/// </summary>
|
|
/// <param name="address"></param>
|
|
/// <returns></returns>
|
|
public BasicBlock<T> CreateBlock(ulong address)
|
|
{
|
|
var block = new BasicBlock<T>(address);
|
|
block.Address = address;
|
|
block.UserData.Add(block.Address.ToString("X"), block);
|
|
Nodes.Add(block);
|
|
return block;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new basic block and adds it to the control flow graph.
|
|
/// </summary>
|
|
/// <param name="address"></param>
|
|
/// <returns></returns>
|
|
public BasicBlock<T> TryCreateBlock(ulong address)
|
|
{
|
|
var name = address.ToString("X");
|
|
if (Nodes.Contains(name))
|
|
return (BasicBlock<T>)Nodes[name];
|
|
|
|
var block = new BasicBlock<T>(address);
|
|
block.Address = address;
|
|
block.UserData.Add(name, block);
|
|
Nodes.Add(block);
|
|
return block;
|
|
}
|
|
|
|
public IEnumerable<BasicBlock<T>> GetBlocks()
|
|
{
|
|
return Nodes.Select(x => x.GetBlock<T>());
|
|
}
|
|
|
|
public IEnumerable<T> GetInstructions()
|
|
{
|
|
return Nodes.SelectMany(x => x.GetBlock<T>().Instructions);
|
|
}
|
|
|
|
public bool WhileEachBlockInReversePostOrder(BasicBlock<T> block, Func<BasicBlock<T>, bool> func)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return GraphFormatter.FormatGraph(this);
|
|
}
|
|
|
|
public static ControlFlowGraph<T> Clone(ControlFlowGraph<T> src)
|
|
{
|
|
// Create a new destination control flow graph.
|
|
var dst = new ControlFlowGraph<T>(src.StartAddress);
|
|
|
|
// Create a mapping of <src block, dst block>.
|
|
var blockMapping = src.GetBlocks().ToDictionary(x => x, x => dst.CreateBlock(x.Address));
|
|
|
|
foreach((BasicBlock<T> srcBlock, BasicBlock<T> dstBlock) in blockMapping)
|
|
{
|
|
// For each source outgoing edge, create a new outgoing edge which utilizes the corresponding basic blocks in the dst control flow graph.
|
|
var clonedEdges = srcBlock.GetOutgoingEdges().Select(x => new BlockEdge<T>(blockMapping[x.SourceBlock], blockMapping[x.TargetBlock]));
|
|
|
|
// Add all of the newly created outgoing edges.
|
|
dstBlock.AddOutgoingEdges(clonedEdges);
|
|
|
|
// Copy over the instructions.
|
|
dstBlock.Instructions.AddRange(srcBlock.Instructions);
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
}
|
|
}
|