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