Commit 8cbcb4fa2c6d5fb84552ab141c6e35d33323aa18

Authored by aurel32
1 parent 33759846

Fix broken PPC user space single stepping

(Jason Wessel)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4421 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 39 additions and 23 deletions
target-ppc/translate.c
... ... @@ -29,6 +29,10 @@
29 29 #include "tcg-op.h"
30 30 #include "qemu-common.h"
31 31  
  32 +#define CPU_SINGLE_STEP 0x1
  33 +#define CPU_BRANCH_STEP 0x2
  34 +#define GDBSTUB_SINGLE_STEP 0x4
  35 +
32 36 /* Include definitions for instructions classes and implementations flags */
33 37 //#define DO_SINGLE_STEP
34 38 //#define PPC_DEBUG_DISAS
... ... @@ -2785,7 +2789,7 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2785 2789 TranslationBlock *tb;
2786 2790 tb = ctx->tb;
2787 2791 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2788   - !ctx->singlestep_enabled) {
  2792 + likely(!ctx->singlestep_enabled)) {
2789 2793 tcg_gen_goto_tb(n);
2790 2794 gen_set_T1(dest);
2791 2795 #if defined(TARGET_PPC64)
... ... @@ -2803,8 +2807,20 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2803 2807 else
2804 2808 #endif
2805 2809 gen_op_b_T1();
2806   - if (ctx->singlestep_enabled)
2807   - gen_op_debug();
  2810 + if (unlikely(ctx->singlestep_enabled)) {
  2811 + if ((ctx->singlestep_enabled &
  2812 + (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
  2813 + ctx->exception == POWERPC_EXCP_BRANCH) {
  2814 + target_ulong tmp = ctx->nip;
  2815 + ctx->nip = dest;
  2816 + GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
  2817 + ctx->nip = tmp;
  2818 + }
  2819 + if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
  2820 + gen_update_nip(ctx, dest);
  2821 + gen_op_debug();
  2822 + }
  2823 + }
2808 2824 tcg_gen_exit_tb(0);
2809 2825 }
2810 2826 }
... ... @@ -2824,6 +2840,7 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2824 2840 {
2825 2841 target_ulong li, target;
2826 2842  
  2843 + ctx->exception = POWERPC_EXCP_BRANCH;
2827 2844 /* sign extend LI */
2828 2845 #if defined(TARGET_PPC64)
2829 2846 if (ctx->sf_mode)
... ... @@ -2842,7 +2859,6 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2842 2859 if (LK(ctx->opcode))
2843 2860 gen_setlr(ctx, ctx->nip);
2844 2861 gen_goto_tb(ctx, 0, target);
2845   - ctx->exception = POWERPC_EXCP_BRANCH;
2846 2862 }
2847 2863  
2848 2864 #define BCOND_IM 0
... ... @@ -2857,6 +2873,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
2857 2873 uint32_t bi = BI(ctx->opcode);
2858 2874 uint32_t mask;
2859 2875  
  2876 + ctx->exception = POWERPC_EXCP_BRANCH;
2860 2877 if ((bo & 0x4) == 0)
2861 2878 gen_op_dec_ctr();
2862 2879 switch(type) {
... ... @@ -2906,7 +2923,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
2906 2923 case 6:
2907 2924 if (type == BCOND_IM) {
2908 2925 gen_goto_tb(ctx, 0, target);
2909   - goto out;
  2926 + return;
2910 2927 } else {
2911 2928 #if defined(TARGET_PPC64)
2912 2929 if (ctx->sf_mode)
... ... @@ -2985,12 +3002,12 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
2985 3002 #endif
2986 3003 gen_op_btest_T1(ctx->nip);
2987 3004 no_test:
2988   - if (ctx->singlestep_enabled)
  3005 + if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
  3006 + gen_update_nip(ctx, ctx->nip);
2989 3007 gen_op_debug();
  3008 + }
2990 3009 tcg_gen_exit_tb(0);
2991 3010 }
2992   - out:
2993   - ctx->exception = POWERPC_EXCP_BRANCH;
2994 3011 }
2995 3012  
2996 3013 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
... ... @@ -6150,7 +6167,6 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6150 6167 target_ulong pc_start;
6151 6168 uint16_t *gen_opc_end;
6152 6169 int supervisor, little_endian;
6153   - int single_step, branch_step;
6154 6170 int j, lj = -1;
6155 6171  
6156 6172 pc_start = tb->pc;
... ... @@ -6184,14 +6200,13 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6184 6200 else
6185 6201 ctx.altivec_enabled = 0;
6186 6202 if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6187   - single_step = 1;
  6203 + ctx.singlestep_enabled = CPU_SINGLE_STEP;
6188 6204 else
6189   - single_step = 0;
  6205 + ctx.singlestep_enabled = 0;
6190 6206 if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6191   - branch_step = 1;
6192   - else
6193   - branch_step = 0;
6194   - ctx.singlestep_enabled = env->singlestep_enabled || single_step == 1;
  6207 + ctx.singlestep_enabled |= CPU_BRANCH_STEP;
  6208 + if (unlikely(env->singlestep_enabled))
  6209 + ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6195 6210 #if defined (DO_SINGLE_STEP) && 0
6196 6211 /* Single step trace mode */
6197 6212 msr_se = 1;
... ... @@ -6284,14 +6299,11 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6284 6299 handler->count++;
6285 6300 #endif
6286 6301 /* Check trace mode exceptions */
6287   - if (unlikely(branch_step != 0 &&
6288   - ctx.exception == POWERPC_EXCP_BRANCH)) {
6289   - GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6290   - } else if (unlikely(single_step != 0 &&
6291   - (ctx.nip <= 0x100 || ctx.nip > 0xF00 ||
6292   - (ctx.nip & 0xFC) != 0x04) &&
6293   - ctx.exception != POWERPC_SYSCALL &&
6294   - ctx.exception != POWERPC_EXCP_TRAP)) {
  6302 + if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
  6303 + (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
  6304 + ctx.exception != POWERPC_SYSCALL &&
  6305 + ctx.exception != POWERPC_EXCP_TRAP &&
  6306 + ctx.exception != POWERPC_EXCP_BRANCH)) {
6295 6307 GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6296 6308 } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6297 6309 (env->singlestep_enabled))) {
... ... @@ -6307,6 +6319,10 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6307 6319 if (ctx.exception == POWERPC_EXCP_NONE) {
6308 6320 gen_goto_tb(&ctx, 0, ctx.nip);
6309 6321 } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
  6322 + if (unlikely(env->singlestep_enabled)) {
  6323 + gen_update_nip(&ctx, ctx.nip);
  6324 + gen_op_debug();
  6325 + }
6310 6326 /* Generate the return instruction */
6311 6327 tcg_gen_exit_tb(0);
6312 6328 }
... ...