Fix wrong sync after UC_ERR_[READ, WRITE, FETCH]_[UNMAPPED, PROT] (#1368)
* Fix wrong sync after UC_ERR_[READ, WRITE, FETCH]_[UNMAPPED, PROT] Note that: 1. We only guarantee the pc (and other internal states) is correct if and only of `uc_emu_start` returns without any error (or errors have been handled in callbacks.). 2. If memory read/write error isn't handled by hooks, the state is undefined and the pc is probably wrong if no hook is installed. This fixes #1323. * Rename variables * Add note in unicorn.h * Refine test_i386_invalid_mem_read_in_tb
This commit is contained in:
@ -327,17 +327,31 @@ static tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
|
||||
* or timer mode is in effect, since these already fix the PC.
|
||||
*/
|
||||
if (!HOOK_EXISTS(env->uc, UC_HOOK_CODE) && !env->uc->timeout) {
|
||||
if (cc->synchronize_from_tb) {
|
||||
// avoid sync twice when helper_uc_tracecode() already did this.
|
||||
if (env->uc->emu_counter <= env->uc->emu_count &&
|
||||
!env->uc->stop_request && !env->uc->quit_request)
|
||||
cc->synchronize_from_tb(cpu, tb);
|
||||
} else {
|
||||
assert(cc->set_pc);
|
||||
// avoid sync twice when helper_uc_tracecode() already did this.
|
||||
if (env->uc->emu_counter <= env->uc->emu_count &&
|
||||
!env->uc->stop_request && !env->uc->quit_request)
|
||||
cc->set_pc(cpu, tb->pc);
|
||||
// We should sync pc for R/W error.
|
||||
switch (env->invalid_error) {
|
||||
case UC_ERR_WRITE_PROT:
|
||||
case UC_ERR_READ_PROT:
|
||||
case UC_ERR_FETCH_PROT:
|
||||
case UC_ERR_WRITE_UNMAPPED:
|
||||
case UC_ERR_READ_UNMAPPED:
|
||||
case UC_ERR_FETCH_UNMAPPED:
|
||||
case UC_ERR_WRITE_UNALIGNED:
|
||||
case UC_ERR_READ_UNALIGNED:
|
||||
case UC_ERR_FETCH_UNALIGNED:
|
||||
break;
|
||||
default:
|
||||
if (cc->synchronize_from_tb) {
|
||||
// avoid sync twice when helper_uc_tracecode() already did this.
|
||||
if (env->uc->emu_counter <= env->uc->emu_count &&
|
||||
!env->uc->stop_request && !env->uc->quit_request)
|
||||
cc->synchronize_from_tb(cpu, tb);
|
||||
} else {
|
||||
assert(cc->set_pc);
|
||||
// avoid sync twice when helper_uc_tracecode() already did this.
|
||||
if (env->uc->emu_counter <= env->uc->emu_count &&
|
||||
!env->uc->stop_request && !env->uc->quit_request)
|
||||
cc->set_pc(cpu, tb->pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user