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,6 +29,10 @@
29 #include "tcg-op.h" 29 #include "tcg-op.h"
30 #include "qemu-common.h" 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 /* Include definitions for instructions classes and implementations flags */ 36 /* Include definitions for instructions classes and implementations flags */
33 //#define DO_SINGLE_STEP 37 //#define DO_SINGLE_STEP
34 //#define PPC_DEBUG_DISAS 38 //#define PPC_DEBUG_DISAS
@@ -2785,7 +2789,7 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, @@ -2785,7 +2789,7 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2785 TranslationBlock *tb; 2789 TranslationBlock *tb;
2786 tb = ctx->tb; 2790 tb = ctx->tb;
2787 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && 2791 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2788 - !ctx->singlestep_enabled) { 2792 + likely(!ctx->singlestep_enabled)) {
2789 tcg_gen_goto_tb(n); 2793 tcg_gen_goto_tb(n);
2790 gen_set_T1(dest); 2794 gen_set_T1(dest);
2791 #if defined(TARGET_PPC64) 2795 #if defined(TARGET_PPC64)
@@ -2803,8 +2807,20 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, @@ -2803,8 +2807,20 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2803 else 2807 else
2804 #endif 2808 #endif
2805 gen_op_b_T1(); 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 tcg_gen_exit_tb(0); 2824 tcg_gen_exit_tb(0);
2809 } 2825 }
2810 } 2826 }
@@ -2824,6 +2840,7 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) @@ -2824,6 +2840,7 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2824 { 2840 {
2825 target_ulong li, target; 2841 target_ulong li, target;
2826 2842
  2843 + ctx->exception = POWERPC_EXCP_BRANCH;
2827 /* sign extend LI */ 2844 /* sign extend LI */
2828 #if defined(TARGET_PPC64) 2845 #if defined(TARGET_PPC64)
2829 if (ctx->sf_mode) 2846 if (ctx->sf_mode)
@@ -2842,7 +2859,6 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) @@ -2842,7 +2859,6 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2842 if (LK(ctx->opcode)) 2859 if (LK(ctx->opcode))
2843 gen_setlr(ctx, ctx->nip); 2860 gen_setlr(ctx, ctx->nip);
2844 gen_goto_tb(ctx, 0, target); 2861 gen_goto_tb(ctx, 0, target);
2845 - ctx->exception = POWERPC_EXCP_BRANCH;  
2846 } 2862 }
2847 2863
2848 #define BCOND_IM 0 2864 #define BCOND_IM 0
@@ -2857,6 +2873,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type) @@ -2857,6 +2873,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
2857 uint32_t bi = BI(ctx->opcode); 2873 uint32_t bi = BI(ctx->opcode);
2858 uint32_t mask; 2874 uint32_t mask;
2859 2875
  2876 + ctx->exception = POWERPC_EXCP_BRANCH;
2860 if ((bo & 0x4) == 0) 2877 if ((bo & 0x4) == 0)
2861 gen_op_dec_ctr(); 2878 gen_op_dec_ctr();
2862 switch(type) { 2879 switch(type) {
@@ -2906,7 +2923,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type) @@ -2906,7 +2923,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
2906 case 6: 2923 case 6:
2907 if (type == BCOND_IM) { 2924 if (type == BCOND_IM) {
2908 gen_goto_tb(ctx, 0, target); 2925 gen_goto_tb(ctx, 0, target);
2909 - goto out; 2926 + return;
2910 } else { 2927 } else {
2911 #if defined(TARGET_PPC64) 2928 #if defined(TARGET_PPC64)
2912 if (ctx->sf_mode) 2929 if (ctx->sf_mode)
@@ -2985,12 +3002,12 @@ static always_inline void gen_bcond (DisasContext *ctx, int type) @@ -2985,12 +3002,12 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
2985 #endif 3002 #endif
2986 gen_op_btest_T1(ctx->nip); 3003 gen_op_btest_T1(ctx->nip);
2987 no_test: 3004 no_test:
2988 - if (ctx->singlestep_enabled) 3005 + if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
  3006 + gen_update_nip(ctx, ctx->nip);
2989 gen_op_debug(); 3007 gen_op_debug();
  3008 + }
2990 tcg_gen_exit_tb(0); 3009 tcg_gen_exit_tb(0);
2991 } 3010 }
2992 - out:  
2993 - ctx->exception = POWERPC_EXCP_BRANCH;  
2994 } 3011 }
2995 3012
2996 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW) 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,7 +6167,6 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6150 target_ulong pc_start; 6167 target_ulong pc_start;
6151 uint16_t *gen_opc_end; 6168 uint16_t *gen_opc_end;
6152 int supervisor, little_endian; 6169 int supervisor, little_endian;
6153 - int single_step, branch_step;  
6154 int j, lj = -1; 6170 int j, lj = -1;
6155 6171
6156 pc_start = tb->pc; 6172 pc_start = tb->pc;
@@ -6184,14 +6200,13 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, @@ -6184,14 +6200,13 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6184 else 6200 else
6185 ctx.altivec_enabled = 0; 6201 ctx.altivec_enabled = 0;
6186 if ((env->flags & POWERPC_FLAG_SE) && msr_se) 6202 if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6187 - single_step = 1; 6203 + ctx.singlestep_enabled = CPU_SINGLE_STEP;
6188 else 6204 else
6189 - single_step = 0; 6205 + ctx.singlestep_enabled = 0;
6190 if ((env->flags & POWERPC_FLAG_BE) && msr_be) 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 #if defined (DO_SINGLE_STEP) && 0 6210 #if defined (DO_SINGLE_STEP) && 0
6196 /* Single step trace mode */ 6211 /* Single step trace mode */
6197 msr_se = 1; 6212 msr_se = 1;
@@ -6284,14 +6299,11 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, @@ -6284,14 +6299,11 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6284 handler->count++; 6299 handler->count++;
6285 #endif 6300 #endif
6286 /* Check trace mode exceptions */ 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 GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0); 6307 GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6296 } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || 6308 } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6297 (env->singlestep_enabled))) { 6309 (env->singlestep_enabled))) {
@@ -6307,6 +6319,10 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, @@ -6307,6 +6319,10 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6307 if (ctx.exception == POWERPC_EXCP_NONE) { 6319 if (ctx.exception == POWERPC_EXCP_NONE) {
6308 gen_goto_tb(&ctx, 0, ctx.nip); 6320 gen_goto_tb(&ctx, 0, ctx.nip);
6309 } else if (ctx.exception != POWERPC_EXCP_BRANCH) { 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 /* Generate the return instruction */ 6326 /* Generate the return instruction */
6311 tcg_gen_exit_tb(0); 6327 tcg_gen_exit_tb(0);
6312 } 6328 }