From a9025c58a47d985dd0cec10344b5f33ded1ac51c Mon Sep 17 00:00:00 2001 From: h01G3r <63418746+h01G3r@users.noreply.github.com> Date: Thu, 20 Aug 2020 17:24:04 +0200 Subject: [PATCH] fixes an issue with ARM APSR register handling: (#1317) - Q flag / GE flag were not included in APSR register (read/write) - UC_ARM_REG_APSR_NZCV register constant was ignored completely. - regression test added --- qemu/target-arm/unicorn_arm.c | 6 ++++++ tests/regress/arm_apsr_access.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/regress/arm_apsr_access.py diff --git a/qemu/target-arm/unicorn_arm.c b/qemu/target-arm/unicorn_arm.c index 0e1b1828..d5b9a7d9 100644 --- a/qemu/target-arm/unicorn_arm.c +++ b/qemu/target-arm/unicorn_arm.c @@ -69,6 +69,9 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun else { switch(regid) { case UC_ARM_REG_APSR: + *(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env) & (CPSR_NZCV | CPSR_Q | CPSR_GE); + break; + case UC_ARM_REG_APSR_NZCV: *(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env) & CPSR_NZCV; break; case UC_ARM_REG_CPSR: @@ -132,6 +135,9 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, i else { switch(regid) { case UC_ARM_REG_APSR: + cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, (CPSR_NZCV | CPSR_Q | CPSR_GE)); + break; + case UC_ARM_REG_APSR_NZCV: cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV); break; case UC_ARM_REG_CPSR: diff --git a/tests/regress/arm_apsr_access.py b/tests/regress/arm_apsr_access.py new file mode 100644 index 00000000..33c10fd9 --- /dev/null +++ b/tests/regress/arm_apsr_access.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +from unicorn import * +from unicorn.arm_const import * + +import regress + +class APSRAccess(regress.RegressTest): + + def runTest(self): + code = ( + b'\x00\x00\xa0\xe1' + # 0: mov r0, r0 + b'\x08\x10\x9f\xe5' + # 4: ldr r1, [pc, #8] + b'\x01\xf0\x28\xe1' + # 8: 01 f0 28 e1 msr apsr_nzcvq, r1 + b'\x00\x00\xa0\xe1' + # c: mov r0, r0 + b'\x00\x00\xa0\xe1' + # 10: mov r0, r0 + b'\x00\x00\x00\xff') # 14: data for inst @4 + + uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) + uc.mem_map(0x1000, 0x1000) + uc.mem_write(0x1000, code) # bxeq lr; mov r0, r0 + + uc.reg_write(UC_ARM_REG_APSR, 0) + uc.emu_start(0x1000, 0x100c) + + self.assertEqual(uc.reg_read(UC_ARM_REG_APSR), 0xf8000000) + self.assertEqual(uc.reg_read(UC_ARM_REG_APSR_NZCV), 0xf0000000) + +if __name__ == '__main__': + regress.main()