Added ARM coproc registers (#684)

* Added ARM coproc registers

* Added regression test for vfp
This commit is contained in:
Parker Thompson 2017-01-24 19:56:19 -08:00 committed by Nguyen Anh Quynh
parent a735576dd3
commit 053ecd7bf4
3 changed files with 87 additions and 0 deletions

View file

@ -24,6 +24,9 @@ typedef enum uc_arm_reg {
UC_ARM_REG_FPSCR_NZCV, UC_ARM_REG_FPSCR_NZCV,
UC_ARM_REG_FPSID, UC_ARM_REG_FPSID,
UC_ARM_REG_ITSTATE, UC_ARM_REG_ITSTATE,
UC_ARM_REG_C1_C0_2,
UC_ARM_REG_C13_C0_2,
UC_ARM_REG_C13_C0_3,
UC_ARM_REG_LR, UC_ARM_REG_LR,
UC_ARM_REG_PC, UC_ARM_REG_PC,
UC_ARM_REG_SP, UC_ARM_REG_SP,

View file

@ -77,6 +77,15 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
case UC_ARM_REG_R15: case UC_ARM_REG_R15:
*(int32_t *)value = ARM_CPU(uc, mycpu)->env.regs[15]; *(int32_t *)value = ARM_CPU(uc, mycpu)->env.regs[15];
break; break;
case UC_ARM_REG_C1_C0_2:
*(int32_t *)value = ARM_CPU(uc, mycpu)->env.cp15.c1_coproc;
break;
case UC_ARM_REG_C13_C0_3:
*(int32_t *)value = ARM_CPU(uc, mycpu)->env.cp15.tpidrro_el0;
break;
case UC_ARM_REG_FPEXC:
*(int32_t *)value = ARM_CPU(uc, mycpu)->env.vfp.xregs[ARM_VFP_FPEXC];
break;
} }
} }
} }
@ -119,6 +128,16 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, i
uc->quit_request = true; uc->quit_request = true;
uc_emu_stop(uc); uc_emu_stop(uc);
break;
case UC_ARM_REG_C1_C0_2:
ARM_CPU(uc, mycpu)->env.cp15.c1_coproc = *(int32_t *)value;
break;
case UC_ARM_REG_C13_C0_3:
ARM_CPU(uc, mycpu)->env.cp15.tpidrro_el0 = *(int32_t *)value;
break;
case UC_ARM_REG_FPEXC:
ARM_CPU(uc, mycpu)->env.vfp.xregs[ARM_VFP_FPEXC] = *(int32_t *)value;
break; break;
} }
} }

View file

@ -0,0 +1,65 @@
#include <unicorn/unicorn.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ADDRESS 0x1000
#define ARM_VMOV "\xC0\xEF\x10\x00" // VMOV.I32 D16, #0 ; Vector Move
int main()
{
uc_engine *uc;
uc_err err;
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
if (err) {
printf("uc_open %d\n", err);
return 1;
}
uint64_t tmp_val;
err = uc_reg_read(uc, UC_ARM_REG_C1_C0_2, &tmp_val);
if (err) {
printf("uc_open %d\n", err);
return 1;
}
tmp_val = tmp_val | (0xf << 20);
err = uc_reg_write(uc, UC_ARM_REG_C1_C0_2, &tmp_val);
if (err) {
printf("uc_open %d\n", err);
return 1;
}
size_t enable_vfp = 0x40000000;
err = uc_reg_write(uc, UC_ARM_REG_FPEXC, &enable_vfp);
if (err) {
printf("uc_open %d\n", err);
return 1;
}
err = uc_mem_map(uc, ADDRESS, 4 * 1024, UC_PROT_ALL);
if (err) {
printf("uc_mem_map %d\n", err);
return 1;
}
err = uc_mem_write(uc, ADDRESS, ARM_VMOV, sizeof(ARM_VMOV) - 1);
if (err) {
printf("uc_mem_map %s\n", uc_strerror(err));
return 1;
}
err = uc_emu_start(uc, ADDRESS, 0, 0, 1);
if (err) {
printf("uc_emu_start: %s\n", uc_strerror(err));
return 1;
}
printf("Success\n");
uc_close(uc);
return 0;
}