[PATCH 09/15] winedbg: Support qXfer:libraries:read request.

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


This makes gdb frontend able to list loaded libraries so it can then
parse debug information. It seems that it also supports PE/ELF mix, so
this is nice. Sometimes debug info is still off, so not 100% accurate
yet.

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

diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index ca605259ec6..6e6ff558081 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -1673,6 +1673,55 @@ static enum packet_return packet_query_remote_command(struct gdb_context* gdbctx
     return packet_reply_error(gdbctx, EINVAL);
 }
 
+static BOOL CALLBACK packet_query_libraries_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
+{
+    struct gdb_context* gdbctx = ctx;
+    IMAGEHLP_MODULE64 imh_mod = {sizeof(imh_mod)};
+    SymGetModuleInfo64(gdbctx->process->handle, base, &imh_mod);
+
+    packet_reply_add(gdbctx, "<library name=\"");
+
+    if (strcmp(mod_name, "[vdso].so") == 0)
+        packet_reply_add(gdbctx, "linux-vdso.so.1");
+    else if (imh_mod.LoadedImageName[0] == '/')
+        packet_reply_add(gdbctx, imh_mod.LoadedImageName);
+    else
+    {
+        UNICODE_STRING nt_name;
+        ANSI_STRING ansi_name;
+        char * unix_path;
+
+        RtlInitAnsiString( &ansi_name, imh_mod.LoadedImageName );
+        RtlAnsiStringToUnicodeString( &nt_name, &ansi_name, TRUE );
+
+        if ((unix_path = wine_get_unix_file_name( nt_name.Buffer )))
+            packet_reply_add(gdbctx, unix_path);
+        else
+            packet_reply_add(gdbctx, mod_name);
+
+        HeapFree( GetProcessHeap(), 0, unix_path );
+        RtlFreeUnicodeString( &nt_name );
+    }
+
+    packet_reply_add(gdbctx, "\"><segment address=\"0x");
+    packet_reply_val(gdbctx, imh_mod.BaseOfImage, sizeof(imh_mod.BaseOfImage));
+    packet_reply_add(gdbctx, "\"/></library>");
+
+    return TRUE;
+}
+
+static void packet_query_libraries(struct gdb_context* gdbctx)
+{
+    BOOL opt;
+    /* this will resynchronize builtin dbghelp's internal ELF module list */
+    SymLoadModule(gdbctx->process->handle, 0, 0, 0, 0, 0);
+    packet_reply_add(gdbctx, "<library-list>");
+    opt = SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, TRUE);
+    SymEnumerateModules64(gdbctx->process->handle, packet_query_libraries_cb, gdbctx);
+    SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
+    packet_reply_add(gdbctx, "</library-list>");
+}
+
 static enum packet_return packet_query(struct gdb_context* gdbctx)
 {
     int off, len;
@@ -1764,6 +1813,7 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
         {
             packet_reply_open(gdbctx);
             packet_reply_add(gdbctx, "qXfer:features:read+;");
+            packet_reply_add(gdbctx, "qXfer:libraries:read+;");
             packet_reply_close(gdbctx);
             return packet_done;
         }
@@ -1801,6 +1851,14 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
             packet_reply_close_xfer(gdbctx, off, len);
             return packet_done;
         }
+
+        if (snscanf(gdbctx->in_packet, gdbctx->in_packet_len, "Xfer:libraries:read::%x,%x", &off, &len) == 2)
+        {
+            packet_reply_open_xfer(gdbctx);
+            packet_query_libraries(gdbctx);
+            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