(&mut self, addr: u64, buf: &mut [u8])
| 113 | |
| 114 | impl<I: IoMemory> IoMemory for FuzzwareMmioHandler<I> { |
| 115 | fn read(&mut self, addr: u64, buf: &mut [u8]) -> MemResult<()> { |
| 116 | unsafe { fuzzware::reload_fuzz_consumption_timer(self.uc_ptr) }; |
| 117 | |
| 118 | let pc = unsafe { |
| 119 | let ctx = (*self.uc_ptr).ctx.cast::<crate::unicorn_api::Context>().as_mut().unwrap(); |
| 120 | let vm = &mut *ctx.vm; |
| 121 | vm.cpu.read_pc() as u32 |
| 122 | }; |
| 123 | |
| 124 | let key = if self.access_contexts { ((pc as u64) << 32) | addr } else { addr }; |
| 125 | if self.models.is_empty() { |
| 126 | // Avoid doing any extra work if models are not enabled. |
| 127 | return self.source.read(key, buf); |
| 128 | } |
| 129 | |
| 130 | if let Some(model) = self.models.iter().find(|x| x.matches_context(pc as u64, addr)) { |
| 131 | let value = match &model.kind { |
| 132 | &ModelKind::Bitextract { size, left_shift, mask } => { |
| 133 | let mut buf = [0; 4]; |
| 134 | self.source.read(key, &mut buf[..size as usize])?; |
| 135 | (u32::from_le_bytes(buf) << left_shift) & mask |
| 136 | } |
| 137 | ModelKind::Constant { val } => *val, |
| 138 | ModelKind::Set { values } => match values.len() { |
| 139 | 0 => 0, |
| 140 | 1 => values[0], |
| 141 | n => { |
| 142 | let mut buf = [0; 1]; |
| 143 | self.source.read(key, &mut buf)?; |
| 144 | values[buf[0] as usize % n] |
| 145 | } |
| 146 | }, |
| 147 | ModelKind::Passthrough { id } => self.passthrough[*id], |
| 148 | }; |
| 149 | copy_u32(buf, value); |
| 150 | return Ok(()); |
| 151 | } |
| 152 | |
| 153 | // Fallback to unmodeled. |
| 154 | self.source.read(key, buf) |
| 155 | } |
| 156 | |
| 157 | fn write(&mut self, addr: u64, value: &[u8]) -> MemResult<()> { |
| 158 | if self.models.is_empty() || !self.passthrough.is_empty() { |
nothing calls this directly
no test coverage detected