• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Base debugging operations for single threaded targets.
2 
3 use crate::arch::Arch;
4 use crate::common::Signal;
5 use crate::target::{Target, TargetResult};
6 
7 /// Base required debugging operations for single threaded targets.
8 pub trait SingleThreadBase: Target {
9     /// Read the target's registers.
read_registers( &mut self, regs: &mut <Self::Arch as Arch>::Registers, ) -> TargetResult<(), Self>10     fn read_registers(
11         &mut self,
12         regs: &mut <Self::Arch as Arch>::Registers,
13     ) -> TargetResult<(), Self>;
14 
15     /// Write the target's registers.
write_registers(&mut self, regs: &<Self::Arch as Arch>::Registers) -> TargetResult<(), Self>16     fn write_registers(&mut self, regs: &<Self::Arch as Arch>::Registers)
17         -> TargetResult<(), Self>;
18 
19     /// Support for single-register access.
20     /// See [`SingleRegisterAccess`] for more details.
21     ///
22     /// While this is an optional feature, it is **highly recommended** to
23     /// implement it when possible, as it can significantly improve performance
24     /// on certain architectures.
25     ///
26     /// [`SingleRegisterAccess`]:
27     /// super::single_register_access::SingleRegisterAccess
28     #[inline(always)]
support_single_register_access( &mut self, ) -> Option<super::single_register_access::SingleRegisterAccessOps<'_, (), Self>>29     fn support_single_register_access(
30         &mut self,
31     ) -> Option<super::single_register_access::SingleRegisterAccessOps<'_, (), Self>> {
32         None
33     }
34 
35     /// Read bytes from the specified address range.
36     ///
37     /// If the requested address range could not be accessed (e.g: due to
38     /// MMU protection, unhanded page fault, etc...), an appropriate
39     /// non-fatal error should be returned.
read_addrs( &mut self, start_addr: <Self::Arch as Arch>::Usize, data: &mut [u8], ) -> TargetResult<(), Self>40     fn read_addrs(
41         &mut self,
42         start_addr: <Self::Arch as Arch>::Usize,
43         data: &mut [u8],
44     ) -> TargetResult<(), Self>;
45 
46     /// Write bytes to the specified address range.
47     ///
48     /// If the requested address range could not be accessed (e.g: due to
49     /// MMU protection, unhanded page fault, etc...), an appropriate
50     /// non-fatal error should be returned.
write_addrs( &mut self, start_addr: <Self::Arch as Arch>::Usize, data: &[u8], ) -> TargetResult<(), Self>51     fn write_addrs(
52         &mut self,
53         start_addr: <Self::Arch as Arch>::Usize,
54         data: &[u8],
55     ) -> TargetResult<(), Self>;
56 
57     /// Support for resuming the target (e.g: via `continue` or `step`)
58     #[inline(always)]
support_resume(&mut self) -> Option<SingleThreadResumeOps<'_, Self>>59     fn support_resume(&mut self) -> Option<SingleThreadResumeOps<'_, Self>> {
60         None
61     }
62 }
63 
64 /// Target extension - support for resuming single threaded targets.
65 pub trait SingleThreadResume: Target {
66     /// Resume execution on the target.
67     ///
68     /// The GDB client may also include a `signal` which should be passed to the
69     /// target.
70     ///
71     /// # Additional Considerations
72     ///
73     /// ### Adjusting PC after a breakpoint is hit
74     ///
75     /// The [GDB remote serial protocol documentation](https://sourceware.org/gdb/current/onlinedocs/gdb/Stop-Reply-Packets.html#swbreak-stop-reason)
76     /// notes the following:
77     ///
78     /// > On some architectures, such as x86, at the architecture level, when a
79     /// > breakpoint instruction executes the program counter points at the
80     /// > breakpoint address plus an offset. On such targets, the stub is
81     /// > responsible for adjusting the PC to point back at the breakpoint
82     /// > address.
83     ///
84     /// Omitting PC adjustment may result in unexpected execution flow and/or
85     /// breakpoints not appearing to work correctly.
resume(&mut self, signal: Option<Signal>) -> Result<(), Self::Error>86     fn resume(&mut self, signal: Option<Signal>) -> Result<(), Self::Error>;
87 
88     /// Support for optimized [single stepping].
89     ///
90     /// [single stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#index-stepi
91     #[inline(always)]
support_single_step(&mut self) -> Option<SingleThreadSingleStepOps<'_, Self>>92     fn support_single_step(&mut self) -> Option<SingleThreadSingleStepOps<'_, Self>> {
93         None
94     }
95 
96     /// Support for optimized [range stepping].
97     ///
98     /// [range stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping
99     #[inline(always)]
support_range_step(&mut self) -> Option<SingleThreadRangeSteppingOps<'_, Self>>100     fn support_range_step(&mut self) -> Option<SingleThreadRangeSteppingOps<'_, Self>> {
101         None
102     }
103 
104     /// Support for [reverse stepping] a target.
105     ///
106     /// [reverse stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html
107     #[inline(always)]
support_reverse_step( &mut self, ) -> Option<super::reverse_exec::ReverseStepOps<'_, (), Self>>108     fn support_reverse_step(
109         &mut self,
110     ) -> Option<super::reverse_exec::ReverseStepOps<'_, (), Self>> {
111         None
112     }
113 
114     /// Support for [reverse continuing] a target.
115     ///
116     /// [reverse continuing]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html
117     #[inline(always)]
support_reverse_cont( &mut self, ) -> Option<super::reverse_exec::ReverseContOps<'_, (), Self>>118     fn support_reverse_cont(
119         &mut self,
120     ) -> Option<super::reverse_exec::ReverseContOps<'_, (), Self>> {
121         None
122     }
123 }
124 
125 define_ext!(SingleThreadResumeOps, SingleThreadResume);
126 
127 /// Target Extension - Optimized single stepping for single threaded targets.
128 /// See [`SingleThreadResume::support_single_step`].
129 pub trait SingleThreadSingleStep: Target + SingleThreadResume {
130     /// [Single step] the target.
131     ///
132     /// Single stepping will step the target a single "step" - typically a
133     /// single instruction.
134     /// The GDB client may also include a `signal` which should be passed to the
135     /// target.
136     ///
137     /// [Single step]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#index-stepi
step(&mut self, signal: Option<Signal>) -> Result<(), Self::Error>138     fn step(&mut self, signal: Option<Signal>) -> Result<(), Self::Error>;
139 }
140 
141 define_ext!(SingleThreadSingleStepOps, SingleThreadSingleStep);
142 
143 /// Target Extension - Optimized range stepping for single threaded targets.
144 /// See [`SingleThreadResume::support_range_step`].
145 pub trait SingleThreadRangeStepping: Target + SingleThreadResume {
146     /// [Range step] the target.
147     ///
148     /// Range Stepping will step the target once, and keep stepping the target
149     /// as long as execution remains between the specified start (inclusive)
150     /// and end (exclusive) addresses, or another stop condition is met
151     /// (e.g: a breakpoint it hit).
152     ///
153     /// If the range is empty (`start` == `end`), then the action becomes
154     /// equivalent to the ‘s’ action. In other words, single-step once, and
155     /// report the stop (even if the stepped instruction jumps to start).
156     ///
157     /// _Note:_ A stop reply may be sent at any point even if the PC is still
158     /// within the stepping range; for example, it is valid to implement range
159     /// stepping in a degenerate way as a single instruction step operation.
160     ///
161     /// [Range step]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping
resume_range_step( &mut self, start: <Self::Arch as Arch>::Usize, end: <Self::Arch as Arch>::Usize, ) -> Result<(), Self::Error>162     fn resume_range_step(
163         &mut self,
164         start: <Self::Arch as Arch>::Usize,
165         end: <Self::Arch as Arch>::Usize,
166     ) -> Result<(), Self::Error>;
167 }
168 
169 define_ext!(SingleThreadRangeSteppingOps, SingleThreadRangeStepping);
170