(data: &mut Self, cpu: &mut Cpu, addr: u64)
| 89 | |
| 90 | impl HookHandler for PathTracer { |
| 91 | fn call(data: &mut Self, cpu: &mut Cpu, addr: u64) { |
| 92 | // Avoid using up too much memory if we end up with an extremely long execution. |
| 93 | if data.blocks.len() > 0x100_0000 { |
| 94 | data.blocks.truncate(0); |
| 95 | } |
| 96 | |
| 97 | let handler = cpu.mem.get_io_memory_mut(data.mmio_handler).as_any(); |
| 98 | |
| 99 | let mut offset = 0; |
| 100 | let mut last_read = 0; |
| 101 | let mut last_value = 0; |
| 102 | if let Some(handler) = handler.downcast_ref::<FuzzwareMmioHandler<GlobalMmioSource>>() { |
| 103 | offset = handler.source.offset; |
| 104 | } |
| 105 | if let Some(handler) = handler.downcast_ref::<FuzzwareMmioHandler<MultiStream>>() { |
| 106 | offset = handler.source.bytes_read(); |
| 107 | if let Some(tracer) = handler |
| 108 | .source |
| 109 | .tracer |
| 110 | .as_ref() |
| 111 | .and_then(|x| x.as_any().downcast_ref::<MultiStreamTracer>()) |
| 112 | { |
| 113 | (last_read, last_value) = |
| 114 | tracer.reads.last().map_or((0, 0), |(addr, value, _)| (*addr, *value)) |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | let icount = cpu.icount(); |
| 119 | if let Some(prev) = data.blocks.last().map(|prev| prev.icount) { |
| 120 | debug_assert!(icount >= prev, "icount went backwards! (was: {prev}, now: {icount})"); |
| 121 | } |
| 122 | data.blocks.push(TraceEntry { |
| 123 | pc: addr, |
| 124 | sp: cpu.read_reg(cpu.arch.reg_sp), |
| 125 | icount, |
| 126 | fuzz_offset: offset as u32, |
| 127 | last_read: last_read as u32, |
| 128 | last_value: last_value as u32, |
| 129 | }) |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | pub fn add_path_tracer(vm: &mut icicle_vm::Vm, mmio: IoHandler) -> anyhow::Result<PathTracerRef> { |
nothing calls this directly
no test coverage detected