1 //! Traits to encode architecture-specific target information. 2 //! 3 //! # Community created `Arch` Implementations 4 //! 5 //! Before getting your hands dirty and implementing a new `Arch` from scratch, 6 //! make sure to check out [`gdbstub_arch`](https://docs.rs/gdbstub_arch), a 7 //! companion crate to `gdbstub` which aggregates community-created `Arch` 8 //! implementations for most common architectures! 9 //! 10 //! > _Note:_ Prior to `gdbstub 0.5`, `Arch` implementations were distributed as 11 //! a part of the main `gdbstub` crate (under the `gdbstub::arch` module). This 12 //! wasn't ideal, any `gdbstub::arch`-level breaking-changes forced the _entire_ 13 //! `gdbstub` crate to release a new (potentially breaking!) version. 14 //! 15 //! > Having community-created `Arch` implementations distributed in a separate 16 //! crate helps minimize any unnecessary "version churn" in `gdbstub` core. 17 18 use core::fmt::Debug; 19 use core::num::NonZeroUsize; 20 21 use num_traits::{FromPrimitive, PrimInt, Unsigned}; 22 23 use crate::internal::{BeBytes, LeBytes}; 24 25 /// Register identifier for target registers. 26 /// 27 /// These identifiers are used by GDB to signal which register to read/wite when 28 /// performing [single register accesses]. 29 /// 30 /// [single register accesses]: 31 /// crate::target::ext::base::single_register_access::SingleRegisterAccess 32 pub trait RegId: Sized + Debug { 33 /// Map raw GDB register number to a corresponding `RegId` and optional 34 /// register size. 35 /// 36 /// If the register size is specified here, gdbstub will include a runtime 37 /// check that ensures target implementations do not send back more 38 /// bytes than the register allows. 39 /// 40 /// Returns `None` if the register is not available. from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)>41 fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)>; 42 } 43 44 /// Stub implementation -- Returns `None` for all raw IDs. 45 impl RegId for () { from_raw_id(_id: usize) -> Option<(Self, Option<NonZeroUsize>)>46 fn from_raw_id(_id: usize) -> Option<(Self, Option<NonZeroUsize>)> { 47 None 48 } 49 } 50 51 /// Methods to read/write architecture-specific registers. 52 /// 53 /// Registers must be de/serialized in the order specified by the architecture's 54 /// `<target>.xml` in the GDB source tree. 55 /// 56 /// e.g: for ARM: 57 /// github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml 58 // TODO: add way to de/serialize arbitrary "missing"/"uncollected" registers. 59 pub trait Registers: Default + Debug + Clone + PartialEq { 60 /// The type of the architecture's program counter / instruction pointer. 61 /// Must match with the corresponding `Arch::Usize`. 62 type ProgramCounter: Copy; 63 64 /// Return the value of the program counter / instruction pointer. pc(&self) -> Self::ProgramCounter65 fn pc(&self) -> Self::ProgramCounter; 66 67 /// Serialize `self` into a GDB register bytestream. 68 /// 69 /// Missing registers are serialized by passing `None` to write_byte. gdb_serialize(&self, write_byte: impl FnMut(Option<u8>))70 fn gdb_serialize(&self, write_byte: impl FnMut(Option<u8>)); 71 72 /// Deserialize a GDB register bytestream into `self`. 73 #[allow(clippy::result_unit_err)] gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()>74 fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()>; 75 } 76 77 /// Breakpoint kind for specific architectures. 78 /// 79 /// This trait corresponds to the _kind_ field of the "z" and "Z" breakpoint 80 /// packets, as documented [here](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#insert-breakpoint-or-watchpoint-packet). 81 /// 82 /// A breakpoint "kind" is architecture-specific and typically indicates the 83 /// size of the breakpoint in bytes that should be inserted. As such, most 84 /// architectures will set `BreakpointKind = usize`. 85 /// 86 /// Some architectures, such as ARM and MIPS, have additional meanings for 87 /// _kind_. See the [Architecture-Specific Protocol Details](https://sourceware.org/gdb/current/onlinedocs/gdb/Architecture_002dSpecific-Protocol-Details.html#Architecture_002dSpecific-Protocol-Details) 88 /// section of the GBD documentation for more details. 89 /// 90 /// If no architecture-specific value is being used, _kind_ should be set to 91 /// '0', and the `BreakpointKind` associated type should be `()`. 92 pub trait BreakpointKind: Sized + Debug { 93 /// Parse `Self` from a raw usize. from_usize(kind: usize) -> Option<Self>94 fn from_usize(kind: usize) -> Option<Self>; 95 } 96 97 impl BreakpointKind for () { from_usize(kind: usize) -> Option<Self>98 fn from_usize(kind: usize) -> Option<Self> { 99 if kind != 0 { 100 None 101 } else { 102 Some(()) 103 } 104 } 105 } 106 107 impl BreakpointKind for usize { 108 #[allow(clippy::wrong_self_convention)] from_usize(kind: usize) -> Option<Self>109 fn from_usize(kind: usize) -> Option<Self> { 110 Some(kind) 111 } 112 } 113 114 /// Encodes architecture-specific information, such as pointer size, register 115 /// layout, etc... 116 /// 117 /// Types implementing `Arch` should be 118 /// [Zero-variant Enums](https://doc.rust-lang.org/reference/items/enumerations.html#zero-variant-enums), 119 /// as `Arch` impls are only ever used at the type level, and should never be 120 /// explicitly instantiated. 121 pub trait Arch { 122 /// The architecture's pointer size (e.g: `u32` on a 32-bit system). 123 type Usize: Debug + FromPrimitive + PrimInt + Unsigned + BeBytes + LeBytes; 124 125 /// The architecture's register file. See [`Registers`] for more details. 126 type Registers: Registers<ProgramCounter = Self::Usize>; 127 128 /// The architecture's breakpoint "kind", used to determine the "size" 129 /// of breakpoint to set. See [`BreakpointKind`] for more details. 130 type BreakpointKind: BreakpointKind; 131 132 /// Register identifier enum/struct. 133 /// 134 /// Used to access individual registers via `Target::read/write_register`. 135 /// 136 /// > NOTE: An arch's `RegId` type is not strictly required to have a 1:1 137 /// correspondence with the `Registers` type, and may include register 138 /// identifiers which are separate from the main `Registers` structure. 139 /// (e.g: the RISC-V Control and Status registers) 140 type RegId: RegId; 141 142 /// (optional) Return the arch's description XML file (`target.xml`). 143 /// 144 /// Implementing this method enables GDB to automatically detect the 145 /// target's architecture, saving the hassle of having to run `set 146 /// architecture <arch>` when starting a debugging session. 147 /// 148 /// These descriptions can be quite succinct. For example, the target 149 /// description for an `armv4t` target can be as simple as: 150 /// 151 /// ``` 152 /// r#"<target version="1.0"><architecture>armv4t</architecture></target>"#; 153 /// ``` 154 /// 155 /// See the [GDB docs](https://sourceware.org/gdb/current/onlinedocs/gdb/Target-Description-Format.html) 156 /// for details on the target description XML format. 157 #[inline(always)] target_description_xml() -> Option<&'static str>158 fn target_description_xml() -> Option<&'static str> { 159 None 160 } 161 162 /// (optional) (LLDB extension) Return register info for the specified 163 /// register. 164 /// 165 /// Implementing this method enables LLDB to dynamically query the target's 166 /// register information one by one. 167 /// 168 /// Some targets don't have register context in the compiled version of the 169 /// debugger. Help the debugger by dynamically supplying the register info 170 /// from the target. The debugger will request the register info in a 171 /// sequential manner till an error packet is received. In LLDB, the 172 /// register info search has the following 173 /// [order](https://github.com/llvm/llvm-project/blob/369ce54bb302f209239b8ebc77ad824add9df089/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp#L397-L402): 174 /// 175 /// 1. Use the target definition python file if one is specified. 176 /// 2. If the target definition doesn't have any of the info from the 177 /// target.xml (registers) then proceed to read the `target.xml`. 178 /// 3. Fall back on the `qRegisterInfo` packets. 179 /// 4. Use hardcoded defaults if available. 180 /// 181 /// See the LLDB [gdb-remote docs](https://github.com/llvm-mirror/lldb/blob/d01083a850f577b85501a0902b52fd0930de72c7/docs/lldb-gdb-remote.txt#L396) 182 /// for more details on the available information that a single register can 183 /// be described by and [#99](https://github.com/daniel5151/gdbstub/issues/99) 184 /// for more information on LLDB compatibility. 185 #[inline(always)] lldb_register_info(reg_id: usize) -> Option<lldb::RegisterInfo<'static>>186 fn lldb_register_info(reg_id: usize) -> Option<lldb::RegisterInfo<'static>> { 187 let _ = reg_id; 188 None 189 } 190 191 /// Encode how the mainline GDB client handles target support for 192 /// single-step on this particular architecture. 193 /// 194 /// # Context 195 /// 196 /// According to the spec, supporting single step _should_ be quite 197 /// straightforward: 198 /// 199 /// - The GDB client sends a `vCont?` packet to enumerate supported 200 /// resumption modes 201 /// - If the target supports single-step, it responds with the `s;S` 202 /// capability as part of the response, omitting it if it is not 203 /// supported. 204 /// - Later, when the user attempts to `stepi`, the GDB client sends a `s` 205 /// resumption reason if it is supported, falling back to setting a 206 /// temporary breakpoint + continue to "emulate" the single step. 207 /// 208 /// Unfortunately, the reality is that the mainline GDB client does _not_ do 209 /// this on all architectures... 210 /// 211 /// - On certain architectures (e.g: x86), GDB will _unconditionally_ assume 212 /// single-step support, regardless whether or not the target reports 213 /// supports it. 214 /// - On certain architectures (e.g: MIPS), GDB will _never_ use single-step 215 /// support, even in the target has explicitly reported support for it. 216 /// 217 /// This is a bug, and has been reported at 218 /// <https://sourceware.org/bugzilla/show_bug.cgi?id=28440>. 219 /// 220 /// For a easy repro of this behavior, also see 221 /// <https://github.com/daniel5151/gdb-optional-step-bug>. 222 /// 223 /// # Implications 224 /// 225 /// Unfortunately, even if these idiosyncratic behaviors get fixed in the 226 /// mainline GDB client, it will be quite a while until the typical 227 /// user's distro-provided GDB client includes this bugfix. 228 /// 229 /// As such, `gdbstub` has opted to include this method as a "guard rail" to 230 /// preemptively detect cases of this idiosyncratic behavior, and throw a 231 /// pre-init error that informs the user of the potential issues they may 232 /// run into. 233 /// 234 /// # Writing a proper implementation 235 /// 236 /// To check whether or not a particular architecture exhibits this 237 /// behavior, an implementation should temporarily override this method to 238 /// return [`SingleStepGdbBehavior::Optional`], toggle target support for 239 /// single-step on/off, and observe the behavior of the GDB client after 240 /// invoking `stepi`. 241 /// 242 /// If single-stepping was **disabled**, yet the client nonetheless sent a 243 /// `vCont` packet with a `s` resume action, then this architecture 244 /// _does not_ support optional single stepping, and this method should 245 /// return [`SingleStepGdbBehavior::Required`]. 246 /// 247 /// If single-stepping was **disabled**, and the client attempted to set a 248 /// temporary breakpoint (using the `z` packet), and then sent a `vCont` 249 /// packet with a `c` resume action, then this architecture _does_ 250 /// support optional single stepping, and this method should return 251 /// [`SingleStepGdbBehavior::Optional`]. 252 /// 253 /// If single-stepping was **enabled**, yet the client did _not_ send a 254 /// `vCont` packet with a `s` resume action, then this architecture 255 /// _ignores_ single stepping entirely, and this method should return 256 /// [`SingleStepGdbBehavior::Ignored`]. single_step_gdb_behavior() -> SingleStepGdbBehavior257 fn single_step_gdb_behavior() -> SingleStepGdbBehavior; 258 } 259 260 /// Encodes how the mainline GDB client handles target support for single-step 261 /// on a particular architecture. 262 /// 263 /// See [Arch::single_step_gdb_behavior] for details. 264 #[non_exhaustive] 265 #[derive(Debug, Clone, Copy)] 266 pub enum SingleStepGdbBehavior { 267 /// GDB will use single-stepping if available, falling back to using 268 /// a temporary breakpoint + continue if unsupported. 269 /// 270 /// e.g: ARM 271 Optional, 272 /// GDB will unconditionally send single-step packets, _requiring_ the 273 /// target to handle these requests. 274 /// 275 /// e.g: x86/x64 276 Required, 277 /// GDB will never use single-stepping, regardless if it's supported by the 278 /// stub. It will always use a temporary breakpoint + continue. 279 /// 280 /// e.g: MIPS 281 Ignored, 282 /// Unknown behavior - no one has tested this platform yet. If possible, 283 /// please conduct a test + upstream your findings to `gdbstub_arch`. 284 #[doc(hidden)] 285 Unknown, 286 } 287 288 /// LLDB-specific types supporting [`Arch::lldb_register_info`] and 289 /// [`LldbRegisterInfoOverride`] APIs. 290 /// 291 /// [`LldbRegisterInfoOverride`]: crate::target::ext::lldb_register_info_override::LldbRegisterInfoOverride 292 pub mod lldb { 293 /// The architecture's register information of a single register. 294 pub enum RegisterInfo<'a> { 295 /// The register info of a single register that should be written. 296 Register(Register<'a>), 297 /// The `qRegisterInfo` query shall be concluded. 298 Done, 299 } 300 301 /// Describes the register info for a single register of 302 /// the target. 303 pub struct Register<'a> { 304 /// The primary register name. 305 pub name: &'a str, 306 /// An alternate name for the register. 307 pub alt_name: Option<&'a str>, 308 /// Size in bits of a register. 309 pub bitsize: usize, 310 /// The offset within the 'g' and 'G' packet of the register data for 311 /// this register. 312 pub offset: usize, 313 /// The encoding type of the register. 314 pub encoding: Encoding, 315 /// The preferred format for display of this register. 316 pub format: Format, 317 /// The register set name this register belongs to. 318 pub set: &'a str, 319 /// The GCC compiler registers number for this register. 320 /// 321 /// _Note:_ This denotes the same `KEY:VALUE;` pair as `ehframe:VALUE;`. 322 /// See the LLDB [source](https://github.com/llvm/llvm-project/blob/b92436efcb7813fc481b30f2593a4907568d917a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp#L493). 323 pub gcc: Option<usize>, 324 /// The DWARF register number for this register that is used for this 325 /// register in the debug information. 326 pub dwarf: Option<usize>, 327 /// Specify as a generic register. 328 pub generic: Option<Generic>, 329 /// Other concrete register values this register is contained in. 330 pub container_regs: Option<&'a [usize]>, 331 /// Specifies which register values should be invalidated when this 332 /// register is modified. 333 pub invalidate_regs: Option<&'a [usize]>, 334 } 335 336 /// Describes the encoding type of the register. 337 #[non_exhaustive] 338 pub enum Encoding { 339 /// Unsigned integer 340 Uint, 341 /// Signed integer 342 Sint, 343 /// IEEE 754 float 344 IEEE754, 345 /// Vector register 346 Vector, 347 } 348 349 /// Describes the preferred format for display of this register. 350 #[non_exhaustive] 351 pub enum Format { 352 /// Binary format 353 Binary, 354 /// Decimal format 355 Decimal, 356 /// Hexadecimal format 357 Hex, 358 /// Floating point format 359 Float, 360 /// 8 bit signed int vector 361 VectorSInt8, 362 /// 8 bit unsigned int vector 363 VectorUInt8, 364 /// 16 bit signed int vector 365 VectorSInt16, 366 /// 16 bit unsigned int vector 367 VectorUInt16, 368 /// 32 bit signed int vector 369 VectorSInt32, 370 /// 32 bit unsigned int vector 371 VectorUInt32, 372 /// 32 bit floating point vector 373 VectorFloat32, 374 /// 128 bit unsigned int vector 375 VectorUInt128, 376 } 377 378 /// Describes the generic types that most CPUs have. 379 #[non_exhaustive] 380 pub enum Generic { 381 /// Program counter register 382 Pc, 383 /// Stack pointer register 384 Sp, 385 /// Frame pointer register 386 Fp, 387 /// Return address register 388 Ra, 389 /// CPU flags register 390 Flags, 391 /// Function argument 1 392 Arg1, 393 /// Function argument 2 394 Arg2, 395 /// Function argument 3 396 Arg3, 397 /// Function argument 4 398 Arg4, 399 /// Function argument 5 400 Arg5, 401 /// Function argument 6 402 Arg6, 403 /// Function argument 7 404 Arg7, 405 /// Function argument 8 406 Arg8, 407 } 408 } 409