1 use crate::emu::Emu;
2 use gdbstub::target;
3 use gdbstub::target::ext::breakpoints::WatchKind;
4 use gdbstub::target::TargetResult;
5 
6 impl target::ext::breakpoints::Breakpoints for Emu {
7     #[inline(always)]
support_sw_breakpoint( &mut self, ) -> Option<target::ext::breakpoints::SwBreakpointOps<'_, Self>>8     fn support_sw_breakpoint(
9         &mut self,
10     ) -> Option<target::ext::breakpoints::SwBreakpointOps<'_, Self>> {
11         Some(self)
12     }
13 
14     #[inline(always)]
support_hw_watchpoint( &mut self, ) -> Option<target::ext::breakpoints::HwWatchpointOps<'_, Self>>15     fn support_hw_watchpoint(
16         &mut self,
17     ) -> Option<target::ext::breakpoints::HwWatchpointOps<'_, Self>> {
18         Some(self)
19     }
20 }
21 
22 impl target::ext::breakpoints::SwBreakpoint for Emu {
add_sw_breakpoint( &mut self, addr: u32, _kind: gdbstub_arch::arm::ArmBreakpointKind, ) -> TargetResult<bool, Self>23     fn add_sw_breakpoint(
24         &mut self,
25         addr: u32,
26         _kind: gdbstub_arch::arm::ArmBreakpointKind,
27     ) -> TargetResult<bool, Self> {
28         self.breakpoints.push(addr);
29         Ok(true)
30     }
31 
remove_sw_breakpoint( &mut self, addr: u32, _kind: gdbstub_arch::arm::ArmBreakpointKind, ) -> TargetResult<bool, Self>32     fn remove_sw_breakpoint(
33         &mut self,
34         addr: u32,
35         _kind: gdbstub_arch::arm::ArmBreakpointKind,
36     ) -> TargetResult<bool, Self> {
37         match self.breakpoints.iter().position(|x| *x == addr) {
38             None => return Ok(false),
39             Some(pos) => self.breakpoints.remove(pos),
40         };
41 
42         Ok(true)
43     }
44 }
45 
46 impl target::ext::breakpoints::HwWatchpoint for Emu {
add_hw_watchpoint( &mut self, addr: u32, len: u32, kind: WatchKind, ) -> TargetResult<bool, Self>47     fn add_hw_watchpoint(
48         &mut self,
49         addr: u32,
50         len: u32,
51         kind: WatchKind,
52     ) -> TargetResult<bool, Self> {
53         for addr in addr..(addr + len) {
54             match kind {
55                 WatchKind::Write => self.watchpoints.push(addr),
56                 WatchKind::Read => self.watchpoints.push(addr),
57                 WatchKind::ReadWrite => self.watchpoints.push(addr),
58             };
59         }
60 
61         Ok(true)
62     }
63 
remove_hw_watchpoint( &mut self, addr: u32, len: u32, kind: WatchKind, ) -> TargetResult<bool, Self>64     fn remove_hw_watchpoint(
65         &mut self,
66         addr: u32,
67         len: u32,
68         kind: WatchKind,
69     ) -> TargetResult<bool, Self> {
70         for addr in addr..(addr + len) {
71             let pos = match self.watchpoints.iter().position(|x| *x == addr) {
72                 None => return Ok(false),
73                 Some(pos) => pos,
74             };
75 
76             match kind {
77                 WatchKind::Write => self.watchpoints.remove(pos),
78                 WatchKind::Read => self.watchpoints.remove(pos),
79                 WatchKind::ReadWrite => self.watchpoints.remove(pos),
80             };
81         }
82 
83         Ok(true)
84     }
85 }
86