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