diff --git a/capstone-rs/src/arch/arm.rs b/capstone-rs/src/arch/arm.rs index c9d0c148..909d2c66 100644 --- a/capstone-rs/src/arch/arm.rs +++ b/capstone-rs/src/arch/arm.rs @@ -206,6 +206,11 @@ impl ArmInsnDetail<'_> { pub fn update_flags(&self) -> bool { self.0.update_flags } + + /// Whether this is a post-index writeback (only applicable when `writeback` is true) + pub fn post_index(&self) -> bool { + self.0.post_index + } /// Whether writeback is required pub fn writeback(&self) -> bool { @@ -219,7 +224,7 @@ impl ArmInsnDetail<'_> { } impl_PartialEq_repr_fields!(ArmInsnDetail<'a> [ 'a ]; - usermode, vector_size, vector_data, cps_mode, cps_flag, cc, update_flags, writeback, + usermode, vector_size, vector_data, cps_mode, cps_flag, cc, update_flags, post_index, writeback, mem_barrier, operands ); diff --git a/capstone-rs/src/arch/arm64.rs b/capstone-rs/src/arch/arm64.rs index 11e97fd3..fe0b88fb 100644 --- a/capstone-rs/src/arch/arm64.rs +++ b/capstone-rs/src/arch/arm64.rs @@ -167,6 +167,11 @@ impl Arm64InsnDetail<'_> { self.0.update_flags } + /// Whether this is a post-index writeback (only applicable when `writeback` is true) + pub fn post_index(&self) -> bool { + self.0.post_index + } + /// Whether writeback is required pub fn writeback(&self) -> bool { self.0.writeback @@ -174,7 +179,7 @@ impl Arm64InsnDetail<'_> { } impl_PartialEq_repr_fields!(Arm64InsnDetail<'a> [ 'a ]; - cc, update_flags, writeback, operands + cc, update_flags, post_index, writeback, operands ); impl Arm64OpMem { diff --git a/capstone-rs/src/test.rs b/capstone-rs/src/test.rs index 2b3a66c5..c8fc2601 100644 --- a/capstone-rs/src/test.rs +++ b/capstone-rs/src/test.rs @@ -1186,6 +1186,92 @@ fn test_arch_arm_detail() { ); } +#[cfg(feature = "arch_arm")] +#[test] +fn test_arch_arm_writeback() { + let mut cs = Capstone::new() + .arm() + .mode(arm::ArchMode::Arm) + .build() + .unwrap(); + cs.set_detail(true).unwrap(); + + // ldr r0, [r1] + // ldr r0, [r1], #4 + // ldr r0, [r1, #4]! + let insns = cs + .disasm_all( + b"\x00\x00\x91\xe5\x04\x00\x91\xe4\x04\x00\xb1\xe5", + START_TEST_ADDR, + ) + .expect("Failed to disassemble"); + let insns: Vec<_> = insns.iter().collect(); + + let insn = insns[0]; + let detail = cs.insn_detail(insn).expect("Could not get detail"); + let arch_detail = detail.arch_detail(); + let arm_detail = arch_detail.arm().expect("Failed to get arm detail"); + assert_eq!(false, arm_detail.writeback()); + assert_eq!(false, arm_detail.post_index()); + + let insn = insns[1]; + let detail = cs.insn_detail(insn).expect("Could not get detail"); + let arch_detail = detail.arch_detail(); + let arm_detail = arch_detail.arm().expect("Failed to get arm detail"); + assert_eq!(true, arm_detail.writeback()); + assert_eq!(true, arm_detail.post_index()); + + let insn = insns[2]; + let detail = cs.insn_detail(insn).expect("Could not get detail"); + let arch_detail = detail.arch_detail(); + let arm_detail = arch_detail.arm().expect("Failed to get arm detail"); + assert_eq!(true, arm_detail.writeback()); + assert_eq!(false, arm_detail.post_index()); +} + +#[cfg(feature = "arch_arm64")] +#[test] +fn test_arch_arm64_writeback() { + let mut cs = Capstone::new() + .arm64() + .mode(arm64::ArchMode::Arm) + .build() + .unwrap(); + cs.set_detail(true).unwrap(); + + // ldr x0, [x19] + // ldr x8, [x16, #0x28]! + // ldp x24, x23, [sp], #0x40 + let insns = cs + .disasm_all( + b"\x60\x02\x40\xf9\x08\x8e\x42\xf8\xf8\x5f\xc4\xa8", + START_TEST_ADDR, + ) + .expect("Failed to disassemble"); + let insns: Vec<_> = insns.iter().collect(); + + let insn = insns[0]; + let detail = cs.insn_detail(insn).expect("Could not get detail"); + let arch_detail = detail.arch_detail(); + let arm64_detail = arch_detail.arm64().expect("Failed to get arm64 detail"); + assert_eq!(false, arm64_detail.writeback()); + assert_eq!(false, arm64_detail.post_index()); + + let insn = insns[1]; + let detail = cs.insn_detail(insn).expect("Could not get detail"); + let arch_detail = detail.arch_detail(); + let arm64_detail = arch_detail.arm64().expect("Failed to get arm64 detail"); + assert_eq!(true, arm64_detail.writeback()); + assert_eq!(false, arm64_detail.post_index()); + + let insn = insns[2]; + let detail = cs.insn_detail(insn).expect("Could not get detail"); + let arch_detail = detail.arch_detail(); + let arm64_detail = arch_detail.arm64().expect("Failed to get arm64 detail"); + assert_eq!(true, arm64_detail.writeback()); + assert_eq!(true, arm64_detail.post_index()); +} + #[cfg(feature = "arch_arm64")] #[test] fn test_arch_arm64() {