diff --git a/capstone-rs/src/arch/arm.rs b/capstone-rs/src/arch/arm.rs index aa598c7..be8376f 100644 --- a/capstone-rs/src/arch/arm.rs +++ b/capstone-rs/src/arch/arm.rs @@ -1,16 +1,16 @@ //! Contains arm-specific types -use core::convert::From; +use core::convert::{From, TryInto}; use core::{cmp, fmt, slice}; use capstone_sys::{ - arm_op_mem, arm_op_type, cs_arm, cs_arm_op, arm_shifter, - cs_arm_op__bindgen_ty_2}; + arm_op_mem, arm_op_type, arm_shifter, cs_ac_type, cs_arm, cs_arm_op, cs_arm_op__bindgen_ty_2}; use libc::c_uint; pub use crate::arch::arch_builder::arm::*; use crate::arch::DetailsArchInsn; use crate::instruction::{RegId, RegIdInt}; +use crate::RegAccessType; pub use capstone_sys::arm_insn_group as ArmInsnGroup; pub use capstone_sys::arm_insn as ArmInsn; @@ -129,6 +129,10 @@ pub struct ArmOperand { /// Operand type pub op_type: ArmOperandType, + + /// How is this operand accessed? NOTE: this field is irrelevant if engine + /// is compiled in DIET mode. + pub access: Option } /// ARM operand @@ -252,7 +256,8 @@ impl Default for ArmOperand { vector_index: None, subtracted: false, shift: ArmShift::Invalid, - op_type: ArmOperandType::Invalid + op_type: ArmOperandType::Invalid, + access: None } } } @@ -271,6 +276,7 @@ impl<'a> From<&'a cs_arm_op> for ArmOperand { shift, op_type, subtracted: op.subtracted, + access: cs_ac_type(op.access as _).try_into().ok(), } } } diff --git a/capstone-rs/src/test.rs b/capstone-rs/src/test.rs index 3569b86..6463c05 100644 --- a/capstone-rs/src/test.rs +++ b/capstone-rs/src/test.rs @@ -912,8 +912,14 @@ fn test_arch_arm_detail() { use crate::arch::arm::*; use capstone_sys::arm_op_mem; - let r0_op = ArmOperand { + let r0_op_read = ArmOperand { op_type: Reg(RegId(ArmReg::ARM_REG_R0 as RegIdInt)), + access: Some(RegAccessType::ReadOnly), + ..Default::default() + }; + let r0_op_write = ArmOperand { + op_type: Reg(RegId(ArmReg::ARM_REG_R0 as RegIdInt)), + access: Some(RegAccessType::WriteOnly), ..Default::default() }; @@ -944,6 +950,7 @@ fn test_arch_arm_detail() { &[ ArmOperand { op_type: Reg(RegId(ArmReg::ARM_REG_LR as RegIdInt)), + access: Some(RegAccessType::ReadOnly), ..Default::default() }, ArmOperand { @@ -954,6 +961,7 @@ fn test_arch_arm_detail() { disp: -4, lshift: 0, })), + access: Some(RegAccessType::WriteOnly), ..Default::default() }, ], @@ -962,7 +970,7 @@ fn test_arch_arm_detail() { DII::new( "andeq", b"\x00\x00\x00\x00", - &[r0_op.clone(), r0_op.clone(), r0_op.clone()], + &[r0_op_write.clone(), r0_op_read.clone(), r0_op_read.clone()], ), // str r8, [r2, #-0x3e0]! DII::new( @@ -971,6 +979,7 @@ fn test_arch_arm_detail() { &[ ArmOperand { op_type: Reg(RegId(ArmReg::ARM_REG_R8 as RegIdInt)), + access: Some(RegAccessType::ReadOnly), ..Default::default() }, ArmOperand { @@ -981,6 +990,7 @@ fn test_arch_arm_detail() { disp: -992, lshift: 0, })), + access: Some(RegAccessType::WriteOnly), ..Default::default() }, ], @@ -998,7 +1008,7 @@ fn test_arch_arm_detail() { op_type: Imm(0), ..Default::default() }, - r0_op.clone(), + r0_op_read.clone(), ArmOperand { op_type: Cimm(3), ..Default::default() @@ -1018,7 +1028,7 @@ fn test_arch_arm_detail() { "mov", b"\x00\x00\xa0\xe3", &[ - r0_op, + r0_op_write, ArmOperand { op_type: Imm(0), ..Default::default() @@ -1043,6 +1053,7 @@ fn test_arch_arm_detail() { b"\x70\x47", &[ArmOperand { op_type: Reg(RegId(ArmReg::ARM_REG_LR as RegIdInt)), + access: Some(RegAccessType::ReadOnly), ..Default::default() }], )],