mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-02 10:51:06 +00:00
target/arm: Set btype for indirect branches
Backports commit 001d47b6efbe4795ed77366986b8ef384ab8b127 from qemu
This commit is contained in:
parent
11736a659b
commit
4dc5f80683
|
@ -151,6 +151,20 @@ static void reset_btype(DisasContext *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_btype(DisasContext *s, int val)
|
||||||
|
{
|
||||||
|
TCGv_i32 tcg_val;
|
||||||
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
|
|
||||||
|
/* BTYPE is a 2-bit field, and 0 should be done with reset_btype. */
|
||||||
|
tcg_debug_assert(val >= 1 && val <= 3);
|
||||||
|
|
||||||
|
tcg_val = tcg_const_i32(tcg_ctx, val);
|
||||||
|
tcg_gen_st_i32(tcg_ctx, tcg_val, tcg_ctx->cpu_env, offsetof(CPUARMState, btype));
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tcg_val);
|
||||||
|
s->btype = -1;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
|
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags)
|
fprintf_function cpu_fprintf, int flags)
|
||||||
|
@ -2063,6 +2077,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
unsigned int opc, op2, op3, rn, op4;
|
unsigned int opc, op2, op3, rn, op4;
|
||||||
|
unsigned btype_mod = 2; /* 0: BR, 1: BLR, 2: other */
|
||||||
TCGv_i64 dst;
|
TCGv_i64 dst;
|
||||||
TCGv_i64 modifier;
|
TCGv_i64 modifier;
|
||||||
|
|
||||||
|
@ -2080,6 +2095,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
case 0: /* BR */
|
case 0: /* BR */
|
||||||
case 1: /* BLR */
|
case 1: /* BLR */
|
||||||
case 2: /* RET */
|
case 2: /* RET */
|
||||||
|
btype_mod = opc;
|
||||||
switch (op3) {
|
switch (op3) {
|
||||||
case 0:
|
case 0:
|
||||||
/* BR, BLR, RET */
|
/* BR, BLR, RET */
|
||||||
|
@ -2123,7 +2139,6 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
default:
|
default:
|
||||||
goto do_unallocated;
|
goto do_unallocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_a64_set_pc(s, dst);
|
gen_a64_set_pc(s, dst);
|
||||||
/* BLR also needs to load return address */
|
/* BLR also needs to load return address */
|
||||||
if (opc == 1) {
|
if (opc == 1) {
|
||||||
|
@ -2139,6 +2154,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
if ((op3 & ~1) != 2) {
|
if ((op3 & ~1) != 2) {
|
||||||
goto do_unallocated;
|
goto do_unallocated;
|
||||||
}
|
}
|
||||||
|
btype_mod = opc & 1;
|
||||||
if (s->pauth_active) {
|
if (s->pauth_active) {
|
||||||
dst = new_tmp_a64(s);
|
dst = new_tmp_a64(s);
|
||||||
modifier = cpu_reg_sp(s, op4);
|
modifier = cpu_reg_sp(s, op4);
|
||||||
|
@ -2218,6 +2234,26 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (btype_mod) {
|
||||||
|
case 0: /* BR */
|
||||||
|
if (dc_isar_feature(aa64_bti, s)) {
|
||||||
|
/* BR to {x16,x17} or !guard -> 1, else 3. */
|
||||||
|
set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* BLR */
|
||||||
|
if (dc_isar_feature(aa64_bti, s)) {
|
||||||
|
/* BLR sets BTYPE to 2, regardless of source guarded page. */
|
||||||
|
set_btype(s, 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* RET or none of the above. */
|
||||||
|
/* BTYPE will be set to 0 by normal end-of-insn processing. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
s->base.is_jmp = DISAS_JUMP;
|
s->base.is_jmp = DISAS_JUMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue