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; } }