Rebuilt hflags when swithing modes

Or we may get the wrong mode during translation
This commit is contained in:
lazymio 2022-01-14 19:37:48 +01:00
parent 36afa1022c
commit 6ed2214399
No known key found for this signature in database
GPG Key ID: DFF27E34A47CB873
2 changed files with 62 additions and 0 deletions

View File

@ -252,6 +252,7 @@ static void reg_write(CPUARMState *env, unsigned int regid, const void *value)
if (!arm_feature(env, ARM_FEATURE_M)) { if (!arm_feature(env, ARM_FEATURE_M)) {
cpsr_write(env, *(uint32_t *)value, cpsr_write(env, *(uint32_t *)value,
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByUnicorn); (CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByUnicorn);
arm_rebuild_hflags(env);
} else { } else {
// Same with UC_ARM_REG_APSR_NZCVQ // Same with UC_ARM_REG_APSR_NZCVQ
v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value); v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value);
@ -259,9 +260,11 @@ static void reg_write(CPUARMState *env, unsigned int regid, const void *value)
break; break;
case UC_ARM_REG_APSR_NZCV: case UC_ARM_REG_APSR_NZCV:
cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByUnicorn); cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByUnicorn);
arm_rebuild_hflags(env);
break; break;
case UC_ARM_REG_CPSR: case UC_ARM_REG_CPSR:
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByUnicorn); cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByUnicorn);
arm_rebuild_hflags(env);
break; break;
case UC_ARM_REG_SPSR: case UC_ARM_REG_SPSR:
env->spsr = *(uint32_t *)value; env->spsr = *(uint32_t *)value;

View File

@ -471,6 +471,64 @@ static void test_arm_mrc()
OK(uc_close(uc)); OK(uc_close(uc));
} }
static void test_arm_hflags_rebuilt()
{
// MRS r6, apsr
// BIC r6, r6, #&1F
// ORR r6, r6, #&10
// MSR cpsr_c, r6
// SWI OS_EnterOS
// MSR cpsr_c, r6
char code[] = "\x00\x60\x0f\xe1\x1f\x60\xc6\xe3\x10\x60\x86\xe3\x06\xf0\x21"
"\xe1\x16\x00\x02\xef\x06\xf0\x21\xe1";
uc_engine *uc;
uint32_t r_cpsr, r_spsr, r_r13, r_r14, r_pc;
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM, code, sizeof(code) - 1,
UC_CPU_ARM_CORTEX_A9);
r_cpsr = 0x40000013; // SVC32
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
r_spsr = 0x40000013;
OK(uc_reg_write(uc, UC_ARM_REG_SPSR, &r_spsr));
r_r13 = 0x12345678; // SP
OK(uc_reg_write(uc, UC_ARM_REG_R13, &r_r13));
r_r14 = 0x00102220; // LR
OK(uc_reg_write(uc, UC_ARM_REG_R14, &r_r14));
r_cpsr = 0x40000010; // USR32
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
r_r13 = 0x0010000; // SP
OK(uc_reg_write(uc, UC_ARM_REG_R13, &r_r13));
r_r14 = 0x0001234; // LR
OK(uc_reg_write(uc, UC_ARM_REG_R14, &r_r14));
uc_assert_err(
UC_ERR_EXCEPTION,
uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
r_cpsr = 0x60000013;
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
r_cpsr = 0x60000010;
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
r_cpsr = 0x60000013;
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
OK(uc_reg_read(uc, UC_ARM_REG_PC, &r_pc));
OK(uc_emu_start(uc, r_pc, code_start + sizeof(code) - 1, 0, 0));
OK(uc_reg_read(uc, UC_ARM_REG_CPSR, &r_cpsr));
OK(uc_reg_read(uc, UC_ARM_REG_R13, &r_r13));
OK(uc_reg_read(uc, UC_ARM_REG_R14, &r_r14));
TEST_CHECK(r_cpsr == 0x60000010);
TEST_CHECK(r_r13 == 0x00010000);
TEST_CHECK(r_r14 == 0x00001234);
OK(uc_close(uc));
}
TEST_LIST = {{"test_arm_nop", test_arm_nop}, TEST_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_thumb_sub", test_arm_thumb_sub}, {"test_arm_thumb_sub", test_arm_thumb_sub},
{"test_armeb_sub", test_armeb_sub}, {"test_armeb_sub", test_armeb_sub},
@ -486,4 +544,5 @@ TEST_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_not_allow_privilege_escalation", {"test_arm_not_allow_privilege_escalation",
test_arm_not_allow_privilege_escalation}, test_arm_not_allow_privilege_escalation},
{"test_arm_mrc", test_arm_mrc}, {"test_arm_mrc", test_arm_mrc},
{"test_arm_hflags_rebuilt", test_arm_hflags_rebuilt},
{NULL, NULL}}; {NULL, NULL}};