// ----------------------------------------------------------------------------- // SymbolTableDiff.cs // Sprint: SPRINT_20260106_001_003_BINDEX_symbol_table_diff // Tasks: SYM-001, SYM-002, SYM-003, SYM-004, SYM-005 // Description: Symbol table diff model for comparing exports/imports between binaries // ----------------------------------------------------------------------------- using System.Text.Json.Serialization; namespace StellaOps.BinaryIndex.Builders.SymbolDiff; /// /// Complete symbol table diff between two binaries. /// public sealed record SymbolTableDiff { /// Content-addressed diff ID (sha256 of canonical JSON). [JsonPropertyName("diff_id")] public required string DiffId { get; init; } /// Base binary identity. [JsonPropertyName("base")] public required BinaryRef Base { get; init; } /// Target binary identity. [JsonPropertyName("target")] public required BinaryRef Target { get; init; } /// Exported symbol changes. [JsonPropertyName("exports")] public required SymbolChangeSummary Exports { get; init; } /// Imported symbol changes. [JsonPropertyName("imports")] public required SymbolChangeSummary Imports { get; init; } /// Version map changes. [JsonPropertyName("versions")] public required VersionMapDiff Versions { get; init; } /// GOT/PLT changes (dynamic linking). [JsonPropertyName("dynamic")] public DynamicLinkingDiff? Dynamic { get; init; } /// Overall ABI compatibility assessment. [JsonPropertyName("abi_compatibility")] public required AbiCompatibility AbiCompatibility { get; init; } /// When this diff was computed (UTC). [JsonPropertyName("computed_at")] public required DateTimeOffset ComputedAt { get; init; } /// Schema version for forward compatibility. [JsonPropertyName("schema_version")] public string SchemaVersion { get; init; } = "1.0"; } /// Reference to a binary. public sealed record BinaryRef { [JsonPropertyName("path")] public required string Path { get; init; } [JsonPropertyName("sha256")] public required string Sha256 { get; init; } [JsonPropertyName("build_id")] public string? BuildId { get; init; } [JsonPropertyName("architecture")] public required string Architecture { get; init; } [JsonPropertyName("format")] public required BinaryFormat Format { get; init; } [JsonPropertyName("file_size")] public long FileSize { get; init; } } /// Binary format. [JsonConverter(typeof(JsonStringEnumConverter))] public enum BinaryFormat { Elf, Pe, MachO, Unknown } /// Summary of symbol changes. public sealed record SymbolChangeSummary { [JsonPropertyName("added")] public required IReadOnlyList Added { get; init; } [JsonPropertyName("removed")] public required IReadOnlyList Removed { get; init; } [JsonPropertyName("modified")] public required IReadOnlyList Modified { get; init; } [JsonPropertyName("renamed")] public required IReadOnlyList Renamed { get; init; } /// Count summaries. [JsonPropertyName("counts")] public required SymbolChangeCounts Counts { get; init; } } /// Count summary for symbol changes. public sealed record SymbolChangeCounts { [JsonPropertyName("added")] public int Added { get; init; } [JsonPropertyName("removed")] public int Removed { get; init; } [JsonPropertyName("modified")] public int Modified { get; init; } [JsonPropertyName("renamed")] public int Renamed { get; init; } [JsonPropertyName("unchanged")] public int Unchanged { get; init; } [JsonPropertyName("total_base")] public int TotalBase { get; init; } [JsonPropertyName("total_target")] public int TotalTarget { get; init; } } /// A symbol that was added or removed. public sealed record SymbolChange { [JsonPropertyName("name")] public required string Name { get; init; } [JsonPropertyName("demangled_name")] public string? DemangledName { get; init; } [JsonPropertyName("type")] public required SymbolType Type { get; init; } [JsonPropertyName("binding")] public required SymbolBinding Binding { get; init; } [JsonPropertyName("visibility")] public required SymbolVisibility Visibility { get; init; } [JsonPropertyName("section")] public string? Section { get; init; } [JsonPropertyName("address")] public ulong Address { get; init; } [JsonPropertyName("size")] public ulong Size { get; init; } [JsonPropertyName("version")] public string? Version { get; init; } [JsonPropertyName("fingerprint")] public string? Fingerprint { get; init; } } /// A symbol that was modified (same name, different attributes). public sealed record SymbolModification { [JsonPropertyName("name")] public required string Name { get; init; } [JsonPropertyName("demangled_name")] public string? DemangledName { get; init; } [JsonPropertyName("base")] public required SymbolAttributes Base { get; init; } [JsonPropertyName("target")] public required SymbolAttributes Target { get; init; } [JsonPropertyName("changes")] public required IReadOnlyList Changes { get; init; } [JsonPropertyName("is_abi_breaking")] public bool IsAbiBreaking { get; init; } } /// Symbol attributes for comparison. public sealed record SymbolAttributes { [JsonPropertyName("type")] public required SymbolType Type { get; init; } [JsonPropertyName("binding")] public required SymbolBinding Binding { get; init; } [JsonPropertyName("visibility")] public required SymbolVisibility Visibility { get; init; } [JsonPropertyName("section")] public string? Section { get; init; } [JsonPropertyName("address")] public ulong Address { get; init; } [JsonPropertyName("size")] public ulong Size { get; init; } [JsonPropertyName("version")] public string? Version { get; init; } [JsonPropertyName("fingerprint")] public string? Fingerprint { get; init; } } /// A specific attribute change. public sealed record AttributeChange { [JsonPropertyName("attribute")] public required string Attribute { get; init; } [JsonPropertyName("base_value")] public string? BaseValue { get; init; } [JsonPropertyName("target_value")] public string? TargetValue { get; init; } [JsonPropertyName("severity")] public required ChangeSeverity Severity { get; init; } } /// A symbol that was renamed (detected via fingerprint matching). public sealed record SymbolRename { [JsonPropertyName("base_name")] public required string BaseName { get; init; } [JsonPropertyName("target_name")] public required string TargetName { get; init; } [JsonPropertyName("base_demangled")] public string? BaseDemangled { get; init; } [JsonPropertyName("target_demangled")] public string? TargetDemangled { get; init; } [JsonPropertyName("fingerprint")] public required string Fingerprint { get; init; } [JsonPropertyName("similarity")] public double Similarity { get; init; } [JsonPropertyName("confidence")] public required RenameConfidence Confidence { get; init; } } /// Symbol type classification. [JsonConverter(typeof(JsonStringEnumConverter))] public enum SymbolType { NoType, Object, Function, Section, File, Common, Tls, Unknown } /// Symbol binding. [JsonConverter(typeof(JsonStringEnumConverter))] public enum SymbolBinding { Local, Global, Weak, Unknown } /// Symbol visibility. [JsonConverter(typeof(JsonStringEnumConverter))] public enum SymbolVisibility { Default, Internal, Hidden, Protected, Unknown } /// Severity of a change. [JsonConverter(typeof(JsonStringEnumConverter))] public enum ChangeSeverity { Info, Low, Medium, High, Critical } /// Confidence level for rename detection. [JsonConverter(typeof(JsonStringEnumConverter))] public enum RenameConfidence { VeryHigh, High, Medium, Low, VeryLow }