summaryrefslogtreecommitdiffstats
path: root/target/i386/gdbstub.c
diff options
context:
space:
mode:
authorPeter Maydell2019-02-05 20:39:22 +0100
committerPeter Maydell2019-02-05 20:39:22 +0100
commit3e29da9fd81002a0c03041aaa26dea6d9dd9bd65 (patch)
treeacd21f31ace26a41b261fe462ae26c782ffb42d2 /target/i386/gdbstub.c
parentMerge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190205'... (diff)
parentqueue: fix QTAILQ_FOREACH_REVERSE_SAFE (diff)
downloadqemu-3e29da9fd81002a0c03041aaa26dea6d9dd9bd65.tar.gz
qemu-3e29da9fd81002a0c03041aaa26dea6d9dd9bd65.tar.xz
qemu-3e29da9fd81002a0c03041aaa26dea6d9dd9bd65.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* cpu-exec fixes (Emilio, Laurent) * TCG bugfix in queue.h (Paolo) * high address load for linuxboot (Zhijian) * PVH support (Liam, Stefano) * misc i386 changes (Paolo, Robert, Doug) * configure tweak for openpty (Thomas) * elf2dmp port to Windows (Viktor) * initial improvements to Makefile infrastructure (Yang + GSoC 2013) # gpg: Signature made Tue 05 Feb 2019 17:34:42 GMT # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (76 commits) queue: fix QTAILQ_FOREACH_REVERSE_SAFE scsi-generic: Convert from DPRINTF() macro to trace events scsi-disk: Convert from DPRINTF() macro to trace events pc: Use hotplug_handler_(plug|unplug|unplug_request) i386: hvf: Fix smp boot hangs hw/vfio/Makefile.objs: Create new CONFIG_* variables for VFIO core and PCI hw/i2c/Makefile.objs: Create new CONFIG_* variables for EEPROM and ACPI controller hw/tricore/Makefile.objs: Create CONFIG_* for tricore hw/openrisc/Makefile.objs: Create CONFIG_* for openrisc hw/moxie/Makefile.objs: Conditionally build moxie hw/hppa/Makefile.objs: Create CONFIG_* for hppa hw/cris/Makefile.objs: Create CONFIG_* for cris hw/alpha/Makefile.objs: Create CONFIG_* for alpha hw/sparc64/Makefile.objs: Create CONFIG_* for sparc64 hw/riscv/Makefile.objs: Create CONFIG_* for riscv boards hw/nios2/Makefile.objs: Conditionally build nios2 hw/xtensa/Makefile.objs: Build xtensa_sim and xtensa_fpga conditionally hw/lm32/Makefile.objs: Conditionally build lm32 and milkmyst hw/sparc/Makefile.objs: CONFIG_* for sun4m and leon3 created hw/s390/Makefile.objs: Create new CONFIG_* variables for s390x boards and devices ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # qemu-deprecated.texi
Diffstat (limited to 'target/i386/gdbstub.c')
-rw-r--r--target/i386/gdbstub.c193
1 files changed, 189 insertions, 4 deletions
diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index 9b94ab852c..1221433bc7 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,47 @@ 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:
+#ifdef CONFIG_SOFTMMU
+ tpr = cpu_get_apic_tpr(cpu->apic_state);
+#else
+ tpr = 0;
+#endif
+ 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 +335,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 +385,59 @@ 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) {
+#ifdef CONFIG_SOFTMMU
+ cpu_set_apic_tpr(cpu->apic_state, ldq_p(mem_buf));
+#endif
+ return 8;
+ }
+#ifdef CONFIG_SOFTMMU
+ cpu_set_apic_tpr(cpu->apic_state, ldl_p(mem_buf));
+#endif
+ 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. */