unicorn
unicorn copied to clipboard
Unicorn 2: Support ARM Advanced SIMD Instructions
I have a firmware that working on ARMv7 architecture. I try to emulate the firmware and I have found a problem with the support for SIMD instructions, for example: VPUSH instruction.
Source environment
I built unicorn on the dev branch at sha 6c1cbef6ac505d355033aef1176b684d02e1eb3a
.
This has been tested on Windows system on Intel hardware
Failure
The failure appears if I try to execute any Advanced SIMD Instruction.
Following the documentation, SIMD instructions are supported from ARMv7 and later. https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/VPUSH
https://developer.arm.com/documentation/100076/0200/a32-t32-instruction-set-reference/advanced-simd-instructions--32-bit-
Test code
Test code which exhibits this problem here:
diff --git "a/tests/unit/test_arm.c" "b/tests/unit/test_arm.c"
index 1efd5682..ca4e973d 100644
--- "a/tests/unit/test_arm.c"
+++ "b/tests/unit/test_arm.c"
@@ -751,6 +751,25 @@ static void test_armeb_ldrb(void)
OK(uc_close(uc));
}
+static void test_arm_vpush(void)
+{
+ uc_engine *uc;
+ const char test_code[] = "\x08\x0B\x2D\xED"; // VPUSH {D0-D3}
+ uint64_t stack_address = 0x800000;
+ uint64_t stack_size = 2 * 1024 * 1024;
+ int sp = stack_size / 2;
+
+ uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM,
+ test_code, sizeof(test_code)-1, UC_CPU_ARM_CORTEX_A7);
+
+ OK(uc_mem_map(uc, stack_address, stack_size, UC_PROT_ALL));
+ OK(uc_reg_write(uc, UC_ARM_REG_SP, &sp));
+
+ OK(uc_emu_start(uc, code_start, code_start + sizeof(test_code) - 1, 0, 0));
+
+ OK(uc_close(uc));
+}
+
TEST_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_thumb_sub", test_arm_thumb_sub},
{"test_armeb_sub", test_armeb_sub},
@@ -773,4 +792,5 @@ TEST_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_be_cpsr_sctlr", test_arm_be_cpsr_sctlr},
{"test_arm_switch_endian", test_arm_switch_endian},
{"test_armeb_ldrb", test_armeb_ldrb},
+ {"test_arm_vpush", test_arm_vpush},
{NULL, NULL}};
\ No newline at end of file
Failing output (Unicorn 2)
Test test_arm_nop... [ OK ]
Test test_arm_thumb_sub... [ OK ]
Test test_armeb_sub... [ OK ]
Test test_armeb_be8_sub... [ OK ]
Test test_arm_thumbeb_sub... [ OK ]
Test test_arm_thumb_ite... [ OK ]
Test test_arm_m_thumb_mrs... [ OK ]
Test test_arm_m_control... [ OK ]
Test test_arm_m_exc_return... [ OK ]
Test test_arm_und32_to_svc32... [ OK ]
Test test_arm_usr32_to_svc32... [ OK ]
Test test_arm_v8... [ OK ]
Test test_arm_thumb_smlabb... [ OK ]
Test test_arm_not_allow_privilege_escalation... [ OK ]
Test test_arm_mrc... [ OK ]
Test test_arm_hflags_rebuilt... [ OK ]
Test test_arm_mem_access_abort... [ OK ]
Test test_arm_read_sctlr... [ OK ]
Test test_arm_be_cpsr_sctlr... [ OK ]
Test test_arm_switch_endian... [ OK ]
Test test_armeb_ldrb... [ OK ]
Test test_arm_vpush... [ FAILED ]
test_arm.c:768: Check __err == UC_ERR_OK... failed
Invalid instruction (UC_ERR_INSN_INVALID)
FAILED: 1 of 22 unit tests has failed.
Expect
Test test_arm_nop... [ OK ]
Test test_arm_thumb_sub... [ OK ]
Test test_armeb_sub... [ OK ]
Test test_armeb_be8_sub... [ OK ]
Test test_arm_thumbeb_sub... [ OK ]
Test test_arm_thumb_ite... [ OK ]
Test test_arm_m_thumb_mrs... [ OK ]
Test test_arm_m_control... [ OK ]
Test test_arm_m_exc_return... [ OK ]
Test test_arm_und32_to_svc32... [ OK ]
Test test_arm_usr32_to_svc32... [ OK ]
Test test_arm_v8... [ OK ]
Test test_arm_thumb_smlabb... [ OK ]
Test test_arm_not_allow_privilege_escalation... [ OK ]
Test test_arm_mrc... [ OK ]
Test test_arm_hflags_rebuilt... [ OK ]
Test test_arm_mem_access_abort... [ OK ]
Test test_arm_read_sctlr... [ OK ]
Test test_arm_be_cpsr_sctlr... [ OK ]
Test test_arm_switch_endian... [ OK ]
Test test_armeb_ldrb... [ OK ]
Test test_arm_vpush... [ OK ]