From 149121539b6cc8a349be513d834da91ba37a3253 Mon Sep 17 00:00:00 2001 From: el poto rico <48299807+elp0t0r1c0@users.noreply.github.com> Date: Sun, 10 May 2020 15:50:00 +0200 Subject: [PATCH] [arm64] Add some cool registers (#1253) I've added the following registers to the API: * PSTATE * Exception link registers (ELR_ELx) * Stack pointers registers (SP_ELx) * MMU (TTBRn_EL1) * Exception syndrom registers (ESR_ELx) * Faulting virtual address registers (FAR_ELx) * PAR (PAR_EL1) * MAIR (MAIR_EL1) * Vector base address registers (VBAR_ELx) --- include/unicorn/arm64.h | 39 ++++++++++++++++++++++- qemu/target-arm/unicorn_aarch64.c | 52 ++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) 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; } }