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<(), 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, SingleStepGdbBehavior}; 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 top-level `GdbStubError::TargetError`! 325 Fatal(E), 326 } 327 328 /// Converts a `()` into a `TargetError::NonFatal`. 329 impl<E> From<()> for TargetError<E> { from(_: ()) -> TargetError<E>330 fn from(_: ()) -> TargetError<E> { 331 TargetError::NonFatal 332 } 333 } 334 335 /// Converts a `std::io::Error` into a `TargetError::Io`. 336 #[cfg(feature = "std")] 337 impl<E> From<std::io::Error> for TargetError<E> { from(e: std::io::Error) -> TargetError<E>338 fn from(e: std::io::Error) -> TargetError<E> { 339 TargetError::Io(e) 340 } 341 } 342 343 /// A specialized `Result` type for `Target` operations. Supports reporting 344 /// non-fatal errors back to the GDB client. 345 /// 346 /// See [`TargetError`] for more details. 347 /// 348 /// _Note:_ While it's typically parameterized as `TargetResult<T, Self>`, the 349 /// error value is in-fact `TargetError<Self::Error>` (not `Self`). 350 pub type TargetResult<T, Tgt> = Result<T, TargetError<<Tgt as Target>::Error>>; 351 352 /// Describes the architecture and capabilities of a target which can be 353 /// debugged by [`GdbStub`](../struct.GdbStub.html). 354 /// 355 /// The [`Target`](trait.Target.html) trait describes how to control and modify 356 /// a system's execution state during a GDB debugging session, and serves as the 357 /// primary bridge between `gdbstub`'s generic protocol implementation and a 358 /// target's project/platform-specific code. 359 /// 360 /// **`Target` is the most important trait in `gdbstub`, and must be implemented 361 /// by anyone who uses the library!** 362 /// 363 /// Please refer to the the documentation in the [`target` module](self) 364 /// for more information on how to implement and work with `Target` and its 365 /// various extension traits. 366 pub trait Target { 367 /// The target's architecture. 368 type Arch: Arch; 369 370 /// A target-specific **fatal** error. 371 type Error; 372 373 /// Base operations such as reading/writing from memory/registers, 374 /// stopping/resuming the target, etc.... 375 /// 376 /// For example, on a single-threaded target: 377 /// 378 /// ```rust 379 /// use gdbstub::target::Target; 380 /// use gdbstub::target::ext::base::BaseOps; 381 /// use gdbstub::target::ext::base::singlethread::SingleThreadBase; 382 /// # use gdbstub::target::TargetResult; 383 /// # struct MyTarget; 384 /// 385 /// impl Target for MyTarget { 386 /// // ... 387 /// # type Arch = gdbstub_arch::arm::Armv4t; 388 /// # type Error = (); 389 /// 390 /// fn base_ops(&mut self) -> BaseOps<Self::Arch, Self::Error> { 391 /// BaseOps::SingleThread(self) 392 /// } 393 /// } 394 /// 395 /// // ...and then implement the associated base IDET 396 /// impl SingleThreadBase for MyTarget { 397 /// // ... 398 /// # fn read_registers( 399 /// # &mut self, 400 /// # regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs, 401 /// # ) -> TargetResult<(), Self> { todo!() } 402 /// # 403 /// # fn write_registers( 404 /// # &mut self, 405 /// # regs: &gdbstub_arch::arm::reg::ArmCoreRegs 406 /// # ) -> TargetResult<(), Self> { todo!() } 407 /// # 408 /// # fn read_addrs( 409 /// # &mut self, 410 /// # start_addr: u32, 411 /// # data: &mut [u8], 412 /// # ) -> TargetResult<(), Self> { todo!() } 413 /// # 414 /// # fn write_addrs( 415 /// # &mut self, 416 /// # start_addr: u32, 417 /// # data: &[u8], 418 /// # ) -> TargetResult<(), Self> { todo!() } 419 /// } 420 /// ``` base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>421 fn base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>; 422 423 /// If the target supports resumption, but hasn't implemented explicit 424 /// support for software breakpoints (via 425 /// [`SwBreakpoints`](ext::breakpoints::SwBreakpoint)), notify the user 426 /// that the GDB client may set "implicit" software breakpoints by 427 /// rewriting the target's instruction stream. 428 /// 429 /// Targets that wish to use the GDB client's implicit software breakpoint 430 /// handler must explicitly **opt-in** to this somewhat surprising GDB 431 /// feature by overriding this method to return `true`. 432 /// 433 /// If you are reading these docs after having encountered a 434 /// [`GdbStubError::ImplicitSwBreakpoints`] error, it's quite likely that 435 /// you'll want to implement explicit support for software breakpoints. 436 /// 437 /// # Context 438 /// 439 /// An "implicit" software breakpoint is set by the GDB client by manually 440 /// writing a software breakpoint instruction into target memory via the 441 /// target's `write_addrs` implementation. i.e: the GDB client will 442 /// overwrite the target's instruction stream with a software breakpoint 443 /// instruction, with the expectation that the target has a implemented a 444 /// breakpoint exception handler. 445 /// 446 /// # Implications 447 /// 448 /// While this is a reasonable (and useful!) bit of behavior when targeting 449 /// many classes of remote stub (e.g: bare-metal, separate process), there 450 /// are many `gdbstub` implementations that do _not_ implement "software 451 /// breakpoints" by naively rewriting the target's instruction stream. 452 /// 453 /// - e.g: a `gdbstub` implemented in an emulator is unlikely to implement 454 /// "software breakpoints" by hooking into the emulated hardware's 455 /// breakpoint handler, and would likely implement "breakpoints" by 456 /// maintaining a list of addresses to stop at as part of its core 457 /// interpreter loop. 458 /// - e.g: a `gdbstub` implemented in a hypervisor would require special 459 /// coordination with the guest kernel to support software breakpoints, as 460 /// there would need to be some way to distinguish between "in-guest" 461 /// debugging, and "hypervisor" debugging. 462 /// 463 /// As such, `gdbstub` includes this `guard_rail_implicit_sw_breakpoints` 464 /// method. 465 /// 466 /// As the name suggests, this method acts as a "guard rail" that 467 /// warns users from accidentally opting into this "implicit" breakpoint 468 /// functionality, and being exceptionally confused as to why their 469 /// target is acting weird. 470 /// 471 /// If `gdbstub` detects that the target has not implemented a software 472 /// breakpoint handler, it will check if 473 /// `guard_rail_implicit_sw_breakpoints()` has been enabled, and if it 474 /// has not, it will trigger a runtime error that points the user at this 475 /// very documentation. 476 /// 477 /// # A note on breakpoints 478 /// 479 /// Aside from setting breakpoints at the explicit behest of the user (e.g: 480 /// when setting breakpoints via the `b` command in GDB), the GDB client may 481 /// also set/remove _temporary breakpoints_ as part of other commands. 482 /// 483 /// e.g: On targets without native support for hardware single-stepping, 484 /// calling `stepi` in GDB will result in the GDB client setting a temporary 485 /// breakpoint on the next instruction + resuming via `continue` instead. 486 /// 487 /// [`GdbStubError::ImplicitSwBreakpoints`]: 488 /// crate::stub::GdbStubError::ImplicitSwBreakpoints 489 #[inline(always)] guard_rail_implicit_sw_breakpoints(&self) -> bool490 fn guard_rail_implicit_sw_breakpoints(&self) -> bool { 491 false 492 } 493 494 /// Override the arch-level value for [`Arch::single_step_gdb_behavior`]. 495 /// 496 /// If you are reading these docs after having encountered a 497 /// [`GdbStubError::SingleStepGdbBehavior`] error, you may need to either: 498 /// 499 /// - implement support for single-step 500 /// - disable existing support for single step 501 /// - be a Good Citizen and perform a quick test to see what kind of 502 /// behavior your Arch exhibits. 503 /// 504 /// # WARNING 505 /// 506 /// Unless you _really_ know what you're doing (e.g: working on a dynamic 507 /// target implementation, attempting to fix the underlying bug, etc...), 508 /// you should **not** override this method, and instead follow the advice 509 /// the error gives you. 510 /// 511 /// Incorrectly setting this method may lead to "unexpected packet" runtime 512 /// errors! 513 /// 514 /// # Details 515 /// 516 /// This method provides an "escape hatch" for disabling a workaround for a 517 /// bug in the mainline GDB client implementation. 518 /// 519 /// To squelch all errors, this method can be set to return 520 /// [`SingleStepGdbBehavior::Optional`] (though as mentioned above - you 521 /// should only do so if you're sure that's the right behavior). 522 /// 523 /// For more information, see the documentation for 524 /// [`Arch::single_step_gdb_behavior`]. 525 /// 526 /// [`GdbStubError::SingleStepGdbBehavior`]: 527 /// crate::stub::GdbStubError::SingleStepGdbBehavior 528 #[inline(always)] guard_rail_single_step_gdb_behavior(&self) -> SingleStepGdbBehavior529 fn guard_rail_single_step_gdb_behavior(&self) -> SingleStepGdbBehavior { 530 <Self::Arch as Arch>::single_step_gdb_behavior() 531 } 532 533 /// Enable/disable using the more efficient `X` packet to write to target 534 /// memory (as opposed to the basic `M` packet). 535 /// 536 /// By default, this method returns `true`. 537 /// 538 /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto 539 /// a particularly resource-constrained platform, you may as well leave this 540 /// optimization enabled. 541 #[inline(always)] use_x_upcase_packet(&self) -> bool542 fn use_x_upcase_packet(&self) -> bool { 543 true 544 } 545 546 /// Whether `gdbstub` should provide a "stub" `resume` implementation on 547 /// targets without support for resumption. 548 /// 549 /// At the time of writing, the mainline GDB client does not gracefully 550 /// handle targets that do not support support resumption, and will hang 551 /// indefinitely if a user inadvertently attempts to `continue` or `step` 552 /// such a target. 553 /// 554 /// To make the `gdbstub` user experience a bit better, the library includes 555 /// bit of "stub" code to gracefully handle these cases. 556 /// 557 /// If a user attempts to resume a target that hasn't implemented support 558 /// for resumption, `gdbstub` will write a brief message back to the GDB 559 /// client console, and will immediately return a "stopped with TRAP" stop 560 /// reason. 561 /// 562 /// This method controls whether or not this bt of behavior is enabled. 563 /// 564 /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto 565 /// a particularly resource-constrained platform, you may as well leave this 566 /// enabled. The resulting stub code is entirely optimized out on targets 567 /// that implement support for resumption. 568 #[inline(always)] use_resume_stub(&self) -> bool569 fn use_resume_stub(&self) -> bool { 570 true 571 } 572 573 /// Enable/Disable the use of run-length encoding on outgoing packets. 574 /// 575 /// This is enabled by default, as RLE can save substantial amounts of 576 /// bandwidth down the wire. 577 /// 578 /// _Author's note:_ There are essentially no reasons to disable RLE, unless 579 /// you happen to be using a custom GDB client that doesn't support RLE. 580 #[inline(always)] use_rle(&self) -> bool581 fn use_rle(&self) -> bool { 582 true 583 } 584 585 /// Whether to send a target description XML to the client. 586 /// 587 /// Setting this to `false` will override both 588 /// [`Target::support_target_description_xml_override`] and the associated 589 /// [`Arch::target_description_xml`]. 590 /// 591 /// _Author's note:_ Having the GDB client autodetect your target's 592 /// architecture and register set is really useful, so unless you're 593 /// _really_ trying to squeeze `gdbstub` onto a particularly 594 /// resource-constrained platform, you may as well leave this enabled. 595 #[inline(always)] use_target_description_xml(&self) -> bool596 fn use_target_description_xml(&self) -> bool { 597 true 598 } 599 600 /// (LLDB extension) Whether to send register information to the client. 601 /// 602 /// Setting this to `false` will override both 603 /// [`Target::support_lldb_register_info_override`] and the associated 604 /// [`Arch::lldb_register_info`]. 605 /// 606 /// _Author's note:_ Having the LLDB client autodetect your target's 607 /// register set is really useful, so unless you're _really_ trying to 608 /// squeeze `gdbstub` onto a particularly resource-constrained platform, you 609 /// may as well leave this enabled. 610 #[inline(always)] use_lldb_register_info(&self) -> bool611 fn use_lldb_register_info(&self) -> bool { 612 true 613 } 614 615 /// Support for setting / removing breakpoints. 616 #[inline(always)] support_breakpoints(&mut self) -> Option<ext::breakpoints::BreakpointsOps<'_, Self>>617 fn support_breakpoints(&mut self) -> Option<ext::breakpoints::BreakpointsOps<'_, Self>> { 618 None 619 } 620 621 /// Support for handling custom GDB `monitor` commands. 622 #[inline(always)] support_monitor_cmd(&mut self) -> Option<ext::monitor_cmd::MonitorCmdOps<'_, Self>>623 fn support_monitor_cmd(&mut self) -> Option<ext::monitor_cmd::MonitorCmdOps<'_, Self>> { 624 None 625 } 626 627 /// Support for Extended Mode operations. 628 #[inline(always)] support_extended_mode(&mut self) -> Option<ext::extended_mode::ExtendedModeOps<'_, Self>>629 fn support_extended_mode(&mut self) -> Option<ext::extended_mode::ExtendedModeOps<'_, Self>> { 630 None 631 } 632 633 /// Support for handling requests to get the target's current section (or 634 /// segment) offsets. 635 #[inline(always)] support_section_offsets( &mut self, ) -> Option<ext::section_offsets::SectionOffsetsOps<'_, Self>>636 fn support_section_offsets( 637 &mut self, 638 ) -> Option<ext::section_offsets::SectionOffsetsOps<'_, Self>> { 639 None 640 } 641 642 /// Support for overriding the target description XML specified by 643 /// `Target::Arch`. 644 #[inline(always)] support_target_description_xml_override( &mut self, ) -> Option<ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<'_, Self>>645 fn support_target_description_xml_override( 646 &mut self, 647 ) -> Option<ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<'_, Self>> 648 { 649 None 650 } 651 652 /// (LLDB extension) Support for overriding the register info specified by 653 /// `Target::Arch`. 654 #[inline(always)] support_lldb_register_info_override( &mut self, ) -> Option<ext::lldb_register_info_override::LldbRegisterInfoOverrideOps<'_, Self>>655 fn support_lldb_register_info_override( 656 &mut self, 657 ) -> Option<ext::lldb_register_info_override::LldbRegisterInfoOverrideOps<'_, Self>> { 658 None 659 } 660 661 /// Support for reading the target's memory map. 662 #[inline(always)] support_memory_map(&mut self) -> Option<ext::memory_map::MemoryMapOps<'_, Self>>663 fn support_memory_map(&mut self) -> Option<ext::memory_map::MemoryMapOps<'_, Self>> { 664 None 665 } 666 667 /// Support for setting / removing syscall catchpoints. 668 #[inline(always)] support_catch_syscalls( &mut self, ) -> Option<ext::catch_syscalls::CatchSyscallsOps<'_, Self>>669 fn support_catch_syscalls( 670 &mut self, 671 ) -> Option<ext::catch_syscalls::CatchSyscallsOps<'_, Self>> { 672 None 673 } 674 675 /// Support for Host I/O operations. 676 #[inline(always)] support_host_io(&mut self) -> Option<ext::host_io::HostIoOps<'_, Self>>677 fn support_host_io(&mut self) -> Option<ext::host_io::HostIoOps<'_, Self>> { 678 None 679 } 680 681 /// Support for reading the current exec-file. 682 #[inline(always)] support_exec_file(&mut self) -> Option<ext::exec_file::ExecFileOps<'_, Self>>683 fn support_exec_file(&mut self) -> Option<ext::exec_file::ExecFileOps<'_, Self>> { 684 None 685 } 686 687 /// Support for reading the target's Auxillary Vector. 688 #[inline(always)] support_auxv(&mut self) -> Option<ext::auxv::AuxvOps<'_, Self>>689 fn support_auxv(&mut self) -> Option<ext::auxv::AuxvOps<'_, Self>> { 690 None 691 } 692 } 693 694 macro_rules! __delegate { 695 (fn $op:ident(&mut $this:ident) $($sig:tt)*) => { 696 fn $op(&mut $this) $($sig)* { 697 (**$this).$op() 698 } 699 }; 700 701 (fn $op:ident(&$this:ident) $($sig:tt)*) => { 702 fn $op(&$this) $($sig)* { 703 (**$this).$op() 704 } 705 } 706 } 707 708 macro_rules! __delegate_support { 709 ($ext:ident) => { 710 paste::paste! { 711 __delegate!(fn [<support_ $ext>](&mut self) -> Option<ext::$ext::[<$ext:camel Ops>]<'_, Self>>); 712 } 713 }; 714 } 715 716 macro_rules! impl_dyn_target { 717 ($type:ty) => { 718 impl<A, E> Target for $type 719 where 720 A: Arch, 721 { 722 type Arch = A; 723 type Error = E; 724 725 __delegate!(fn base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>); 726 727 __delegate!(fn guard_rail_implicit_sw_breakpoints(&self) -> bool); 728 __delegate!(fn guard_rail_single_step_gdb_behavior(&self) -> SingleStepGdbBehavior); 729 730 __delegate!(fn use_x_upcase_packet(&self) -> bool); 731 __delegate!(fn use_resume_stub(&self) -> bool); 732 __delegate!(fn use_rle(&self) -> bool); 733 __delegate!(fn use_target_description_xml(&self) -> bool); 734 __delegate!(fn use_lldb_register_info(&self) -> bool); 735 736 __delegate_support!(breakpoints); 737 __delegate_support!(monitor_cmd); 738 __delegate_support!(extended_mode); 739 __delegate_support!(section_offsets); 740 __delegate_support!(target_description_xml_override); 741 __delegate_support!(lldb_register_info_override); 742 __delegate_support!(memory_map); 743 __delegate_support!(catch_syscalls); 744 __delegate_support!(host_io); 745 __delegate_support!(exec_file); 746 __delegate_support!(auxv); 747 } 748 }; 749 } 750 751 impl_dyn_target!(&mut dyn Target<Arch = A, Error = E>); 752 #[cfg(feature = "alloc")] 753 impl_dyn_target!(alloc::boxed::Box<dyn Target<Arch = A, Error = E>>); 754