reg_read and reg_write now work with registers W0 through W30 in Aarch64 (#716)

* reg_read and reg_write now work with registers W0 through W30 in Aarch64 emulaton

* Added a regress test for the ARM64 reg_read and reg_write on 32-bit registers (W0-W30)
Added a new macro in uc_priv.h (WRITE_DWORD_TO_QWORD), in order to write to the lower 32 bits of a 64 bit value without overwriting the whole value when using reg_write

* Fixed WRITE_DWORD macro

reg_write would zero out the high order bits when writing to 32 bit registers

e.g. uc.reg_write(UC_X86_REG_EAX, 0) would also set register RAX to zero
This commit is contained in:
Elton G
2017-01-15 13:13:35 +01:00
committed by Nguyen Anh Quynh
parent 55f0292aa9
commit 47150b6df3
3 changed files with 39 additions and 5 deletions

View File

@@ -50,9 +50,11 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int co
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28)
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) {
*(int64_t *)value = ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0];
else {
} else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) {
*(int32_t *)value = READ_DWORD(ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_W0]);
} else {
switch(regid) {
default: break;
case UC_ARM64_REG_X29:
@@ -82,9 +84,11 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals,
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28)
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) {
ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0] = *(uint64_t *)value;
else {
} else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) {
WRITE_DWORD(ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_W0], *(uint32_t *)value);
} else {
switch(regid) {
default: break;
case UC_ARM64_REG_X29: