Improve support for loading DLLs at run time in gdbserver.
authorEli Zaretskii <eliz@gnu.org>
Sun, 11 Apr 2021 18:37:29 +0000 (21:37 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sun, 11 Apr 2021 18:37:29 +0000 (21:37 +0300)
This fixes win32-low.cc in the same way as a recent change in
windows-nat.c did for GDB: if the lpImageName member of the load-DLL
debug event doesn't allow us to find the file name of the DLL, then
loop over all the DLLs mapped into the inferior to find the one loaded
at the same base address as given by the lpBaseOfDll member of the
debug event.

gdbserver/ChangeLog:

2021-04-11  Eli Zaretskii  <eliz@gnu.org>

* win32-low.cc (win32_add_dll): New function, with body almost
identical to what win32_add_all_dlls did.  Accepts one argument;
if that is non-NULL, returns the file name of the DLL that is
loaded at the base address equal to that argument, or NULL if not
found.  If the argument is NULL, add all the DLLs loaded by the
inferior to the list of solibs and return NULL.
(win32_add_all_dlls): Now a thin wrapper around win32_add_dll.
(windows_nat::handle_load_dll) [!_WIN32_WCE]: If get_image_name
failed to glean the file name of the DLL, call win32_add_dll to
try harder using the lpBaseOfDll member of the load-DLL event.

gdbserver/ChangeLog
gdbserver/win32-low.cc

index 58ed0f0e69bfdb402a0cbdcf67523387a950e7e5..029a2e472f50a16abb18bce540c44785e3deac67 100644 (file)
@@ -1,3 +1,16 @@
+2021-04-11  Eli Zaretskii  <eliz@gnu.org>
+
+       * win32-low.cc (win32_add_dll): New function, with body almost
+       identical to what win32_add_all_dlls did.  Accepts one argument;
+       if that is non-NULL, returns the file name of the DLL that is
+       loaded at the base address equal to that argument, or NULL if not
+       found.  If the argument is NULL, add all the DLLs loaded by the
+       inferior to the list of solibs and return NULL.
+       (win32_add_all_dlls): Now a thin wrapper around win32_add_dll.
+       (windows_nat::handle_load_dll) [!_WIN32_WCE]: If get_image_name
+       failed to glean the file name of the DLL, call win32_add_dll to
+       try harder using the lpBaseOfDll member of the load-DLL event.
+
 2021-03-30  Luis Machado  <luis.machado@linaro.org>
 
        * server.cc (handle_general_set, handle_query): Update variable
index 1f319a251b4de7d4c83032e5f79d1449b8d28dc2..f6d35ca9843e2d1e417154dda37fdb5c349ceee2 100644 (file)
@@ -1165,11 +1165,13 @@ load_psapi (void)
 
 #ifndef _WIN32_WCE
 
-/* Iterate over all DLLs currently mapped by our inferior, and
-   add them to our list of solibs.  */
+/* Iterate over all DLLs currently mapped by our inferior, looking for
+   a DLL loaded at LOAD_ADDR; if found, return its file name,
+   otherwise return NULL.  If LOAD_ADDR is NULL, add all mapped DLLs
+   to our list of solibs.  */
 
-static void
-win32_add_all_dlls (void)
+static char *
+win32_add_dll (LPVOID load_addr)
 {
   size_t i;
   HMODULE dh_buf[1];
@@ -1178,7 +1180,7 @@ win32_add_all_dlls (void)
   BOOL ok;
 
   if (!load_psapi ())
-    return;
+    return NULL;
 
   cbNeeded = 0;
 #ifdef __x86_64__
@@ -1196,11 +1198,11 @@ win32_add_all_dlls (void)
                                      &cbNeeded);
 
   if (!ok || !cbNeeded)
-    return;
+    return NULL;
 
   DllHandle = (HMODULE *) alloca (cbNeeded);
   if (!DllHandle)
-    return;
+    return NULL;
 
 #ifdef __x86_64__
   if (wow64_process)
@@ -1216,7 +1218,7 @@ win32_add_all_dlls (void)
                                      cbNeeded,
                                      &cbNeeded);
   if (!ok)
-    return;
+    return NULL;
 
   char system_dir[MAX_PATH];
   char syswow_dir[MAX_PATH];
@@ -1252,7 +1254,7 @@ win32_add_all_dlls (void)
   for (i = 1; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++)
     {
       MODULEINFO mi;
-      char dll_name[MAX_PATH];
+      static char dll_name[MAX_PATH];
 
       if (!(*win32_GetModuleInformation) (current_process_handle,
                                          DllHandle[i],
@@ -1265,6 +1267,9 @@ win32_add_all_dlls (void)
                                         MAX_PATH) == 0)
        continue;
 
+      if (load_addr != nullptr && mi.lpBaseOfDll != load_addr)
+       continue;
+
       const char *name = dll_name;
       /* Convert the DLL path of 32bit processes returned by
         GetModuleFileNameEx from the 64bit system directory to the
@@ -1279,10 +1284,27 @@ win32_add_all_dlls (void)
          name = syswow_dll_path.c_str();
        }
 
-      win32_add_one_solib (name, (CORE_ADDR) (uintptr_t) mi.lpBaseOfDll);
+      if (load_addr != nullptr)
+       {
+         if (name != dll_name)
+           strcpy (dll_name, name);
+         return dll_name;
+       }
+      else
+       win32_add_one_solib (name, (CORE_ADDR) (uintptr_t) mi.lpBaseOfDll);
     }
+  return NULL;
 }
-#endif
+
+/* Iterate over all DLLs currently mapped by our inferior, and
+   add them to our list of solibs.  */
+
+static void
+win32_add_all_dlls (void)
+{
+  win32_add_dll (NULL);
+}
+#endif /* !_WIN32_WCE */
 
 typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD);
 typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32);
@@ -1298,7 +1320,12 @@ windows_nat::handle_load_dll ()
 
   dll_name = get_image_name (current_process_handle,
                             event->lpImageName, event->fUnicode);
-  if (!dll_name)
+#ifndef _WIN32_WCE
+  if (dll_name == nullptr
+      && event->lpBaseOfDll != nullptr)
+    dll_name = win32_add_dll (event->lpBaseOfDll);
+#endif
+  if (dll_name == nullptr)
     return;
 
   win32_add_one_solib (dll_name, (CORE_ADDR) (uintptr_t) event->lpBaseOfDll);