Files
git.stella-ops.org/src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Builders/SymbolDiff/SymbolTableDiff.cs

316 lines
8.5 KiB
C#

// -----------------------------------------------------------------------------
// 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;
/// <summary>
/// Complete symbol table diff between two binaries.
/// </summary>
public sealed record SymbolTableDiff
{
/// <summary>Content-addressed diff ID (sha256 of canonical JSON).</summary>
[JsonPropertyName("diff_id")]
public required string DiffId { get; init; }
/// <summary>Base binary identity.</summary>
[JsonPropertyName("base")]
public required BinaryRef Base { get; init; }
/// <summary>Target binary identity.</summary>
[JsonPropertyName("target")]
public required BinaryRef Target { get; init; }
/// <summary>Exported symbol changes.</summary>
[JsonPropertyName("exports")]
public required SymbolChangeSummary Exports { get; init; }
/// <summary>Imported symbol changes.</summary>
[JsonPropertyName("imports")]
public required SymbolChangeSummary Imports { get; init; }
/// <summary>Version map changes.</summary>
[JsonPropertyName("versions")]
public required VersionMapDiff Versions { get; init; }
/// <summary>GOT/PLT changes (dynamic linking).</summary>
[JsonPropertyName("dynamic")]
public DynamicLinkingDiff? Dynamic { get; init; }
/// <summary>Overall ABI compatibility assessment.</summary>
[JsonPropertyName("abi_compatibility")]
public required AbiCompatibility AbiCompatibility { get; init; }
/// <summary>When this diff was computed (UTC).</summary>
[JsonPropertyName("computed_at")]
public required DateTimeOffset ComputedAt { get; init; }
/// <summary>Schema version for forward compatibility.</summary>
[JsonPropertyName("schema_version")]
public string SchemaVersion { get; init; } = "1.0";
}
/// <summary>Reference to a binary.</summary>
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; }
}
/// <summary>Binary format.</summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum BinaryFormat
{
Elf,
Pe,
MachO,
Unknown
}
/// <summary>Summary of symbol changes.</summary>
public sealed record SymbolChangeSummary
{
[JsonPropertyName("added")]
public required IReadOnlyList<SymbolChange> Added { get; init; }
[JsonPropertyName("removed")]
public required IReadOnlyList<SymbolChange> Removed { get; init; }
[JsonPropertyName("modified")]
public required IReadOnlyList<SymbolModification> Modified { get; init; }
[JsonPropertyName("renamed")]
public required IReadOnlyList<SymbolRename> Renamed { get; init; }
/// <summary>Count summaries.</summary>
[JsonPropertyName("counts")]
public required SymbolChangeCounts Counts { get; init; }
}
/// <summary>Count summary for symbol changes.</summary>
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; }
}
/// <summary>A symbol that was added or removed.</summary>
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; }
}
/// <summary>A symbol that was modified (same name, different attributes).</summary>
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<AttributeChange> Changes { get; init; }
[JsonPropertyName("is_abi_breaking")]
public bool IsAbiBreaking { get; init; }
}
/// <summary>Symbol attributes for comparison.</summary>
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; }
}
/// <summary>A specific attribute change.</summary>
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; }
}
/// <summary>A symbol that was renamed (detected via fingerprint matching).</summary>
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; }
}
/// <summary>Symbol type classification.</summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum SymbolType
{
NoType,
Object,
Function,
Section,
File,
Common,
Tls,
Unknown
}
/// <summary>Symbol binding.</summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum SymbolBinding
{
Local,
Global,
Weak,
Unknown
}
/// <summary>Symbol visibility.</summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum SymbolVisibility
{
Default,
Internal,
Hidden,
Protected,
Unknown
}
/// <summary>Severity of a change.</summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ChangeSeverity
{
Info,
Low,
Medium,
High,
Critical
}
/// <summary>Confidence level for rename detection.</summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum RenameConfidence
{
VeryHigh,
High,
Medium,
Low,
VeryLow
}