diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 6b8004dc..842415f2 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_aarch64 #define helper_divu_i64 helper_divu_i64_aarch64 #define helper_double_saturate helper_double_saturate_aarch64 +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_aarch64 #define helper_exception_internal helper_exception_internal_aarch64 #define helper_exception_return helper_exception_return_aarch64 #define helper_exception_with_syndrome helper_exception_with_syndrome_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 9205a359..05716ae8 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_aarch64eb #define helper_divu_i64 helper_divu_i64_aarch64eb #define helper_double_saturate helper_double_saturate_aarch64eb +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_aarch64eb #define helper_exception_internal helper_exception_internal_aarch64eb #define helper_exception_return helper_exception_return_aarch64eb #define helper_exception_with_syndrome helper_exception_with_syndrome_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 2c6d61ca..c5487240 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_arm #define helper_divu_i64 helper_divu_i64_arm #define helper_double_saturate helper_double_saturate_arm +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_arm #define helper_exception_internal helper_exception_internal_arm #define helper_exception_return helper_exception_return_arm #define helper_exception_with_syndrome helper_exception_with_syndrome_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 6ba9e124..7c8feead 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_armeb #define helper_divu_i64 helper_divu_i64_armeb #define helper_double_saturate helper_double_saturate_armeb +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_armeb #define helper_exception_internal helper_exception_internal_armeb #define helper_exception_return helper_exception_return_armeb #define helper_exception_with_syndrome helper_exception_with_syndrome_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index fdafd258..86a971e3 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -973,6 +973,7 @@ symbols = ( 'helper_divu_i32', 'helper_divu_i64', 'helper_double_saturate', + 'helper_exception_bkpt_insn', 'helper_exception_internal', 'helper_exception_return', 'helper_exception_with_syndrome', diff --git a/qemu/m68k.h b/qemu/m68k.h index 32513a5f..25de61d1 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_m68k #define helper_divu_i64 helper_divu_i64_m68k #define helper_double_saturate helper_double_saturate_m68k +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_m68k #define helper_exception_internal helper_exception_internal_m68k #define helper_exception_return helper_exception_return_m68k #define helper_exception_with_syndrome helper_exception_with_syndrome_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 8b539661..a943b309 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_mips #define helper_divu_i64 helper_divu_i64_mips #define helper_double_saturate helper_double_saturate_mips +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_mips #define helper_exception_internal helper_exception_internal_mips #define helper_exception_return helper_exception_return_mips #define helper_exception_with_syndrome helper_exception_with_syndrome_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 9010919b..8ca8f55a 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_mips64 #define helper_divu_i64 helper_divu_i64_mips64 #define helper_double_saturate helper_double_saturate_mips64 +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_mips64 #define helper_exception_internal helper_exception_internal_mips64 #define helper_exception_return helper_exception_return_mips64 #define helper_exception_with_syndrome helper_exception_with_syndrome_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index a2e44acd..f64ab3e8 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_mips64el #define helper_divu_i64 helper_divu_i64_mips64el #define helper_double_saturate helper_double_saturate_mips64el +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_mips64el #define helper_exception_internal helper_exception_internal_mips64el #define helper_exception_return helper_exception_return_mips64el #define helper_exception_with_syndrome helper_exception_with_syndrome_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 6ff8943e..b2b86e55 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_mipsel #define helper_divu_i64 helper_divu_i64_mipsel #define helper_double_saturate helper_double_saturate_mipsel +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_mipsel #define helper_exception_internal helper_exception_internal_mipsel #define helper_exception_return helper_exception_return_mipsel #define helper_exception_with_syndrome helper_exception_with_syndrome_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 76036bd9..487bbb83 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_powerpc #define helper_divu_i64 helper_divu_i64_powerpc #define helper_double_saturate helper_double_saturate_powerpc +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_powerpc #define helper_exception_internal helper_exception_internal_powerpc #define helper_exception_return helper_exception_return_powerpc #define helper_exception_with_syndrome helper_exception_with_syndrome_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 2b96df45..25ca7e54 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_sparc #define helper_divu_i64 helper_divu_i64_sparc #define helper_double_saturate helper_double_saturate_sparc +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_sparc #define helper_exception_internal helper_exception_internal_sparc #define helper_exception_return helper_exception_return_sparc #define helper_exception_with_syndrome helper_exception_with_syndrome_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 9961a6ce..2bea55ae 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_sparc64 #define helper_divu_i64 helper_divu_i64_sparc64 #define helper_double_saturate helper_double_saturate_sparc64 +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_sparc64 #define helper_exception_internal helper_exception_internal_sparc64 #define helper_exception_return helper_exception_return_sparc64 #define helper_exception_with_syndrome helper_exception_with_syndrome_sparc64 diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index c25938a7..524e013d 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -49,6 +49,7 @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32) DEF_HELPER_2(exception_internal, void, env, i32) DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32) +DEF_HELPER_2(exception_bkpt_insn, void, env, i32) DEF_HELPER_1(setend, void, env) DEF_HELPER_2(wfi, void, env, i32) DEF_HELPER_1(wfe, void, env) diff --git a/qemu/target/arm/op_helper.c b/qemu/target/arm/op_helper.c index d3460aa7..a71f3847 100644 --- a/qemu/target/arm/op_helper.c +++ b/qemu/target/arm/op_helper.c @@ -489,6 +489,14 @@ void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp, raise_exception(env, excp, syndrome, target_el); } +/* Raise an EXCP_BKPT with the specified syndrome register value, + * targeting the correct exception level for debug exceptions. + */ +void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome) +{ + raise_exception(env, EXCP_BKPT, syndrome, arm_debug_target_el(env)); +} + uint32_t HELPER(cpsr_read)(CPUARMState *env) { return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED); diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 66e13fff..e7bc82cb 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -340,6 +340,19 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp, s->base.is_jmp = DISAS_NORETURN; } +static void gen_exception_bkpt_insn(DisasContext *s, int offset, + uint32_t syndrome) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + TCGv_i32 tcg_syn; + + gen_a64_set_pc_im(s, s->pc - offset); + tcg_syn = tcg_const_i32(tcg_ctx, syndrome); + gen_helper_exception_bkpt_insn(tcg_ctx, tcg_ctx->cpu_env, tcg_syn); + tcg_temp_free_i32(tcg_ctx, tcg_syn); + s->base.is_jmp = DISAS_NORETURN; +} + static void gen_ss_advance(DisasContext *s) { TCGContext *tcg_ctx = s->uc->tcg_ctx; @@ -1907,8 +1920,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) break; } /* BRK */ - gen_exception_insn(s, 4, EXCP_BKPT, syn_aa64_bkpt(imm16), - default_exception_el(s)); + gen_exception_bkpt_insn(s, 4, syn_aa64_bkpt(imm16)); break; case 2: if (op2_ll != 0) { diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 11f349e1..b8a8130f 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -1292,6 +1292,19 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp, s->base.is_jmp = DISAS_NORETURN; } +static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + TCGv_i32 tcg_syn; + + gen_set_condexec(s); + gen_set_pc_im(s, s->pc - offset); + tcg_syn = tcg_const_i32(tcg_ctx, syn); + gen_helper_exception_bkpt_insn(tcg_ctx, tcg_ctx->cpu_env, tcg_syn); + tcg_temp_free_i32(tcg_ctx, tcg_syn); + s->base.is_jmp = DISAS_NORETURN; +} + /* Force a TB lookup after an instruction that changes the CPU state. */ static inline void gen_lookup_tb(DisasContext *s) { @@ -8953,9 +8966,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq case 1: /* bkpt */ ARCH(5); - gen_exception_insn(s, 4, EXCP_BKPT, - syn_aa32_bkpt(imm16, false), - default_exception_el(s)); + gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false)); break; case 2: /* Hypervisor call (v7) */ @@ -12191,8 +12202,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) { int imm8 = extract32(insn, 0, 8); ARCH(5); - gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true), - default_exception_el(s)); + gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true)); break; } diff --git a/qemu/x86_64.h b/qemu/x86_64.h index d987b500..9461f5e4 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -967,6 +967,7 @@ #define helper_divu_i32 helper_divu_i32_x86_64 #define helper_divu_i64 helper_divu_i64_x86_64 #define helper_double_saturate helper_double_saturate_x86_64 +#define helper_exception_bkpt_insn helper_exception_bkpt_insn_x86_64 #define helper_exception_internal helper_exception_internal_x86_64 #define helper_exception_return helper_exception_return_x86_64 #define helper_exception_with_syndrome helper_exception_with_syndrome_x86_64