load_helper only call cpu_loop_exit() when emulation is running
The load_helper is sometimes called from register writes. When the load fails check if emulation is running before jump out of the emulated code.
This commit is contained in:
parent
1d9c5c7653
commit
073c4b74ca
@ -1520,21 +1520,25 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
|
|||||||
mr = find_memory_region(uc, paddr);
|
mr = find_memory_region(uc, paddr);
|
||||||
if (mr == NULL) {
|
if (mr == NULL) {
|
||||||
uc->invalid_error = UC_ERR_MAP;
|
uc->invalid_error = UC_ERR_MAP;
|
||||||
|
if (!uc->cpu->stopped) {
|
||||||
cpu_exit(uc->cpu);
|
cpu_exit(uc->cpu);
|
||||||
// XXX(@lazymio): We have to exit early so that the target register won't be overwritten
|
// XXX(@lazymio): We have to exit early so that the target register won't be overwritten
|
||||||
// because qemu might generate tcg code like:
|
// because qemu might generate tcg code like:
|
||||||
// qemu_ld_i64 x0,x1,leq,8 sync: 0 dead: 0 1
|
// qemu_ld_i64 x0,x1,leq,8 sync: 0 dead: 0 1
|
||||||
// where we don't have a change to recover x0 value
|
// where we don't have a change to recover x0 value
|
||||||
cpu_loop_exit(uc->cpu);
|
cpu_loop_exit(uc->cpu);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uc->invalid_addr = paddr;
|
uc->invalid_addr = paddr;
|
||||||
uc->invalid_error = error_code;
|
uc->invalid_error = error_code;
|
||||||
// printf("***** Invalid fetch (unmapped memory) at " TARGET_FMT_lx "\n", addr);
|
// printf("***** Invalid fetch (unmapped memory) at " TARGET_FMT_lx "\n", addr);
|
||||||
|
if (!uc->cpu->stopped) {
|
||||||
cpu_exit(uc->cpu);
|
cpu_exit(uc->cpu);
|
||||||
// See comments above
|
// See comments above
|
||||||
cpu_loop_exit(uc->cpu);
|
cpu_loop_exit(uc->cpu);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1588,9 +1592,11 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
|
|||||||
uc->invalid_addr = paddr;
|
uc->invalid_addr = paddr;
|
||||||
uc->invalid_error = UC_ERR_READ_PROT;
|
uc->invalid_error = UC_ERR_READ_PROT;
|
||||||
// printf("***** Invalid memory read (non-readable) at " TARGET_FMT_lx "\n", addr);
|
// printf("***** Invalid memory read (non-readable) at " TARGET_FMT_lx "\n", addr);
|
||||||
|
if (!uc->cpu->stopped) {
|
||||||
cpu_exit(uc->cpu);
|
cpu_exit(uc->cpu);
|
||||||
// See comments above
|
// See comments above
|
||||||
cpu_loop_exit(uc->cpu);
|
cpu_loop_exit(uc->cpu);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1618,9 +1624,11 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
|
|||||||
uc->invalid_addr = paddr;
|
uc->invalid_addr = paddr;
|
||||||
uc->invalid_error = UC_ERR_FETCH_PROT;
|
uc->invalid_error = UC_ERR_FETCH_PROT;
|
||||||
// printf("***** Invalid fetch (non-executable) at " TARGET_FMT_lx "\n", addr);
|
// printf("***** Invalid fetch (non-executable) at " TARGET_FMT_lx "\n", addr);
|
||||||
|
if (!uc->cpu->stopped) {
|
||||||
cpu_exit(uc->cpu);
|
cpu_exit(uc->cpu);
|
||||||
// See comments above
|
// See comments above
|
||||||
cpu_loop_exit(uc->cpu);
|
cpu_loop_exit(uc->cpu);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1415,6 +1415,17 @@ static void test_x86_vtlb(void)
|
|||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_x86_segmentation()
|
||||||
|
{
|
||||||
|
uc_engine *uc;
|
||||||
|
uint64_t fs = 0x53;
|
||||||
|
uc_x86_mmr gdtr = { 0, 0xfffff8076d962000, 0x57, 0 };
|
||||||
|
|
||||||
|
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
|
||||||
|
OK(uc_reg_write(uc, UC_X86_REG_GDTR, &gdtr));
|
||||||
|
uc_assert_err(UC_ERR_EXCEPTION, uc_reg_write(uc, UC_X86_REG_FS, &fs));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_LIST = {
|
TEST_LIST = {
|
||||||
{"test_x86_in", test_x86_in},
|
{"test_x86_in", test_x86_in},
|
||||||
@ -1461,4 +1472,5 @@ TEST_LIST = {
|
|||||||
{"test_x86_16_incorrect_ip", test_x86_16_incorrect_ip},
|
{"test_x86_16_incorrect_ip", test_x86_16_incorrect_ip},
|
||||||
{"test_x86_mmu", test_x86_mmu},
|
{"test_x86_mmu", test_x86_mmu},
|
||||||
{"test_x86_vtlb", test_x86_vtlb},
|
{"test_x86_vtlb", test_x86_vtlb},
|
||||||
|
{"test_x86_segmentation", test_x86_segmentation},
|
||||||
{NULL, NULL}};
|
{NULL, NULL}};
|
||||||
|
Loading…
Reference in New Issue
Block a user