mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-12 22:45:38 +00:00
cpu-exec: fix icount out-of-bounds access
When icount is active, tb_add_jump is surprisingly called with an out of bounds basic block index. I have no idea how that can work, but it does not seem like a good idea. Clear *last_tb for all TB_EXIT_ICOUNT_EXPIRED cases, even when all you have to do is refill icount_extra. Backports commit d8dea6fbcbed177ca5d23ab77b3834a9437f0e88 from qemu
This commit is contained in:
parent
6820964e2f
commit
9404dbf74e
qemu
|
@ -395,7 +395,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
|
|||
|
||||
/* execute the generated code */
|
||||
ret = cpu_tb_exec(cpu, tb);
|
||||
*last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
|
||||
tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
|
||||
*tb_exit = ret & TB_EXIT_MASK;
|
||||
switch (*tb_exit) {
|
||||
case TB_EXIT_REQUESTED:
|
||||
|
@ -419,6 +419,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
|
|||
abort();
|
||||
#else
|
||||
int insns_left = cpu->icount_decr.u32;
|
||||
*last_tb = NULL;
|
||||
if (cpu->icount_extra && insns_left >= 0) {
|
||||
/* Refill decrementer and continue execution. */
|
||||
cpu->icount_extra += insns_left;
|
||||
|
@ -428,18 +429,18 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
|
|||
} else {
|
||||
if (insns_left > 0) {
|
||||
/* Execute remaining instructions. */
|
||||
cpu_exec_nocache(cpu, insns_left, *last_tb, false);
|
||||
cpu_exec_nocache(cpu, insns_left, tb, false);
|
||||
// Unicorn: commented out
|
||||
//align_clocks(sc, cpu);
|
||||
}
|
||||
cpu->exception_index = EXCP_INTERRUPT;
|
||||
*last_tb = NULL;
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
*last_tb = tb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -338,6 +338,7 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
|
|||
static inline void tb_add_jump(TranslationBlock *tb, int n,
|
||||
TranslationBlock *tb_next)
|
||||
{
|
||||
assert(n < ARRAY_SIZE(tb->jmp_list_next));
|
||||
if (tb->jmp_list_next[n]) {
|
||||
/* Another thread has already done this while we were
|
||||
* outside of the lock; nothing to do in this case */
|
||||
|
|
Loading…
Reference in a new issue