• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use armv4t_emu::Memory;
2 
3 pub enum AccessKind {
4     Read,
5     Write,
6 }
7 
8 pub struct Access {
9     pub kind: AccessKind,
10     pub addr: u32,
11     pub val: u32,
12     pub len: usize,
13 }
14 
15 /// Wraps a `Memory` object, logging any accesses with the provided callback.
16 #[derive(Debug)]
17 pub struct MemSniffer<'a, M, F: FnMut(Access)> {
18     mem: &'a mut M,
19     addrs: &'a [u32],
20     on_access: F,
21 }
22 
23 impl<'a, M: Memory, F: FnMut(Access)> MemSniffer<'a, M, F> {
new(mem: &'a mut M, addrs: &'a [u32], on_access: F) -> MemSniffer<'a, M, F>24     pub fn new(mem: &'a mut M, addrs: &'a [u32], on_access: F) -> MemSniffer<'a, M, F> {
25         MemSniffer {
26             mem,
27             addrs,
28             on_access,
29         }
30     }
31 }
32 
33 macro_rules! impl_memsniff_r {
34     ($fn:ident, $ret:ty) => {
35         fn $fn(&mut self, addr: u32) -> $ret {
36             let ret = self.mem.$fn(addr);
37             if self.addrs.contains(&addr) {
38                 (self.on_access)(Access {
39                     kind: AccessKind::Read,
40                     addr,
41                     val: ret as u32,
42                     len: ret.to_le_bytes().len(),
43                 });
44             }
45             ret
46         }
47     };
48 }
49 
50 macro_rules! impl_memsniff_w {
51     ($fn:ident, $val:ty) => {
52         fn $fn(&mut self, addr: u32, val: $val) {
53             self.mem.$fn(addr, val);
54             if self.addrs.contains(&addr) {
55                 (self.on_access)(Access {
56                     kind: AccessKind::Write,
57                     addr,
58                     val: val as u32,
59                     len: val.to_le_bytes().len(),
60                 });
61             }
62         }
63     };
64 }
65 
66 impl<'a, M: Memory, F: FnMut(Access)> Memory for MemSniffer<'a, M, F> {
67     impl_memsniff_r!(r8, u8);
68     impl_memsniff_r!(r16, u16);
69     impl_memsniff_r!(r32, u32);
70     impl_memsniff_w!(w8, u8);
71     impl_memsniff_w!(w16, u16);
72     impl_memsniff_w!(w32, u32);
73 }
74