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