// Copyright (c) StellaOps. All rights reserved. // Licensed under AGPL-3.0-or-later. See LICENSE in the project root. using System.Collections.Immutable; namespace StellaOps.BinaryIndex.Semantic; /// /// A function lifted to intermediate representation. /// /// Function name (may be empty for unnamed functions). /// Start address of the function. /// IR statements comprising the function body. /// Basic blocks in the function. /// Control flow graph. public sealed record LiftedFunction( string Name, ulong Address, ImmutableArray Statements, ImmutableArray BasicBlocks, ControlFlowGraph Cfg); /// /// A function transformed to Static Single Assignment (SSA) form. /// /// Function name. /// Start address of the function. /// SSA statements comprising the function body. /// SSA basic blocks in the function. /// Definition-use chains for dataflow analysis. public sealed record SsaFunction( string Name, ulong Address, ImmutableArray Statements, ImmutableArray BasicBlocks, DefUseChains DefUse); /// /// An intermediate representation statement. /// /// Unique statement ID within the function. /// Original instruction address. /// Statement kind. /// Operation name (e.g., add, sub, load). /// Destination operand (if any). /// Source operands. /// Additional metadata. public sealed record IrStatement( int Id, ulong Address, IrStatementKind Kind, string Operation, IrOperand? Destination, ImmutableArray Sources, ImmutableDictionary? Metadata = null); /// /// Kind of IR statement. /// public enum IrStatementKind { /// Unknown statement kind. Unknown = 0, /// Assignment: dest = expr. Assign, /// Binary operation: dest = src1 op src2. BinaryOp, /// Unary operation: dest = op src. UnaryOp, /// Memory load: dest = [addr]. Load, /// Memory store: [addr] = src. Store, /// Unconditional jump. Jump, /// Conditional jump. ConditionalJump, /// Function call. Call, /// Function return. Return, /// No operation. Nop, /// PHI node (for SSA form). Phi, /// System call. Syscall, /// Interrupt. Interrupt, /// Cast/type conversion. Cast, /// Comparison. Compare, /// Sign/zero extension. Extend } /// /// An operand in an IR statement. /// /// Operand kind. /// Name (for temporaries and registers). /// Constant value (for immediates). /// Size in bits. /// Whether this is a memory reference. public sealed record IrOperand( IrOperandKind Kind, string? Name, long? Value, int BitSize, bool IsMemory = false); /// /// Kind of IR operand. /// public enum IrOperandKind { /// Unknown operand kind. Unknown = 0, /// CPU register. Register, /// IR temporary variable. Temporary, /// Immediate constant value. Immediate, /// Memory address. Memory, /// Program counter / instruction pointer. ProgramCounter, /// Stack pointer. StackPointer, /// Base pointer / frame pointer. FramePointer, /// Flags/condition register. Flags, /// Undefined value (for SSA). Undefined, /// Label / address reference. Label } /// /// A basic block in the intermediate representation. /// /// Unique block ID within the function. /// Block label/name. /// Start address of the block. /// End address of the block (exclusive). /// IDs of statements in this block. /// IDs of predecessor blocks. /// IDs of successor blocks. public sealed record IrBasicBlock( int Id, string Label, ulong StartAddress, ulong EndAddress, ImmutableArray StatementIds, ImmutableArray Predecessors, ImmutableArray Successors); /// /// Control flow graph for a function. /// /// ID of the entry block. /// IDs of exit blocks. /// CFG edges. public sealed record ControlFlowGraph( int EntryBlockId, ImmutableArray ExitBlockIds, ImmutableArray Edges); /// /// An edge in the control flow graph. /// /// Source block ID. /// Target block ID. /// Edge kind. /// Condition for conditional edges. public sealed record CfgEdge( int SourceBlockId, int TargetBlockId, CfgEdgeKind Kind, string? Condition = null); /// /// Kind of CFG edge. /// public enum CfgEdgeKind { /// Sequential fall-through. FallThrough, /// Unconditional jump. Jump, /// Conditional branch taken. ConditionalTrue, /// Conditional branch not taken. ConditionalFalse, /// Function call edge. Call, /// Function return edge. Return, /// Indirect jump (computed target). Indirect, /// Exception/interrupt edge. Exception } /// /// An SSA statement with versioned variables. /// /// Unique statement ID within the function. /// Original instruction address. /// Statement kind. /// Operation name. /// Destination SSA variable (if any). /// Source SSA variables. /// For PHI nodes: mapping from predecessor block to variable version. public sealed record SsaStatement( int Id, ulong Address, IrStatementKind Kind, string Operation, SsaVariable? Destination, ImmutableArray Sources, ImmutableDictionary? PhiSources = null); /// /// An SSA variable (versioned). /// /// Original variable/register name. /// SSA version number. /// Size in bits. /// Variable kind. public sealed record SsaVariable( string BaseName, int Version, int BitSize, SsaVariableKind Kind); /// /// Kind of SSA variable. /// public enum SsaVariableKind { /// CPU register. Register, /// IR temporary. Temporary, /// Memory location. Memory, /// Immediate constant. Constant, /// PHI result. Phi } /// /// An SSA basic block. /// /// Unique block ID. /// Block label. /// PHI nodes at block entry. /// Non-PHI statements. /// Predecessor block IDs. /// Successor block IDs. public sealed record SsaBasicBlock( int Id, string Label, ImmutableArray PhiNodes, ImmutableArray Statements, ImmutableArray Predecessors, ImmutableArray Successors); /// /// Definition-use chains for SSA form. /// /// Maps variable to its defining statement. /// Maps variable to statements that use it. public sealed record DefUseChains( ImmutableDictionary Definitions, ImmutableDictionary> Uses);