[PATCH 6/8] winedbg: Support qXfer:libraries:read request.
Rémi Bernon
rbernon at codeweavers.com
Thu Apr 2 08:55:19 CDT 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 but debug info for PE files is still completely off.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
programs/winedbg/gdbproxy.c | 72 +++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 70735afd0646..4f1e2a3c2fd8 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -1472,6 +1472,66 @@ static void packet_query_target_xml(struct gdb_context* gdbctx, struct backend_c
packet_reply_add(gdbctx, "</target>");
}
+static BOOL CALLBACK packet_query_libraries_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
+{
+ struct gdb_context* gdbctx = ctx;
+ IMAGEHLP_MODULE64 mod;
+ DWORD64 addr;
+ BOOL is_wow64;
+ char* tmp;
+
+ mod.SizeOfStruct = sizeof(mod);
+ SymGetModuleInfo64(gdbctx->process->handle, base, &mod);
+
+ packet_reply_add(gdbctx, "<library name=\"");
+ if (strcmp(mod.LoadedImageName, "[vdso].so") == 0)
+ packet_reply_add(gdbctx, "linux-vdso.so.1");
+ else if (mod.LoadedImageName[0] == '/')
+ packet_reply_add(gdbctx, mod.LoadedImageName);
+ else
+ {
+ UNICODE_STRING nt_name;
+ ANSI_STRING ansi_name;
+ char * unix_path;
+
+ RtlInitAnsiString(&ansi_name, mod.LoadedImageName);
+ RtlAnsiStringToUnicodeString(&nt_name, &ansi_name, TRUE);
+
+ if ((unix_path = wine_get_unix_file_name(nt_name.Buffer)))
+ {
+ if (IsWow64Process(gdbctx->process->handle, &is_wow64) &&
+ is_wow64 && (tmp = strstr(unix_path, "system32")))
+ memcpy(tmp, "syswow64", 8);
+ packet_reply_add(gdbctx, unix_path);
+ }
+ else
+ packet_reply_add(gdbctx, mod.LoadedImageName);
+
+ HeapFree(GetProcessHeap(), 0, unix_path);
+ RtlFreeUnicodeString(&nt_name);
+ }
+
+ addr = mod.BaseOfImage;
+
+ packet_reply_add(gdbctx, "\"><segment address=\"0x");
+ packet_reply_val(gdbctx, addr, sizeof(addr));
+ 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;
@@ -1565,6 +1625,7 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
packet_reply_open(gdbctx);
packet_reply_add(gdbctx, "QStartNoAckMode+;");
packet_reply_add(gdbctx, "qXfer:features:read+;");
+ packet_reply_add(gdbctx, "qXfer:libraries:read+;");
packet_reply_close(gdbctx);
return packet_done;
}
@@ -1605,6 +1666,17 @@ static enum packet_return packet_query(struct gdb_context* gdbctx)
packet_reply_close_xfer(gdbctx, off, len);
return packet_done;
}
+
+ if (sscanf(gdbctx->in_packet, "Xfer:libraries:read::%x,%x", &off, &len) == 2)
+ {
+ if (!gdbctx->process)
+ return packet_error;
+
+ 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.26.0.rc2
More information about the wine-devel
mailing list