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