aboutsummaryrefslogtreecommitdiff
path: root/gdbstub/gdbstub.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdbstub/gdbstub.c')
-rw-r--r--gdbstub/gdbstub.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index d08568c..dd5fb56 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -20,7 +20,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
- * SPDX-License-Identifier: LGPL-2.0+
+ * SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "qemu/osdep.h"
@@ -28,6 +28,7 @@
#include "qemu/cutils.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
+#include "qemu/target-info.h"
#include "trace.h"
#include "exec/gdbstub.h"
#include "gdbstub/commands.h"
@@ -41,8 +42,8 @@
#endif
#include "hw/core/cpu.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/runstate.h"
+#include "system/hw_accel.h"
+#include "system/runstate.h"
#include "exec/replay-core.h"
#include "exec/hwaddr.h"
@@ -354,7 +355,6 @@ static const char *get_feature_xml(const char *p, const char **newp,
GDBProcess *process)
{
CPUState *cpu = gdb_get_first_cpu_in_process(process);
- CPUClass *cc = CPU_GET_CLASS(cpu);
GDBRegisterState *r;
size_t len;
@@ -377,11 +377,11 @@ static const char *get_feature_xml(const char *p, const char **newp,
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>"));
- if (cc->gdb_arch_name) {
+ if (cpu->cc->gdb_arch_name) {
g_ptr_array_add(
xml,
g_markup_printf_escaped("<architecture>%s</architecture>",
- cc->gdb_arch_name(cpu)));
+ cpu->cc->gdb_arch_name(cpu)));
}
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
@@ -520,11 +520,10 @@ GArray *gdb_get_register_list(CPUState *cpu)
int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
{
- CPUClass *cc = CPU_GET_CLASS(cpu);
GDBRegisterState *r;
- if (reg < cc->gdb_num_core_regs) {
- return cc->gdb_read_register(cpu, buf, reg);
+ if (reg < cpu->cc->gdb_num_core_regs) {
+ return cpu->cc->gdb_read_register(cpu, buf, reg);
}
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
@@ -536,13 +535,12 @@ int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
return 0;
}
-static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
+int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
{
- CPUClass *cc = CPU_GET_CLASS(cpu);
GDBRegisterState *r;
- if (reg < cc->gdb_num_core_regs) {
- return cc->gdb_write_register(cpu, mem_buf, reg);
+ if (reg < cpu->cc->gdb_num_core_regs) {
+ return cpu->cc->gdb_write_register(cpu, mem_buf, reg);
}
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
@@ -568,15 +566,30 @@ static void gdb_register_feature(CPUState *cpu, int base_reg,
g_array_append_val(cpu->gdb_regs, s);
}
+static const char *gdb_get_core_xml_file(CPUState *cpu)
+{
+ CPUClass *cc = cpu->cc;
+
+ /*
+ * The CPU class can provide the XML filename via a method,
+ * or as a simple fixed string field.
+ */
+ if (cc->gdb_get_core_xml_file) {
+ return cc->gdb_get_core_xml_file(cpu);
+ }
+ return cc->gdb_core_xml_file;
+}
+
void gdb_init_cpu(CPUState *cpu)
{
- CPUClass *cc = CPU_GET_CLASS(cpu);
+ CPUClass *cc = cpu->cc;
const GDBFeature *feature;
+ const char *xmlfile = gdb_get_core_xml_file(cpu);
cpu->gdb_regs = g_array_new(false, false, sizeof(GDBRegisterState));
- if (cc->gdb_core_xml_file) {
- feature = gdb_find_static_feature(cc->gdb_core_xml_file);
+ if (xmlfile) {
+ feature = gdb_find_static_feature(xmlfile);
gdb_register_feature(cpu, 0,
cc->gdb_read_register, cc->gdb_write_register,
feature);
@@ -1331,8 +1344,8 @@ static void handle_read_all_regs(GArray *params, void *user_ctx)
len += gdb_read_register(gdbserver_state.g_cpu,
gdbserver_state.mem_buf,
reg_id);
+ g_assert(len == gdbserver_state.mem_buf->len);
}
- g_assert(len == gdbserver_state.mem_buf->len);
gdb_memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
gdb_put_strbuf();
@@ -1585,6 +1598,18 @@ static void handle_query_threads(GArray *params, void *user_ctx)
gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
}
+static void handle_query_gdb_server_version(GArray *params, void *user_ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ g_string_printf(gdbserver_state.str_buf, "name:qemu-%s;version:%s;",
+ target_name(), QEMU_VERSION);
+#else
+ g_string_printf(gdbserver_state.str_buf, "name:qemu-system-%s;version:%s;",
+ target_name(), QEMU_VERSION);
+#endif
+ gdb_put_strbuf();
+}
+
static void handle_query_first_threads(GArray *params, void *user_ctx)
{
gdbserver_state.query_cpu = gdb_first_attached_cpu();
@@ -1646,11 +1671,8 @@ void gdb_extend_qsupported_features(char *qflags)
static void handle_query_supported(GArray *params, void *user_ctx)
{
- CPUClass *cc;
-
g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
- cc = CPU_GET_CLASS(first_cpu);
- if (cc->gdb_core_xml_file) {
+ if (gdb_get_core_xml_file(first_cpu)) {
g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
}
@@ -1697,7 +1719,6 @@ static void handle_query_supported(GArray *params, void *user_ctx)
static void handle_query_xfer_features(GArray *params, void *user_ctx)
{
GDBProcess *process;
- CPUClass *cc;
unsigned long len, total_len, addr;
const char *xml;
const char *p;
@@ -1708,8 +1729,7 @@ static void handle_query_xfer_features(GArray *params, void *user_ctx)
}
process = gdb_get_cpu_process(gdbserver_state.g_cpu);
- cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
- if (!cc->gdb_core_xml_file) {
+ if (!gdb_get_core_xml_file(gdbserver_state.g_cpu)) {
gdb_put_packet("");
return;
}
@@ -1836,6 +1856,10 @@ static const GdbCmdParseEntry gdb_gen_query_table[] = {
.cmd = "sThreadInfo",
},
{
+ .handler = handle_query_gdb_server_version,
+ .cmd = "GDBServerVersion",
+ },
+ {
.handler = handle_query_first_threads,
.cmd = "fThreadInfo",
},