mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 00:05:36 +00:00
target/arm: Fix temp double-free in sve ldr/str
The temp that gets assigned to clean_addr has been allocated with new_tmp_a64, which means that it will be freed at the end of the instruction. Freeing it earlier leads to assertion failure. The loop creates a complication, in which we allocate a new local temp, which does need freeing, and the final code path is shared between the loop and non-loop. Fix this complication by adding new_tmp_a64_local so that the new local temp is freed at the end, and can be treated exactly like the non-loop path. Fixes: bba87d0a0f4 Backports commit 4b4dc9750a0aa0b9766bd755bf6512a84744ce8a from qemu
This commit is contained in:
parent
54e2107bdf
commit
57c66389c2
|
@ -4858,6 +4858,7 @@
|
|||
#define mte_checkN_ mte_checkN__aarch64
|
||||
#define mte_probe1 mte_probe1_aarch64
|
||||
#define new_tmp_a64 new_tmp_a64_aarch64
|
||||
#define new_tmp_a64_local new_tmp_a64_local_aarch64
|
||||
#define new_tmp_a64_zero new_tmp_a64_zero_aarch64
|
||||
#define pmsav8_mpu_lookup pmsav8_mpu_lookup_aarch64
|
||||
#define pmu_op_start pmu_op_start_aarch64
|
||||
|
|
|
@ -4858,6 +4858,7 @@
|
|||
#define mte_checkN_ mte_checkN__aarch64eb
|
||||
#define mte_probe1 mte_probe1_aarch64eb
|
||||
#define new_tmp_a64 new_tmp_a64_aarch64eb
|
||||
#define new_tmp_a64_local new_tmp_a64_local_aarch64eb
|
||||
#define new_tmp_a64_zero new_tmp_a64_zero_aarch64eb
|
||||
#define pmsav8_mpu_lookup pmsav8_mpu_lookup_aarch64eb
|
||||
#define pmu_op_start pmu_op_start_aarch64eb
|
||||
|
|
|
@ -4998,6 +4998,7 @@ aarch64_symbols = (
|
|||
'mte_checkN_',
|
||||
'mte_probe1',
|
||||
'new_tmp_a64',
|
||||
'new_tmp_a64_local',
|
||||
'new_tmp_a64_zero',
|
||||
'pmsav8_mpu_lookup',
|
||||
'pmu_op_start',
|
||||
|
|
|
@ -607,6 +607,14 @@ TCGv_i64 new_tmp_a64(DisasContext *s)
|
|||
return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64(tcg_ctx);
|
||||
}
|
||||
|
||||
TCGv_i64 new_tmp_a64_local(DisasContext *s)
|
||||
{
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||
assert(s->tmp_a64_count < TMP_A64_MAX);
|
||||
return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_local_new_i64(tcg_ctx);
|
||||
}
|
||||
|
||||
|
||||
TCGv_i64 new_tmp_a64_zero(DisasContext *s)
|
||||
{
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||
|
|
|
@ -30,6 +30,7 @@ void unallocated_encoding(DisasContext *s);
|
|||
} while (0)
|
||||
|
||||
TCGv_i64 new_tmp_a64(DisasContext *s);
|
||||
TCGv_i64 new_tmp_a64_local(DisasContext *s);
|
||||
TCGv_i64 new_tmp_a64_zero(DisasContext *s);
|
||||
TCGv_i64 cpu_reg(DisasContext *s, int reg);
|
||||
TCGv_i64 cpu_reg_sp(DisasContext *s, int reg);
|
||||
|
|
|
@ -4521,9 +4521,8 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
|
|||
|
||||
/* Copy the clean address into a local temp, live across the loop. */
|
||||
t0 = clean_addr;
|
||||
clean_addr = tcg_temp_local_new_i64(tcg_ctx);
|
||||
clean_addr = new_tmp_a64_local(s);
|
||||
tcg_gen_mov_i64(tcg_ctx, clean_addr, t0);
|
||||
tcg_temp_free_i64(tcg_ctx, t0);
|
||||
|
||||
gen_set_label(tcg_ctx, loop);
|
||||
|
||||
|
@ -4571,7 +4570,6 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
|
|||
tcg_gen_st_i64(tcg_ctx, t0, tcg_ctx->cpu_env, vofs + len_align);
|
||||
tcg_temp_free_i64(tcg_ctx, t0);
|
||||
}
|
||||
tcg_temp_free_i64(tcg_ctx, clean_addr);
|
||||
}
|
||||
|
||||
/* Similarly for stores. */
|
||||
|
@ -4613,9 +4611,8 @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
|
|||
|
||||
/* Copy the clean address into a local temp, live across the loop. */
|
||||
t0 = clean_addr;
|
||||
clean_addr = tcg_temp_local_new_i64(tcg_ctx);
|
||||
clean_addr = new_tmp_a64_local(s);
|
||||
tcg_gen_mov_i64(tcg_ctx, clean_addr, t0);
|
||||
tcg_temp_free_i64(tcg_ctx, t0);
|
||||
|
||||
gen_set_label(tcg_ctx, loop);
|
||||
|
||||
|
@ -4659,7 +4656,6 @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
|
|||
}
|
||||
tcg_temp_free_i64(tcg_ctx, t0);
|
||||
}
|
||||
tcg_temp_free_i64(tcg_ctx, clean_addr);
|
||||
}
|
||||
|
||||
static bool trans_LDR_zri(DisasContext *s, arg_rri *a)
|
||||
|
|
Loading…
Reference in a new issue