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