From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([209.51.188.92]:58677) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gmWH0-0007mC-NJ for qemu-devel@nongnu.org; Wed, 23 Jan 2019 23:05:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gmWGv-0001RO-Mx for qemu-devel@nongnu.org; Wed, 23 Jan 2019 23:05:49 -0500 Received: from mail-qk1-x72b.google.com ([2607:f8b0:4864:20::72b]:42626) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gmWGv-0001Fp-Bg for qemu-devel@nongnu.org; Wed, 23 Jan 2019 23:05:45 -0500 Received: by mail-qk1-x72b.google.com with SMTP id 68so2445074qke.9 for ; Wed, 23 Jan 2019 20:05:43 -0800 (PST) From: Doug Gale Date: Thu, 24 Jan 2019 00:34:57 -0330 Message-Id: <20190124040457.2546-1-doug16k@gmail.com> Subject: [Qemu-devel] [PATCH] gdbstub: Fix i386/x86_64 machine description and add control registers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini , Richard Henderson , Eduardo Habkost Cc: qemu-devel@nongnu.org, Doug Gale Signed-off-by: Doug Gale --- configure | 4 +- gdb-xml/i386-32bit-core.xml | 65 ----------- gdb-xml/i386-32bit-sse.xml | 52 --------- gdb-xml/i386-32bit.xml | 184 ++++++++++++++++++++++++++++++- gdb-xml/i386-64bit-core.xml | 73 ------------- gdb-xml/i386-64bit-sse.xml | 60 ----------- gdb-xml/i386-64bit.xml | 210 +++++++++++++++++++++++++++++++++++- target/i386/cpu.c | 4 +- target/i386/gdbstub.c | 186 +++++++++++++++++++++++++++++++- 9 files changed, 573 insertions(+), 265 deletions(-) delete mode 100644 gdb-xml/i386-32bit-core.xml delete mode 100644 gdb-xml/i386-32bit-sse.xml delete mode 100644 gdb-xml/i386-64bit-core.xml delete mode 100644 gdb-xml/i386-64bit-sse.xml diff --git a/configure b/configure index 4ea3f14883..c55a97b91c 100755 --- a/configure +++ b/configure @@ -7121,14 +7121,14 @@ TARGET_ABI_DIR="" case "$target_name" in i386) mttcg="yes" - gdb_xml_files="i386-32bit.xml i386-32bit-core.xml i386-32bit-sse.xml" + gdb_xml_files="i386-32bit.xml" target_compiler=$cross_cc_i386 target_compiler_cflags=$cross_cc_ccflags_i386 ;; x86_64) TARGET_BASE_ARCH=i386 mttcg="yes" - gdb_xml_files="i386-64bit.xml i386-64bit-core.xml i386-64bit-sse.xml" + gdb_xml_files="i386-64bit.xml" target_compiler=$cross_cc_x86_64 ;; alpha) diff --git a/gdb-xml/i386-32bit-core.xml b/gdb-xml/i386-32bit-core.xml deleted file mode 100644 index 7aeeeca3b2..0000000000 --- a/gdb-xml/i386-32bit-core.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-32bit-sse.xml b/gdb-xml/i386-32bit-sse.xml deleted file mode 100644 index 57678473d6..0000000000 --- a/gdb-xml/i386-32bit-sse.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-32bit.xml b/gdb-xml/i386-32bit.xml index 956fc7f45f..872fcea9c2 100644 --- a/gdb-xml/i386-32bit.xml +++ b/gdb-xml/i386-32bit.xml @@ -8,7 +8,185 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/i386-64bit-core.xml b/gdb-xml/i386-64bit-core.xml deleted file mode 100644 index 5088d84ceb..0000000000 --- a/gdb-xml/i386-64bit-core.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-64bit-sse.xml b/gdb-xml/i386-64bit-sse.xml deleted file mode 100644 index e86efc9ce5..0000000000 --- a/gdb-xml/i386-64bit-sse.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-64bit.xml b/gdb-xml/i386-64bit.xml index 0b2f00ccbe..6d88969211 100644 --- a/gdb-xml/i386-64bit.xml +++ b/gdb-xml/i386-64bit.xml @@ -5,10 +5,212 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/target/i386/cpu.c b/target/i386/cpu.c index fa37203d89..1e20f6f5ca 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5826,10 +5826,10 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->gdb_arch_name = x86_gdb_arch_name; #ifdef TARGET_X86_64 cc->gdb_core_xml_file = "i386-64bit.xml"; - cc->gdb_num_core_regs = 57; + cc->gdb_num_core_regs = 66; #else cc->gdb_core_xml_file = "i386-32bit.xml"; - cc->gdb_num_core_regs = 41; + cc->gdb_num_core_regs = 50; #endif #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) cc->debug_excp_handler = breakpoint_handler; diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c index 9b94ab852c..3c20b927f0 100644 --- a/target/i386/gdbstub.c +++ b/target/i386/gdbstub.c @@ -32,18 +32,61 @@ static const int gpr_map[16] = { #endif static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +/* + * Keep these in sync with assignment to + * gdb_num_core_regs in target/i386/cpu.c + * and with the machine description + */ + +/* + * SEG: 6 segments, plus fs_base, gs_base, kernel_gs_base + */ + +/* + * general regs -----> 8 or 16 + */ +#define IDX_NB_IP 1 +#define IDX_NB_FLAGS 1 +#define IDX_NB_SEG (6 + 3) +#define IDX_NB_CTL 6 +#define IDX_NB_FP 16 +/* + * fpu regs ----------> 8 or 16 + */ +#define IDX_NB_MXCSR 1 +/* + * total ----> 8+1+1+9+6+16+8+1=50 or 16+1+1+9+6+16+16+1=66 + */ + #define IDX_IP_REG CPU_NB_REGS -#define IDX_FLAGS_REG (IDX_IP_REG + 1) -#define IDX_SEG_REGS (IDX_FLAGS_REG + 1) -#define IDX_FP_REGS (IDX_SEG_REGS + 6) -#define IDX_XMM_REGS (IDX_FP_REGS + 16) +#define IDX_FLAGS_REG (IDX_IP_REG + IDX_NB_IP) +#define IDX_SEG_REGS (IDX_FLAGS_REG + IDX_NB_FLAGS) +#define IDX_CTL_REGS (IDX_SEG_REGS + IDX_NB_SEG) +#define IDX_FP_REGS (IDX_CTL_REGS + IDX_NB_CTL) +#define IDX_XMM_REGS (IDX_FP_REGS + IDX_NB_FP) #define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) +#define IDX_CTL_CR0_REG (IDX_CTL_REGS + 0) +#define IDX_CTL_CR2_REG (IDX_CTL_REGS + 1) +#define IDX_CTL_CR3_REG (IDX_CTL_REGS + 2) +#define IDX_CTL_CR4_REG (IDX_CTL_REGS + 3) +#define IDX_CTL_CR8_REG (IDX_CTL_REGS + 4) +#define IDX_CTL_EFER_REG (IDX_CTL_REGS + 5) + +#ifdef TARGET_X86_64 +#define GDB_FORCE_64 1 +#else +#define GDB_FORCE_64 0 +#endif + + int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; + uint64_t tpr; + /* N.B. GDB can't deal with changes in registers or sizes in the middle of a session. So if we're in 32-bit mode on a 64-bit cpu, still act as if we're on a 64-bit cpu. */ @@ -105,6 +148,28 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_SEG_REGS + 5: return gdb_get_reg32(mem_buf, env->segs[R_GS].selector); + case IDX_SEG_REGS + 6: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->segs[R_FS].base); + } + return gdb_get_reg32(mem_buf, env->segs[R_FS].base); + + case IDX_SEG_REGS + 7: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->segs[R_GS].base); + } + return gdb_get_reg32(mem_buf, env->segs[R_GS].base); + + case IDX_SEG_REGS + 8: +#ifdef TARGET_X86_64 + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->kernelgsbase); + } + return gdb_get_reg32(mem_buf, env->kernelgsbase); +#else + return gdb_get_reg32(mem_buf, 0); +#endif + case IDX_FP_REGS + 8: return gdb_get_reg32(mem_buf, env->fpuc); case IDX_FP_REGS + 9: @@ -125,6 +190,44 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_MXCSR_REG: return gdb_get_reg32(mem_buf, env->mxcsr); + + case IDX_CTL_CR0_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[0]); + } + return gdb_get_reg32(mem_buf, env->cr[0]); + + case IDX_CTL_CR2_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[2]); + } + return gdb_get_reg32(mem_buf, env->cr[2]); + + case IDX_CTL_CR3_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[3]); + } + return gdb_get_reg32(mem_buf, env->cr[3]); + + case IDX_CTL_CR4_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[4]); + } + return gdb_get_reg32(mem_buf, env->cr[4]); + + case IDX_CTL_CR8_REG: + tpr = cpu_get_apic_tpr(cpu->apic_state); + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, tpr); + } + return gdb_get_reg32(mem_buf, tpr); + + case IDX_CTL_EFER_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->efer); + } + return gdb_get_reg32(mem_buf, env->efer); + } } return 0; @@ -229,6 +332,32 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_SEG_REGS + 5: return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf); + case IDX_SEG_REGS + 6: + if (env->hflags & HF_CS64_MASK) { + env->segs[R_FS].base = ldq_p(mem_buf); + return 8; + } + env->segs[R_FS].base = ldl_p(mem_buf); + return 4; + + case IDX_SEG_REGS + 7: + if (env->hflags & HF_CS64_MASK) { + env->segs[R_GS].base = ldq_p(mem_buf); + return 8; + } + env->segs[R_GS].base = ldl_p(mem_buf); + return 4; + +#ifdef TARGET_X86_64 + case IDX_SEG_REGS + 8: + if (env->hflags & HF_CS64_MASK) { + env->kernelgsbase = ldq_p(mem_buf); + return 8; + } + env->kernelgsbase = ldl_p(mem_buf); + return 4; +#endif + case IDX_FP_REGS + 8: cpu_set_fpuc(env, ldl_p(mem_buf)); return 4; @@ -253,6 +382,55 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_MXCSR_REG: cpu_set_mxcsr(env, ldl_p(mem_buf)); return 4; + + case IDX_CTL_CR0_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_x86_update_cr0(env, ldq_p(mem_buf)); + return 8; + } + cpu_x86_update_cr0(env, ldl_p(mem_buf)); + return 4; + + case IDX_CTL_CR2_REG: + if (env->hflags & HF_CS64_MASK) { + env->cr[2] = ldq_p(mem_buf); + return 8; + } + env->cr[2] = ldl_p(mem_buf); + return 4; + + case IDX_CTL_CR3_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_x86_update_cr3(env, ldq_p(mem_buf)); + return 8; + } + cpu_x86_update_cr3(env, ldl_p(mem_buf)); + return 4; + + case IDX_CTL_CR4_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_x86_update_cr4(env, ldq_p(mem_buf)); + return 8; + } + cpu_x86_update_cr4(env, ldl_p(mem_buf)); + return 4; + + case IDX_CTL_CR8_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_set_apic_tpr(cpu->apic_state, ldq_p(mem_buf)); + return 8; + } + cpu_set_apic_tpr(cpu->apic_state, ldl_p(mem_buf)); + return 4; + + case IDX_CTL_EFER_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_load_efer(env, ldq_p(mem_buf)); + return 8; + } + cpu_load_efer(env, ldl_p(mem_buf)); + return 4; + } } /* Unrecognised register. */ -- 2.17.1