diff options
author | Fabien Chouteau | 2019-03-25 12:45:54 +0100 |
---|---|---|
committer | Palmer Dabbelt | 2019-05-24 21:09:22 +0200 |
commit | 6e2716d8ca4edf3597307accef7af36e8ad966eb (patch) | |
tree | f009cae605d716ba41226406841fb32b1768b3c2 /target/riscv/translate.c | |
parent | target/riscv: Do not allow sfence.vma from user mode (diff) | |
download | qemu-6e2716d8ca4edf3597307accef7af36e8ad966eb.tar.gz qemu-6e2716d8ca4edf3597307accef7af36e8ad966eb.tar.xz qemu-6e2716d8ca4edf3597307accef7af36e8ad966eb.zip |
RISC-V: fix single stepping over ret and other branching instructions
This patch introduces wrappers around the tcg_gen_exit_tb() and
tcg_gen_lookup_and_goto_ptr() functions that handle single stepping,
i.e. call gen_exception_debug() when single stepping is enabled.
Theses functions are then used instead of the originals, bringing single
stepping handling in places where it was previously ignored such as jalr
and system branch instructions (ecall, mret, sret, etc.).
Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'target/riscv/translate.c')
-rw-r--r-- | target/riscv/translate.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 2ff6b49487..840ecbef36 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -109,6 +109,26 @@ static void gen_exception_debug(void) tcg_temp_free_i32(helper_tmp); } +/* Wrapper around tcg_gen_exit_tb that handles single stepping */ +static void exit_tb(DisasContext *ctx) +{ + if (ctx->base.singlestep_enabled) { + gen_exception_debug(); + } else { + tcg_gen_exit_tb(NULL, 0); + } +} + +/* Wrapper around tcg_gen_lookup_and_goto_ptr that handles single stepping */ +static void lookup_and_goto_ptr(DisasContext *ctx) +{ + if (ctx->base.singlestep_enabled) { + gen_exception_debug(); + } else { + tcg_gen_lookup_and_goto_ptr(); + } +} + static void gen_exception_illegal(DisasContext *ctx) { generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST); @@ -138,14 +158,14 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) /* chaining is only allowed when the jump is to the same page */ tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_pc, dest); + + /* No need to check for single stepping here as use_goto_tb() will + * return false in case of single stepping. + */ tcg_gen_exit_tb(ctx->base.tb, n); } else { tcg_gen_movi_tl(cpu_pc, dest); - if (ctx->base.singlestep_enabled) { - gen_exception_debug(); - } else { - tcg_gen_lookup_and_goto_ptr(); - } + lookup_and_goto_ptr(ctx); } } |