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 crate::internal::BeBytes; 19 use crate::internal::LeBytes; 20 use core::fmt::Debug; 21 use core::num::NonZeroUsize; 22 use num_traits::FromPrimitive; 23 use num_traits::PrimInt; 24 use num_traits::Unsigned; 25 26 /// Register identifier for target registers. 27 /// 28 /// These identifiers are used by GDB to signal which register to read/wite when 29 /// performing [single register accesses]. 30 /// 31 /// [single register accesses]: 32 /// crate::target::ext::base::single_register_access::SingleRegisterAccess 33 pub trait RegId: Sized + Debug { 34 /// Map raw GDB register number to a corresponding `RegId` and optional 35 /// register size. 36 /// 37 /// If the register size is specified here, gdbstub will include a runtime 38 /// check that ensures target implementations do not send back more 39 /// bytes than the register allows. 40 /// 41 /// Returns `None` if the register is not available. from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)>42 fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)>; 43 } 44 45 /// Stub implementation -- Returns `None` for all raw IDs. 46 impl RegId for () { from_raw_id(_id: usize) -> Option<(Self, Option<NonZeroUsize>)>47 fn from_raw_id(_id: usize) -> Option<(Self, Option<NonZeroUsize>)> { 48 None 49 } 50 } 51 52 /// Methods to read/write architecture-specific registers. 53 /// 54 /// Registers must be de/serialized in the order specified by the architecture's 55 /// `<target>.xml` in the GDB source tree. 56 /// 57 /// e.g: for ARM: 58 /// github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml 59 // TODO: add way to de/serialize arbitrary "missing"/"uncollected" registers. 60 pub trait Registers: Default + Debug + Clone + PartialEq { 61 /// The type of the architecture's program counter / instruction pointer. 62 /// Must match with the corresponding `Arch::Usize`. 63 type ProgramCounter: Copy; 64 65 /// Return the value of the program counter / instruction pointer. pc(&self) -> Self::ProgramCounter66 fn pc(&self) -> Self::ProgramCounter; 67 68 /// Serialize `self` into a GDB register bytestream. 69 /// 70 /// Missing registers are serialized by passing `None` to write_byte. gdb_serialize(&self, write_byte: impl FnMut(Option<u8>))71 fn gdb_serialize(&self, write_byte: impl FnMut(Option<u8>)); 72 73 /// Deserialize a GDB register bytestream into `self`. 74 #[allow(clippy::result_unit_err)] gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()>75 fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()>; 76 } 77 78 /// Breakpoint kind for specific architectures. 79 /// 80 /// This trait corresponds to the _kind_ field of the "z" and "Z" breakpoint 81 /// packets, as documented [here](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#insert-breakpoint-or-watchpoint-packet). 82 /// 83 /// A breakpoint "kind" is architecture-specific and typically indicates the 84 /// size of the breakpoint in bytes that should be inserted. As such, most 85 /// architectures will set `BreakpointKind = usize`. 86 /// 87 /// Some architectures, such as ARM and MIPS, have additional meanings for 88 /// _kind_. See the [Architecture-Specific Protocol Details](https://sourceware.org/gdb/current/onlinedocs/gdb/Architecture_002dSpecific-Protocol-Details.html#Architecture_002dSpecific-Protocol-Details) 89 /// section of the GBD documentation for more details. 90 /// 91 /// If no architecture-specific value is being used, _kind_ should be set to 92 /// '0', and the `BreakpointKind` associated type should be `()`. 93 pub trait BreakpointKind: Sized + Debug { 94 /// Parse `Self` from a raw usize. from_usize(kind: usize) -> Option<Self>95 fn from_usize(kind: usize) -> Option<Self>; 96 } 97 98 impl BreakpointKind for () { from_usize(kind: usize) -> Option<Self>99 fn from_usize(kind: usize) -> Option<Self> { 100 if kind != 0 { 101 None 102 } else { 103 Some(()) 104 } 105 } 106 } 107 108 impl BreakpointKind for usize { 109 #[allow(clippy::wrong_self_convention)] from_usize(kind: usize) -> Option<Self>110 fn from_usize(kind: usize) -> Option<Self> { 111 Some(kind) 112 } 113 } 114 115 /// Encodes architecture-specific information, such as pointer size, register 116 /// layout, etc... 117 /// 118 /// Types implementing `Arch` should be 119 /// [Zero-variant Enums](https://doc.rust-lang.org/reference/items/enumerations.html#zero-variant-enums), 120 /// as `Arch` impls are only ever used at the type level, and should never be 121 /// explicitly instantiated. 122 pub trait Arch { 123 /// The architecture's pointer size (e.g: `u32` on a 32-bit system). 124 type Usize: Debug + FromPrimitive + PrimInt + Unsigned + BeBytes + LeBytes; 125 126 /// The architecture's register file. See [`Registers`] for more details. 127 type Registers: Registers<ProgramCounter = Self::Usize>; 128 129 /// The architecture's breakpoint "kind", used to determine the "size" 130 /// of breakpoint to set. See [`BreakpointKind`] for more details. 131 type BreakpointKind: BreakpointKind; 132 133 /// Register identifier enum/struct. 134 /// 135 /// Used to access individual registers via `Target::read/write_register`. 136 /// 137 /// > NOTE: An arch's `RegId` type is not strictly required to have a 1:1 138 /// correspondence with the `Registers` type, and may include register 139 /// identifiers which are separate from the main `Registers` structure. 140 /// (e.g: the RISC-V Control and Status registers) 141 type RegId: RegId; 142 143 /// (optional) Return the arch's description XML file (`target.xml`). 144 /// 145 /// Implementing this method enables GDB to automatically detect the 146 /// target's architecture, saving the hassle of having to run `set 147 /// architecture <arch>` when starting a debugging session. 148 /// 149 /// These descriptions can be quite succinct. For example, the target 150 /// description for an `armv4t` target can be as simple as: 151 /// 152 /// ``` 153 /// r#"<target version="1.0"><architecture>armv4t</architecture></target>"#; 154 /// ``` 155 /// 156 /// See the [GDB docs](https://sourceware.org/gdb/current/onlinedocs/gdb/Target-Description-Format.html) 157 /// for details on the target description XML format. 158 #[inline(always)] target_description_xml() -> Option<&'static str>159 fn target_description_xml() -> Option<&'static str> { 160 None 161 } 162 163 /// (optional) (LLDB extension) Return register info for the specified 164 /// register. 165 /// 166 /// Implementing this method enables LLDB to dynamically query the target's 167 /// register information one by one. 168 /// 169 /// Some targets don't have register context in the compiled version of the 170 /// debugger. Help the debugger by dynamically supplying the register info 171 /// from the target. The debugger will request the register info in a 172 /// sequential manner till an error packet is received. In LLDB, the 173 /// register info search has the following 174 /// [order](https://github.com/llvm/llvm-project/blob/369ce54bb302f209239b8ebc77ad824add9df089/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp#L397-L402): 175 /// 176 /// 1. Use the target definition python file if one is specified. 177 /// 2. If the target definition doesn't have any of the info from the 178 /// target.xml (registers) then proceed to read the `target.xml`. 179 /// 3. Fall back on the `qRegisterInfo` packets. 180 /// 4. Use hardcoded defaults if available. 181 /// 182 /// See the LLDB [gdb-remote docs](https://github.com/llvm-mirror/lldb/blob/d01083a850f577b85501a0902b52fd0930de72c7/docs/lldb-gdb-remote.txt#L396) 183 /// for more details on the available information that a single register can 184 /// be described by and [#99](https://github.com/daniel5151/gdbstub/issues/99) 185 /// for more information on LLDB compatibility. 186 #[inline(always)] lldb_register_info(reg_id: usize) -> Option<lldb::RegisterInfo<'static>>187 fn lldb_register_info(reg_id: usize) -> Option<lldb::RegisterInfo<'static>> { 188 let _ = reg_id; 189 None 190 } 191 } 192 193 /// LLDB-specific types supporting [`Arch::lldb_register_info`] and 194 /// [`LldbRegisterInfoOverride`] APIs. 195 /// 196 /// [`LldbRegisterInfoOverride`]: crate::target::ext::lldb_register_info_override::LldbRegisterInfoOverride 197 pub mod lldb { 198 /// The architecture's register information of a single register. 199 pub enum RegisterInfo<'a> { 200 /// The register info of a single register that should be written. 201 Register(Register<'a>), 202 /// The `qRegisterInfo` query shall be concluded. 203 Done, 204 } 205 206 /// Describes the register info for a single register of 207 /// the target. 208 pub struct Register<'a> { 209 /// The primary register name. 210 pub name: &'a str, 211 /// An alternate name for the register. 212 pub alt_name: Option<&'a str>, 213 /// Size in bits of a register. 214 pub bitsize: usize, 215 /// The offset within the 'g' and 'G' packet of the register data for 216 /// this register. 217 pub offset: usize, 218 /// The encoding type of the register. 219 pub encoding: Encoding, 220 /// The preferred format for display of this register. 221 pub format: Format, 222 /// The register set name this register belongs to. 223 pub set: &'a str, 224 /// The GCC compiler registers number for this register. 225 /// 226 /// _Note:_ This denotes the same `KEY:VALUE;` pair as `ehframe:VALUE;`. 227 /// See the LLDB [source](https://github.com/llvm/llvm-project/blob/b92436efcb7813fc481b30f2593a4907568d917a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp#L493). 228 pub gcc: Option<usize>, 229 /// The DWARF register number for this register that is used for this 230 /// register in the debug information. 231 pub dwarf: Option<usize>, 232 /// Specify as a generic register. 233 pub generic: Option<Generic>, 234 /// Other concrete register values this register is contained in. 235 pub container_regs: Option<&'a [usize]>, 236 /// Specifies which register values should be invalidated when this 237 /// register is modified. 238 pub invalidate_regs: Option<&'a [usize]>, 239 } 240 241 /// Describes the encoding type of the register. 242 #[non_exhaustive] 243 pub enum Encoding { 244 /// Unsigned integer 245 Uint, 246 /// Signed integer 247 Sint, 248 /// IEEE 754 float 249 IEEE754, 250 /// Vector register 251 Vector, 252 } 253 254 /// Describes the preferred format for display of this register. 255 #[non_exhaustive] 256 pub enum Format { 257 /// Binary format 258 Binary, 259 /// Decimal format 260 Decimal, 261 /// Hexadecimal format 262 Hex, 263 /// Floating point format 264 Float, 265 /// 8 bit signed int vector 266 VectorSInt8, 267 /// 8 bit unsigned int vector 268 VectorUInt8, 269 /// 16 bit signed int vector 270 VectorSInt16, 271 /// 16 bit unsigned int vector 272 VectorUInt16, 273 /// 32 bit signed int vector 274 VectorSInt32, 275 /// 32 bit unsigned int vector 276 VectorUInt32, 277 /// 32 bit floating point vector 278 VectorFloat32, 279 /// 128 bit unsigned int vector 280 VectorUInt128, 281 } 282 283 /// Describes the generic types that most CPUs have. 284 #[non_exhaustive] 285 pub enum Generic { 286 /// Program counter register 287 Pc, 288 /// Stack pointer register 289 Sp, 290 /// Frame pointer register 291 Fp, 292 /// Return address register 293 Ra, 294 /// CPU flags register 295 Flags, 296 /// Function argument 1 297 Arg1, 298 /// Function argument 2 299 Arg2, 300 /// Function argument 3 301 Arg3, 302 /// Function argument 4 303 Arg4, 304 /// Function argument 5 305 Arg5, 306 /// Function argument 6 307 Arg6, 308 /// Function argument 7 309 Arg7, 310 /// Function argument 8 311 Arg8, 312 } 313 } 314