libafl_qemu cpu_target cfg (#383)

* cpu_target

* report

* track mmap in x64 snapshots
This commit is contained in:
Andrea Fioraldi 2021-11-17 12:50:10 +01:00 committed by GitHub
parent 4d24012245
commit fd5e793e57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 240 additions and 80 deletions

View File

@ -40,7 +40,6 @@ use libafl::{
Error, Error,
}; };
use libafl_qemu::{ use libafl_qemu::{
amd64::Amd64Regs,
asan::QemuAsanHelper, asan::QemuAsanHelper,
cmplog, cmplog,
cmplog::{CmpLogObserver, QemuCmpLogHelper}, cmplog::{CmpLogObserver, QemuCmpLogHelper},
@ -49,7 +48,7 @@ use libafl_qemu::{
elf::EasyElf, elf::EasyElf,
emu, filter_qemu_args, init_with_asan, emu, filter_qemu_args, init_with_asan,
snapshot::QemuSnapshotHelper, snapshot::QemuSnapshotHelper,
MmapPerms, QemuExecutor, MmapPerms, QemuExecutor, Regs,
}; };
/// The fuzzer main /// The fuzzer main
@ -175,10 +174,10 @@ fn fuzz(
println!( println!(
"Break at {:#x}", "Break at {:#x}",
emu::read_reg::<_, u64>(Amd64Regs::Rip).unwrap() emu::read_reg::<_, u64>(Regs::Rip).unwrap()
); );
let stack_ptr: u64 = emu::read_reg(Amd64Regs::Rsp).unwrap(); let stack_ptr: u64 = emu::read_reg(Regs::Rsp).unwrap();
let mut ret_addr = [0u64]; let mut ret_addr = [0u64];
emu::read_mem(stack_ptr, &mut ret_addr); emu::read_mem(stack_ptr, &mut ret_addr);
let ret_addr = ret_addr[0]; let ret_addr = ret_addr[0];
@ -293,10 +292,10 @@ fn fuzz(
emu::write_mem(input_addr, buf); emu::write_mem(input_addr, buf);
emu::write_reg(Amd64Regs::Rdi, input_addr).unwrap(); emu::write_reg(Regs::Rdi, input_addr).unwrap();
emu::write_reg(Amd64Regs::Rsi, len).unwrap(); emu::write_reg(Regs::Rsi, len).unwrap();
emu::write_reg(Amd64Regs::Rip, test_one_input_ptr).unwrap(); emu::write_reg(Regs::Rip, test_one_input_ptr).unwrap();
emu::write_reg(Amd64Regs::Rsp, stack_ptr).unwrap(); emu::write_reg(Regs::Rsp, stack_ptr).unwrap();
emu::run(); emu::run();

View File

@ -32,6 +32,8 @@ fn main() {
"cc".to_owned() "cc".to_owned()
}); });
println!("cargo:rustc-cfg=cpu_target=\"{}\"", cpu_target);
let out_dir = env::var_os("OUT_DIR").unwrap(); let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = out_dir.to_string_lossy().to_string(); let out_dir = out_dir.to_string_lossy().to_string();
let out_dir_path = Path::new(&out_dir); let out_dir_path = Path::new(&out_dir);

View File

@ -6,7 +6,7 @@ use pyo3::prelude::*;
#[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)] #[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)]
#[repr(i32)] #[repr(i32)]
pub enum Aarch64Regs { pub enum Regs {
X0 = 0, X0 = 0,
X1 = 1, X1 = 1,
X2 = 2, X2 = 2,
@ -38,17 +38,20 @@ pub enum Aarch64Regs {
X28 = 28, X28 = 28,
X29 = 29, X29 = 29,
X30 = 30, X30 = 30,
Sp = 31,
Pc = 32,
Pstate = 33,
} }
/// alias registers /// alias registers
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
impl Aarch64Regs { impl Regs {
pub const Fp: Aarch64Regs = Aarch64Regs::X29; pub const Fp: Regs = Regs::X29;
pub const Lr: Aarch64Regs = Aarch64Regs::X30; pub const Lr: Regs = Regs::X30;
} }
#[cfg(feature = "python")] #[cfg(feature = "python")]
impl IntoPy<PyObject> for Aarch64Regs { impl IntoPy<PyObject> for Regs {
fn into_py(self, py: Python) -> PyObject { fn into_py(self, py: Python) -> PyObject {
let n: i32 = self.into(); let n: i32 = self.into();
n.into_py(py) n.into_py(py)

View File

@ -7,7 +7,7 @@ use pyo3::prelude::*;
/// Registers for the ARM instruction set. /// Registers for the ARM instruction set.
#[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)] #[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)]
#[repr(i32)] #[repr(i32)]
pub enum ArmRegs { pub enum Regs {
R0 = 0, R0 = 0,
R1 = 1, R1 = 1,
R2 = 2, R2 = 2,
@ -28,18 +28,18 @@ pub enum ArmRegs {
/// alias registers /// alias registers
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
impl ArmRegs { impl Regs {
pub const Sp: ArmRegs = ArmRegs::R13; pub const Sp: Regs = Regs::R13;
pub const Lr: ArmRegs = ArmRegs::R14; pub const Lr: Regs = Regs::R14;
pub const Pc: ArmRegs = ArmRegs::R15; pub const Pc: Regs = Regs::R15;
pub const Sb: ArmRegs = ArmRegs::R9; pub const Sb: Regs = Regs::R9;
pub const Sl: ArmRegs = ArmRegs::R10; pub const Sl: Regs = Regs::R10;
pub const Fp: ArmRegs = ArmRegs::R11; pub const Fp: Regs = Regs::R11;
pub const Ip: ArmRegs = ArmRegs::R12; pub const Ip: Regs = Regs::R12;
} }
#[cfg(feature = "python")] #[cfg(feature = "python")]
impl IntoPy<PyObject> for ArmRegs { impl IntoPy<PyObject> for Regs {
fn into_py(self, py: Python) -> PyObject { fn into_py(self, py: Python) -> PyObject {
let n: i32 = self.into(); let n: i32 = self.into();
n.into_py(py) n.into_py(py)

View File

@ -1375,7 +1375,7 @@ int asan_giovese_report_and_crash(int access_type, target_ulong addr, size_t n,
"==%d==ABORTING\n", "==%d==ABORTING\n",
getpid()); getpid());
signal(SIGABRT, SIG_DFL); // signal(SIGABRT, SIG_DFL);
abort(); abort();
} }
@ -1491,7 +1491,7 @@ int asan_giovese_badfree(target_ulong addr, target_ulong pc) {
": bad-free %s\n", printable_pc); ": bad-free %s\n", printable_pc);
fprintf(stderr, "==%d==ABORTING\n", getpid()); fprintf(stderr, "==%d==ABORTING\n", getpid());
signal(SIGABRT, SIG_DFL); //signal(SIGABRT, SIG_DFL);
abort(); abort();
} }

View File

@ -1,12 +1,13 @@
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, state::HasMetadata}; use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, state::HasMetadata};
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::{env, fs}; use std::{env, fs, ptr};
use crate::{ use crate::{
emu, emu,
emu::SyscallHookResult, emu::SyscallHookResult,
executor::QemuExecutor, executor::QemuExecutor,
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter}, helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
Regs,
}; };
// TODO at some point, merge parts with libafl_frida // TODO at some point, merge parts with libafl_frida
@ -58,7 +59,7 @@ pub enum PoisonKind {
#[repr(C)] #[repr(C)]
struct CallContext { struct CallContext {
pub addresses: *const u64, pub addresses: *const u64,
pub tid: u32, pub tid: i32,
pub size: u32, pub size: u32,
} }
@ -80,20 +81,35 @@ extern "C" {
fn asan_giovese_store2(ptr: *const u8) -> i32; fn asan_giovese_store2(ptr: *const u8) -> i32;
fn asan_giovese_store4(ptr: *const u8) -> i32; fn asan_giovese_store4(ptr: *const u8) -> i32;
fn asan_giovese_store8(ptr: *const u8) -> i32; fn asan_giovese_store8(ptr: *const u8) -> i32;
// int asan_giovese_loadN(void* ptr, size_t n);
fn asan_giovese_loadN(ptr: *const u8, n: usize) -> i32; fn asan_giovese_loadN(ptr: *const u8, n: usize) -> i32;
// int asan_giovese_storeN(void* ptr, size_t n);
fn asan_giovese_storeN(ptr: *const u8, n: usize) -> i32; fn asan_giovese_storeN(ptr: *const u8, n: usize) -> i32;
// int asan_giovese_poison_region(void* ptr, size_t n, uint8_t poison_byte);
fn asan_giovese_poison_region(ptr: *const u8, n: usize, poison: u8) -> i32; fn asan_giovese_poison_region(ptr: *const u8, n: usize, poison: u8) -> i32;
// int asan_giovese_unpoison_region(void* ptr, size_t n);
fn asan_giovese_unpoison_region(ptr: *const u8, n: usize) -> i32; fn asan_giovese_unpoison_region(ptr: *const u8, n: usize) -> i32;
// struct chunk_info* asan_giovese_alloc_search(target_ulong query);
fn asan_giovese_alloc_search(query: u64) -> *mut ChunkInfo; fn asan_giovese_alloc_search(query: u64) -> *mut ChunkInfo;
// void asan_giovese_alloc_remove(target_ulong start, target_ulong end);
fn asan_giovese_alloc_remove(start: u64, end: u64); fn asan_giovese_alloc_remove(start: u64, end: u64);
// void asan_giovese_alloc_insert(target_ulong start, target_ulong end, struct call_context* alloc_ctx);
fn asan_giovese_alloc_insert(start: u64, end: u64, alloc_ctx: *const CallContext); fn asan_giovese_alloc_insert(start: u64, end: u64, alloc_ctx: *const CallContext);
fn asan_giovese_report_and_crash(
access_type: i32,
addr: u64,
n: usize,
pc: u64,
bp: u64,
sp: u64,
);
fn asan_giovese_badfree(addr: u64, pc: u64);
}
#[no_mangle]
extern "C" fn asan_giovese_printaddr(_addr: u64) -> *const u8 {
// Just addresses ATM
ptr::null()
}
#[no_mangle]
unsafe extern "C" fn asan_giovese_populate_context(ctx: *mut CallContext, _pc: u64) {
let ctx = ctx.as_mut().unwrap();
ctx.tid = libc::gettid() as i32;
ctx.size = 0;
} }
static mut ASAN_INITED: bool = false; static mut ASAN_INITED: bool = false;
@ -201,14 +217,14 @@ impl QemuAsanHelper {
if let Some(ck) = ckinfo.as_mut() { if let Some(ck) = ckinfo.as_mut() {
if ck.start != addr { if ck.start != addr {
// Free not the start of the chunk // Free not the start of the chunk
std::process::abort(); asan_giovese_badfree(addr, emu::read_reg(Regs::Pc).unwrap_or(u64::MAX));
} }
let ctx: *const CallContext = let ctx: *const CallContext =
libc::calloc(core::mem::size_of::<CallContext>(), 1) as *const _; libc::calloc(core::mem::size_of::<CallContext>(), 1) as *const _;
ck.free_ctx = ctx; ck.free_ctx = ctx;
} else { } else {
// Free of wild ptr // Free of wild ptr
std::process::abort(); asan_giovese_badfree(addr, emu::read_reg(Regs::Pc).unwrap_or(u64::MAX));
} }
} }
} }
@ -220,62 +236,152 @@ impl QemuAsanHelper {
} }
pub fn read_1(&mut self, addr: u64) { pub fn read_1(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_load1(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_load1(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
0,
addr,
1,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn read_2(&mut self, addr: u64) { pub fn read_2(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_load2(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_load2(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
0,
addr,
2,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn read_4(&mut self, addr: u64) { pub fn read_4(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_load4(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_load4(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
0,
addr,
4,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn read_8(&mut self, addr: u64) { pub fn read_8(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_load8(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_load8(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
0,
addr,
8,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn read_n(&mut self, addr: u64, size: usize) { pub fn read_n(&mut self, addr: u64, size: usize) {
if self.enabled() && unsafe { asan_giovese_loadN(emu::g2h(addr), size) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_loadN(emu::g2h(addr), size) != 0 {
asan_giovese_report_and_crash(
0,
addr,
size,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn write_1(&mut self, addr: u64) { pub fn write_1(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_store1(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_store1(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
1,
addr,
1,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn write_2(&mut self, addr: u64) { pub fn write_2(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_store2(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_store2(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
1,
addr,
2,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn write_4(&mut self, addr: u64) { pub fn write_4(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_store4(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_store4(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
1,
addr,
4,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn write_8(&mut self, addr: u64) { pub fn write_8(&mut self, addr: u64) {
if self.enabled() && unsafe { asan_giovese_store8(emu::g2h(addr)) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_store8(emu::g2h(addr)) != 0 {
asan_giovese_report_and_crash(
1,
addr,
8,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }
pub fn write_n(&mut self, addr: u64, size: usize) { pub fn write_n(&mut self, addr: u64, size: usize) {
if self.enabled() && unsafe { asan_giovese_storeN(emu::g2h(addr), size) != 0 } { unsafe {
std::process::abort(); if self.enabled() && asan_giovese_storeN(emu::g2h(addr), size) != 0 {
asan_giovese_report_and_crash(
1,
addr,
size,
emu::read_reg(Regs::Pc).unwrap_or(u64::MAX),
0,
emu::read_reg(Regs::Sp).unwrap_or(u64::MAX),
);
}
} }
} }

View File

@ -6,7 +6,7 @@ use pyo3::prelude::*;
#[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)] #[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)]
#[repr(i32)] #[repr(i32)]
pub enum X86Regs { pub enum Regs {
Eax = 0, Eax = 0,
Ebx = 1, Ebx = 1,
Ecx = 2, Ecx = 2,
@ -21,13 +21,13 @@ pub enum X86Regs {
/// alias registers /// alias registers
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
impl X86Regs { impl Regs {
pub const Sp: X86Regs = X86Regs::Esp; pub const Sp: Regs = Regs::Esp;
pub const Pc: X86Regs = X86Regs::Eip; pub const Pc: Regs = Regs::Eip;
} }
#[cfg(feature = "python")] #[cfg(feature = "python")]
impl IntoPy<PyObject> for X86Regs { impl IntoPy<PyObject> for Regs {
fn into_py(self, py: Python) -> PyObject { fn into_py(self, py: Python) -> PyObject {
let n: i32 = self.into(); let n: i32 = self.into();
n.into_py(py) n.into_py(py)

View File

@ -1,9 +1,18 @@
use std::env; use std::env;
pub mod aarch64; pub mod aarch64;
pub mod amd64;
pub mod arm; pub mod arm;
pub mod x86; pub mod i386;
pub mod x86_64;
#[cfg(cpu_target = "aarch64")]
pub use aarch64::*;
#[cfg(cpu_target = "arm")]
pub use arm::*;
#[cfg(cpu_target = "i386")]
pub use i386::*;
#[cfg(cpu_target = "x86_64")]
pub use x86_64::*;
pub mod elf; pub mod elf;
@ -210,19 +219,12 @@ pub fn python_module(py: Python, m: &PyModule) -> PyResult<()> {
emu::remove_hook(addr); emu::remove_hook(addr);
} }
let x86m = PyModule::new(py, "x86")?; let regsm = PyModule::new(py, "regs")?;
for r in x86::X86Regs::iter() { for r in Regs::iter() {
let v: i32 = r.into(); let v: i32 = r.into();
x86m.add(&format!("{:?}", r), v)?; regsm.add(&format!("{:?}", r), v)?;
} }
m.add_submodule(x86m)?; m.add_submodule(regsm)?;
let amd64m = PyModule::new(py, "amd64")?;
for r in amd64::Amd64Regs::iter() {
let v: i32 = r.into();
amd64m.add(&format!("{:?}", r), v)?;
}
m.add_submodule(amd64m)?;
let mmapm = PyModule::new(py, "mmap")?; let mmapm = PyModule::new(py, "mmap")?;
for r in emu::MmapPerms::iter() { for r in emu::MmapPerms::iter() {

View File

@ -1,9 +1,11 @@
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, state::HasMetadata}; use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, state::HasMetadata};
use std::collections::HashMap; use std::collections::HashMap;
#[cfg(cpu_target = "x86_64")]
use crate::TARGET_NR_mmap;
use crate::{ use crate::{
emu, emu,
emu::GuestMaps, emu::{GuestMaps, SyscallHookResult},
executor::QemuExecutor, executor::QemuExecutor,
helper::{QemuHelper, QemuHelperTuple}, helper::{QemuHelper, QemuHelperTuple},
}; };
@ -23,6 +25,7 @@ pub struct QemuSnapshotHelper {
pub pages: HashMap<u64, SnapshotPageInfo>, pub pages: HashMap<u64, SnapshotPageInfo>,
pub dirty: Vec<u64>, pub dirty: Vec<u64>,
pub brk: u64, pub brk: u64,
pub new_maps: Vec<(u64, usize)>,
pub empty: bool, pub empty: bool,
} }
@ -35,6 +38,7 @@ impl QemuSnapshotHelper {
pages: HashMap::default(), pages: HashMap::default(),
dirty: vec![], dirty: vec![],
brk: 0, brk: 0,
new_maps: vec![],
empty: true, empty: true,
} }
} }
@ -101,6 +105,18 @@ impl QemuSnapshotHelper {
} }
} }
emu::set_brk(self.brk); emu::set_brk(self.brk);
self.reset_maps();
}
pub fn add_mapped(&mut self, start: u64, size: usize) {
self.new_maps.push((start, size));
}
pub fn reset_maps(&mut self) {
for (addr, size) in &self.new_maps {
drop(emu::unmap(*addr, *size));
}
self.new_maps.clear();
} }
} }
@ -126,6 +142,11 @@ where
executor.hook_write2_execution(trace_write2_snapshot::<I, QT, S>); executor.hook_write2_execution(trace_write2_snapshot::<I, QT, S>);
executor.hook_write1_execution(trace_write1_snapshot::<I, QT, S>); executor.hook_write1_execution(trace_write1_snapshot::<I, QT, S>);
executor.hook_write_n_execution(trace_write_n_snapshot::<I, QT, S>); executor.hook_write_n_execution(trace_write_n_snapshot::<I, QT, S>);
#[cfg(cpu_target = "x86_64")]
{
executor.hook_syscalls(trace_mmap_snapshot::<I, QT, S>);
}
} }
fn pre_exec(&mut self, _input: &I) { fn pre_exec(&mut self, _input: &I) {
@ -196,3 +217,30 @@ pub fn trace_write_n_snapshot<I, QT, S>(
.unwrap(); .unwrap();
h.access(addr, size); h.access(addr, size);
} }
#[cfg(cpu_target = "x86_64")]
pub fn trace_mmap_snapshot<I, QT, S>(
helpers: &mut QT,
_state: &mut S,
sys_num: i32,
a0: u64,
a1: u64,
_a2: u64,
_a3: u64,
_a4: u64,
_a5: u64,
_a6: u64,
_a7: u64,
) -> SyscallHookResult
where
I: Input,
QT: QemuHelperTuple<I, S>,
{
if sys_num == TARGET_NR_mmap {
let h = helpers
.match_first_type_mut::<QemuSnapshotHelper>()
.unwrap();
h.add_mapped(a0, a1 as usize);
}
SyscallHookResult::new(None)
}

View File

@ -6,7 +6,7 @@ use pyo3::prelude::*;
#[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)] #[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)]
#[repr(i32)] #[repr(i32)]
pub enum Amd64Regs { pub enum Regs {
Rax = 0, Rax = 0,
Rbx = 1, Rbx = 1,
Rcx = 2, Rcx = 2,
@ -29,13 +29,13 @@ pub enum Amd64Regs {
/// alias registers /// alias registers
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
impl Amd64Regs { impl Regs {
pub const Sp: Amd64Regs = Amd64Regs::Rsp; pub const Sp: Regs = Regs::Rsp;
pub const Pc: Amd64Regs = Amd64Regs::Rip; pub const Pc: Regs = Regs::Rip;
} }
#[cfg(feature = "python")] #[cfg(feature = "python")]
impl IntoPy<PyObject> for Amd64Regs { impl IntoPy<PyObject> for Regs {
fn into_py(self, py: Python) -> PyObject { fn into_py(self, py: Python) -> PyObject {
let n: i32 = self.into(); let n: i32 = self.into();
n.into_py(py) n.into_py(py)