[PATCH 08/15] winedbg: Support qXfer:features:read request.

Rémi Bernon rbernon at codeweavers.com
Mon Jan 27 06:07:11 CST 2020


The most important thing here is to report another osabi, so that gdb
does not assume the target is GNU/Linux.

The register list is not strictly required for the gdb frontend but
lldb can use it. Also it makes things more consistent.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 programs/winedbg/gdbproxy.c | 185 +++++++++++++++++++++++++++++-------
 1 file changed, 149 insertions(+), 36 deletions(-)

diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index fdab2a9755f..ca605259ec6 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -192,39 +192,150 @@ static unsigned char checksum(const char* ptr, int len)
     return cksum;
 }
 
+static const char target_xml[] =
+    "<target>"
+    "<osabi>Cygwin</osabi>"
 #ifdef __i386__
-static const char target_xml[] = "";
+    "<architecture>i386</architecture>"
+    "<feature name=\"org.gnu.gdb.i386.core\">"
+    "<reg name=\"eax\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ecx\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"edx\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ebx\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"esp\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ebp\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"esi\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"edi\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"eip\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"eflags\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"cs\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ss\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ds\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"es\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fs\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"gs\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"st0\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st1\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st2\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st3\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st4\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st5\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st6\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st7\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"fctrl\" bitsize=\"16\" type=\"uint16\"/>"
+    "<reg name=\"fstat\" bitsize=\"16\" type=\"uint16\"/>"
+    "<reg name=\"ftag\"  bitsize=\"16\" type=\"uint16\"/>"
+    "<reg name=\"fiseg\" bitsize=\"16\" type=\"uint16\"/>"
+    "<reg name=\"fioff\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"foseg\" bitsize=\"16\" type=\"uint16\"/>"
+    "<reg name=\"fooff\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fop\"   bitsize=\"16\" type=\"uint16\"/>"
+    "</feature>"
+
+    "<feature name=\"org.gnu.gdb.i386.sse\">"
+    "<reg name=\"xmm0\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm1\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm2\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm3\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm4\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm5\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm6\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm7\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"mxcsr\" bitsize=\"32\" type=\"uint32\"/>"
+    "</feature>"
 #elif defined(__powerpc__)
-static const char target_xml[] = "";
+    "<architecture>powerpc:common</architecture>"
 #elif defined(__x86_64__)
-static const char target_xml[] = "";
+    "<architecture>i386:x86-64</architecture>"
+    "<feature name=\"org.gnu.gdb.i386.core\">"
+    "<reg name=\"rax\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rbx\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rcx\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rdx\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rsi\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rdi\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rbp\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rsp\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r8\"  bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r9\"  bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r10\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r11\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r12\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r13\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r14\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"r15\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"rip\" bitsize=\"64\" type=\"uint64\"/>"
+    "<reg name=\"eflags\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"cs\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ss\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ds\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"es\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fs\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"gs\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"st0\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st1\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st2\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st3\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st4\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st5\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st6\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"st7\" bitsize=\"80\" type=\"i387_ext\"/>"
+    "<reg name=\"fctrl\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fstat\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"ftag\"  bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fiseg\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fioff\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"foseg\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fooff\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"fop\"   bitsize=\"32\" type=\"uint32\"/>"
+    "</feature>"
+
+    "<feature name=\"org.gnu.gdb.i386.sse\">"
+    "<reg name=\"xmm0\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm1\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm2\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm3\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm4\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm5\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm6\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm7\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm8\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm9\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm10\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm11\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm12\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm13\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm14\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"xmm15\" bitsize=\"128\" type=\"uint128\"/>"
+    "<reg name=\"mxcsr\" bitsize=\"32\" type=\"uint32\"/>"
+    "</feature>"
 #elif defined(__arm__)
-static const char target_xml[] =
-    "l <target><architecture>arm</architecture>\n"
-    "<feature name=\"org.gnu.gdb.arm.core\">\n"
-    "    <reg name=\"r0\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r1\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r2\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r3\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r4\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r5\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r6\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r7\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r8\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r9\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r10\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r11\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"r12\" bitsize=\"32\" type=\"uint32\"/>\n"
-    "    <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\n"
-    "    <reg name=\"lr\" bitsize=\"32\"/>\n"
-    "    <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n"
-    "    <reg name=\"cpsr\" bitsize=\"32\"/>\n"
-    "</feature></target>\n";
+    "<architecture>arm</architecture>"
+    "<feature name=\"org.gnu.gdb.arm.core\">"
+    "<reg name=\"r0\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r1\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r2\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r3\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r4\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r5\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r6\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r7\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r8\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r9\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r10\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r11\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"r12\" bitsize=\"32\" type=\"uint32\"/>"
+    "<reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>"
+    "<reg name=\"lr\" bitsize=\"32\"/>"
+    "<reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>"
+    "<reg name=\"cpsr\" bitsize=\"32\"/>"
+    "</feature>"
 #elif defined(__aarch64__)
-static const char target_xml[] = "";
+    "<architecture>aarch64</architecture>"
 #else
 # error Define the registers map for your CPU
 #endif
+    "</target>";
 
 static inline void* cpu_register_ptr(struct gdb_context *gdbctx,
     dbg_ctx_t *ctx, unsigned idx)
@@ -1564,6 +1675,8 @@ static enum packet_return packet_query_remote_command(struct gdb_context* gdbctx
 
 static enum packet_return packet_query(struct gdb_context* gdbctx)
 {
+    int off, len;
+
     switch (gdbctx->in_packet[0])
     {
     case 'f':
@@ -1649,15 +1762,10 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
             return packet_ok;
         if (strncmp(gdbctx->in_packet, "Supported", 9) == 0)
         {
-            if (*target_xml)
-                return packet_reply(gdbctx, "PacketSize=400;qXfer:features:read+");
-            else
-            {
-                /* no features supported */
-                packet_reply_open(gdbctx);
-                packet_reply_close(gdbctx);
-                return packet_done;
-            }
+            packet_reply_open(gdbctx);
+            packet_reply_add(gdbctx, "qXfer:features:read+;");
+            packet_reply_close(gdbctx);
+            return packet_done;
         }
         break;
     case 'T':
@@ -1686,8 +1794,13 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
         }
         break;
     case 'X':
-        if (*target_xml && strncmp(gdbctx->in_packet, "Xfer:features:read:target.xml", 29) == 0)
-            return packet_reply(gdbctx, target_xml);
+        if (snscanf(gdbctx->in_packet, gdbctx->in_packet_len, "Xfer:features:read:target.xml:%x,%x", &off, &len) == 2)
+        {
+            packet_reply_open_xfer(gdbctx);
+            packet_reply_add(gdbctx, target_xml);
+            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));
-- 
2.25.0




More information about the wine-devel mailing list