Fix WOW64 process system DLL paths

GetModuleFileNameEx returns for some DLLs of WOW64 processes
the path inside the 64bit system directory instead of the 32bit
syswow64 directory.

Problem happens e.g. with dbghelp.dll:

(gdb) start
Temporary breakpoint 1 at 0x415a00: file fiber.cpp, line 430.
Starting program: C:\src\tests\fiber.exe
warning: `C:\Windows\system32\dbghelp.dll': Shared library architecture i386:x86-64 is not compatible with target architecture i386.

Temporary breakpoint 1, main () at fiber.cpp:430
430     {
(gdb) info sharedlibrary
From        To          Syms Read   Shared Object Library
0x77070000  0x771d4d20  Yes (*)     C:\Windows\SysWOW64\ntdll.dll
0x74dc0000  0x74ebad9c  Yes (*)     C:\Windows\syswow64\kernel32.dll
0x75341000  0x75386a18  Yes (*)     C:\Windows\syswow64\KernelBase.dll
0x6f6a1000  0x6f7c48fc  Yes (*)     C:\Windows\system32\dbghelp.dll
0x74d01000  0x74dab2c4  Yes (*)     C:\Windows\syswow64\msvcrt.dll
(*): Shared library is missing debugging information.

This detects this situation and converts the DLL path to the
syswow64 equivalent.

gdb/ChangeLog:

2020-03-25  Hannes Domani  <ssbssa@yahoo.de>

	* windows-nat.c (windows_add_all_dlls): Fix system dll paths.
This commit is contained in:
Hannes Domani 2020-03-24 18:03:08 +01:00
parent 4c83662712
commit d503b685c6
2 changed files with 45 additions and 3 deletions

View File

@ -1,3 +1,7 @@
2020-03-25 Hannes Domani <ssbssa@yahoo.de>
* windows-nat.c (windows_add_all_dlls): Fix system dll paths.
2020-03-25 Tom de Vries <tdevries@suse.de>
* symtab.h (is_main_symtab_of_compunit_symtab): New function.

View File

@ -2058,16 +2058,39 @@ windows_add_all_dlls (void)
return;
}
#ifdef __x86_64__
char system_dir[__PMAX];
char syswow_dir[__PMAX];
size_t system_dir_len = 0;
if (wow64_process)
{
UINT len = GetSystemDirectoryA (system_dir, sizeof (system_dir));
/* Error check. */
gdb_assert (len != 0);
/* Check that we have passed a large enough buffer. */
gdb_assert (len < sizeof (system_dir));
len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
/* Error check. */
gdb_assert (len != 0);
/* Check that we have passed a large enough buffer. */
gdb_assert (len < sizeof (syswow_dir));
strcat (system_dir, "\\");
strcat (syswow_dir, "\\");
system_dir_len = strlen (system_dir);
}
#endif
for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
{
MODULEINFO mi;
#ifdef __USEWIDE
wchar_t dll_name[__PMAX];
char name[__PMAX];
char dll_name_mb[__PMAX];
#else
char dll_name[__PMAX];
char *name;
#endif
const char *name;
if (GetModuleInformation (current_process_handle, hmodules[i],
&mi, sizeof (mi)) == 0)
continue;
@ -2075,10 +2098,25 @@ windows_add_all_dlls (void)
dll_name, sizeof (dll_name)) == 0)
continue;
#ifdef __USEWIDE
wcstombs (name, dll_name, __PMAX);
wcstombs (dll_name_mb, dll_name, __PMAX);
name = dll_name_mb;
#else
name = dll_name;
#endif
#ifdef __x86_64__
/* Convert the DLL path of WOW64 processes returned by
GetModuleFileNameEx from the 64bit system directory to the
32bit syswow64 directory if necessary. */
std::string syswow_dll_path;
if (wow64_process
&& strncasecmp (name, system_dir, system_dir_len) == 0
&& strchr (name + system_dir_len, '\\') == nullptr)
{
syswow_dll_path = syswow_dir;
syswow_dll_path += name + system_dir_len;
name = syswow_dll_path.c_str();
}
#endif
solib_end->next = windows_make_so (name, mi.lpBaseOfDll);
solib_end = solib_end->next;