Share DLL code between gdb and gdbserver
This moves the new DLL-loading code into nat/windows-nat.c, and changes both gdb and gdbserver to use the shared code. One client-provided callback, handle_load_dll, is changed to allow the code to be shared. This callback was actually never called from nat/windows-nat.c; maybe I had planned to share more here and then didn't finish... I'm not sure. gdb/ChangeLog 2021-04-30 Tom Tromey <tromey@adacore.com> * windows-nat.c (windows_nat::handle_load_dll): Update. (windows_nat_target::get_windows_debug_event): Call dll_loaded_event. (windows_add_all_dlls, windows_add_dll): Move to nat/windows-nat.c. * nat/windows-nat.h (handle_load_dll): Change parameters. (dll_loaded_event, windows_add_all_dlls): Declare. * nat/windows-nat.c (windows_add_dll, windows_add_all_dlls): Move from windows-nat.c. (dll_loaded_event): New function. gdbserver/ChangeLog 2021-04-30 Tom Tromey <tromey@adacore.com> * win32-low.cc (do_initial_child_stuff): Update. (windows_nat::handle_load_dll): Rename from win32_add_one_solib. Change parameter type. (win32_add_dll, win32_add_all_dlls) (windows_nat::handle_load_dll): Remove. (get_child_debug_event): Call dll_loaded_event.
This commit is contained in:
parent
de07187290
commit
e228ef975e
@ -1,3 +1,16 @@
|
||||
2021-04-30 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* windows-nat.c (windows_nat::handle_load_dll): Update.
|
||||
(windows_nat_target::get_windows_debug_event): Call
|
||||
dll_loaded_event.
|
||||
(windows_add_all_dlls, windows_add_dll): Move to
|
||||
nat/windows-nat.c.
|
||||
* nat/windows-nat.h (handle_load_dll): Change parameters.
|
||||
(dll_loaded_event, windows_add_all_dlls): Declare.
|
||||
* nat/windows-nat.c (windows_add_dll, windows_add_all_dlls): Move
|
||||
from windows-nat.c.
|
||||
(dll_loaded_event): New function.
|
||||
|
||||
2021-04-30 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* nat/windows-nat.h (GenerateConsoleCtrlEvent): New define.
|
||||
|
@ -333,6 +333,168 @@ handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
|
||||
#undef DEBUG_EXCEPTION_SIMPLE
|
||||
}
|
||||
|
||||
/* Iterate over all DLLs currently mapped by our inferior, looking for
|
||||
a DLL which is loaded at LOAD_ADDR. If found, add the DLL to our
|
||||
list of solibs; otherwise do nothing. LOAD_ADDR NULL means add all
|
||||
DLLs to the list of solibs; this is used when the inferior finishes
|
||||
its initialization, and all the DLLs it statically depends on are
|
||||
presumed loaded. */
|
||||
|
||||
static void
|
||||
windows_add_dll (LPVOID load_addr)
|
||||
{
|
||||
HMODULE dummy_hmodule;
|
||||
DWORD cb_needed;
|
||||
HMODULE *hmodules;
|
||||
int i;
|
||||
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
{
|
||||
if (EnumProcessModulesEx (current_process_handle, &dummy_hmodule,
|
||||
sizeof (HMODULE), &cb_needed,
|
||||
LIST_MODULES_32BIT) == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (EnumProcessModules (current_process_handle, &dummy_hmodule,
|
||||
sizeof (HMODULE), &cb_needed) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (cb_needed < 1)
|
||||
return;
|
||||
|
||||
hmodules = (HMODULE *) alloca (cb_needed);
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
{
|
||||
if (EnumProcessModulesEx (current_process_handle, hmodules,
|
||||
cb_needed, &cb_needed,
|
||||
LIST_MODULES_32BIT) == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (EnumProcessModules (current_process_handle, hmodules,
|
||||
cb_needed, &cb_needed) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
char system_dir[MAX_PATH];
|
||||
char syswow_dir[MAX_PATH];
|
||||
size_t system_dir_len = 0;
|
||||
bool convert_syswow_dir = false;
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
#endif
|
||||
{
|
||||
/* This fails on 32bit Windows because it has no SysWOW64 directory,
|
||||
and in this case a path conversion isn't necessary. */
|
||||
UINT len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
|
||||
if (len > 0)
|
||||
{
|
||||
/* Check that we have passed a large enough buffer. */
|
||||
gdb_assert (len < sizeof (syswow_dir));
|
||||
|
||||
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));
|
||||
|
||||
strcat (system_dir, "\\");
|
||||
strcat (syswow_dir, "\\");
|
||||
system_dir_len = strlen (system_dir);
|
||||
|
||||
convert_syswow_dir = true;
|
||||
}
|
||||
|
||||
}
|
||||
for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
|
||||
{
|
||||
MODULEINFO mi;
|
||||
#ifdef __USEWIDE
|
||||
wchar_t dll_name[MAX_PATH];
|
||||
char dll_name_mb[MAX_PATH];
|
||||
#else
|
||||
char dll_name[MAX_PATH];
|
||||
#endif
|
||||
const char *name;
|
||||
if (GetModuleInformation (current_process_handle, hmodules[i],
|
||||
&mi, sizeof (mi)) == 0)
|
||||
continue;
|
||||
|
||||
if (GetModuleFileNameEx (current_process_handle, hmodules[i],
|
||||
dll_name, sizeof (dll_name)) == 0)
|
||||
continue;
|
||||
#ifdef __USEWIDE
|
||||
wcstombs (dll_name_mb, dll_name, MAX_PATH);
|
||||
name = dll_name_mb;
|
||||
#else
|
||||
name = dll_name;
|
||||
#endif
|
||||
/* Convert the DLL path of 32bit processes returned by
|
||||
GetModuleFileNameEx from the 64bit system directory to the
|
||||
32bit syswow64 directory if necessary. */
|
||||
std::string syswow_dll_path;
|
||||
if (convert_syswow_dir
|
||||
&& 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();
|
||||
}
|
||||
|
||||
/* Record the DLL if either LOAD_ADDR is NULL or the address
|
||||
at which the DLL was loaded is equal to LOAD_ADDR. */
|
||||
if (!(load_addr != nullptr && mi.lpBaseOfDll != load_addr))
|
||||
{
|
||||
handle_load_dll (name, mi.lpBaseOfDll);
|
||||
if (load_addr != nullptr)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See nat/windows-nat.h. */
|
||||
|
||||
void
|
||||
dll_loaded_event ()
|
||||
{
|
||||
gdb_assert (current_event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT);
|
||||
|
||||
LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
|
||||
const char *dll_name;
|
||||
|
||||
/* Try getting the DLL name via the lpImageName field of the event.
|
||||
Note that Microsoft documents this fields as strictly optional,
|
||||
in the sense that it might be NULL. And the first DLL event in
|
||||
particular is explicitly documented as "likely not pass[ed]"
|
||||
(source: MSDN LOAD_DLL_DEBUG_INFO structure). */
|
||||
dll_name = get_image_name (current_process_handle,
|
||||
event->lpImageName, event->fUnicode);
|
||||
/* If the DLL name could not be gleaned via lpImageName, try harder
|
||||
by enumerating all the DLLs loaded into the inferior, looking for
|
||||
one that is loaded at base address = lpBaseOfDll. */
|
||||
if (dll_name != nullptr)
|
||||
handle_load_dll (dll_name, event->lpBaseOfDll);
|
||||
else if (event->lpBaseOfDll != nullptr)
|
||||
windows_add_dll (event->lpBaseOfDll);
|
||||
}
|
||||
|
||||
/* See nat/windows-nat.h. */
|
||||
|
||||
void
|
||||
windows_add_all_dlls ()
|
||||
{
|
||||
windows_add_dll (nullptr);
|
||||
}
|
||||
|
||||
/* See nat/windows-nat.h. */
|
||||
|
||||
bool
|
||||
|
@ -135,9 +135,12 @@ extern int handle_output_debug_string (struct target_waitstatus *ourstatus);
|
||||
This function assumes that the current event did not occur during
|
||||
inferior initialization.
|
||||
|
||||
DLL_NAME is the name of the library. BASE is the base load
|
||||
address.
|
||||
|
||||
This function must be supplied by the embedding application. */
|
||||
|
||||
extern void handle_load_dll ();
|
||||
extern void handle_load_dll (const char *dll_name, LPVOID base);
|
||||
|
||||
/* Handle a DLL unload event.
|
||||
|
||||
@ -234,6 +237,15 @@ typedef enum
|
||||
extern handle_exception_result handle_exception
|
||||
(struct target_waitstatus *ourstatus, bool debug_exceptions);
|
||||
|
||||
/* Call to indicate that a DLL was loaded. */
|
||||
|
||||
extern void dll_loaded_event ();
|
||||
|
||||
/* Iterate over all DLLs currently mapped by our inferior, and
|
||||
add them to our list of solibs. */
|
||||
|
||||
extern void windows_add_all_dlls ();
|
||||
|
||||
/* Return true if there is a pending stop matching
|
||||
desired_stop_thread_id. If DEBUG_EVENTS is true, logging will be
|
||||
enabled. */
|
||||
|
@ -787,38 +787,13 @@ windows_make_so (const char *name, LPVOID load_addr)
|
||||
return so;
|
||||
}
|
||||
|
||||
static bool windows_add_dll (LPVOID);
|
||||
|
||||
/* See nat/windows-nat.h. */
|
||||
|
||||
void
|
||||
windows_nat::handle_load_dll ()
|
||||
windows_nat::handle_load_dll (const char *dll_name, LPVOID base)
|
||||
{
|
||||
LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
|
||||
const char *dll_name;
|
||||
|
||||
/* Try getting the DLL name via the lpImageName field of the event.
|
||||
Note that Microsoft documents this fields as strictly optional,
|
||||
in the sense that it might be NULL. And the first DLL event in
|
||||
particular is explicitly documented as "likely not pass[ed]"
|
||||
(source: MSDN LOAD_DLL_DEBUG_INFO structure). */
|
||||
dll_name = get_image_name (current_process_handle,
|
||||
event->lpImageName, event->fUnicode);
|
||||
/* If the DLL name could not be gleaned via lpImageName, try harder
|
||||
by enumerating all the DLLs loaded into the inferior, looking for
|
||||
one that is loaded at base address = lpBaseOfDll. */
|
||||
if (dll_name != nullptr)
|
||||
{
|
||||
|
||||
solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
|
||||
solib_end = solib_end->next;
|
||||
}
|
||||
else if (event->lpBaseOfDll != nullptr
|
||||
&& windows_add_dll (event->lpBaseOfDll))
|
||||
dll_name = solib_end->so_name;
|
||||
|
||||
if (dll_name == nullptr)
|
||||
return;
|
||||
solib_end->next = windows_make_so (dll_name, base);
|
||||
solib_end = solib_end->next;
|
||||
|
||||
lm_info_windows *li = (lm_info_windows *) solib_end->lm_info;
|
||||
|
||||
@ -1641,7 +1616,7 @@ windows_nat_target::get_windows_debug_event (int pid,
|
||||
CloseHandle (current_event.u.LoadDll.hFile);
|
||||
if (saw_create != 1 || ! windows_initialization_done)
|
||||
break;
|
||||
catch_errors (handle_load_dll);
|
||||
catch_errors (dll_loaded_event);
|
||||
ourstatus->kind = TARGET_WAITKIND_LOADED;
|
||||
ourstatus->value.integer = 0;
|
||||
thread_id = current_event.dwThreadId;
|
||||
@ -1823,145 +1798,6 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate over all DLLs currently mapped by our inferior, and
|
||||
add them to our list of solibs. */
|
||||
|
||||
static void
|
||||
windows_add_all_dlls (void)
|
||||
{
|
||||
windows_add_dll (NULL);
|
||||
}
|
||||
|
||||
/* Iterate over all DLLs currently mapped by our inferior, looking for
|
||||
a DLL which is loaded at LOAD_ADDR. If found, add the DLL to our
|
||||
list of solibs and return 'true'; otherwise do nothing and return
|
||||
'false'. LOAD_ADDR NULL means add all DLLs to the list of solibs;
|
||||
this is used when the inferior finishes its initialization, and all
|
||||
the DLLs it statically depends on are presumed loaded. */
|
||||
|
||||
static bool
|
||||
windows_add_dll (LPVOID load_addr)
|
||||
{
|
||||
HMODULE dummy_hmodule;
|
||||
DWORD cb_needed;
|
||||
HMODULE *hmodules;
|
||||
int i;
|
||||
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
{
|
||||
if (EnumProcessModulesEx (current_process_handle, &dummy_hmodule,
|
||||
sizeof (HMODULE), &cb_needed,
|
||||
LIST_MODULES_32BIT) == 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (EnumProcessModules (current_process_handle, &dummy_hmodule,
|
||||
sizeof (HMODULE), &cb_needed) == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cb_needed < 1)
|
||||
return false;
|
||||
|
||||
hmodules = (HMODULE *) alloca (cb_needed);
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
{
|
||||
if (EnumProcessModulesEx (current_process_handle, hmodules,
|
||||
cb_needed, &cb_needed,
|
||||
LIST_MODULES_32BIT) == 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (EnumProcessModules (current_process_handle, hmodules,
|
||||
cb_needed, &cb_needed) == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
char system_dir[__PMAX];
|
||||
char syswow_dir[__PMAX];
|
||||
size_t system_dir_len = 0;
|
||||
bool convert_syswow_dir = false;
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
#endif
|
||||
{
|
||||
/* This fails on 32bit Windows because it has no SysWOW64 directory,
|
||||
and in this case a path conversion isn't necessary. */
|
||||
UINT len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
|
||||
if (len > 0)
|
||||
{
|
||||
/* Check that we have passed a large enough buffer. */
|
||||
gdb_assert (len < sizeof (syswow_dir));
|
||||
|
||||
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));
|
||||
|
||||
strcat (system_dir, "\\");
|
||||
strcat (syswow_dir, "\\");
|
||||
system_dir_len = strlen (system_dir);
|
||||
|
||||
convert_syswow_dir = true;
|
||||
}
|
||||
|
||||
}
|
||||
for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
|
||||
{
|
||||
MODULEINFO mi;
|
||||
#ifdef __USEWIDE
|
||||
wchar_t dll_name[__PMAX];
|
||||
char dll_name_mb[__PMAX];
|
||||
#else
|
||||
char dll_name[__PMAX];
|
||||
#endif
|
||||
const char *name;
|
||||
if (GetModuleInformation (current_process_handle, hmodules[i],
|
||||
&mi, sizeof (mi)) == 0)
|
||||
continue;
|
||||
|
||||
if (GetModuleFileNameEx (current_process_handle, hmodules[i],
|
||||
dll_name, sizeof (dll_name)) == 0)
|
||||
continue;
|
||||
#ifdef __USEWIDE
|
||||
wcstombs (dll_name_mb, dll_name, __PMAX);
|
||||
name = dll_name_mb;
|
||||
#else
|
||||
name = dll_name;
|
||||
#endif
|
||||
/* Convert the DLL path of 32bit processes returned by
|
||||
GetModuleFileNameEx from the 64bit system directory to the
|
||||
32bit syswow64 directory if necessary. */
|
||||
std::string syswow_dll_path;
|
||||
if (convert_syswow_dir
|
||||
&& 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();
|
||||
}
|
||||
|
||||
/* Record the DLL if either LOAD_ADDR is NULL or the address
|
||||
at which the DLL was loaded is equal to LOAD_ADDR. */
|
||||
if (!(load_addr != nullptr && mi.lpBaseOfDll != load_addr))
|
||||
{
|
||||
solib_end->next = windows_make_so (name, mi.lpBaseOfDll);
|
||||
solib_end = solib_end->next;
|
||||
if (load_addr != nullptr)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return load_addr == nullptr ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
|
||||
{
|
||||
|
@ -1,3 +1,12 @@
|
||||
2021-04-30 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* win32-low.cc (do_initial_child_stuff): Update.
|
||||
(windows_nat::handle_load_dll): Rename from win32_add_one_solib.
|
||||
Change parameter type.
|
||||
(win32_add_dll, win32_add_all_dlls)
|
||||
(windows_nat::handle_load_dll): Remove.
|
||||
(get_child_debug_event): Call dll_loaded_event.
|
||||
|
||||
2021-04-30 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* win32-low.cc (GETPROCADDRESS): Remove.
|
||||
|
@ -90,8 +90,6 @@ const struct target_desc *wow64_win32_tdesc;
|
||||
|
||||
#define NUM_REGS (the_low_target.num_regs ())
|
||||
|
||||
static void win32_add_all_dlls (void);
|
||||
|
||||
/* Get the thread ID from the current selected inferior (the current
|
||||
thread). */
|
||||
static ptid_t
|
||||
@ -419,7 +417,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
|
||||
Rather than try to work around this sort of issue, it is much
|
||||
simpler to just ignore DLL load/unload events during the startup
|
||||
phase, and then process them all in one batch now. */
|
||||
win32_add_all_dlls ();
|
||||
windows_add_all_dlls ();
|
||||
|
||||
child_initialization_done = 1;
|
||||
}
|
||||
@ -937,9 +935,13 @@ win32_process_target::resume (thread_resume *resume_info, size_t n)
|
||||
child_continue (continue_status, tid);
|
||||
}
|
||||
|
||||
static void
|
||||
win32_add_one_solib (const char *name, CORE_ADDR load_addr)
|
||||
/* See nat/windows-nat.h. */
|
||||
|
||||
void
|
||||
windows_nat::handle_load_dll (const char *name, LPVOID base)
|
||||
{
|
||||
CORE_ADDR load_addr = (CORE_ADDR) (uintptr_t) base;
|
||||
|
||||
char buf[MAX_PATH + 1];
|
||||
char buf2[MAX_PATH + 1];
|
||||
|
||||
@ -987,162 +989,6 @@ win32_add_one_solib (const char *name, CORE_ADDR load_addr)
|
||||
loaded_dll (buf2, load_addr);
|
||||
}
|
||||
|
||||
/* 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 char *
|
||||
win32_add_dll (LPVOID load_addr)
|
||||
{
|
||||
size_t i;
|
||||
HMODULE dh_buf[1];
|
||||
HMODULE *DllHandle = dh_buf;
|
||||
DWORD cbNeeded;
|
||||
BOOL ok;
|
||||
|
||||
cbNeeded = 0;
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
ok = EnumProcessModulesEx (current_process_handle,
|
||||
DllHandle,
|
||||
sizeof (HMODULE),
|
||||
&cbNeeded,
|
||||
LIST_MODULES_32BIT);
|
||||
else
|
||||
#endif
|
||||
ok = EnumProcessModules (current_process_handle,
|
||||
DllHandle,
|
||||
sizeof (HMODULE),
|
||||
&cbNeeded);
|
||||
|
||||
if (!ok || !cbNeeded)
|
||||
return NULL;
|
||||
|
||||
DllHandle = (HMODULE *) alloca (cbNeeded);
|
||||
if (!DllHandle)
|
||||
return NULL;
|
||||
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
ok = EnumProcessModulesEx (current_process_handle,
|
||||
DllHandle,
|
||||
cbNeeded,
|
||||
&cbNeeded,
|
||||
LIST_MODULES_32BIT);
|
||||
else
|
||||
#endif
|
||||
ok = EnumProcessModules (current_process_handle,
|
||||
DllHandle,
|
||||
cbNeeded,
|
||||
&cbNeeded);
|
||||
if (!ok)
|
||||
return NULL;
|
||||
|
||||
char system_dir[MAX_PATH];
|
||||
char syswow_dir[MAX_PATH];
|
||||
size_t system_dir_len = 0;
|
||||
bool convert_syswow_dir = false;
|
||||
#ifdef __x86_64__
|
||||
if (wow64_process)
|
||||
#endif
|
||||
{
|
||||
/* This fails on 32bit Windows because it has no SysWOW64 directory,
|
||||
and in this case a path conversion isn't necessary. */
|
||||
UINT len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
|
||||
if (len > 0)
|
||||
{
|
||||
/* Check that we have passed a large enough buffer. */
|
||||
gdb_assert (len < sizeof (syswow_dir));
|
||||
|
||||
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));
|
||||
|
||||
strcat (system_dir, "\\");
|
||||
strcat (syswow_dir, "\\");
|
||||
system_dir_len = strlen (system_dir);
|
||||
|
||||
convert_syswow_dir = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i = 1; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++)
|
||||
{
|
||||
MODULEINFO mi;
|
||||
static char dll_name[MAX_PATH];
|
||||
|
||||
if (!GetModuleInformation (current_process_handle,
|
||||
DllHandle[i],
|
||||
&mi,
|
||||
sizeof (mi)))
|
||||
continue;
|
||||
if (GetModuleFileNameExA (current_process_handle,
|
||||
DllHandle[i],
|
||||
dll_name,
|
||||
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
|
||||
32bit syswow64 directory if necessary. */
|
||||
std::string syswow_dll_path;
|
||||
if (convert_syswow_dir
|
||||
&& strncasecmp (dll_name, system_dir, system_dir_len) == 0
|
||||
&& strchr (dll_name + system_dir_len, '\\') == nullptr)
|
||||
{
|
||||
syswow_dll_path = syswow_dir;
|
||||
syswow_dll_path += dll_name + system_dir_len;
|
||||
name = syswow_dll_path.c_str();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* See nat/windows-nat.h. */
|
||||
|
||||
void
|
||||
windows_nat::handle_load_dll ()
|
||||
{
|
||||
LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
|
||||
const char *dll_name;
|
||||
|
||||
dll_name = get_image_name (current_process_handle,
|
||||
event->lpImageName, event->fUnicode);
|
||||
if (dll_name == nullptr
|
||||
&& event->lpBaseOfDll != nullptr)
|
||||
dll_name = win32_add_dll (event->lpBaseOfDll);
|
||||
if (dll_name == nullptr)
|
||||
return;
|
||||
|
||||
win32_add_one_solib (dll_name, (CORE_ADDR) (uintptr_t) event->lpBaseOfDll);
|
||||
}
|
||||
|
||||
/* See nat/windows-nat.h. */
|
||||
|
||||
void
|
||||
@ -1367,7 +1213,7 @@ get_child_debug_event (DWORD *continue_status,
|
||||
CloseHandle (current_event.u.LoadDll.hFile);
|
||||
if (! child_initialization_done)
|
||||
break;
|
||||
handle_load_dll ();
|
||||
dll_loaded_event ();
|
||||
|
||||
ourstatus->kind = TARGET_WAITKIND_LOADED;
|
||||
ourstatus->value.sig = GDB_SIGNAL_TRAP;
|
||||
|
Loading…
x
Reference in New Issue
Block a user