From c3d536eac6c1f1567cde7e8fff1b9e4056215806 Mon Sep 17 00:00:00 2001 From: Rubens Brandao Date: Thu, 16 May 2024 15:13:35 -0300 Subject: [PATCH 1/2] Create types to represent Architecture ids, avoiding naked u32 --- arch/riscv/src/lib.rs | 109 +++++------ rust/examples/pdb-ng/src/symbol_parser.rs | 4 +- rust/src/architecture.rs | 224 ++++++++++++---------- rust/src/callingconvention.rs | 52 ++--- rust/src/llil/lifting.rs | 29 +-- rust/src/llil/mod.rs | 5 +- rust/src/llil/operation.rs | 19 +- 7 files changed, 231 insertions(+), 211 deletions(-) diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs index 91a418f7e..31790b6d2 100644 --- a/arch/riscv/src/lib.rs +++ b/arch/riscv/src/lib.rs @@ -9,6 +9,7 @@ use std::fmt; use std::hash::Hash; use std::marker::PhantomData; +use binaryninja::architecture::{IntrinsicId, RegisterId}; use binaryninja::relocation::{Relocation, RelocationHandlerExt}; use binaryninja::{ add_optional_plugin_dependency, architecture, @@ -81,7 +82,7 @@ enum Intrinsic { #[derive(Copy, Clone)] struct Register { - id: u32, + id: RegisterId, _dis: PhantomData, } @@ -92,7 +93,7 @@ struct RiscVIntrinsic { } impl Register { - fn new(id: u32) -> Self { + fn new(id: RegisterId) -> Self { Self { id, _dis: PhantomData, @@ -102,10 +103,10 @@ impl Register { fn reg_type(&self) -> RegType { let int_reg_count = ::int_reg_count(); - if self.id < int_reg_count { - RegType::Integer(self.id) + if self.id.0 < int_reg_count { + RegType::Integer(self.id.0) } else { - RegType::Float(self.id - int_reg_count) + RegType::Float(self.id.0 - int_reg_count) } } } @@ -113,7 +114,7 @@ impl Register { impl From> for Register { fn from(reg: riscv_dis::IntReg) -> Self { Self { - id: reg.id(), + id: RegisterId(reg.id()), _dis: PhantomData, } } @@ -124,7 +125,7 @@ impl From> for Register { let int_reg_count = ::int_reg_count(); Self { - id: reg.id() + int_reg_count, + id: RegisterId(reg.id() + int_reg_count), _dis: PhantomData, } } @@ -191,7 +192,7 @@ impl architecture::Register for Register { *self } - fn id(&self) -> u32 { + fn id(&self) -> RegisterId { self.id } } @@ -268,7 +269,12 @@ impl fmt::Debug for Register { } impl RiscVIntrinsic { - fn id_from_parts(id: u32, sz1: Option, sz2: Option, rm: Option) -> u32 { + fn id_from_parts( + id: u32, + sz1: Option, + sz2: Option, + rm: Option, + ) -> IntrinsicId { let sz1 = sz1.unwrap_or(0); let sz2 = sz2.unwrap_or(0); let rm = match rm { @@ -284,13 +290,13 @@ impl RiscVIntrinsic { id |= sz1 as u32; id |= (sz2 as u32) << 8; id |= (rm as u32) << 16; - id + IntrinsicId(id) } - fn parts_from_id(id: u32) -> Option<(u32, u8, u8, RoundMode)> { - let sz1 = (id & 0xff) as u8; - let sz2 = ((id >> 8) & 0xff) as u8; - let rm = match (id >> 16) & 0xf { + fn parts_from_id(id: IntrinsicId) -> Option<(u32, u8, u8, RoundMode)> { + let sz1 = (id.0 & 0xff) as u8; + let sz2 = ((id.0 >> 8) & 0xff) as u8; + let rm = match (id.0 >> 16) & 0xf { 0 => RoundMode::Dynamic, 1 => RoundMode::RoundNearestEven, 2 => RoundMode::RoundTowardZero, @@ -299,10 +305,10 @@ impl RiscVIntrinsic { 5 => RoundMode::RoundMaxMagnitude, _ => return None, }; - Some(((id >> 20) & 0xfff, sz1, sz2, rm)) + Some(((id.0 >> 20) & 0xfff, sz1, sz2, rm)) } - fn from_id(id: u32) -> Option> { + fn from_id(id: IntrinsicId) -> Option> { match Self::parts_from_id(id) { Some((0, _, _, _)) => Some(Intrinsic::Uret.into()), Some((1, _, _, _)) => Some(Intrinsic::Sret.into()), @@ -467,7 +473,7 @@ impl architecture::Intrinsic for RiscVIntrinsic { } } - fn id(&self) -> u32 { + fn id(&self) -> IntrinsicId { match self.id { Intrinsic::Uret => Self::id_from_parts(0, None, None, None), Intrinsic::Sret => Self::id_from_parts(1, None, None, None), @@ -1083,7 +1089,7 @@ impl architecture::Architecture fo ($op:ident, $t:expr, $f:expr) => {{ let rd = Register::from($op.rd()); match rd.id { - 0 => $f.append(), + RegisterId(0) => $f.append(), _ => il.set_reg(rd.size(), rd, $t).append(), } }}; @@ -1833,13 +1839,9 @@ impl architecture::Architecture fo reg_count += 32; } - let mut res = Vec::with_capacity(reg_count as usize); - - for i in 0..reg_count { - res.push(Register::new(i)); - } - - res + (0..reg_count) + .map(|i| Register::new(RegisterId(i))) + .collect() } fn registers_full_width(&self) -> Vec { @@ -1847,31 +1849,25 @@ impl architecture::Architecture fo } fn registers_global(&self) -> Vec { - let mut regs = Vec::with_capacity(2); - - for i in &[3, 4] { - regs.push(Register::new(*i)); - } - - regs + vec![Register::new(RegisterId(3)), Register::new(RegisterId(4))] } fn stack_pointer_reg(&self) -> Option { - Some(Register::new(2)) + Some(Register::new(RegisterId(2))) } fn link_reg(&self) -> Option { - Some(Register::new(1)) + Some(Register::new(RegisterId(1))) } - fn register_from_id(&self, id: u32) -> Option { + fn register_from_id(&self, id: RegisterId) -> Option { let mut reg_count = ::int_reg_count(); if ::Float::present() { reg_count += 32; } - if id > reg_count { + if id.0 > reg_count { None } else { Some(Register::new(id)) @@ -1951,7 +1947,7 @@ impl architecture::Architecture fo res.iter().map(|i| (*i).into()).collect() } - fn intrinsic_from_id(&self, id: u32) -> Option { + fn intrinsic_from_id(&self, id: IntrinsicId) -> Option { RiscVIntrinsic::from_id(id) } @@ -2632,7 +2628,7 @@ impl CallingConventionBase for Ris 1u32, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 28, 29, 30, 31, ] { if i < &int_reg_count { - regs.push(Register::new(*i)); + regs.push(Register::new(RegisterId(*i))); } } @@ -2640,7 +2636,7 @@ impl CallingConventionBase for Ris for i in &[ 0u32, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 28, 29, 30, 31, ] { - regs.push(Register::new(*i + int_reg_count)); + regs.push(Register::new(RegisterId(*i + int_reg_count))); } } @@ -2653,13 +2649,13 @@ impl CallingConventionBase for Ris for i in &[8u32, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27] { if i < &int_reg_count { - regs.push(Register::new(*i)); + regs.push(Register::new(RegisterId(*i))); } } if ::Float::present() { for i in &[8u32, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27] { - regs.push(Register::new(*i + int_reg_count)); + regs.push(Register::new(RegisterId(*i + int_reg_count))); } } @@ -2667,29 +2663,20 @@ impl CallingConventionBase for Ris } fn int_arg_registers(&self) -> Vec> { - let mut regs = Vec::with_capacity(8); let int_reg_count = ::int_reg_count(); - - for i in &[10, 11, 12, 13, 14, 15, 16, 17] { - if i < &int_reg_count { - regs.push(Register::new(*i)); - } - } - - regs + (10..=17) + .filter(|i| i < &int_reg_count) + .map(|i| Register::new(RegisterId(i))) + .collect() } fn float_arg_registers(&self) -> Vec> { - let mut regs = Vec::with_capacity(8); - if ::Float::present() { let int_reg_count = ::int_reg_count(); - for i in &[10, 11, 12, 13, 14, 15, 16, 17] { - regs.push(Register::new(*i + int_reg_count)); - } + (10..=17).map(|i| Register::new(RegisterId(i + int_reg_count))).collect() + } else { + vec![] } - - regs } fn arg_registers_shared_index(&self) -> bool { @@ -2709,17 +2696,17 @@ impl CallingConventionBase for Ris // a0 == x10 fn return_int_reg(&self) -> Option> { - Some(Register::new(10)) + Some(Register::new(RegisterId(10))) } // a1 == x11 fn return_hi_int_reg(&self) -> Option> { - Some(Register::new(11)) + Some(Register::new(RegisterId(11))) } fn return_float_reg(&self) -> Option> { if ::Float::present() { let int_reg_count = ::int_reg_count(); - Some(Register::new(10 + int_reg_count)) + Some(Register::new(RegisterId(10 + int_reg_count))) } else { None } @@ -2727,7 +2714,7 @@ impl CallingConventionBase for Ris // gp == x3 fn global_pointer_reg(&self) -> Option> { - Some(Register::new(3)) + Some(Register::new(RegisterId(3))) } fn implicitly_defined_registers(&self) -> Vec> { diff --git a/rust/examples/pdb-ng/src/symbol_parser.rs b/rust/examples/pdb-ng/src/symbol_parser.rs index 7f418747f..d733d95e1 100644 --- a/rust/examples/pdb-ng/src/symbol_parser.rs +++ b/rust/examples/pdb-ng/src/symbol_parser.rs @@ -2010,13 +2010,13 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { self.log(|| format!("Register {:?} ==> {:?}", reg, xreg)); self.arch .register_by_name(xreg.to_string().to_lowercase()) - .map(|reg| reg.id() as i64) + .map(|reg| reg.id().0 as i64) } Some(AMD64(areg)) => { self.log(|| format!("Register {:?} ==> {:?}", reg, areg)); self.arch .register_by_name(areg.to_string().to_lowercase()) - .map(|reg| reg.id() as i64) + .map(|reg| reg.id().0 as i64) } // TODO: Other arches _ => None, diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index 713e8bf1e..d1f413c51 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -190,6 +190,13 @@ pub trait RegisterInfo: Sized { fn implicit_extend(&self) -> ImplicitRegisterExtend; } +pub trait ArchitectureFromId { + type Output: Sized; + fn into_value(self, arch: &A) -> Option; +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct RegisterId(pub u32); pub trait Register: Sized + Clone + Copy + Hash + Eq { type InfoType: RegisterInfo; @@ -199,7 +206,7 @@ pub trait Register: Sized + Clone + Copy + Hash + Eq { /// Unique identifier for this `Register`. /// /// *MUST* be in the range [0, 0x7fff_ffff] - fn id(&self) -> u32; + fn id(&self) -> RegisterId; } pub trait RegisterStackInfo: Sized { @@ -212,6 +219,8 @@ pub trait RegisterStackInfo: Sized { fn stack_top_reg(&self) -> Self::RegType; } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct RegisterStackId(pub u32); pub trait RegisterStack: Sized + Clone + Copy { type InfoType: RegisterStackInfo< RegType = Self::RegType, @@ -227,9 +236,11 @@ pub trait RegisterStack: Sized + Clone + Copy { /// Unique identifier for this `RegisterStack`. /// /// *MUST* be in the range [0, 0x7fff_ffff] - fn id(&self) -> u32; + fn id(&self) -> RegisterStackId; } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct FlagId(pub u32); pub trait Flag: Sized + Clone + Copy + Hash + Eq { type FlagClass: FlagClass; @@ -239,9 +250,11 @@ pub trait Flag: Sized + Clone + Copy + Hash + Eq { /// Unique identifier for this `Flag`. /// /// *MUST* be in the range [0, 0x7fff_ffff] - fn id(&self) -> u32; + fn id(&self) -> FlagId; } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct FlagWriteId(pub u32); pub trait FlagWrite: Sized + Clone + Copy { type FlagType: Flag; type FlagClass: FlagClass; @@ -253,11 +266,13 @@ pub trait FlagWrite: Sized + Clone + Copy { /// /// *MUST NOT* be 0. /// *MUST* be in the range [1, 0x7fff_ffff] - fn id(&self) -> u32; + fn id(&self) -> FlagWriteId; fn flags_written(&self) -> Vec; } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct FlagClassId(pub u32); pub trait FlagClass: Sized + Clone + Copy + Hash + Eq { fn name(&self) -> Cow; @@ -265,9 +280,11 @@ pub trait FlagClass: Sized + Clone + Copy + Hash + Eq { /// /// *MUST NOT* be 0. /// *MUST* be in the range [1, 0x7fff_ffff] - fn id(&self) -> u32; + fn id(&self) -> FlagClassId; } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct FlagGroupId(pub u32); pub trait FlagGroup: Sized + Clone + Copy { type FlagType: Flag; type FlagClass: FlagClass; @@ -277,7 +294,7 @@ pub trait FlagGroup: Sized + Clone + Copy { /// Unique identifier for this `FlagGroup`. /// /// *MUST* be in the range [0, 0x7fff_ffff] - fn id(&self) -> u32; + fn id(&self) -> FlagGroupId; /// Returns the list of flags that need to be resolved in order /// to take the clean flag resolution path -- at time of writing, @@ -306,11 +323,13 @@ pub trait FlagGroup: Sized + Clone + Copy { fn flag_conditions(&self) -> HashMap; } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct IntrinsicId(pub u32); pub trait Intrinsic: Sized + Clone + Copy { fn name(&self) -> Cow; /// Unique identifier for this `Intrinsic`. - fn id(&self) -> u32; + fn id(&self) -> IntrinsicId; /// Reeturns the list of the input names and types for this intrinsic. fn inputs(&self) -> Vec>; @@ -465,22 +484,22 @@ pub trait Architecture: 'static + Sized + AsRef { None } - fn register_from_id(&self, id: u32) -> Option; + fn register_from_id(&self, id: RegisterId) -> Option; - fn register_stack_from_id(&self, _id: u32) -> Option { + fn register_stack_from_id(&self, _id: RegisterStackId) -> Option { None } - fn flag_from_id(&self, _id: u32) -> Option { + fn flag_from_id(&self, _id: FlagId) -> Option { None } - fn flag_write_from_id(&self, _id: u32) -> Option { + fn flag_write_from_id(&self, _id: FlagWriteId) -> Option { None } - fn flag_class_from_id(&self, _id: u32) -> Option { + fn flag_class_from_id(&self, _id: FlagClassId) -> Option { None } - fn flag_group_from_id(&self, _id: u32) -> Option { + fn flag_group_from_id(&self, _id: FlagGroupId) -> Option { None } @@ -490,7 +509,7 @@ pub trait Architecture: 'static + Sized + AsRef { fn intrinsic_class(&self, _id: u32) -> binaryninjacore_sys::BNIntrinsicClass { binaryninjacore_sys::BNIntrinsicClass::GeneralIntrinsicClass } - fn intrinsic_from_id(&self, _id: u32) -> Option { + fn intrinsic_from_id(&self, _id: IntrinsicId) -> Option { None } @@ -571,7 +590,7 @@ impl RegisterStack for UnusedRegisterStack { fn name(&self) -> Cow { unreachable!() } - fn id(&self) -> u32 { + fn id(&self) -> RegisterStackId { unreachable!() } fn info(&self) -> Self::InfoType { @@ -591,7 +610,7 @@ impl Flag for UnusedFlag { fn role(&self, _class: Option) -> FlagRole { unreachable!() } - fn id(&self) -> u32 { + fn id(&self) -> FlagId { unreachable!() } } @@ -605,7 +624,7 @@ impl FlagWrite for UnusedFlag { fn class(&self) -> Option { unreachable!() } - fn id(&self) -> u32 { + fn id(&self) -> FlagWriteId { unreachable!() } fn flags_written(&self) -> Vec { @@ -617,7 +636,7 @@ impl FlagClass for UnusedFlag { fn name(&self) -> Cow { unreachable!() } - fn id(&self) -> u32 { + fn id(&self) -> FlagClassId { unreachable!() } } @@ -628,7 +647,7 @@ impl FlagGroup for UnusedFlag { fn name(&self) -> Cow { unreachable!() } - fn id(&self) -> u32 { + fn id(&self) -> FlagGroupId { unreachable!() } fn flags_required(&self) -> Vec { @@ -647,7 +666,7 @@ impl Intrinsic for UnusedIntrinsic { fn name(&self) -> Cow { unreachable!() } - fn id(&self) -> u32 { + fn id(&self) -> IntrinsicId { unreachable!() } fn inputs(&self) -> Vec> { @@ -710,8 +729,8 @@ impl Register for CoreRegister { }) } - fn id(&self) -> u32 { - self.1 + fn id(&self) -> RegisterId { + RegisterId(self.1) } } @@ -775,8 +794,8 @@ impl RegisterStack for CoreRegisterStack { }) } - fn id(&self) -> u32 { - self.1 + fn id(&self) -> RegisterStackId { + RegisterStackId(self.1) } } @@ -810,8 +829,8 @@ impl Flag for CoreFlag { unsafe { BNGetArchitectureFlagRole(self.0, self.1, class_id) } } - fn id(&self) -> u32 { - self.1 + fn id(&self) -> FlagId { + FlagId(self.1) } } @@ -837,8 +856,8 @@ impl FlagWrite for CoreFlagWrite { } } - fn id(&self) -> u32 { - self.1 + fn id(&self) -> FlagWriteId { + FlagWriteId(self.1) } fn flags_written(&self) -> Vec { @@ -890,8 +909,8 @@ impl FlagClass for CoreFlagClass { } } - fn id(&self) -> u32 { - self.1 + fn id(&self) -> FlagClassId { + FlagClassId(self.1) } } @@ -917,8 +936,8 @@ impl FlagGroup for CoreFlagGroup { } } - fn id(&self) -> u32 { - self.1 + fn id(&self) -> FlagGroupId { + FlagGroupId(self.1) } fn flags_required(&self) -> Vec { @@ -988,8 +1007,8 @@ impl Intrinsic for crate::architecture::CoreIntrinsic { } } - fn id(&self) -> u32 { - self.1 + fn id(&self) -> IntrinsicId { + IntrinsicId(self.1) } fn inputs(&self) -> Vec> { @@ -1368,7 +1387,7 @@ impl Architecture for CoreArchitecture { condition: FlagCondition, class: Option, ) -> Vec { - let class_id = class.map(|c| c.id()).unwrap_or(0); + let class_id = class.map(|c| c.id().0).unwrap_or(0); unsafe { let mut count: usize = 0; @@ -1404,34 +1423,34 @@ impl Architecture for CoreArchitecture { } } - fn register_from_id(&self, id: u32) -> Option { + fn register_from_id(&self, id: RegisterId) -> Option { // TODO validate in debug builds - Some(CoreRegister(self.0, id)) + Some(CoreRegister(self.0, id.0)) } - fn register_stack_from_id(&self, id: u32) -> Option { + fn register_stack_from_id(&self, id: RegisterStackId) -> Option { // TODO validate in debug builds - Some(CoreRegisterStack(self.0, id)) + Some(CoreRegisterStack(self.0, id.0)) } - fn flag_from_id(&self, id: u32) -> Option { + fn flag_from_id(&self, id: FlagId) -> Option { // TODO validate in debug builds - Some(CoreFlag(self.0, id)) + Some(CoreFlag(self.0, id.0)) } - fn flag_write_from_id(&self, id: u32) -> Option { + fn flag_write_from_id(&self, id: FlagWriteId) -> Option { // TODO validate in debug builds - Some(CoreFlagWrite(self.0, id)) + Some(CoreFlagWrite(self.0, id.0)) } - fn flag_class_from_id(&self, id: u32) -> Option { + fn flag_class_from_id(&self, id: FlagClassId) -> Option { // TODO validate in debug builds - Some(CoreFlagClass(self.0, id)) + Some(CoreFlagClass(self.0, id.0)) } - fn flag_group_from_id(&self, id: u32) -> Option { + fn flag_group_from_id(&self, id: FlagGroupId) -> Option { // TODO validate in debug builds - Some(CoreFlagGroup(self.0, id)) + Some(CoreFlagGroup(self.0, id.0)) } fn intrinsics(&self) -> Vec { @@ -1454,9 +1473,9 @@ impl Architecture for CoreArchitecture { unsafe { BNGetArchitectureIntrinsicClass(self.0, id) } } - fn intrinsic_from_id(&self, id: u32) -> Option { + fn intrinsic_from_id(&self, id: IntrinsicId) -> Option { // TODO validate in debug builds - Some(CoreIntrinsic(self.0, id)) + Some(CoreIntrinsic(self.0, id.0)) } fn can_assemble(&self) -> bool { @@ -1591,7 +1610,7 @@ pub trait ArchitectureExt: Architecture { BNGetArchitectureRegisterByName(self.as_ref().0, name.as_ref().as_ptr() as *mut _) } { 0xffff_ffff => None, - reg => self.register_from_id(reg), + reg => self.register_from_id(RegisterId(reg)), } } @@ -1865,7 +1884,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - match custom_arch.register_from_id(reg) { + match custom_arch.register_from_id(RegisterId(reg)) { Some(reg) => BnString::new(reg.name().as_ref()).into_raw(), None => BnString::new("invalid_reg").into_raw(), } @@ -1877,7 +1896,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - match custom_arch.flag_from_id(flag) { + match custom_arch.flag_from_id(FlagId(flag)) { Some(flag) => BnString::new(flag.name().as_ref()).into_raw(), None => BnString::new("invalid_flag").into_raw(), } @@ -1889,7 +1908,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - match custom_arch.flag_write_from_id(flag_write) { + match custom_arch.flag_write_from_id(FlagWriteId(flag_write)) { Some(flag_write) => BnString::new(flag_write.name().as_ref()).into_raw(), None => BnString::new("invalid_flag_write").into_raw(), } @@ -1901,7 +1920,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - match custom_arch.flag_class_from_id(class) { + match custom_arch.flag_class_from_id(FlagClassId(class)) { Some(class) => BnString::new(class.name().as_ref()).into_raw(), None => BnString::new("invalid_flag_class").into_raw(), } @@ -1913,16 +1932,18 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - match custom_arch.flag_group_from_id(group) { + match custom_arch.flag_group_from_id(FlagGroupId(group)) { Some(group) => BnString::new(group.name().as_ref()).into_raw(), None => BnString::new("invalid_flag_group").into_raw(), } } - fn alloc_register_list + ExactSizeIterator>( - items: I, - count: &mut usize, - ) -> *mut u32 { + fn alloc_ids_list(items: I, count: &mut usize) -> *mut u32 + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { + let items = items.into_iter(); let len = items.len(); *count = len; @@ -1945,7 +1966,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_full_width(); - alloc_register_list(regs.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(regs.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_registers_all(ctxt: *mut c_void, count: *mut usize) -> *mut u32 @@ -1955,7 +1976,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_all(); - alloc_register_list(regs.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(regs.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_registers_global(ctxt: *mut c_void, count: *mut usize) -> *mut u32 @@ -1965,7 +1986,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_global(); - alloc_register_list(regs.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(regs.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_registers_system(ctxt: *mut c_void, count: *mut usize) -> *mut u32 @@ -1975,7 +1996,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_system(); - alloc_register_list(regs.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(regs.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_flags(ctxt: *mut c_void, count: *mut usize) -> *mut u32 @@ -1985,7 +2006,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let flags = custom_arch.flags(); - alloc_register_list(flags.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(flags.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_flag_write_types(ctxt: *mut c_void, count: *mut usize) -> *mut u32 @@ -1995,7 +2016,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let flag_writes = custom_arch.flag_write_types(); - alloc_register_list(flag_writes.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(flag_writes.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_semantic_flag_classes(ctxt: *mut c_void, count: *mut usize) -> *mut u32 @@ -2005,7 +2026,9 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let flag_classes = custom_arch.flag_classes(); - alloc_register_list(flag_classes.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(flag_classes.iter().map(|r| r.id().0), unsafe { + &mut *count + }) } extern "C" fn cb_semantic_flag_groups(ctxt: *mut c_void, count: *mut usize) -> *mut u32 @@ -2015,7 +2038,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let flag_groups = custom_arch.flag_groups(); - alloc_register_list(flag_groups.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(flag_groups.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_flag_role(ctxt: *mut c_void, flag: u32, class: u32) -> BNFlagRole @@ -2025,8 +2048,8 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; if let (Some(flag), class) = ( - custom_arch.flag_from_id(flag), - custom_arch.flag_class_from_id(class), + custom_arch.flag_from_id(FlagId(flag)), + custom_arch.flag_class_from_id(FlagClassId(class)), ) { flag.role(class) } else { @@ -2044,10 +2067,10 @@ where A: 'static + Architecture> + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; - let class = custom_arch.flag_class_from_id(class); + let class = custom_arch.flag_class_from_id(FlagClassId(class)); let flags = custom_arch.flags_required_for_flag_condition(cond, class); - alloc_register_list(flags.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(flags.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_flags_required_for_semantic_flag_group( @@ -2060,9 +2083,9 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - if let Some(group) = custom_arch.flag_group_from_id(group) { + if let Some(group) = custom_arch.flag_group_from_id(FlagGroupId(group)) { let flags = group.flags_required(); - alloc_register_list(flags.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(flags.iter().map(|r| r.id().0), unsafe { &mut *count }) } else { unsafe { *count = 0; @@ -2081,7 +2104,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - if let Some(group) = custom_arch.flag_group_from_id(group) { + if let Some(group) = custom_arch.flag_group_from_id(FlagGroupId(group)) { let flag_conditions = group.flag_conditions(); unsafe { @@ -2093,7 +2116,7 @@ where for (i, (class, cond)) in flag_conditions.iter().enumerate() { let out = out_slice.get_unchecked_mut(i); - out.semanticClass = class.id(); + out.semanticClass = class.id().0; out.condition = *cond; } @@ -2129,9 +2152,9 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - if let Some(write_type) = custom_arch.flag_write_from_id(write_type) { + if let Some(write_type) = custom_arch.flag_write_from_id(FlagWriteId(write_type)) { let written = write_type.flags_written(); - alloc_register_list(written.iter().map(|f| f.id()), unsafe { &mut *count }) + alloc_ids_list(written.iter().map(|f| f.id().0), unsafe { &mut *count }) } else { unsafe { *count = 0; @@ -2149,9 +2172,9 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch - .flag_write_from_id(write_type) + .flag_write_from_id(FlagWriteId(write_type)) .map(|w| w.class()) - .and_then(|c| c.map(|c| c.id())) + .and_then(|c| c.map(|c| c.id().0)) .unwrap_or(0) } @@ -2173,8 +2196,8 @@ where handle: ctxt as *mut A, }; - let flag_write = custom_arch.flag_write_from_id(flag_write); - let flag = custom_arch.flag_from_id(flag); + let flag_write = custom_arch.flag_write_from_id(FlagWriteId(flag_write)); + let flag = custom_arch.flag_from_id(FlagId(flag)); let operands = unsafe { slice::from_raw_parts(operands_raw, operand_count) }; let mut lifter = unsafe { Lifter::from_raw(custom_arch_handle, il) }; @@ -2226,7 +2249,7 @@ where handle: ctxt as *mut A, }; - let class = custom_arch.flag_class_from_id(class); + let class = custom_arch.flag_class_from_id(FlagClassId(class)); let mut lifter = unsafe { Lifter::from_raw(custom_arch_handle, il) }; if let Some(expr) = custom_arch.flag_cond_llil(cond, class, &mut lifter) { @@ -2252,7 +2275,7 @@ where let mut lifter = unsafe { Lifter::from_raw(custom_arch_handle, il) }; - if let Some(group) = custom_arch.flag_group_from_id(group) { + if let Some(group) = custom_arch.flag_group_from_id(FlagGroupId(group)) { if let Some(expr) = custom_arch.flag_group_llil(group, &mut lifter) { // TODO verify that returned expr is a bool value return expr.expr_idx; @@ -2282,12 +2305,12 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let result = unsafe { &mut *result }; - if let Some(reg) = custom_arch.register_from_id(reg) { + if let Some(reg) = custom_arch.register_from_id(RegisterId(reg)) { let info = reg.info(); result.fullWidthRegister = match info.parent() { - Some(p) => p.id(), - None => reg.id(), + Some(p) => p.id().0, + None => reg.id().0, }; result.offset = info.offset(); @@ -2303,7 +2326,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; if let Some(reg) = custom_arch.stack_pointer_reg() { - reg.id() + reg.id().0 } else { 0xffff_ffff } @@ -2316,7 +2339,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; if let Some(reg) = custom_arch.link_reg() { - reg.id() + reg.id().0 } else { 0xffff_ffff } @@ -2328,7 +2351,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - match custom_arch.register_stack_from_id(stack) { + match custom_arch.register_stack_from_id(RegisterStackId(stack)) { Some(stack) => BnString::new(stack.name().as_ref()).into_raw(), None => BnString::new("invalid_reg_stack").into_raw(), } @@ -2341,7 +2364,7 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.register_stacks(); - alloc_register_list(regs.iter().map(|r| r.id()), unsafe { &mut *count }) + alloc_ids_list(regs.iter().map(|r| r.id().0), unsafe { &mut *count }) } extern "C" fn cb_reg_stack_info( @@ -2354,22 +2377,22 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let result = unsafe { &mut *result }; - if let Some(stack) = custom_arch.register_stack_from_id(stack) { + if let Some(stack) = custom_arch.register_stack_from_id(RegisterStackId(stack)) { let info = stack.info(); let (reg, count) = info.storage_regs(); - result.firstStorageReg = reg.id(); + result.firstStorageReg = reg.id().0; result.storageCount = count; if let Some((reg, count)) = info.top_relative_regs() { - result.firstTopRelativeReg = reg.id(); + result.firstTopRelativeReg = reg.id().0; result.topRelativeCount = count; } else { result.firstTopRelativeReg = 0xffff_ffff; result.topRelativeCount = 0; } - result.stackTopReg = info.stack_top_reg().id(); + result.stackTopReg = info.stack_top_reg().id().0; } } @@ -2386,7 +2409,7 @@ where A: 'static + Architecture> + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; - match custom_arch.intrinsic_from_id(intrinsic) { + match custom_arch.intrinsic_from_id(IntrinsicId(intrinsic)) { Some(intrinsic) => BnString::new(intrinsic.name().as_ref()).into_raw(), None => BnString::new("invalid_intrinsic").into_raw(), } @@ -2398,7 +2421,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; let intrinsics = custom_arch.intrinsics(); - alloc_register_list(intrinsics.iter().map(|i| i.id()), unsafe { &mut *count }) + alloc_ids_list(intrinsics.iter().map(|i| i.id().0), unsafe { &mut *count }) } extern "C" fn cb_intrinsic_inputs( @@ -2411,7 +2434,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - let Some(intrinsic) = custom_arch.intrinsic_from_id(intrinsic) else { + let Some(intrinsic) = custom_arch.intrinsic_from_id(IntrinsicId(intrinsic)) else { unsafe { *count = 0; } @@ -2419,7 +2442,10 @@ where }; let inputs = intrinsic.inputs(); - let mut res: Box<[_]> = inputs.into_iter().map(|input| unsafe { Ref::into_raw(input) }.0).collect(); + let mut res: Box<[_]> = inputs + .into_iter() + .map(|input| unsafe { Ref::into_raw(input) }.0) + .collect(); unsafe { *count = res.len(); @@ -2459,7 +2485,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; - if let Some(intrinsic) = custom_arch.intrinsic_from_id(intrinsic) { + if let Some(intrinsic) = custom_arch.intrinsic_from_id(IntrinsicId(intrinsic)) { let inputs = intrinsic.outputs(); let mut res: Box<[_]> = inputs.iter().map(|input| input.as_ref().into()).collect(); diff --git a/rust/src/callingconvention.rs b/rust/src/callingconvention.rs index e7888131b..2ca5fd0b8 100644 --- a/rust/src/callingconvention.rs +++ b/rust/src/callingconvention.rs @@ -24,10 +24,8 @@ use std::slice; use binaryninjacore_sys::*; -use crate::architecture::{Architecture, ArchitectureExt, CoreArchitecture, Register}; -use crate::rc::{ - CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable, -}; +use crate::architecture::{Architecture, ArchitectureExt, CoreArchitecture, Register, RegisterId}; +use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::string::*; // TODO @@ -81,10 +79,12 @@ where }) } - fn alloc_register_list + ExactSizeIterator>( - items: I, - count: &mut usize, - ) -> *mut u32 { + fn alloc_ids_list(items: I, count: &mut usize) -> *mut u32 + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { + let items = items.into_iter(); let len = items.len(); *count = len; @@ -120,7 +120,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); let regs = ctxt.cc.caller_saved_registers(); - alloc_register_list(regs.iter().map(|r| r.id()), &mut *count) + alloc_ids_list(regs.iter().map(|r| r.id().0), &mut *count) }) } @@ -132,7 +132,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); let regs = ctxt.cc.callee_saved_registers(); - alloc_register_list(regs.iter().map(|r| r.id()), &mut *count) + alloc_ids_list(regs.iter().map(|r| r.id().0), &mut *count) }) } @@ -144,7 +144,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); let regs = ctxt.cc.int_arg_registers(); - alloc_register_list(regs.iter().map(|r| r.id()), &mut *count) + alloc_ids_list(regs.iter().map(|r| r.id().0), &mut *count) }) } @@ -156,7 +156,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); let regs = ctxt.cc.float_arg_registers(); - alloc_register_list(regs.iter().map(|r| r.id()), &mut *count) + alloc_ids_list(regs.iter().map(|r| r.id().0), &mut *count) }) } @@ -215,7 +215,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); match ctxt.cc.return_int_reg() { - Some(r) => r.id(), + Some(r) => r.id().0, _ => 0xffff_ffff, } }) @@ -229,7 +229,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); match ctxt.cc.return_hi_int_reg() { - Some(r) => r.id(), + Some(r) => r.id().0, _ => 0xffff_ffff, } }) @@ -243,7 +243,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); match ctxt.cc.return_float_reg() { - Some(r) => r.id(), + Some(r) => r.id().0, _ => 0xffff_ffff, } }) @@ -257,7 +257,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); match ctxt.cc.global_pointer_reg() { - Some(r) => r.id(), + Some(r) => r.id().0, _ => 0xffff_ffff, } }) @@ -274,7 +274,7 @@ where let ctxt = &*(ctxt as *mut CustomCallingConventionContext); let regs = ctxt.cc.implicitly_defined_registers(); - alloc_register_list(regs.iter().map(|r| r.id()), &mut *count) + alloc_ids_list(regs.iter().map(|r| r.id().0), &mut *count) }) } @@ -466,7 +466,7 @@ impl CallingConvention { let vars: *mut BNVariable = if let Some(permitted_args) = permitted_registers { let mut permitted_regs = vec![]; for r in permitted_args { - permitted_regs.push(r.id()); + permitted_regs.push(r.id().0); } unsafe { @@ -529,7 +529,7 @@ impl CallingConventionBase for CallingConvention { let res = slice::from_raw_parts(regs, count) .iter() .map(|&r| { - arch.register_from_id(r) + arch.register_from_id(RegisterId(r)) .expect("bad reg id from CallingConvention") }) .collect(); @@ -549,7 +549,7 @@ impl CallingConventionBase for CallingConvention { let res = slice::from_raw_parts(regs, count) .iter() .map(|&r| { - arch.register_from_id(r) + arch.register_from_id(RegisterId(r)) .expect("bad reg id from CallingConvention") }) .collect(); @@ -569,7 +569,7 @@ impl CallingConventionBase for CallingConvention { let res = slice::from_raw_parts(regs, count) .iter() .map(|&r| { - arch.register_from_id(r) + arch.register_from_id(RegisterId(r)) .expect("bad reg id from CallingConvention") }) .collect(); @@ -589,7 +589,7 @@ impl CallingConventionBase for CallingConvention { let res = slice::from_raw_parts(regs, count) .iter() .map(|&r| { - arch.register_from_id(r) + arch.register_from_id(RegisterId(r)) .expect("bad reg id from CallingConvention") }) .collect(); @@ -618,28 +618,28 @@ impl CallingConventionBase for CallingConvention { fn return_int_reg(&self) -> Option { match unsafe { BNGetIntegerReturnValueRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(RegisterId(id)), _ => None, } } fn return_hi_int_reg(&self) -> Option { match unsafe { BNGetHighIntegerReturnValueRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(RegisterId(id)), _ => None, } } fn return_float_reg(&self) -> Option { match unsafe { BNGetFloatReturnValueRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(RegisterId(id)), _ => None, } } fn global_pointer_reg(&self) -> Option { match unsafe { BNGetGlobalPointerRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(RegisterId(id)), _ => None, } } diff --git a/rust/src/llil/lifting.rs b/rust/src/llil/lifting.rs index daf95ac3f..d4d246ded 100644 --- a/rust/src/llil/lifting.rs +++ b/rust/src/llil/lifting.rs @@ -55,7 +55,7 @@ impl RegisterOrConstant { match self { RegisterOrConstant::Register(_, r) => BNRegisterOrConstant { constant: false, - reg: r.id(), + reg: r.id().0, value: 0, }, RegisterOrConstant::Constant(_, value) => BNRegisterOrConstant { @@ -168,7 +168,7 @@ impl FlagWriteOp { RegisterOrConstant::Constant(size, operand.value) } else { let il_reg = if 0x8000_0000 & operand.reg == 0 { - Register::ArchReg(arch.register_from_id(operand.reg).unwrap()) + Register::ArchReg(arch.register_from_id(RegisterId(operand.reg)).unwrap()) } else { Register::Temp(operand.reg) }; @@ -400,7 +400,7 @@ where use binaryninjacore_sys::BNGetDefaultArchitectureFlagConditionLowLevelIL; let handle = arch.as_ref(); - let class_id = class.map(|c| c.id()).unwrap_or(0); + let class_id = class.map(|c| c.id().0).unwrap_or(0); unsafe { let expr_idx = @@ -609,7 +609,7 @@ where { pub fn with_flag_write(mut self, flag_write: A::FlagWrite) -> Self { // TODO verify valid id - self.flags = flag_write.id(); + self.flags = flag_write.id().0; self } @@ -1006,7 +1006,7 @@ where // TODO verify valid id let reg = match reg.into() { - Register::ArchReg(r) => r.id(), + Register::ArchReg(r) => r.id().0, Register::Temp(r) => 0x8000_0000 | r, }; @@ -1030,7 +1030,7 @@ where // TODO verify valid id let dest_reg = match dest_reg.into() { - Register::ArchReg(r) => r.id(), + Register::ArchReg(r) => r.id().0, Register::Temp(r) => 0x8000_0000 | r, }; @@ -1065,13 +1065,13 @@ where // TODO verify valid id let hi_reg = match hi_reg.into() { - Register::ArchReg(r) => r.id(), + Register::ArchReg(r) => r.id().0, Register::Temp(r) => 0x8000_0000 | r, }; // TODO verify valid id let lo_reg = match lo_reg.into() { - Register::ArchReg(r) => r.id(), + Register::ArchReg(r) => r.id().0, Register::Temp(r) => 0x8000_0000 | r, }; @@ -1095,8 +1095,9 @@ where use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG; // TODO verify valid id - let expr_idx = - unsafe { BNLowLevelILAddExpr(self.handle, LLIL_FLAG, 0, 0, flag.id() as u64, 0, 0, 0) }; + let expr_idx = unsafe { + BNLowLevelILAddExpr(self.handle, LLIL_FLAG, 0, 0, flag.id().0 as u64, 0, 0, 0) + }; Expression::new(self, expr_idx) } @@ -1129,7 +1130,7 @@ where LLIL_FLAG_GROUP, 0, 0, - group.id() as u64, + group.id().0 as u64, 0, 0, 0, @@ -1158,7 +1159,7 @@ where op: LLIL_SET_FLAG, size: 0, flags: 0, - op1: dest_flag.id() as u64, + op1: dest_flag.id().0 as u64, op2: expr.expr_idx as u64, op3: 0, op4: 0, @@ -1241,7 +1242,7 @@ where .map(|output| { // TODO verify valid id let output = match output.into() { - Register::ArchReg(r) => r.id(), + Register::ArchReg(r) => r.id().0, Register::Temp(r) => 0x8000_0000 | r, }; output as u64 @@ -1281,7 +1282,7 @@ where flags: 0, op1: outputs.len() as u64, op2: output_expr_idx as u64, - op3: intrinsic.id() as u64, + op3: intrinsic.id().0 as u64, op4: input_expr_idx as u64, _ty: PhantomData, } diff --git a/rust/src/llil/mod.rs b/rust/src/llil/mod.rs index b9424e860..1f5b05bfb 100644 --- a/rust/src/llil/mod.rs +++ b/rust/src/llil/mod.rs @@ -22,6 +22,7 @@ use std::fmt; use crate::architecture::Architecture; use crate::architecture::Register as ArchReg; +use crate::architecture::RegisterId; use crate::function::Location; mod block; @@ -56,10 +57,10 @@ pub enum Register { } impl Register { - fn id(&self) -> u32 { + fn id(&self) -> RegisterId { match *self { Register::ArchReg(ref r) => r.id(), - Register::Temp(id) => 0x8000_0000 | id, + Register::Temp(id) => RegisterId(0x8000_0000 | id), } } } diff --git a/rust/src/llil/operation.rs b/rust/src/llil/operation.rs index 3ba4fa785..5b69f0d1f 100644 --- a/rust/src/llil/operation.rs +++ b/rust/src/llil/operation.rs @@ -17,6 +17,8 @@ use binaryninjacore_sys::BNLowLevelILInstruction; use std::marker::PhantomData; use std::mem; +use crate::architecture::{FlagGroupId, FlagWriteId, IntrinsicId}; + use super::*; pub struct Operation<'func, A, M, F, O> @@ -60,7 +62,7 @@ where pub fn flag_write(&self) -> Option { match self.op.flags { 0 => None, - id => self.function.arch().flag_write_from_id(id), + id => self.function.arch().flag_write_from_id(FlagWriteId(id)), } } } @@ -97,7 +99,7 @@ where // TODO: Support register and expression lists pub fn intrinsic(&self) -> Option { let raw_id = self.op.operands[2] as u32; - self.function.arch().intrinsic_from_id(raw_id) + self.function.arch().intrinsic_from_id(IntrinsicId(raw_id)) } } @@ -122,7 +124,7 @@ where } else { self.function .arch() - .register_from_id(raw_id) + .register_from_id(RegisterId(raw_id)) .map(Register::ArchReg) .unwrap_or_else(|| { error!( @@ -161,7 +163,7 @@ where } else { self.function .arch() - .register_from_id(raw_id) + .register_from_id(RegisterId(raw_id)) .map(Register::ArchReg) .unwrap_or_else(|| { error!( @@ -182,7 +184,7 @@ where } else { self.function .arch() - .register_from_id(raw_id) + .register_from_id(RegisterId(raw_id)) .map(Register::ArchReg) .unwrap_or_else(|| { error!( @@ -275,7 +277,7 @@ where } else { self.function .arch() - .register_from_id(raw_id) + .register_from_id(RegisterId(raw_id)) .map(Register::ArchReg) .unwrap_or_else(|| { error!( @@ -432,7 +434,10 @@ where { pub fn flag_group(&self) -> A::FlagGroup { let id = self.op.operands[0] as u32; - self.function.arch().flag_group_from_id(id).unwrap() + self.function + .arch() + .flag_group_from_id(FlagGroupId(id)) + .unwrap() } } From a0e715d9477fb38bf241b68656b2e5bb4403491d Mon Sep 17 00:00:00 2001 From: Rubens Brandao Date: Thu, 16 May 2024 15:15:31 -0300 Subject: [PATCH 2/2] implement the field function for ArchitectureExt --- rust/src/architecture.rs | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index d1f413c51..38eada76c 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -208,6 +208,13 @@ pub trait Register: Sized + Clone + Copy + Hash + Eq { /// *MUST* be in the range [0, 0x7fff_ffff] fn id(&self) -> RegisterId; } +impl ArchitectureFromId for RegisterId { + type Output = A::Register; + + fn into_value(self, arch: &A) -> Option { + arch.register_from_id(self) + } +} pub trait RegisterStackInfo: Sized { type RegStackType: RegisterStack; @@ -238,6 +245,13 @@ pub trait RegisterStack: Sized + Clone + Copy { /// *MUST* be in the range [0, 0x7fff_ffff] fn id(&self) -> RegisterStackId; } +impl ArchitectureFromId for RegisterStackId { + type Output = A::RegisterStack; + + fn into_value(self, arch: &A) -> Option { + arch.register_stack_from_id(self) + } +} #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct FlagId(pub u32); @@ -252,6 +266,13 @@ pub trait Flag: Sized + Clone + Copy + Hash + Eq { /// *MUST* be in the range [0, 0x7fff_ffff] fn id(&self) -> FlagId; } +impl ArchitectureFromId for FlagId { + type Output = A::Flag; + + fn into_value(self, arch: &A) -> Option { + arch.flag_from_id(self) + } +} #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct FlagWriteId(pub u32); @@ -270,6 +291,13 @@ pub trait FlagWrite: Sized + Clone + Copy { fn flags_written(&self) -> Vec; } +impl ArchitectureFromId for FlagWriteId { + type Output = A::FlagWrite; + + fn into_value(self, arch: &A) -> Option { + arch.flag_write_from_id(self) + } +} #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct FlagClassId(pub u32); @@ -282,6 +310,13 @@ pub trait FlagClass: Sized + Clone + Copy + Hash + Eq { /// *MUST* be in the range [1, 0x7fff_ffff] fn id(&self) -> FlagClassId; } +impl ArchitectureFromId for FlagClassId { + type Output = A::FlagClass; + + fn into_value(self, arch: &A) -> Option { + arch.flag_class_from_id(self) + } +} #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct FlagGroupId(pub u32); @@ -322,6 +357,13 @@ pub trait FlagGroup: Sized + Clone + Copy { /// inline it into conditional branches when appropriate. fn flag_conditions(&self) -> HashMap; } +impl ArchitectureFromId for FlagGroupId { + type Output = A::FlagGroup; + + fn into_value(self, arch: &A) -> Option { + arch.flag_group_from_id(self) + } +} #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct IntrinsicId(pub u32); @@ -337,6 +379,13 @@ pub trait Intrinsic: Sized + Clone + Copy { /// Returns the list of the output types for this intrinsic. fn outputs(&self) -> Vec>>; } +impl ArchitectureFromId for IntrinsicId { + type Output = A::Intrinsic; + + fn into_value(self, arch: &A) -> Option { + arch.intrinsic_from_id(self) + } +} pub trait Architecture: 'static + Sized + AsRef { type Handle: Borrow + Clone; @@ -1690,6 +1739,11 @@ pub trait ArchitectureExt: Architecture { { crate::functionrecognizer::register_arch_function_recognizer(self.as_ref(), recognizer); } + + #[inline] + fn field>(&self, id: F) -> Option { + F::into_value(id, self) + } } impl ArchitectureExt for T {}