|
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