allow to change PC during callback. this solves issue #210

This commit is contained in:
Nguyen Anh Quynh
2016-01-28 14:06:17 +08:00
parent e750a4e97c
commit 5a04bcb115
11 changed files with 143 additions and 2 deletions

View File

@@ -66,6 +66,7 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
uintptr_t next_tb;
struct hook *hook;
/* This must be volatile so it is not trashed by longjmp() */
volatile bool have_tb_lock = false;
@@ -100,6 +101,7 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
if (uc->stop_request || uc->invalid_error)
break;
/* if an exception is pending, we execute it here */
if (cpu->exception_index >= 0) {
//printf(">>> GOT INTERRUPT. exception idx = %x\n", cpu->exception_index); // qq

View File

@@ -82,6 +82,9 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
break;
case UC_ARM64_REG_PC:
ARM_CPU(uc, mycpu)->env.pc = *(uint64_t *)value;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
case UC_ARM64_REG_SP:
ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value;

View File

@@ -91,6 +91,9 @@ int arm_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
//case UC_ARM_REG_PC:
case UC_ARM_REG_R15:
ARM_CPU(uc, mycpu)->env.regs[15] = *(uint32_t *)value;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
}
}

View File

@@ -656,9 +656,15 @@ int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
break;
case UC_X86_REG_EIP:
X86_CPU(uc, mycpu)->env.eip = *(uint32_t *)value;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
case UC_X86_REG_IP:
WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value);
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
case UC_X86_REG_CS:
X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint32_t *)value;
@@ -806,12 +812,21 @@ int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
break;
case UC_X86_REG_RIP:
X86_CPU(uc, mycpu)->env.eip = *(uint64_t *)value;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
case UC_X86_REG_EIP:
WRITE_DWORD(X86_CPU(uc, mycpu)->env.eip, *(uint32_t *)value);
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
case UC_X86_REG_IP:
WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value);
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
case UC_X86_REG_CS:
X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint64_t *)value;

View File

@@ -70,6 +70,9 @@ int m68k_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
default: break;
case UC_M68K_REG_PC:
M68K_CPU(uc, mycpu)->env.pc = *(uint32_t *)value;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
}
}

View File

@@ -81,6 +81,9 @@ int mips_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
default: break;
case UC_MIPS_REG_PC:
MIPS_CPU(uc, mycpu)->env.active_tc.PC = *(uint32_t *)value;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
}
}

View File

@@ -87,6 +87,9 @@ int sparc_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
case UC_SPARC_REG_PC:
SPARC_CPU(uc, mycpu)->env.pc = *(uint32_t *)value;
SPARC_CPU(uc, mycpu)->env.npc = *(uint32_t *)value + 4;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);
break;
}
}