namespace X86Disassembler.Analysers;
///
/// Central context for all analysis data related to a disassembled function
///
public class AnalyzerContext
{
///
/// The function being analyzed
///
public AsmFunction Function { get; }
///
/// Dictionary mapping block addresses to instruction blocks
///
public Dictionary BlocksByAddress { get; } = [];
///
/// Dictionary mapping loop header addresses to loops
///
public Dictionary LoopsByHeaderAddress { get; } = [];
///
/// Dictionary mapping block addresses to the loops that contain them
///
public Dictionary> LoopsByBlockAddress { get; } = [];
///
/// Dictionary for storing arbitrary analysis data by address
///
public Dictionary> AnalysisDataByAddress { get; } = [];
///
/// Creates a new analyzer context for the given function
///
/// The function to analyze
public AnalyzerContext(AsmFunction function)
{
Function = function;
// Initialize the block dictionary
foreach (var block in function.Blocks)
{
BlocksByAddress[block.Address] = block;
}
}
///
/// Represents a loop in the control flow graph
///
public class Loop
{
///
/// The header block of the loop (the entry point into the loop)
///
public InstructionBlock Header { get; set; } = null!;
///
/// The blocks that are part of this loop
///
public List Blocks { get; set; } = [];
///
/// The back edge that completes the loop (from a block back to the header)
///
public (InstructionBlock From, InstructionBlock To) BackEdge { get; set; }
///
/// The exit blocks of the loop (blocks that have successors outside the loop)
///
public List ExitBlocks { get; set; } = [];
}
///
/// Stores analysis data for a specific address
///
/// The address to store data for
/// The key for the data
/// The data to store
public void StoreAnalysisData(ulong address, string key, object value)
{
if (!AnalysisDataByAddress.TryGetValue(address, out var dataDict))
{
dataDict = [];
AnalysisDataByAddress[address] = dataDict;
}
dataDict[key] = value;
}
///
/// Retrieves analysis data for a specific address
///
/// The address to retrieve data for
/// The key for the data
/// The stored data, or null if not found
public object? GetAnalysisData(ulong address, string key)
{
if (AnalysisDataByAddress.TryGetValue(address, out var dataDict) &&
dataDict.TryGetValue(key, out var value))
{
return value;
}
return null;
}
///
/// Retrieves typed analysis data for a specific address
///
/// The type of data to retrieve
/// The address to retrieve data for
/// The key for the data
/// The stored data, or default(T) if not found or wrong type
public T? GetAnalysisData(ulong address, string key)
{
var data = GetAnalysisData(address, key);
if (data is T typedData)
{
return typedData;
}
return default;
}
}