|
1 | 1 | use std::borrow::Cow; |
2 | 2 | use std::collections::HashMap; |
3 | 3 | use icicle_cpu::mem::{Mapping, MemError, perm}; |
4 | | -use icicle_cpu::{ExceptionCode, VmExit}; |
| 4 | +use icicle_cpu::{Cpu, ExceptionCode, ValueSource, VarSource, VmExit}; |
5 | 5 | use pyo3::prelude::*; |
6 | 6 | use icicle_vm; |
7 | | -use icicle_vm::linux::LinuxCpu; |
8 | 7 | use pyo3::exceptions::*; |
9 | 8 | use target_lexicon; |
10 | 9 | use indexmap::IndexMap; |
| 10 | +use target_lexicon::Architecture; |
| 11 | +use icicle_cpu::lifter::InstructionSource; |
11 | 12 | use sleigh_runtime::NamedRegister; |
12 | 13 |
|
13 | 14 | // References: |
14 | 15 | // - https://pyo3.rs/main/conversions/tables |
15 | 16 | // - https://pyo3.rs/main/class |
16 | 17 |
|
| 18 | +struct X86FlagsRegHandler { |
| 19 | + pub eflags: pcode::VarNode, |
| 20 | +} |
| 21 | + |
| 22 | +impl icicle_cpu::RegHandler for X86FlagsRegHandler { |
| 23 | + fn read(&mut self, cpu: &mut Cpu) { |
| 24 | + let eflags = icicle_vm::x86::eflags(cpu); |
| 25 | + cpu.write_var::<u32>(self.eflags, eflags); |
| 26 | + } |
| 27 | + |
| 28 | + fn write(&mut self, cpu: &mut Cpu) { |
| 29 | + let eflags = cpu.read_var::<u32>(self.eflags); |
| 30 | + icicle_vm::x86::set_eflags(cpu, eflags); |
| 31 | + } |
| 32 | +} |
| 33 | + |
17 | 34 | #[pyclass(eq, eq_int, module = "icicle")] |
18 | 35 | #[derive(Clone, Debug, PartialEq)] |
19 | 36 | pub enum MemoryProtection { |
@@ -227,7 +244,7 @@ pub struct Icicle { |
227 | 244 | } |
228 | 245 |
|
229 | 246 | fn reg_find<'a>(i: &'a Icicle, name: &str) -> PyResult<&'a NamedRegister> { |
230 | | - let sleigh = i.vm.cpu.sleigh(); |
| 247 | + let sleigh = &i.vm.cpu.arch.sleigh; |
231 | 248 | match sleigh.get_reg(name) { |
232 | 249 | None => { |
233 | 250 | i.regs.get(name.to_lowercase().as_str()) |
@@ -354,19 +371,29 @@ impl Icicle { |
354 | 371 | config.optimize_instructions = optimize_instructions; |
355 | 372 | config.optimize_block = optimize_block; |
356 | 373 |
|
357 | | - let vm = icicle_vm::build(&config) |
| 374 | + let mut vm = icicle_vm::build(&config) |
358 | 375 | .map_err(|e| { |
359 | 376 | PyException::new_err(format!("VM build error: {e}")) |
360 | 377 | })?; |
361 | 378 |
|
362 | 379 | // Populate the lowercase register map |
363 | 380 | let mut regs = HashMap::new(); |
364 | | - let sleigh = vm.cpu.sleigh(); |
| 381 | + let sleigh = &vm.cpu.arch.sleigh; |
365 | 382 | for reg in &sleigh.named_registers { |
366 | 383 | let name = sleigh.get_str(reg.name); |
367 | 384 | regs.insert(name.to_lowercase(), reg.clone()); |
368 | 385 | } |
369 | 386 |
|
| 387 | + // Special handling for x86 flags |
| 388 | + match config.triple.architecture { |
| 389 | + Architecture::X86_32(_) | Architecture::X86_64 | Architecture::X86_64h => { |
| 390 | + let eflags = sleigh.get_reg("eflags").unwrap().var; |
| 391 | + let reg_handler = X86FlagsRegHandler { eflags }; |
| 392 | + vm.cpu.add_reg_handler(eflags.id, Box::new(reg_handler)); |
| 393 | + } |
| 394 | + _ => {} |
| 395 | + } |
| 396 | + |
370 | 397 | Ok(Icicle { |
371 | 398 | architecture, |
372 | 399 | vm, |
@@ -454,7 +481,7 @@ impl Icicle { |
454 | 481 |
|
455 | 482 | pub fn reg_list(&self) -> PyResult<IndexMap<String, (u32, u8)>> { |
456 | 483 | let mut result = IndexMap::new(); |
457 | | - let sleigh = self.vm.cpu.sleigh(); |
| 484 | + let sleigh = &self.vm.cpu.arch.sleigh; |
458 | 485 | for reg in &sleigh.named_registers { |
459 | 486 | let name = sleigh.get_str(reg.name); |
460 | 487 | result.insert(name.to_string(), (reg.offset, reg.var.size)); |
|
0 commit comments