diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 2bc69639925..46e56b6f190 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -168,40 +168,6 @@ static unsigned char checksum(const char* ptr, int len)
return cksum;
}
-#ifdef __i386__
-static const char target_xml[] = "";
-#elif defined(__powerpc__)
-static const char target_xml[] = "";
-#elif defined(__x86_64__)
-static const char target_xml[] = "";
-#elif defined(__arm__)
-static const char target_xml[] =
- "l arm\n"
- "\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "\n";
-#elif defined(__aarch64__)
-static const char target_xml[] = "";
-#else
-# error Define the registers map for your CPU
-#endif
-
static inline void* cpu_register_ptr(struct gdb_context *gdbctx,
dbg_ctx_t *ctx, unsigned idx)
{
@@ -1540,9 +1506,129 @@ static void packet_query_threads(struct gdb_context* gdbctx)
packet_reply_add(gdbctx, "");
}
+static void packet_query_target_xml(struct gdb_context* gdbctx, struct backend_cpu* cpu)
+{
+ const char* feature_prefix = NULL;
+ const char* feature = NULL;
+ char buffer[256];
+ int i;
+
+ packet_reply_add(gdbctx, "");
+ switch (cpu->machine)
+ {
+ case IMAGE_FILE_MACHINE_AMD64:
+ packet_reply_add(gdbctx, "i386:x86-64");
+ feature_prefix = "org.gnu.gdb.i386.";
+ break;
+ case IMAGE_FILE_MACHINE_I386:
+ packet_reply_add(gdbctx, "i386");
+ feature_prefix = "org.gnu.gdb.i386.";
+ break;
+ case IMAGE_FILE_MACHINE_POWERPC:
+ packet_reply_add(gdbctx, "powerpc:common");
+ feature_prefix = "org.gnu.gdb.power.";
+ break;
+ case IMAGE_FILE_MACHINE_ARMNT:
+ packet_reply_add(gdbctx, "arm");
+ feature_prefix = "org.gnu.gdb.arm.";
+ break;
+ case IMAGE_FILE_MACHINE_ARM64:
+ packet_reply_add(gdbctx, "aarch64");
+ feature_prefix = "org.gnu.gdb.aarch64.";
+ break;
+ }
+
+ for (i = 0; i < cpu->gdb_num_regs; ++i)
+ {
+ if (cpu->gdb_register_map[i].feature)
+ {
+ if (feature) packet_reply_add(gdbctx, "");
+ feature = cpu->gdb_register_map[i].feature;
+
+ packet_reply_add(gdbctx, "");
+
+ if (strcmp(feature_prefix, "org.gnu.gdb.i386.") == 0 &&
+ strcmp(feature, "core") == 0)
+ packet_reply_add(gdbctx, ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ "");
+
+ if (strcmp(feature_prefix, "org.gnu.gdb.i386.") == 0 &&
+ strcmp(feature, "sse") == 0)
+ packet_reply_add(gdbctx, ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ "");
+ }
+
+ snprintf(buffer, ARRAY_SIZE(buffer), "gdb_register_map[i].name, 8 * cpu->gdb_register_map[i].gdb_length);
+ packet_reply_add(gdbctx, buffer);
+
+ if (cpu->gdb_register_map[i].type)
+ {
+ packet_reply_add(gdbctx, " type=\"");
+ packet_reply_add(gdbctx, cpu->gdb_register_map[i].type);
+ packet_reply_add(gdbctx, "\"");
+ }
+
+ packet_reply_add(gdbctx, "/>");
+ }
+
+ if (feature) packet_reply_add(gdbctx, "");
+ packet_reply_add(gdbctx, "");
+}
+
static enum packet_return packet_query(struct gdb_context* gdbctx)
{
int off, len;
+ struct backend_cpu *cpu;
switch (gdbctx->in_packet[0])
{
@@ -1633,7 +1719,7 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
packet_reply_add(gdbctx, "QStartNoAckMode+;");
packet_reply_add(gdbctx, "qXfer:libraries:read+;");
packet_reply_add(gdbctx, "qXfer:threads:read+;");
- if (*target_xml) packet_reply_add(gdbctx, "PacketSize=400;qXfer:features:read+");
+ packet_reply_add(gdbctx, "qXfer:features:read+;");
packet_reply_close(gdbctx);
return packet_done;
}
@@ -1684,8 +1770,16 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
return packet_done;
}
- if (*target_xml && strncmp(gdbctx->in_packet, "Xfer:features:read:target.xml", 29) == 0)
- return packet_reply(gdbctx, target_xml);
+ if (sscanf(gdbctx->in_packet, "Xfer:features:read:target.xml:%x,%x", &off, &len) == 2)
+ {
+ if (!gdbctx->process) return packet_error;
+ if (!(cpu = gdbctx->process->be_cpu)) return packet_error;
+
+ packet_reply_open_xfer(gdbctx);
+ packet_query_target_xml(gdbctx, cpu);
+ packet_reply_close_xfer(gdbctx, off, len);
+ return packet_done;
+ }
break;
}
ERR("Unhandled query %s\n", debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));