From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KxPcd-0002n0-8g for qemu-devel@nongnu.org; Tue, 04 Nov 2008 12:23:19 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KxPcc-0002mg-L4 for qemu-devel@nongnu.org; Tue, 04 Nov 2008 12:23:18 -0500 Received: from [199.232.76.173] (port=40204 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KxPcc-0002ma-Cu for qemu-devel@nongnu.org; Tue, 04 Nov 2008 12:23:18 -0500 Received: from lizzard.sbs.de ([194.138.37.39]:21175) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KxPcc-0002b9-9k for qemu-devel@nongnu.org; Tue, 04 Nov 2008 12:23:18 -0500 Message-ID: <491084F7.2050800@siemens.com> Date: Tue, 04 Nov 2008 18:23:03 +0100 From: Jan Kiszka MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] gdbstub: x86-64: reintroduce dynamic register sets Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paul Brook Commit 5459 broke the dynamic register set switching of qemu's gdbstub for x86-64. This prevents setting the correct architecture in gdb when debugging 32 or 16-bit code in a 64-bit emulator. Fix this. Signed-off-by: Jan Kiszka --- gdbstub.c | 54 +++++++++++++++++++++++++++++++++++++++++++----------- target-i386/cpu.h | 7 +++++-- 2 files changed, 48 insertions(+), 13 deletions(-) Index: b/gdbstub.c =================================================================== --- a/gdbstub.c +++ b/gdbstub.c @@ -302,15 +302,22 @@ static const int gpr_map[16] = { 8, 9, 10, 11, 12, 13, 14, 15 }; #else -static const int gpr_map[8] = {0, 1, 2, 3, 4, 5, 6, 7}; +#define gpr_map gpr_map32 #endif +static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; #define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25) static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) { if (n < CPU_NB_REGS) { - GET_REGL(env->regs[gpr_map[n]]); + if (TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK)) { + GET_REGL(env->regs[gpr_map[n]]); + } else if (n < CPU_NB_REGS32) { + GET_REG32(env->regs[gpr_map32[n]]); + } else { + return 0; + } } else if (n >= CPU_NB_REGS + 8 && n < CPU_NB_REGS + 16) { /* FIXME: byteswap float values. */ #ifdef USE_X86LDOUBLE @@ -321,17 +328,25 @@ static int cpu_gdb_read_register(CPUStat return 10; } else if (n >= CPU_NB_REGS + 24) { n -= CPU_NB_REGS + 24; - if (n < CPU_NB_REGS) { + if (n < CPU_NB_REGS32 + || (TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK) + && n < CPU_NB_REGS64)) { stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0)); stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1)); return 16; - } else if (n == CPU_NB_REGS) { + } else if ((TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK) + && n == CPU_NB_REGS64) || n == CPU_NB_REGS32) { GET_REG32(env->mxcsr); - } + } } else { n -= CPU_NB_REGS; switch (n) { - case 0: GET_REGL(env->eip); + case 0: + if (TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK)) { + GET_REG64(env->eip); + } else { + GET_REG32(env->eip); + } case 1: GET_REG32(env->eflags); case 2: GET_REG32(env->segs[R_CS].selector); case 3: GET_REG32(env->segs[R_SS].selector); @@ -359,8 +374,15 @@ static int cpu_gdb_write_register(CPUSta uint32_t tmp; if (i < CPU_NB_REGS) { - env->regs[gpr_map[i]] = ldtul_p(mem_buf); - return sizeof(target_ulong); + if (TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK)) { + env->regs[gpr_map[i]] = ldtul_p(mem_buf); + return sizeof(target_ulong); + } else if (i < CPU_NB_REGS32) { + env->regs[gpr_map32[i]] = ldl_p(mem_buf); + return 4; + } else { + return 0; + } } else if (i >= CPU_NB_REGS + 8 && i < CPU_NB_REGS + 16) { i -= CPU_NB_REGS + 8; #ifdef USE_X86LDOUBLE @@ -369,18 +391,28 @@ static int cpu_gdb_write_register(CPUSta return 10; } else if (i >= CPU_NB_REGS + 24) { i -= CPU_NB_REGS + 24; - if (i < CPU_NB_REGS) { + if (i < CPU_NB_REGS32 + || (TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK) + && i < CPU_NB_REGS64)) { env->xmm_regs[i].XMM_Q(0) = ldq_p(mem_buf); env->xmm_regs[i].XMM_Q(1) = ldq_p(mem_buf + 8); return 16; - } else if (i == CPU_NB_REGS) { + } else if ((TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK) + && i == CPU_NB_REGS64) || i == CPU_NB_REGS32) { env->mxcsr = ldl_p(mem_buf); return 4; } } else { i -= CPU_NB_REGS; switch (i) { - case 0: env->eip = ldtul_p(mem_buf); return sizeof(target_ulong); + case 0: + if (TARGET_LONG_BITS == 64 && (env->hflags & HF_CS64_MASK)) { + env->eip = ldq_p(mem_buf); + return 8; + } else { + env->eip = ldl_p(mem_buf); + return 4; + } case 1: env->eflags = ldl_p(mem_buf); return 4; #if defined(CONFIG_USER_ONLY) #define LOAD_SEG(index, sreg)\ Index: b/target-i386/cpu.h =================================================================== --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -494,10 +494,13 @@ typedef union { #endif #define MMX_Q(n) q +#define CPU_NB_REGS64 16 +#define CPU_NB_REGS32 8 + #ifdef TARGET_X86_64 -#define CPU_NB_REGS 16 +#define CPU_NB_REGS CPU_NB_REGS64 #else -#define CPU_NB_REGS 8 +#define CPU_NB_REGS CPU_NB_REGS32 #endif #define NB_MMU_MODES 2 -- Siemens AG, Corporate Technology, CT SE 2 ES-OS Corporate Competence Center Embedded Linux