diff --git a/include/unicorn/arm64.h b/include/unicorn/arm64.h index fe46f159..0f66518d 100644 --- a/include/unicorn/arm64.h +++ b/include/unicorn/arm64.h @@ -289,7 +289,44 @@ typedef enum uc_arm64_reg { UC_ARM64_REG_TPIDR_EL0, UC_ARM64_REG_TPIDRRO_EL0, UC_ARM64_REG_TPIDR_EL1, - + + UC_ARM64_REG_PSTATE, + + //> exception link registers + UC_ARM64_REG_ELR_EL0, + UC_ARM64_REG_ELR_EL1, + UC_ARM64_REG_ELR_EL2, + UC_ARM64_REG_ELR_EL3, + + //> stack pointers registers + UC_ARM64_REG_SP_EL0, + UC_ARM64_REG_SP_EL1, + UC_ARM64_REG_SP_EL2, + UC_ARM64_REG_SP_EL3, + + //> other CP15 registers + UC_ARM64_REG_TTBR0_EL1, + UC_ARM64_REG_TTBR1_EL1, + + UC_ARM64_REG_ESR_EL0, + UC_ARM64_REG_ESR_EL1, + UC_ARM64_REG_ESR_EL2, + UC_ARM64_REG_ESR_EL3, + + UC_ARM64_REG_FAR_EL0, + UC_ARM64_REG_FAR_EL1, + UC_ARM64_REG_FAR_EL2, + UC_ARM64_REG_FAR_EL3, + + UC_ARM64_REG_PAR_EL1, + + UC_ARM64_REG_MAIR_EL1, + + UC_ARM64_REG_VBAR_EL0, + UC_ARM64_REG_VBAR_EL1, + UC_ARM64_REG_VBAR_EL2, + UC_ARM64_REG_VBAR_EL3, + UC_ARM64_REG_ENDING, // <-- mark the end of the list of registers //> alias registers diff --git a/qemu/target-arm/unicorn_aarch64.c b/qemu/target-arm/unicorn_aarch64.c index 76e580b5..42bd7cc3 100644 --- a/qemu/target-arm/unicorn_aarch64.c +++ b/qemu/target-arm/unicorn_aarch64.c @@ -73,6 +73,16 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int co *(int16_t*)value = READ_WORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_H0)]); } else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) { *(int8_t*)value = READ_BYTE_L(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_B0)]); + } else if (regid >= UC_ARM64_REG_ELR_EL0 && regid <= UC_ARM64_REG_ELR_EL3) { + *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.elr_el[regid - UC_ARM64_REG_ELR_EL0]; + } else if (regid >= UC_ARM64_REG_SP_EL0 && regid <= UC_ARM64_REG_SP_EL3) { + *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.sp_el[regid - UC_ARM64_REG_SP_EL0]; + } else if (regid >= UC_ARM64_REG_ESR_EL0 && regid <= UC_ARM64_REG_ESR_EL3) { + *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.cp15.esr_el[regid - UC_ARM64_REG_ESR_EL0]; + } else if (regid >= UC_ARM64_REG_FAR_EL0 && regid <= UC_ARM64_REG_FAR_EL3) { + *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.cp15.far_el[regid - UC_ARM64_REG_FAR_EL0]; + } else if (regid >= UC_ARM64_REG_VBAR_EL0 && regid <= UC_ARM64_REG_VBAR_EL3) { + *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.cp15.vbar_el[regid - UC_ARM64_REG_VBAR_EL0]; } else { switch(regid) { default: break; @@ -103,6 +113,21 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int co case UC_ARM64_REG_NZCV: *(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env) & CPSR_NZCV; break; + case UC_ARM64_REG_PSTATE: + *(uint32_t *)value = pstate_read(&ARM_CPU(uc, mycpu)->env); + break; + case UC_ARM64_REG_TTBR0_EL1: + *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.ttbr0_el1; + break; + case UC_ARM64_REG_TTBR1_EL1: + *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.ttbr1_el1; + break; + case UC_ARM64_REG_PAR_EL1: + *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.par_el1; + break; + case UC_ARM64_REG_MAIR_EL1: + *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.mair_el1; + break; } } } @@ -138,6 +163,16 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, WRITE_WORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_H0)], *(int16_t*) value); } else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) { WRITE_BYTE_L(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_B0)], *(int8_t*) value); + } else if (regid >= UC_ARM64_REG_ELR_EL0 && regid <= UC_ARM64_REG_ELR_EL3) { + ARM_CPU(uc, mycpu)->env.elr_el[regid - UC_ARM64_REG_ELR_EL0] = *(uint64_t*)value; + } else if (regid >= UC_ARM64_REG_SP_EL0 && regid <= UC_ARM64_REG_SP_EL3) { + ARM_CPU(uc, mycpu)->env.sp_el[regid - UC_ARM64_REG_SP_EL0] = *(uint64_t*)value; + } else if (regid >= UC_ARM64_REG_ESR_EL0 && regid <= UC_ARM64_REG_ESR_EL3) { + ARM_CPU(uc, mycpu)->env.cp15.esr_el[regid - UC_ARM64_REG_ESR_EL0] = *(uint64_t*)value; + } else if (regid >= UC_ARM64_REG_FAR_EL0 && regid <= UC_ARM64_REG_FAR_EL3) { + ARM_CPU(uc, mycpu)->env.cp15.far_el[regid - UC_ARM64_REG_FAR_EL0] = *(uint64_t*)value; + } else if (regid >= UC_ARM64_REG_VBAR_EL0 && regid <= UC_ARM64_REG_VBAR_EL3) { + ARM_CPU(uc, mycpu)->env.cp15.vbar_el[regid - UC_ARM64_REG_VBAR_EL0] = *(uint64_t*)value; } else { switch(regid) { default: break; @@ -169,7 +204,22 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value; break; case UC_ARM64_REG_NZCV: - cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *) value, CPSR_NZCV); + cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV); + break; + case UC_ARM64_REG_PSTATE: + pstate_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value); + break; + case UC_ARM64_REG_TTBR0_EL1: + ARM_CPU(uc, mycpu)->env.cp15.ttbr0_el1 = *(uint64_t *)value; + break; + case UC_ARM64_REG_TTBR1_EL1: + ARM_CPU(uc, mycpu)->env.cp15.ttbr1_el1 = *(uint64_t *)value; + break; + case UC_ARM64_REG_PAR_EL1: + ARM_CPU(uc, mycpu)->env.cp15.par_el1 = *(uint64_t *)value; + break; + case UC_ARM64_REG_MAIR_EL1: + ARM_CPU(uc, mycpu)->env.cp15.mair_el1 = *(uint64_t *)value; break; } }