---
debug/debug-common.c | 42 +++++++++++++++++++++++++++++++++++++++++
debug/debug-gdb.c | 24 +++++++++++++++++++++++
debug/debug-mcd.c | 25 ++++++++++++++++++++++++
gdbstub/meson.build | 4 ++--
gdbstub/system.c | 4 ++++
gdbstub/user.c | 2 ++
include/exec/gdbstub.h | 5 +++++
include/hw/boards.h | 1 +
include/qemu/debug.h | 19 +++++++++++++++++++
include/qemu/typedefs.h | 2 ++
system/cpus.c | 9 ++++++++-
11 files changed, 134 insertions(+), 3 deletions(-)
create mode 100644 debug/debug-common.c
create mode 100644 debug/debug-gdb.c
create mode 100644 debug/debug-mcd.c
create mode 100644 include/qemu/debug.h
diff --git a/debug/debug-common.c b/debug/debug-common.c
new file mode 100644
index 0000000000..8f41b4e6cb
--- /dev/null
+++ b/debug/debug-common.c
@@ -0,0 +1,42 @@
+#include "qemu/osdep.h"
+#include "qemu/ctype.h"
+#include "qemu/cutils.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/cpu/cluster.h"
+#include "hw/boards.h"
+#include "sysemu/hw_accel.h"
+#include "sysemu/runstate.h"
+#include "exec/replay-core.h"
+#include "exec/hwaddr.h"
+#include "qemu/debug.h"
+#include "qom/object_interfaces.h"
+
+static void debug_instance_init(Object *obj)
+{
+}
+
+static void debug_finalize(Object *obj)
+{
+}
+
+static void debug_class_init(ObjectClass *oc, void *data)
+{
+}
+
+static const TypeInfo debug_info = {
+ .name = TYPE_DEBUG,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(DebugState),
+ .instance_init = debug_instance_init,
+ .instance_finalize = debug_finalize,
+ .class_size = sizeof(DebugClass),
+ .class_init = debug_class_init
+};
+
+static void debug_register_types(void)
+{
+ type_register_static(&debug_info);
+}
+
+type_init(debug_register_types);
diff --git a/debug/debug-gdb.c b/debug/debug-gdb.c
new file mode 100644
index 0000000000..9c7bcda95f
--- /dev/null
+++ b/debug/debug-gdb.c
@@ -0,0 +1,24 @@
+#include "qemu/osdep.h"
+#include "qemu/ctype.h"
+#include "qemu/cutils.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/cpu/cluster.h"
+#include "hw/boards.h"
+#include "sysemu/hw_accel.h"
+#include "sysemu/runstate.h"
+#include "exec/replay-core.h"
+#include "exec/hwaddr.h"
+#include "exec/gdbstub.h"
+#include "qemu/debug.h"
+
+void gdb_init_debug_class(void)
+{
+ Object *obj;
+ obj = object_new(TYPE_DEBUG);
+ DebugState *ds = DEBUG(obj);
+ DebugClass *dc = DEBUG_GET_CLASS(ds);
+ dc->set_stop_cpu = gdb_set_stop_cpu;
+ MachineState *ms = MACHINE(qdev_get_machine());
+ ms->debug_state = ds;
+}
diff --git a/debug/debug-mcd.c b/debug/debug-mcd.c
new file mode 100644
index 0000000000..2d3a31be15
--- /dev/null
+++ b/debug/debug-mcd.c
@@ -0,0 +1,25 @@
+#include "qemu/osdep.h"
+#include "qemu/ctype.h"
+#include "qemu/cutils.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/cpu/cluster.h"
+#include "hw/boards.h"
+#include "sysemu/hw_accel.h"
+#include "sysemu/runstate.h"
+#include "exec/replay-core.h"
+#include "exec/hwaddr.h"
+#include "mcdstub/mcdstub.h"
+#include "qemu/debug.h"
+#include "qom/object_interfaces.h"
+
+void mcd_init_debug_class(void)
+{
+ Object *obj;
+ obj = object_new(TYPE_DEBUG);
+ DebugState *ds = DEBUG(obj);
+ DebugClass *dc = DEBUG_GET_CLASS(ds);
+ dc->set_stop_cpu = mcd_set_stop_cpu;
+ MachineState *ms = MACHINE(qdev_get_machine());
+ ms->debug_state = ds;
+}
diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index e5bccba34e..359234595a 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -11,8 +11,8 @@ gdb_user_ss = ss.source_set()
gdb_system_ss = ss.source_set()
# We build two versions of gdbstub, one for each mode
-gdb_user_ss.add(files('gdbstub.c', 'user.c'))
-gdb_system_ss.add(files('gdbstub.c', 'system.c'))
+gdb_user_ss.add(files('gdbstub.c', 'user.c', '../debug/debug-gdb.c'))
+gdb_system_ss.add(files('gdbstub.c', 'system.c', '../debug/debug-gdb.c'))
gdb_user_ss = gdb_user_ss.apply(config_targetos, strict: false)
gdb_system_ss = gdb_system_ss.apply(config_targetos, strict: false)
diff --git a/gdbstub/system.c b/gdbstub/system.c
index 783ac140b9..02ec4875f5 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -14,6 +14,7 @@
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
+#include "qemu/debug.h"
#include "exec/gdbstub.h"
#include "gdbstub/syscalls.h"
#include "exec/hwaddr.h"
@@ -405,6 +406,9 @@ int gdbserver_start(const char *device)
gdbserver_system_state.mon_chr = mon_chr;
gdb_syscall_reset();
+ /* create new debug object */
+ gdb_init_debug_class();
+
return 0;
}
diff --git a/gdbstub/user.c b/gdbstub/user.c
index dbe1d9b887..f8207aa9ef 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -332,8 +332,10 @@ int gdbserver_start(const char *port_or_path)
}
if (port > 0 && gdb_accept_tcp(gdb_fd)) {
+ gdb_init_debug_class();
return 0;
} else if (gdb_accept_socket(gdb_fd)) {
+ gdb_init_debug_class();
gdbserver_user_state.socket_path = g_strdup(port_or_path);
return 0;
}
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 1a01c35f8e..f696e29477 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -48,4 +48,9 @@ void gdb_set_stop_cpu(CPUState *cpu);
/* in gdbstub-xml.c, generated by scripts/feature_to_c.py */
extern const GDBFeature gdb_static_features[];
+/**
+ * gdb_init_debug_class() - initialize gdb-specific DebugClass
+ */
+void gdb_init_debug_class(void);
+
#endif
diff --git a/include/hw/boards.h b/include/hw/boards.h
index a735999298..ffc7756b89 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -400,6 +400,7 @@ struct MachineState {
CpuTopology smp;
struct NVDIMMState *nvdimms_state;
struct NumaState *numa_state;
+ DebugState *debug_state;
};
#define DEFINE_MACHINE(namestr, machine_initfn) \
diff --git a/include/qemu/debug.h b/include/qemu/debug.h
new file mode 100644
index 0000000000..870f3ea152
--- /dev/null
+++ b/include/qemu/debug.h
@@ -0,0 +1,19 @@
+#ifndef QEMU_DEBUG_H
+#define QEMU_DEBUG_H
+
+#include "qom/object.h"
+#include "qemu/typedefs.h"
+
+struct DebugClass {
+ ObjectClass parent_class;
+ void (*set_stop_cpu)(CPUState *cpu);
+};
+
+struct DebugState {
+ Object parent_obj;
+};
+
+#define TYPE_DEBUG "debug"
+OBJECT_DECLARE_TYPE(DebugState, DebugClass, DEBUG)
+
+#endif /* QEMU_DEBUG_H */
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 5abdbc3874..e48b544173 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -46,6 +46,8 @@ typedef struct CpuInfoFast CpuInfoFast;
typedef struct CPUJumpCache CPUJumpCache;
typedef struct CPUState CPUState;
typedef struct CPUTLBEntryFull CPUTLBEntryFull;
+typedef struct DebugClass DebugClass;
+typedef struct DebugState DebugState;
typedef struct DeviceListener DeviceListener;
typedef struct DeviceState DeviceState;
typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
diff --git a/system/cpus.c b/system/cpus.c
index 0848e0dbdb..734173096a 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "monitor/monitor.h"
#include "qemu/coroutine-tls.h"
+#include "qemu/debug.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
@@ -306,7 +307,13 @@ void cpu_handle_guest_debug(CPUState *cpu)
cpu_single_step(cpu, 0);
}
} else {
- gdb_set_stop_cpu(cpu);
+ MachineState *ms = MACHINE(qdev_get_machine());
+ DebugState *ds = ms->debug_state;
+ DebugClass *dc = DEBUG_GET_CLASS(ds);
+
+ if (dc->set_stop_cpu) {
+ dc->set_stop_cpu(cpu);
+ }
qemu_system_debug_request();
cpu->stopped = true;
}
--
2.34.1