1 //! The core [`Target`] trait, and all its various protocol extension traits.
2 //!
3 //! The [`Target`] trait describes how to control and modify a system's
4 //! execution state during a GDB debugging session, and serves as the
5 //! primary bridge between `gdbstub`'s generic protocol implementation and a
6 //! target's project/platform-specific code.
7 //!
8 //! **`Target` is the most important trait in `gdbstub`, and must be implemented
9 //! by all consumers of the library!**
10 //!
11 //! # Implementing `Target`
12 //!
13 //! `gdbstub` uses a technique called ["Inlineable Dyn Extension Traits"](ext)
14 //! (IDETs) to expose an ergonomic and extensible interface to the GDB protocol.
15 //! It's not a very common pattern, and can seem a little "weird" at first
16 //! glance, but IDETs are actually very straightforward to use!
17 //!
18 //! **TL;DR:** Whenever you see a method that returns something that looks like
19 //! `Option<ProtocolExtOps>`, you can enable that protocol extension by
20 //! implementing the `ProtocolExt` type on your target, and overriding the
21 //! `Option<ProtocolExtOps>` method to return `Some(self)`.
22 //!
23 //! Please refer to the [documentation in the `ext` module](ext) for more
24 //! information on IDETs, including a more in-depth explanation of how they
25 //! work, and how `Target` leverages them to provide fine grained control over
26 //! enabled protocol features.
27 //!
28 //! ## Associated Types
29 //!
30 //! - The [`Target::Arch`](trait.Target.html#associatedtype.Arch) associated
31 //!   type encodes information about the target's architecture, such as its
32 //!   pointer size, register layout, etc... `gdbstub` comes with several
33 //!   built-in architecture definitions, which can be found under the
34 //!   [`arch`](../arch/index.html) module.
35 //!
36 //! - The [`Target::Error`](trait.Target.html#associatedtype.Error) associated
37 //!   type allows implementors to plumb-through their own project-specific fatal
38 //!   error type into the `Target` trait. This is a big-boost to library
39 //!   ergonomics, as it enables consumers of `gdbstub` to preserve
40 //!   target-specific context while using `gdbstub`, without having to do any
41 //!   "error-stashing".
42 //!
43 //! For example: consider an emulated target where certain devices might return
44 //! a `MyEmuError::ContractViolation` error whenever they're accessed
45 //! "improperly" (e.g: setting registers in the wrong order). By setting `type
46 //! Error = MyEmuError`, the method signature of the `Target`'s `resume` method
47 //! becomes `fn resume(&mut self, ...) -> Result<_, MyEmuError>`, which makes it
48 //! possible to preserve the target-specific error while using `gdbstub`!
49 //!
50 //! ## Required Methods (Base Protocol)
51 //!
52 //! A minimal `Target` implementation only needs to implement a single method:
53 //! [`Target::base_ops`](trait.Target.html#tymethod.base_ops). This method is
54 //! used to select which set of [`base`](crate::target::ext::base)
55 //! debugging operations will be used to control the target. These are
56 //! fundamental operations such as reading/writing memory, etc...
57 //!
58 //! All other methods are entirely optional! Check out the
59 //! [`ext`](ext#modules) module for a full list of currently supported protocol
60 //! extensions.
61 //!
62 //! ## Optional Protocol Extensions
63 //!
64 //! The GDB protocol is _massive_, and there are plenty of optional protocol
65 //! extensions that targets can implement to enhance the base debugging
66 //! experience.
67 //!
68 //! These protocol extensions range from relatively mundane things such as
69 //! setting/removing breakpoints or reading/writing individual registers, but
70 //! also include fancy things such as support for time travel debugging, running
71 //! shell commands remotely, or even performing file IO on the target!
72 //!
73 //! `gdbstub` uses a somewhat unique approach to exposing these many features,
74 //! called **Inlinable Dyn Extension Traits (IDETs)**. While this might sound a
75 //! bit daunting, the API is actually quite straightforward, and described in
76 //! great detail under the [`ext` module's documentation](ext).
77 //!
78 //! After getting the base protocol up and running, do take a moment to skim
79 //! through and familiarize yourself with the [many different protocol
80 //! extensions](ext# modules) that `gdbstub` implements. There are some really
81 //! nifty ones that you might not even realize you need!
82 //!
83 //! As a suggestion on where to start, consider implementing some of the
84 //! breakpoint related extensions under
85 //! [`breakpoints`](crate::target::ext::breakpoints). While setting/removing
86 //! breakpoints is technically an "optional" part of the GDB protocol, I'm sure
87 //! you'd be hard pressed to find a debugger that doesn't support breakpoints.
88 //!
89 //! ### Note: Missing Protocol Extensions
90 //!
91 //! `gdbstub`'s development is guided by the needs of its contributors, with
92 //! new features being added on an "as-needed" basis.
93 //!
94 //! If there's a GDB protocol extensions you're interested in that hasn't been
95 //! implemented in `gdbstub` yet, (e.g: remote filesystem access, tracepoint
96 //! support, etc...), consider opening an issue / filing a PR on the
97 //! [`gdbstub` GitHub repo](https://github.com/daniel5151/gdbstub/).
98 //!
99 //! Check out the [GDB Remote Configuration Docs](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Configuration.html)
100 //! for a table of GDB commands + their corresponding Remote Serial Protocol
101 //! packets.
102 //!
103 //! ### Example: A fairly minimal Single Threaded `Target`
104 //!
105 //! This example includes a handful of required and optional target features,
106 //! and shows off the basics of how to work with IDETs.
107 //!
108 //! ```rust
109 //! use gdbstub::common::Signal;
110 //! use gdbstub::target::{Target, TargetResult};
111 //! use gdbstub::target::ext::base::BaseOps;
112 //! use gdbstub::target::ext::base::singlethread::{
113 //!     SingleThreadResumeOps, SingleThreadSingleStepOps
114 //! };
115 //! use gdbstub::target::ext::base::singlethread::{
116 //!     SingleThreadBase, SingleThreadResume, SingleThreadSingleStep
117 //! };
118 //! use gdbstub::target::ext::breakpoints::{Breakpoints, SwBreakpoint};
119 //! use gdbstub::target::ext::breakpoints::{BreakpointsOps, SwBreakpointOps};
120 //!
121 //! struct MyTarget;
122 //!
123 //! impl Target for MyTarget {
124 //!     type Error = ();
125 //!     type Arch = gdbstub_arch::arm::Armv4t; // as an example
126 //!
127 //!     #[inline(always)]
128 //!     fn base_ops(&mut self) -> BaseOps<Self::Arch, Self::Error> {
129 //!         BaseOps::SingleThread(self)
130 //!     }
131 //!
132 //!     // opt-in to support for setting/removing breakpoints
133 //!     #[inline(always)]
134 //!     fn support_breakpoints(&mut self) -> Option<BreakpointsOps<Self>> {
135 //!         Some(self)
136 //!     }
137 //! }
138 //!
139 //! impl SingleThreadBase for MyTarget {
140 //!     fn read_registers(
141 //!         &mut self,
142 //!         regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs,
143 //!     ) -> TargetResult<(), Self> { todo!() }
144 //!
145 //!     fn write_registers(
146 //!         &mut self,
147 //!         regs: &gdbstub_arch::arm::reg::ArmCoreRegs
148 //!     ) -> TargetResult<(), Self> { todo!() }
149 //!
150 //!     fn read_addrs(
151 //!         &mut self,
152 //!         start_addr: u32,
153 //!         data: &mut [u8],
154 //!     ) -> TargetResult<usize, Self> { todo!() }
155 //!
156 //!     fn write_addrs(
157 //!         &mut self,
158 //!         start_addr: u32,
159 //!         data: &[u8],
160 //!     ) -> TargetResult<(), Self> { todo!() }
161 //!
162 //!     // most targets will want to support at resumption as well...
163 //!
164 //!     #[inline(always)]
165 //!     fn support_resume(&mut self) -> Option<SingleThreadResumeOps<Self>> {
166 //!         Some(self)
167 //!     }
168 //! }
169 //!
170 //! impl SingleThreadResume for MyTarget {
171 //!     fn resume(
172 //!         &mut self,
173 //!         signal: Option<Signal>,
174 //!     ) -> Result<(), Self::Error> { todo!() }
175 //!
176 //!     // ...and if the target supports resumption, it'll likely want to support
177 //!     // single-step resume as well
178 //!
179 //!     #[inline(always)]
180 //!     fn support_single_step(
181 //!         &mut self
182 //!     ) -> Option<SingleThreadSingleStepOps<'_, Self>> {
183 //!         Some(self)
184 //!     }
185 //! }
186 //!
187 //! impl SingleThreadSingleStep for MyTarget {
188 //!     fn step(
189 //!         &mut self,
190 //!         signal: Option<Signal>,
191 //!     ) -> Result<(), Self::Error> { todo!() }
192 //! }
193 //!
194 //! impl Breakpoints for MyTarget {
195 //!     // there are several kinds of breakpoints - this target uses software breakpoints
196 //!     #[inline(always)]
197 //!     fn support_sw_breakpoint(&mut self) -> Option<SwBreakpointOps<Self>> {
198 //!         Some(self)
199 //!     }
200 //! }
201 //!
202 //! impl SwBreakpoint for MyTarget {
203 //!     fn add_sw_breakpoint(
204 //!         &mut self,
205 //!         addr: u32,
206 //!         kind: gdbstub_arch::arm::ArmBreakpointKind,
207 //!     ) -> TargetResult<bool, Self> { todo!() }
208 //!
209 //!     fn remove_sw_breakpoint(
210 //!         &mut self,
211 //!         addr: u32,
212 //!         kind: gdbstub_arch::arm::ArmBreakpointKind,
213 //!     ) -> TargetResult<bool, Self> { todo!() }
214 //! }
215 //! ```
216 //!
217 //! ## A note on error handling
218 //!
219 //! As you explore the various protocol extension traits, you'll often find that
220 //! functions don't return a typical [`Result<T, Self::Error>`],
221 //! and will instead return a [`TargetResult<T, Self>`].
222 //!
223 //! At first glance this might look a bit strange, since it looks like the `Err`
224 //! variant of `TargetResult` is `Self` instead of `Self::Error`!
225 //!
226 //! Thankfully, there's a good reason for why that's the case. In a nutshell,
227 //! `TargetResult` wraps a typical `Result<T, Self::Error>` with a few
228 //! additional error types which can be reported back to the GDB client via the
229 //! GDB RSP.
230 //!
231 //! For example, if the GDB client tried to read memory from invalid memory,
232 //! instead of immediately terminating the entire debugging session, it's
233 //! possible to simply return a `Err(TargetError::Errno(14)) // EFAULT`, which
234 //! will notify the GDB client that the operation has failed.
235 //!
236 //! See the [`TargetError`] docs for more details.
237 //!
238 //! ## A note on all the `<Self::Arch as Arch>::` syntax
239 //!
240 //! As you explore `Target` and its many extension traits, you'll enounter
241 //! many method signatures that use this pretty gnarly bit of Rust type syntax.
242 //!
243 //! If [rust-lang/rust#38078](https://github.com/rust-lang/rust/issues/38078)
244 //! gets fixed, then types like `<Self::Arch as Arch>::Foo` could be simplified
245 //! to just `Self::Arch::Foo`, but until then, the much more explicit
246 //! [fully qualified syntax](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name)
247 //! must be used instead.
248 //!
249 //! To improve the readability and maintainability of your own implementation,
250 //! it'd be best to swap out the fully qualified syntax with whatever concrete
251 //! type is being used. e.g: on a 32-bit target, instead of cluttering up a
252 //! method implementation with a parameter passed as `(addr: <Self::Arch as
253 //! Arch>::Usize)`, just write `(addr: u32)` directly.
254 use crate::arch::Arch;
255 
256 pub mod ext;
257 
258 /// The error type for various methods on `Target` and its assorted associated
259 /// extension traits.
260 ///
261 /// # Error Handling over the GDB Remote Serial Protocol
262 ///
263 /// The GDB Remote Serial Protocol has less-than-stellar support for error
264 /// handling, typically taking the form of a single-byte
265 /// [`errno`-style error codes](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/errnos.md).
266 /// Moreover, often times the GDB client will simply _ignore_ the specific error
267 /// code returned by the stub, and print a generic failure message instead.
268 ///
269 /// As such, while it's certainly better to use appropriate error codes when
270 /// possible (e.g: returning a `EFAULT` (14) when reading from invalid memory),
271 /// it's often fine to simply return the more general `TargetError::NonFatal`
272 /// instead, and avoid the headache of picking a "descriptive" error code. Under
273 /// the good, `TargetError::NonFatal` is sent to the GDB client as a generic
274 /// `EREMOTEIO` (121) error.
275 ///
276 /// # `From` and `Into` implementations
277 ///
278 /// - `From<()>` -> `TargetError::NonFatal`
279 /// - `From<io::Error>` -> `TargetError::Io(io::Error)` (requires `std` feature)
280 ///
281 /// When using a custom target-specific fatal error type, users are encouraged
282 /// to write the following impl to simplify error handling in `Target` methods:
283 ///
284 /// ```rust
285 /// use gdbstub::target::TargetError;
286 ///
287 /// /// Target-specific Fatal Error
288 /// enum MyTargetFatalError {
289 ///     // ...
290 /// }
291 ///
292 /// impl From<MyTargetFatalError> for TargetError<MyTargetFatalError> {
293 ///     fn from(e: MyTargetFatalError) -> Self {
294 ///         TargetError::Fatal(e)
295 ///     }
296 /// }
297 /// ```
298 ///
299 /// Unfortunately, a blanket impl such as `impl<T: Target> From<T::Error> for
300 /// TargetError<T::Error>` isn't possible, as it could result in impl conflicts.
301 /// For example, if a Target decided to use `()` as its fatal error type, then
302 /// there would be conflict with the existing `From<()>` impl.
303 #[non_exhaustive]
304 pub enum TargetError<E> {
305     /// A non-specific, non-fatal error has occurred.
306     NonFatal,
307     /// Non-fatal I/O Error. Only available when the `std` feature is enabled.
308     ///
309     /// At the moment, this is just shorthand for
310     /// `TargetError::NonFatal(e.raw_os_err().unwrap_or(121))`. Error code `121`
311     /// corresponds to `EREMOTEIO`.
312     ///
313     /// In the future, `gdbstub` may add support for the "QEnableErrorStrings"
314     /// LLDB protocol extension, which would allow sending additional error
315     /// context (in the form of an ASCII string) when an I/O error occurs. If
316     /// this is something you're interested in, consider opening a PR!
317     #[cfg(feature = "std")]
318     Io(std::io::Error),
319     /// An operation-specific non-fatal error code.
320     Errno(u8),
321     /// A target-specific fatal error.
322     ///
323     /// **WARNING:** Returning this error will immediately terminate the GDB
324     /// debugging session, and return a
325     /// [`GdbStubError`](crate::stub::GdbStubError)!
326     Fatal(E),
327 }
328 
329 /// Converts a `()` into a `TargetError::NonFatal`.
330 impl<E> From<()> for TargetError<E> {
from(_: ()) -> TargetError<E>331     fn from(_: ()) -> TargetError<E> {
332         TargetError::NonFatal
333     }
334 }
335 
336 /// Converts a `std::io::Error` into a `TargetError::Io`.
337 #[cfg(feature = "std")]
338 impl<E> From<std::io::Error> for TargetError<E> {
from(e: std::io::Error) -> TargetError<E>339     fn from(e: std::io::Error) -> TargetError<E> {
340         TargetError::Io(e)
341     }
342 }
343 
344 /// A specialized `Result` type for `Target` operations. Supports reporting
345 /// non-fatal errors back to the GDB client.
346 ///
347 /// See [`TargetError`] for more details.
348 ///
349 /// _Note:_ While it's typically parameterized as `TargetResult<T, Self>`, the
350 /// error value is in-fact `TargetError<Self::Error>` (not `Self`).
351 pub type TargetResult<T, Tgt> = Result<T, TargetError<<Tgt as Target>::Error>>;
352 
353 /// Describes the architecture and capabilities of a target which can be
354 /// debugged by [`GdbStub`](../struct.GdbStub.html).
355 ///
356 /// The [`Target`](trait.Target.html) trait describes how to control and modify
357 /// a system's execution state during a GDB debugging session, and serves as the
358 /// primary bridge between `gdbstub`'s generic protocol implementation and a
359 /// target's project/platform-specific code.
360 ///
361 /// **`Target` is the most important trait in `gdbstub`, and must be implemented
362 /// by anyone who uses the library!**
363 ///
364 /// Please refer to the the documentation in the [`target` module](self)
365 /// for more information on how to implement and work with `Target` and its
366 /// various extension traits.
367 pub trait Target {
368     /// The target's architecture.
369     type Arch: Arch;
370 
371     /// A target-specific **fatal** error.
372     type Error;
373 
374     /// Base operations such as reading/writing from memory/registers,
375     /// stopping/resuming the target, etc....
376     ///
377     /// For example, on a single-threaded target:
378     ///
379     /// ```rust
380     /// use gdbstub::target::Target;
381     /// use gdbstub::target::ext::base::BaseOps;
382     /// use gdbstub::target::ext::base::singlethread::SingleThreadBase;
383     /// # use gdbstub::target::TargetResult;
384     /// # struct MyTarget;
385     ///
386     /// impl Target for MyTarget {
387     ///     // ...
388     ///     # type Arch = gdbstub_arch::arm::Armv4t;
389     ///     # type Error = ();
390     ///
391     ///     fn base_ops(&mut self) -> BaseOps<Self::Arch, Self::Error> {
392     ///         BaseOps::SingleThread(self)
393     ///     }
394     /// }
395     ///
396     /// // ...and then implement the associated base IDET
397     /// impl SingleThreadBase for MyTarget {
398     ///     // ...
399     /// #   fn read_registers(
400     /// #       &mut self,
401     /// #       regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs,
402     /// #   ) -> TargetResult<(), Self> { todo!() }
403     /// #
404     /// #   fn write_registers(
405     /// #       &mut self,
406     /// #       regs: &gdbstub_arch::arm::reg::ArmCoreRegs
407     /// #   ) -> TargetResult<(), Self> { todo!() }
408     /// #
409     /// #   fn read_addrs(
410     /// #       &mut self,
411     /// #       start_addr: u32,
412     /// #       data: &mut [u8],
413     /// #   ) -> TargetResult<usize, Self> { todo!() }
414     /// #
415     /// #   fn write_addrs(
416     /// #       &mut self,
417     /// #       start_addr: u32,
418     /// #       data: &[u8],
419     /// #   ) -> TargetResult<(), Self> { todo!() }
420     /// }
421     /// ```
base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>422     fn base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>;
423 
424     /// If the target supports resumption, but hasn't implemented explicit
425     /// support for software breakpoints (via
426     /// [`SwBreakpoints`](ext::breakpoints::SwBreakpoint)), notify the user
427     /// that the GDB client may set "implicit" software breakpoints by
428     /// rewriting the target's instruction stream.
429     ///
430     /// Targets that wish to use the GDB client's implicit software breakpoint
431     /// handler must explicitly **opt-in** to this somewhat surprising GDB
432     /// feature by overriding this method to return `true`.
433     ///
434     /// # Context
435     ///
436     /// An "implicit" software breakpoint is set by the GDB client by manually
437     /// writing a software breakpoint instruction into target memory via the
438     /// target's `write_addrs` implementation. i.e: the GDB client will
439     /// overwrite the target's instruction stream with a software breakpoint
440     /// instruction, with the expectation that the target has a implemented a
441     /// breakpoint exception handler.
442     ///
443     /// # Implications
444     ///
445     /// While this is a reasonable (and useful!) bit of behavior when targeting
446     /// many classes of remote stub (e.g: bare-metal, separate process), there
447     /// are many `gdbstub` implementations that do _not_ implement "software
448     /// breakpoints" by naively rewriting the target's instruction stream.
449     ///
450     /// - e.g: a `gdbstub` implemented in an emulator is unlikely to implement
451     ///   "software breakpoints" by hooking into the emulated hardware's
452     ///   breakpoint handler, and would likely implement "breakpoints" by
453     ///   maintaining a list of addresses to stop at as part of its core
454     ///   interpreter loop.
455     /// - e.g: a `gdbstub` implemented in a hypervisor would require special
456     ///   coordination with the guest kernel to support software breakpoints, as
457     ///   there would need to be some way to distinguish between "in-guest"
458     ///   debugging, and "hypervisor" debugging.
459     ///
460     /// As such, `gdbstub` includes this `guard_rail_implicit_sw_breakpoints`
461     /// method.
462     ///
463     /// As the name suggests, this method acts as a "guard rail" that
464     /// warns users from accidentally opting into this "implicit" breakpoint
465     /// functionality, and being exceptionally confused as to why their
466     /// target is acting weird.
467     ///
468     /// If `gdbstub` detects that the target has not implemented a software
469     /// breakpoint handler, it will check if
470     /// `guard_rail_implicit_sw_breakpoints()` has been enabled, and if it
471     /// has not, it will trigger a runtime error that points the user at this
472     /// very documentation.
473     ///
474     /// # A note on breakpoints
475     ///
476     /// Aside from setting breakpoints at the explicit behest of the user (e.g:
477     /// when setting breakpoints via the `b` command in GDB), the GDB client may
478     /// also set/remove _temporary breakpoints_ as part of other commands.
479     ///
480     /// e.g: On targets without native support for hardware single-stepping,
481     /// calling `stepi` in GDB will result in the GDB client setting a temporary
482     /// breakpoint on the next instruction + resuming via `continue` instead.
483     #[inline(always)]
guard_rail_implicit_sw_breakpoints(&self) -> bool484     fn guard_rail_implicit_sw_breakpoints(&self) -> bool {
485         false
486     }
487 
488     /// Enable/disable support for activating "no ack mode".
489     ///
490     /// By default, this method returns `true`.
491     ///
492     /// _Author's note:_ Unless you're using `gdbstub` with a truly unreliable
493     /// transport line (e.g: a noisy serial connection), it's best to support
494     /// "no ack mode", as it can substantially improve debugging latency.
495     ///
496     /// **Warning:** `gdbstub` doesn't currently implement all necessary
497     /// features for running correctly over a unreliable transport! See issue
498     /// [\#137](https://github.com/daniel5151/gdbstub/issues/137) for details.
499     ///
500     /// # What is "No Ack Mode"?
501     ///
502     /// From the [GDB RSP docs](https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html#Packet-Acknowledgment):
503     ///
504     /// > By default, when either the host or the target machine receives a
505     /// > packet, the first response expected is an acknowledgment: either '+'
506     /// > (to indicate the package was received correctly) or '-' (to request
507     /// > retransmission). This mechanism allows the GDB remote protocol to
508     /// > operate over unreliable transport mechanisms, such as a serial line.
509     /// >
510     /// > In cases where the transport mechanism is itself reliable (such as a
511     /// > pipe or TCP connection), the '+'/'-' acknowledgments are redundant. It
512     /// > may be desirable to disable them in that case to reduce communication
513     /// > overhead, or for other reasons. This can be accomplished by means of
514     /// > the 'QStartNoAckMode' packet
515     #[inline(always)]
use_no_ack_mode(&self) -> bool516     fn use_no_ack_mode(&self) -> bool {
517         true
518     }
519 
520     /// Enable/disable using the more efficient `X` packet to write to target
521     /// memory (as opposed to the basic `M` packet).
522     ///
523     /// By default, this method returns `true`.
524     ///
525     /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto
526     /// a particularly resource-constrained platform, you may as well leave this
527     /// optimization enabled.
528     #[inline(always)]
use_x_upcase_packet(&self) -> bool529     fn use_x_upcase_packet(&self) -> bool {
530         true
531     }
532 
533     /// Whether `gdbstub` should provide a "stub" `resume` implementation on
534     /// targets without support for resumption.
535     ///
536     /// At the time of writing, the mainline GDB client does not gracefully
537     /// handle targets that do not support support resumption, and will hang
538     /// indefinitely if a user inadvertently attempts to `continue` or `step`
539     /// such a target.
540     ///
541     /// To make the `gdbstub` user experience a bit better, the library includes
542     /// bit of "stub" code to gracefully handle these cases.
543     ///
544     /// If a user attempts to resume a target that hasn't implemented support
545     /// for resumption, `gdbstub` will write a brief message back to the GDB
546     /// client console, and will immediately return a "stopped with TRAP" stop
547     /// reason.
548     ///
549     /// This method controls whether or not this bt of behavior is enabled.
550     ///
551     /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto
552     /// a particularly resource-constrained platform, you may as well leave this
553     /// enabled. The resulting stub code is entirely optimized out on targets
554     /// that implement support for resumption.
555     #[inline(always)]
use_resume_stub(&self) -> bool556     fn use_resume_stub(&self) -> bool {
557         true
558     }
559 
560     /// Enable/Disable the use of run-length encoding on outgoing packets.
561     ///
562     /// This is enabled by default, as RLE can save substantial amounts of
563     /// bandwidth down the wire.
564     ///
565     /// _Author's note:_ There are essentially no reasons to disable RLE, unless
566     /// you happen to be using a custom GDB client that doesn't support RLE.
567     #[inline(always)]
use_rle(&self) -> bool568     fn use_rle(&self) -> bool {
569         true
570     }
571 
572     /// Whether to send a target description XML to the client.
573     ///
574     /// Setting this to `false` will override both
575     /// [`Target::support_target_description_xml_override`] and the associated
576     /// [`Arch::target_description_xml`].
577     ///
578     /// _Author's note:_ Having the GDB client autodetect your target's
579     /// architecture and register set is really useful, so unless you're
580     /// _really_ trying to squeeze `gdbstub` onto a particularly
581     /// resource-constrained platform, you may as well leave this enabled.
582     #[inline(always)]
use_target_description_xml(&self) -> bool583     fn use_target_description_xml(&self) -> bool {
584         true
585     }
586 
587     /// (LLDB extension) Whether to send register information to the client.
588     ///
589     /// Setting this to `false` will override both
590     /// [`Target::support_lldb_register_info_override`] and the associated
591     /// [`Arch::lldb_register_info`].
592     ///
593     /// _Author's note:_ Having the LLDB client autodetect your target's
594     /// register set is really useful, so unless you're _really_ trying to
595     /// squeeze `gdbstub` onto a particularly resource-constrained platform, you
596     /// may as well leave this enabled.
597     #[inline(always)]
use_lldb_register_info(&self) -> bool598     fn use_lldb_register_info(&self) -> bool {
599         true
600     }
601 
602     /// Support for setting / removing breakpoints.
603     #[inline(always)]
support_breakpoints(&mut self) -> Option<ext::breakpoints::BreakpointsOps<'_, Self>>604     fn support_breakpoints(&mut self) -> Option<ext::breakpoints::BreakpointsOps<'_, Self>> {
605         None
606     }
607 
608     /// Support for handling custom GDB `monitor` commands.
609     #[inline(always)]
support_monitor_cmd(&mut self) -> Option<ext::monitor_cmd::MonitorCmdOps<'_, Self>>610     fn support_monitor_cmd(&mut self) -> Option<ext::monitor_cmd::MonitorCmdOps<'_, Self>> {
611         None
612     }
613 
614     /// Support for Extended Mode operations.
615     #[inline(always)]
support_extended_mode(&mut self) -> Option<ext::extended_mode::ExtendedModeOps<'_, Self>>616     fn support_extended_mode(&mut self) -> Option<ext::extended_mode::ExtendedModeOps<'_, Self>> {
617         None
618     }
619 
620     /// Support for handling requests to get the target's current section (or
621     /// segment) offsets.
622     #[inline(always)]
support_section_offsets( &mut self, ) -> Option<ext::section_offsets::SectionOffsetsOps<'_, Self>>623     fn support_section_offsets(
624         &mut self,
625     ) -> Option<ext::section_offsets::SectionOffsetsOps<'_, Self>> {
626         None
627     }
628 
629     /// Support for overriding the target description XML specified by
630     /// `Target::Arch`.
631     #[inline(always)]
support_target_description_xml_override( &mut self, ) -> Option<ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<'_, Self>>632     fn support_target_description_xml_override(
633         &mut self,
634     ) -> Option<ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<'_, Self>>
635     {
636         None
637     }
638 
639     /// (LLDB extension) Support for overriding the register info specified by
640     /// `Target::Arch`.
641     #[inline(always)]
support_lldb_register_info_override( &mut self, ) -> Option<ext::lldb_register_info_override::LldbRegisterInfoOverrideOps<'_, Self>>642     fn support_lldb_register_info_override(
643         &mut self,
644     ) -> Option<ext::lldb_register_info_override::LldbRegisterInfoOverrideOps<'_, Self>> {
645         None
646     }
647 
648     /// Support for reading the target's memory map.
649     #[inline(always)]
support_memory_map(&mut self) -> Option<ext::memory_map::MemoryMapOps<'_, Self>>650     fn support_memory_map(&mut self) -> Option<ext::memory_map::MemoryMapOps<'_, Self>> {
651         None
652     }
653 
654     /// Support for setting / removing syscall catchpoints.
655     #[inline(always)]
support_catch_syscalls( &mut self, ) -> Option<ext::catch_syscalls::CatchSyscallsOps<'_, Self>>656     fn support_catch_syscalls(
657         &mut self,
658     ) -> Option<ext::catch_syscalls::CatchSyscallsOps<'_, Self>> {
659         None
660     }
661 
662     /// Support for Host I/O operations.
663     #[inline(always)]
support_host_io(&mut self) -> Option<ext::host_io::HostIoOps<'_, Self>>664     fn support_host_io(&mut self) -> Option<ext::host_io::HostIoOps<'_, Self>> {
665         None
666     }
667 
668     /// Support for reading the current exec-file.
669     #[inline(always)]
support_exec_file(&mut self) -> Option<ext::exec_file::ExecFileOps<'_, Self>>670     fn support_exec_file(&mut self) -> Option<ext::exec_file::ExecFileOps<'_, Self>> {
671         None
672     }
673 
674     /// Support for reading the target's Auxillary Vector.
675     #[inline(always)]
support_auxv(&mut self) -> Option<ext::auxv::AuxvOps<'_, Self>>676     fn support_auxv(&mut self) -> Option<ext::auxv::AuxvOps<'_, Self>> {
677         None
678     }
679 
680     /// Support for reading a list of libraries for SVR4 (System-V/Unix)
681     /// platforms.
682     #[inline(always)]
support_libraries_svr4(&mut self) -> Option<ext::libraries::LibrariesSvr4Ops<'_, Self>>683     fn support_libraries_svr4(&mut self) -> Option<ext::libraries::LibrariesSvr4Ops<'_, Self>> {
684         None
685     }
686 }
687 
688 macro_rules! __delegate {
689     (fn $op:ident(&mut $this:ident) $($sig:tt)*) => {
690         fn $op(&mut $this) $($sig)* {
691             (**$this).$op()
692         }
693     };
694 
695     (fn $op:ident(&$this:ident) $($sig:tt)*) => {
696         fn $op(&$this) $($sig)* {
697             (**$this).$op()
698         }
699     }
700 }
701 
702 macro_rules! __delegate_support {
703     ($ext:ident) => {
704         paste::paste! {
705             __delegate!(fn [<support_ $ext>](&mut self) -> Option<ext::$ext::[<$ext:camel Ops>]<'_, Self>>);
706         }
707     };
708 }
709 
710 macro_rules! impl_dyn_target {
711     ($type:ty) => {
712         impl<A, E> Target for $type
713         where
714             A: Arch,
715         {
716             type Arch = A;
717             type Error = E;
718 
719             __delegate!(fn base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>);
720 
721             __delegate!(fn guard_rail_implicit_sw_breakpoints(&self) -> bool);
722 
723             __delegate!(fn use_no_ack_mode(&self) -> bool);
724             __delegate!(fn use_x_upcase_packet(&self) -> bool);
725             __delegate!(fn use_resume_stub(&self) -> bool);
726             __delegate!(fn use_rle(&self) -> bool);
727             __delegate!(fn use_target_description_xml(&self) -> bool);
728             __delegate!(fn use_lldb_register_info(&self) -> bool);
729 
730             __delegate_support!(breakpoints);
731             __delegate_support!(monitor_cmd);
732             __delegate_support!(extended_mode);
733             __delegate_support!(section_offsets);
734             __delegate_support!(target_description_xml_override);
735             __delegate_support!(lldb_register_info_override);
736             __delegate_support!(memory_map);
737             __delegate_support!(catch_syscalls);
738             __delegate_support!(host_io);
739             __delegate_support!(exec_file);
740             __delegate_support!(auxv);
741         }
742     };
743 }
744 
745 impl_dyn_target!(&mut dyn Target<Arch = A, Error = E>);
746 #[cfg(feature = "alloc")]
747 impl_dyn_target!(alloc::boxed::Box<dyn Target<Arch = A, Error = E>>);
748