Add an i386-system.xml GDB "internal" feature that exposes the six
segment limit registers (cs, ds, es, ss, fs, gs) as read-only system
registers through the GDB coprocessor interface. This makes them
accessible to HMP without relying on the legacy MonitorDef table, which
will be removed in a subsequent commit.

Signed-off-by: Marc-André Lureau <[email protected]>
---
 configs/targets/i386-softmmu.mak   |  2 +-
 configs/targets/x86_64-softmmu.mak |  2 +-
 gdbstub/gdb-xml/i386-system.xml    | 14 ++++++++++++++
 target/i386/cpu.c                  |  9 ---------
 target/i386/gdbstub.c              | 25 +++++++++++++++++++++++++
 5 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/configs/targets/i386-softmmu.mak b/configs/targets/i386-softmmu.mak
index 38a8f85201f9..1424ab6f6834 100644
--- a/configs/targets/i386-softmmu.mak
+++ b/configs/targets/i386-softmmu.mak
@@ -1,6 +1,6 @@
 TARGET_ARCH=i386
 TARGET_KVM_HAVE_GUEST_DEBUG=y
 TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
-TARGET_XML_FILES= i386-32bit.xml
+TARGET_XML_FILES= i386-32bit.xml i386-system.xml
 TARGET_LONG_BITS=32
 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
diff --git a/configs/targets/x86_64-softmmu.mak 
b/configs/targets/x86_64-softmmu.mak
index c7f8746b4f58..51e882b1c747 100644
--- a/configs/targets/x86_64-softmmu.mak
+++ b/configs/targets/x86_64-softmmu.mak
@@ -2,6 +2,6 @@ TARGET_ARCH=x86_64
 TARGET_BASE_ARCH=i386
 TARGET_KVM_HAVE_GUEST_DEBUG=y
 TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
-TARGET_XML_FILES= i386-64bit.xml i386-64bit-apx.xml
+TARGET_XML_FILES= i386-64bit.xml i386-64bit-apx.xml i386-system.xml
 TARGET_LONG_BITS=64
 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
diff --git a/gdbstub/gdb-xml/i386-system.xml b/gdbstub/gdb-xml/i386-system.xml
new file mode 100644
index 000000000000..9868b887eab8
--- /dev/null
+++ b/gdbstub/gdb-xml/i386-system.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<!-- Segment-cache values are read-only; writes are ignored. -->
+<feature name="org.qemu.gdb.i386.system">
+  <reg name="cs.limit" bitsize="32" type="uint32" group="qemu-debug" 
save-restore="no"/>
+  <reg name="ds.limit" bitsize="32" type="uint32" group="qemu-debug" 
save-restore="no"/>
+  <reg name="es.limit" bitsize="32" type="uint32" group="qemu-debug" 
save-restore="no"/>
+  <reg name="ss.limit" bitsize="32" type="uint32" group="qemu-debug" 
save-restore="no"/>
+  <reg name="fs.limit" bitsize="32" type="uint32" group="qemu-debug" 
save-restore="no"/>
+  <reg name="gs.limit" bitsize="32" type="uint32" group="qemu-debug" 
save-restore="no"/>
+</feature>
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5da80ade70eb..37732b65e408 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10893,17 +10893,8 @@ static int64_t monitor_get_pc(MonitorHMP *hmp, const 
struct MonitorDef *md,
 }
 
 static const MonitorDef x86_monitor_defs[] = {
-#define SEG(name, seg) \
-    { name ".limit", offsetof(CPUX86State, segs[seg].limit) },
-    SEG("cs", R_CS)
-    SEG("ds", R_DS)
-    SEG("es", R_ES)
-    SEG("ss", R_SS)
-    SEG("fs", R_FS)
-    SEG("gs", R_GS)
     { "pc", 0, monitor_get_pc, },
     { NULL },
-#undef SEG
 };
 #endif
 
diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index e636ca0f4ae7..c0cde26d978c 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -496,6 +496,25 @@ static int i386_cpu_gdb_set_egprs(CPUState *cs, uint8_t 
*mem_buf, int n)
 }
 #endif
 
+#ifndef CONFIG_USER_ONLY
+static int x86_gdb_read_system(CPUState *cs, GByteArray *buf, int n)
+{
+    CPUX86State *env = cpu_env(cs);
+    static const int segments[] = { R_CS, R_DS, R_ES, R_SS, R_FS, R_GS };
+
+    if (n < 0 || n >= ARRAY_SIZE(segments)) {
+        return 0;
+    }
+    return gdb_get_reg32(buf, env->segs[segments[n]].limit);
+}
+
+static int x86_gdb_write_system(CPUState *cs, uint8_t *buf, int n)
+{
+    /* Segment caches are exposed for inspection only. Ignore writes. */
+    return 4;
+}
+#endif
+
 void x86_cpu_gdb_init(CPUState *cs)
 {
 #ifdef TARGET_X86_64
@@ -517,4 +536,10 @@ void x86_cpu_gdb_init(CPUState *cs)
                              gdb_find_static_feature("i386-32bit-linux.xml"));
 #endif
 #endif
+#ifndef CONFIG_USER_ONLY
+    gdb_register_internal_coprocessor(
+        cs, x86_gdb_read_system,
+        x86_gdb_write_system,
+        gdb_find_static_feature("i386-system.xml"));
+#endif
 }

-- 
2.56.0.116.g6de20f6092dc


Reply via email to