// Copyright (c) StellaOps. All rights reserved. // Licensed under AGPL-3.0-or-later. See LICENSE in the project root. using Microsoft.Extensions.Logging; namespace StellaOps.BinaryIndex.Disassembly; /// /// Default implementation of the disassembly plugin registry. /// public sealed class DisassemblyPluginRegistry : IDisassemblyPluginRegistry { private readonly ILogger _logger; private readonly List _plugins; /// /// Creates a new plugin registry with the given plugins. /// /// The registered plugins. /// Logger instance. public DisassemblyPluginRegistry( IEnumerable plugins, ILogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _plugins = (plugins ?? throw new ArgumentNullException(nameof(plugins))) .OrderByDescending(p => p.Capabilities.Priority) .ToList(); _logger.LogInformation( "Disassembly plugin registry initialized with {Count} plugins: {Plugins}", _plugins.Count, string.Join(", ", _plugins.Select(p => p.Capabilities.PluginId))); } /// public IReadOnlyList Plugins => _plugins; /// public IDisassemblyPlugin? FindPlugin(CpuArchitecture architecture, BinaryFormat format) { var plugin = _plugins.FirstOrDefault(p => p.Capabilities.CanHandle(architecture, format)); if (plugin != null) { _logger.LogDebug( "Selected plugin {Plugin} for architecture {Arch} and format {Format}", plugin.Capabilities.PluginId, architecture, format); } else { _logger.LogWarning( "No plugin found for architecture {Arch} and format {Format}", architecture, format); } return plugin; } /// public IEnumerable FindPluginsForArchitecture(CpuArchitecture architecture) { return _plugins.Where(p => p.Capabilities.SupportsArchitecture(architecture)); } /// public IEnumerable FindPluginsForFormat(BinaryFormat format) { return _plugins.Where(p => p.Capabilities.SupportsFormat(format)); } /// public IDisassemblyPlugin? GetPlugin(string pluginId) { return _plugins.FirstOrDefault(p => p.Capabilities.PluginId.Equals(pluginId, StringComparison.OrdinalIgnoreCase)); } }