1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//! # Plugin System
//!
//! Provides plugin functionality for extending the debugger with custom behaviors.
//!
//! This module implements a plugin system using the [`steckrs`] crate, allowing:
//! - Loading and managing plugins
//! - Defining extension points where plugins can hook into the debugger
//! - Executing plugin hooks at specific points in the debugging lifecycle
//!
//! The plugin system is structured around extension points where plugins can register
//! hooks to be called when certain events occur during debugging, such as receiving signals
//! or setting breakpoints.
//!
//! ## Architecture
//!
//! - [`ExtensionPoint`](steckrs::hook::ExtensionPoint)s define interfaces for plugins to implement
//! - [`Plugin`]s register hooks that implement these extension points
//! - The debugger invokes hooks at appropriate times during execution
//!
//! ## Default Plugins
//!
//! The module includes several built-in plugins:
//! - [`SigtrapGuardPlugin`]: A plugin that prevents the detection of the coreminer debugger with
//! a signal handler for SIGTRAP
//!
//! ## Usage
//!
//! The plugin system is conditionally compiled when the `plugins` feature is enabled.
//! The [`for_hooks!`](crate::for_hooks) macro provides a convenient way to iterate over
//! all enabled hooks for a specific extension point.
//!
//! # Examples
//!
//! ```no_run
//! # use steckrs::hook::ExtensionPoint;
//! # use steckrs::extension_point;
//! # use coreminer::feedback::{Feedback, Status};
//! # use coreminer::plugins::extension_points::EPreSignalHandler;
//! # use coreminer::for_hooks;
//! # use coreminer::ui::DebuggerUI;
//! # use coreminer::debugger::Debugger;
//! # use coreminer::addr::Addr;
//!
//! // use some extension point
//!
//! extension_point!(
//! EEasyPoint: EEasyPointF;
//! fn hello(&self) -> String;
//! );
//!
//! # fn helper<UI: DebuggerUI>(debugger: &mut Debugger<UI>) {
//!
//! // Inside a method that has access to hooks
//! // Iterate over all activated hooks for that extension point
//! for_hooks!(
//! for hook[EEasyPoint] in debugger {
//! println!("{}", hook.inner().hello());
//! }
//! );
//! # }
//! ```
use ;
use ;
use SigtrapGuardPlugin;
/// Creates the default plugin manager with built-in plugins already loaded and activated
///
/// This function initializes a new [`PluginManager`] and loads all default plugins,
/// enabling them automatically. It's used when initializing the debugger.
///
/// # Returns
///
/// A [`PluginManager`] with all default plugins loaded and enabled
///
/// # Examples
///
/// ```no_run
/// use coreminer::plugins::default_plugin_manager;
/// use std::sync::{Arc, Mutex};
///
/// let plugin_manager = Arc::new(Mutex::new(default_plugin_manager()));
/// ```
///
/// # Panics
///
/// Panics if loading or configuring the default plugins fails.
/// Loads and enables a [`Plugin`] in the [`PluginManager`]
///
/// This helper function attempts to load and enable a plugin, handling any errors
/// that occur during the process. If the plugin cannot be enabled, it attempts
/// to unload it to prevent issues.
///
/// # Parameters
///
/// * `manager` - The plugin manager to load the plugin into
/// * `plugin` - The plugin to load and enable
///
/// # Type Parameters
///
/// * `P` - A type that implements the [`Plugin`] trait
/// Executes code for each enabled hook implementing a specific extension point
///
/// This macro simplifies the process of iterating over all enabled hooks for a specific
/// extension point and running code for each hook. It handles locking the plugin manager
/// and retrieving the appropriate hooks.
///
/// # Parameters
///
/// * `$hook_var` - The variable name to bind each hook to within the body
/// * `$extension_point` - The extension point type to find hooks for
/// * `$debugger` - The debugger instance that contains the plugin manager
/// * `$body` - The code block to execute for each hook
///
/// # Examples
///
/// ```no_run
/// # use steckrs::hook::ExtensionPoint;
/// # use coreminer::feedback::{Feedback, Status};
/// # use coreminer::plugins::extension_points::EPreSignalHandler;
/// # use coreminer::for_hooks;
/// # use coreminer::ui::DebuggerUI;
/// # use coreminer::debugger::Debugger;
/// # use coreminer::addr::Addr;
/// # fn helper<UI: DebuggerUI>(debugger: &mut Debugger<UI>) {
///
/// // Inside a method that has access to hooks
/// for_hooks!(
/// for hook[EPreSignalHandler] in debugger {
/// debugger.hook_feedback_loop(hook.name(), |feedback| {
/// // Process the feedback and return a new status
/// println!("Received feedback: {}", feedback);
///
/// if let Feedback::Word(w) = feedback {
/// println!("got word {w}");
/// Ok(Status::PluginContinue)
/// } else {
/// Ok(Status::ReadMem(Addr::from(0xdeadbeef_usize)))
/// }
/// }).unwrap();
/// }
/// );
/// # }
/// ```
///
/// # Panics
///
/// This macro will panic if it cannot acquire the lock on the plugin manager.