ODR warnings for "struct insn_info"
[binutils-gdb.git] / gdb / nat / windows-nat.c
1 /* Internal interfaces for the Windows code
2 Copyright (C) 1995-2022 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19 #include "gdbsupport/common-defs.h"
20 #include "nat/windows-nat.h"
21 #include "gdbsupport/common-debug.h"
22 #include "target/target.h"
23
24 #undef GetModuleFileNameEx
25
26 #ifndef __CYGWIN__
27 #define GetModuleFileNameEx GetModuleFileNameExA
28 #else
29 #include <sys/cygwin.h>
30 #define __USEWIDE
31 typedef wchar_t cygwin_buf_t;
32 #define GetModuleFileNameEx GetModuleFileNameExW
33 #endif
34
35 namespace windows_nat
36 {
37
38 /* The most recent event from WaitForDebugEvent. Unlike
39 current_event, this is guaranteed never to come from a pending
40 stop. This is important because only data from the most recent
41 event from WaitForDebugEvent can be used when calling
42 ContinueDebugEvent. */
43 static DEBUG_EVENT last_wait_event;
44
45 AdjustTokenPrivileges_ftype *AdjustTokenPrivileges;
46 DebugActiveProcessStop_ftype *DebugActiveProcessStop;
47 DebugBreakProcess_ftype *DebugBreakProcess;
48 DebugSetProcessKillOnExit_ftype *DebugSetProcessKillOnExit;
49 EnumProcessModules_ftype *EnumProcessModules;
50 #ifdef __x86_64__
51 EnumProcessModulesEx_ftype *EnumProcessModulesEx;
52 #endif
53 GetModuleInformation_ftype *GetModuleInformation;
54 GetModuleFileNameExA_ftype *GetModuleFileNameExA;
55 GetModuleFileNameExW_ftype *GetModuleFileNameExW;
56 LookupPrivilegeValueA_ftype *LookupPrivilegeValueA;
57 OpenProcessToken_ftype *OpenProcessToken;
58 GetCurrentConsoleFont_ftype *GetCurrentConsoleFont;
59 GetConsoleFontSize_ftype *GetConsoleFontSize;
60 #ifdef __x86_64__
61 Wow64SuspendThread_ftype *Wow64SuspendThread;
62 Wow64GetThreadContext_ftype *Wow64GetThreadContext;
63 Wow64SetThreadContext_ftype *Wow64SetThreadContext;
64 Wow64GetThreadSelectorEntry_ftype *Wow64GetThreadSelectorEntry;
65 #endif
66 GenerateConsoleCtrlEvent_ftype *GenerateConsoleCtrlEvent;
67
68 #define GetThreadDescription dyn_GetThreadDescription
69 typedef HRESULT WINAPI (GetThreadDescription_ftype) (HANDLE, PWSTR *);
70 static GetThreadDescription_ftype *GetThreadDescription;
71
72 /* Note that 'debug_events' must be locally defined in the relevant
73 functions. */
74 #define DEBUG_EVENTS(fmt, ...) \
75 debug_prefixed_printf_cond (debug_events, "windows events", fmt, \
76 ## __VA_ARGS__)
77
78 void
79 windows_thread_info::suspend ()
80 {
81 if (suspended != 0)
82 return;
83
84 if (SuspendThread (h) == (DWORD) -1)
85 {
86 DWORD err = GetLastError ();
87
88 /* We get Access Denied (5) when trying to suspend
89 threads that Windows started on behalf of the
90 debuggee, usually when those threads are just
91 about to exit.
92 We can get Invalid Handle (6) if the main thread
93 has exited. */
94 if (err != ERROR_INVALID_HANDLE && err != ERROR_ACCESS_DENIED)
95 warning (_("SuspendThread (tid=0x%x) failed. (winerr %u)"),
96 (unsigned) tid, (unsigned) err);
97 suspended = -1;
98 }
99 else
100 suspended = 1;
101 }
102
103 void
104 windows_thread_info::resume ()
105 {
106 if (suspended > 0)
107 {
108 stopped_at_software_breakpoint = false;
109
110 if (ResumeThread (h) == (DWORD) -1)
111 {
112 DWORD err = GetLastError ();
113 warning (_("warning: ResumeThread (tid=0x%x) failed. (winerr %u)"),
114 (unsigned) tid, (unsigned) err);
115 }
116 }
117 suspended = 0;
118 }
119
120 const char *
121 windows_thread_info::thread_name ()
122 {
123 if (GetThreadDescription != nullptr)
124 {
125 PWSTR value;
126 HRESULT result = GetThreadDescription (h, &value);
127 if (SUCCEEDED (result))
128 {
129 int needed = WideCharToMultiByte (CP_ACP, 0, value, -1, nullptr, 0,
130 nullptr, nullptr);
131 if (needed != 0)
132 {
133 /* USED_DEFAULT is how we detect that the encoding
134 conversion had to fall back to the substitution
135 character. It seems better to just reject bad
136 conversions here. */
137 BOOL used_default = FALSE;
138 gdb::unique_xmalloc_ptr<char> new_name
139 ((char *) xmalloc (needed));
140 if (WideCharToMultiByte (CP_ACP, 0, value, -1,
141 new_name.get (), needed,
142 nullptr, &used_default) == needed
143 && !used_default
144 && strlen (new_name.get ()) > 0)
145 name = std::move (new_name);
146 }
147 LocalFree (value);
148 }
149 }
150
151 return name.get ();
152 }
153
154 /* Try to determine the executable filename.
155
156 EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.
157
158 Upon success, the filename is stored inside EXE_NAME_RET, and
159 this function returns nonzero.
160
161 Otherwise, this function returns zero and the contents of
162 EXE_NAME_RET is undefined. */
163
164 int
165 windows_process_info::get_exec_module_filename (char *exe_name_ret,
166 size_t exe_name_max_len)
167 {
168 DWORD len;
169 HMODULE dh_buf;
170 DWORD cbNeeded;
171
172 cbNeeded = 0;
173 #ifdef __x86_64__
174 if (wow64_process)
175 {
176 if (!EnumProcessModulesEx (handle,
177 &dh_buf, sizeof (HMODULE), &cbNeeded,
178 LIST_MODULES_32BIT)
179 || !cbNeeded)
180 return 0;
181 }
182 else
183 #endif
184 {
185 if (!EnumProcessModules (handle,
186 &dh_buf, sizeof (HMODULE), &cbNeeded)
187 || !cbNeeded)
188 return 0;
189 }
190
191 /* We know the executable is always first in the list of modules,
192 which we just fetched. So no need to fetch more. */
193
194 #ifdef __CYGWIN__
195 {
196 /* Cygwin prefers that the path be in /x/y/z format, so extract
197 the filename into a temporary buffer first, and then convert it
198 to POSIX format into the destination buffer. */
199 cygwin_buf_t *pathbuf = (cygwin_buf_t *) alloca (exe_name_max_len * sizeof (cygwin_buf_t));
200
201 len = GetModuleFileNameEx (handle,
202 dh_buf, pathbuf, exe_name_max_len);
203 if (len == 0)
204 error (_("Error getting executable filename: %u."),
205 (unsigned) GetLastError ());
206 if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, exe_name_ret,
207 exe_name_max_len) < 0)
208 error (_("Error converting executable filename to POSIX: %d."), errno);
209 }
210 #else
211 len = GetModuleFileNameEx (handle,
212 dh_buf, exe_name_ret, exe_name_max_len);
213 if (len == 0)
214 error (_("Error getting executable filename: %u."),
215 (unsigned) GetLastError ());
216 #endif
217
218 return 1; /* success */
219 }
220
221 const char *
222 windows_process_info::pid_to_exec_file (int pid)
223 {
224 static char path[MAX_PATH];
225 #ifdef __CYGWIN__
226 /* Try to find exe name as symlink target of /proc/<pid>/exe. */
227 int nchars;
228 char procexe[sizeof ("/proc/4294967295/exe")];
229
230 xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid);
231 nchars = readlink (procexe, path, sizeof(path));
232 if (nchars > 0 && nchars < sizeof (path))
233 {
234 path[nchars] = '\0'; /* Got it */
235 return path;
236 }
237 #endif
238
239 /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
240 of gdb, or we're trying to debug a non-Cygwin windows executable. */
241 if (!get_exec_module_filename (path, sizeof (path)))
242 path[0] = '\0';
243
244 return path;
245 }
246
247 /* Return the name of the DLL referenced by H at ADDRESS. UNICODE
248 determines what sort of string is read from the inferior. Returns
249 the name of the DLL, or NULL on error. If a name is returned, it
250 is stored in a static buffer which is valid until the next call to
251 get_image_name. */
252
253 static const char *
254 get_image_name (HANDLE h, void *address, int unicode)
255 {
256 #ifdef __CYGWIN__
257 static char buf[MAX_PATH];
258 #else
259 static char buf[(2 * MAX_PATH) + 1];
260 #endif
261 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
262 char *address_ptr;
263 int len = 0;
264 char b[2];
265 SIZE_T done;
266
267 /* Attempt to read the name of the dll that was detected.
268 This is documented to work only when actively debugging
269 a program. It will not work for attached processes. */
270 if (address == NULL)
271 return NULL;
272
273 /* See if we could read the address of a string, and that the
274 address isn't null. */
275 if (!ReadProcessMemory (h, address, &address_ptr,
276 sizeof (address_ptr), &done)
277 || done != sizeof (address_ptr)
278 || !address_ptr)
279 return NULL;
280
281 /* Find the length of the string. */
282 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
283 && (b[0] != 0 || b[size - 1] != 0) && done == size)
284 continue;
285
286 if (!unicode)
287 ReadProcessMemory (h, address_ptr, buf, len, &done);
288 else
289 {
290 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
291 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
292 &done);
293 #ifdef __CYGWIN__
294 wcstombs (buf, unicode_address, MAX_PATH);
295 #else
296 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
297 0, 0);
298 #endif
299 }
300
301 return buf;
302 }
303
304 /* See nat/windows-nat.h. */
305
306 bool
307 windows_process_info::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
308 {
309 if (rec->NumberParameters >= 3
310 && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
311 {
312 DWORD named_thread_id;
313 windows_thread_info *named_thread;
314 CORE_ADDR thread_name_target;
315
316 thread_name_target = rec->ExceptionInformation[1];
317 named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]);
318
319 if (named_thread_id == (DWORD) -1)
320 named_thread_id = current_event.dwThreadId;
321
322 named_thread = thread_rec (ptid_t (current_event.dwProcessId,
323 named_thread_id, 0),
324 DONT_INVALIDATE_CONTEXT);
325 if (named_thread != NULL)
326 {
327 int thread_name_len;
328 gdb::unique_xmalloc_ptr<char> thread_name
329 = target_read_string (thread_name_target, 1025, &thread_name_len);
330 if (thread_name_len > 0)
331 {
332 thread_name.get ()[thread_name_len - 1] = '\0';
333 named_thread->name = std::move (thread_name);
334 }
335 }
336
337 return true;
338 }
339
340 return false;
341 }
342
343 /* The exception thrown by a program to tell the debugger the name of
344 a thread. The exception record contains an ID of a thread and a
345 name to give it. This exception has no documented name, but MSDN
346 dubs it "MS_VC_EXCEPTION" in one code example. */
347 #define MS_VC_EXCEPTION 0x406d1388
348
349 handle_exception_result
350 windows_process_info::handle_exception (struct target_waitstatus *ourstatus,
351 bool debug_exceptions)
352 {
353 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
354 debug_printf ("gdb: Target exception %s at %s\n", x, \
355 host_address_to_string (\
356 current_event.u.Exception.ExceptionRecord.ExceptionAddress))
357
358 EXCEPTION_RECORD *rec = &current_event.u.Exception.ExceptionRecord;
359 DWORD code = rec->ExceptionCode;
360 handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
361
362 memcpy (&siginfo_er, rec, sizeof siginfo_er);
363
364 /* Record the context of the current thread. */
365 thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
366 DONT_SUSPEND);
367
368 last_sig = GDB_SIGNAL_0;
369
370 switch (code)
371 {
372 case EXCEPTION_ACCESS_VIOLATION:
373 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
374 ourstatus->set_stopped (GDB_SIGNAL_SEGV);
375 if (handle_access_violation (rec))
376 return HANDLE_EXCEPTION_UNHANDLED;
377 break;
378 case STATUS_STACK_OVERFLOW:
379 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
380 ourstatus->set_stopped (GDB_SIGNAL_SEGV);
381 break;
382 case STATUS_FLOAT_DENORMAL_OPERAND:
383 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
384 ourstatus->set_stopped (GDB_SIGNAL_FPE);
385 break;
386 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
387 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
388 ourstatus->set_stopped (GDB_SIGNAL_FPE);
389 break;
390 case STATUS_FLOAT_INEXACT_RESULT:
391 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
392 ourstatus->set_stopped (GDB_SIGNAL_FPE);
393 break;
394 case STATUS_FLOAT_INVALID_OPERATION:
395 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
396 ourstatus->set_stopped (GDB_SIGNAL_FPE);
397 break;
398 case STATUS_FLOAT_OVERFLOW:
399 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
400 ourstatus->set_stopped (GDB_SIGNAL_FPE);
401 break;
402 case STATUS_FLOAT_STACK_CHECK:
403 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
404 ourstatus->set_stopped (GDB_SIGNAL_FPE);
405 break;
406 case STATUS_FLOAT_UNDERFLOW:
407 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
408 ourstatus->set_stopped (GDB_SIGNAL_FPE);
409 break;
410 case STATUS_FLOAT_DIVIDE_BY_ZERO:
411 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
412 ourstatus->set_stopped (GDB_SIGNAL_FPE);
413 break;
414 case STATUS_INTEGER_DIVIDE_BY_ZERO:
415 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
416 ourstatus->set_stopped (GDB_SIGNAL_FPE);
417 break;
418 case STATUS_INTEGER_OVERFLOW:
419 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
420 ourstatus->set_stopped (GDB_SIGNAL_FPE);
421 break;
422 case EXCEPTION_BREAKPOINT:
423 #ifdef __x86_64__
424 if (ignore_first_breakpoint)
425 {
426 /* For WOW64 processes, there are always 2 breakpoint exceptions
427 on startup, first a BREAKPOINT for the 64bit ntdll.dll,
428 then a WX86_BREAKPOINT for the 32bit ntdll.dll.
429 Here we only care about the WX86_BREAKPOINT's. */
430 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT - ignore_first_breakpoint");
431 ourstatus->set_spurious ();
432 ignore_first_breakpoint = false;
433 break;
434 }
435 else if (wow64_process)
436 {
437 /* This breakpoint exception is triggered for WOW64 processes when
438 reaching an int3 instruction in 64bit code.
439 gdb checks for int3 in case of SIGTRAP, this fails because
440 Wow64GetThreadContext can only report the pc of 32bit code, and
441 gdb lets the target process continue.
442 So handle it as SIGINT instead, then the target is stopped
443 unconditionally. */
444 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT - wow64_process");
445 rec->ExceptionCode = DBG_CONTROL_C;
446 ourstatus->set_stopped (GDB_SIGNAL_INT);
447 break;
448 }
449 #endif
450 /* FALLTHROUGH */
451 case STATUS_WX86_BREAKPOINT:
452 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
453 ourstatus->set_stopped (GDB_SIGNAL_TRAP);
454 break;
455 case DBG_CONTROL_C:
456 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
457 ourstatus->set_stopped (GDB_SIGNAL_INT);
458 break;
459 case DBG_CONTROL_BREAK:
460 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
461 ourstatus->set_stopped (GDB_SIGNAL_INT);
462 break;
463 case EXCEPTION_SINGLE_STEP:
464 case STATUS_WX86_SINGLE_STEP:
465 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
466 ourstatus->set_stopped (GDB_SIGNAL_TRAP);
467 break;
468 case EXCEPTION_ILLEGAL_INSTRUCTION:
469 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
470 ourstatus->set_stopped (GDB_SIGNAL_ILL);
471 break;
472 case EXCEPTION_PRIV_INSTRUCTION:
473 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
474 ourstatus->set_stopped (GDB_SIGNAL_ILL);
475 break;
476 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
477 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
478 ourstatus->set_stopped (GDB_SIGNAL_ILL);
479 break;
480 case MS_VC_EXCEPTION:
481 DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
482 if (handle_ms_vc_exception (rec))
483 {
484 ourstatus->set_stopped (GDB_SIGNAL_TRAP);
485 result = HANDLE_EXCEPTION_IGNORED;
486 break;
487 }
488 /* treat improperly formed exception as unknown */
489 /* FALLTHROUGH */
490 default:
491 /* Treat unhandled first chance exceptions specially. */
492 if (current_event.u.Exception.dwFirstChance)
493 return HANDLE_EXCEPTION_UNHANDLED;
494 debug_printf ("gdb: unknown target exception 0x%08x at %s\n",
495 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
496 host_address_to_string (
497 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
498 ourstatus->set_stopped (GDB_SIGNAL_UNKNOWN);
499 break;
500 }
501
502 if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
503 last_sig = ourstatus->sig ();
504
505 return result;
506
507 #undef DEBUG_EXCEPTION_SIMPLE
508 }
509
510 /* See nat/windows-nat.h. */
511
512 void
513 windows_process_info::add_dll (LPVOID load_addr)
514 {
515 HMODULE dummy_hmodule;
516 DWORD cb_needed;
517 HMODULE *hmodules;
518 int i;
519
520 #ifdef __x86_64__
521 if (wow64_process)
522 {
523 if (EnumProcessModulesEx (handle, &dummy_hmodule,
524 sizeof (HMODULE), &cb_needed,
525 LIST_MODULES_32BIT) == 0)
526 return;
527 }
528 else
529 #endif
530 {
531 if (EnumProcessModules (handle, &dummy_hmodule,
532 sizeof (HMODULE), &cb_needed) == 0)
533 return;
534 }
535
536 if (cb_needed < 1)
537 return;
538
539 hmodules = (HMODULE *) alloca (cb_needed);
540 #ifdef __x86_64__
541 if (wow64_process)
542 {
543 if (EnumProcessModulesEx (handle, hmodules,
544 cb_needed, &cb_needed,
545 LIST_MODULES_32BIT) == 0)
546 return;
547 }
548 else
549 #endif
550 {
551 if (EnumProcessModules (handle, hmodules,
552 cb_needed, &cb_needed) == 0)
553 return;
554 }
555
556 char system_dir[MAX_PATH];
557 char syswow_dir[MAX_PATH];
558 size_t system_dir_len = 0;
559 bool convert_syswow_dir = false;
560 #ifdef __x86_64__
561 if (wow64_process)
562 #endif
563 {
564 /* This fails on 32bit Windows because it has no SysWOW64 directory,
565 and in this case a path conversion isn't necessary. */
566 UINT len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
567 if (len > 0)
568 {
569 /* Check that we have passed a large enough buffer. */
570 gdb_assert (len < sizeof (syswow_dir));
571
572 len = GetSystemDirectoryA (system_dir, sizeof (system_dir));
573 /* Error check. */
574 gdb_assert (len != 0);
575 /* Check that we have passed a large enough buffer. */
576 gdb_assert (len < sizeof (system_dir));
577
578 strcat (system_dir, "\\");
579 strcat (syswow_dir, "\\");
580 system_dir_len = strlen (system_dir);
581
582 convert_syswow_dir = true;
583 }
584
585 }
586 for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
587 {
588 MODULEINFO mi;
589 #ifdef __USEWIDE
590 wchar_t dll_name[MAX_PATH];
591 char dll_name_mb[MAX_PATH];
592 #else
593 char dll_name[MAX_PATH];
594 #endif
595 const char *name;
596 if (GetModuleInformation (handle, hmodules[i],
597 &mi, sizeof (mi)) == 0)
598 continue;
599
600 if (GetModuleFileNameEx (handle, hmodules[i],
601 dll_name, sizeof (dll_name)) == 0)
602 continue;
603 #ifdef __USEWIDE
604 wcstombs (dll_name_mb, dll_name, MAX_PATH);
605 name = dll_name_mb;
606 #else
607 name = dll_name;
608 #endif
609 /* Convert the DLL path of 32bit processes returned by
610 GetModuleFileNameEx from the 64bit system directory to the
611 32bit syswow64 directory if necessary. */
612 std::string syswow_dll_path;
613 if (convert_syswow_dir
614 && strncasecmp (name, system_dir, system_dir_len) == 0
615 && strchr (name + system_dir_len, '\\') == nullptr)
616 {
617 syswow_dll_path = syswow_dir;
618 syswow_dll_path += name + system_dir_len;
619 name = syswow_dll_path.c_str();
620 }
621
622 /* Record the DLL if either LOAD_ADDR is NULL or the address
623 at which the DLL was loaded is equal to LOAD_ADDR. */
624 if (!(load_addr != nullptr && mi.lpBaseOfDll != load_addr))
625 {
626 handle_load_dll (name, mi.lpBaseOfDll);
627 if (load_addr != nullptr)
628 return;
629 }
630 }
631 }
632
633 /* See nat/windows-nat.h. */
634
635 void
636 windows_process_info::dll_loaded_event ()
637 {
638 gdb_assert (current_event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT);
639
640 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
641 const char *dll_name;
642
643 /* Try getting the DLL name via the lpImageName field of the event.
644 Note that Microsoft documents this fields as strictly optional,
645 in the sense that it might be NULL. And the first DLL event in
646 particular is explicitly documented as "likely not pass[ed]"
647 (source: MSDN LOAD_DLL_DEBUG_INFO structure). */
648 dll_name = get_image_name (handle, event->lpImageName, event->fUnicode);
649 /* If the DLL name could not be gleaned via lpImageName, try harder
650 by enumerating all the DLLs loaded into the inferior, looking for
651 one that is loaded at base address = lpBaseOfDll. */
652 if (dll_name != nullptr)
653 handle_load_dll (dll_name, event->lpBaseOfDll);
654 else if (event->lpBaseOfDll != nullptr)
655 add_dll (event->lpBaseOfDll);
656 }
657
658 /* See nat/windows-nat.h. */
659
660 void
661 windows_process_info::add_all_dlls ()
662 {
663 add_dll (nullptr);
664 }
665
666 /* See nat/windows-nat.h. */
667
668 bool
669 windows_process_info::matching_pending_stop (bool debug_events)
670 {
671 /* If there are pending stops, and we might plausibly hit one of
672 them, we don't want to actually continue the inferior -- we just
673 want to report the stop. In this case, we just pretend to
674 continue. See the comment by the definition of "pending_stops"
675 for details on why this is needed. */
676 for (const auto &item : pending_stops)
677 {
678 if (desired_stop_thread_id == -1
679 || desired_stop_thread_id == item.thread_id)
680 {
681 DEBUG_EVENTS ("pending stop anticipated, desired=0x%x, item=0x%x",
682 desired_stop_thread_id, item.thread_id);
683 return true;
684 }
685 }
686
687 return false;
688 }
689
690 /* See nat/windows-nat.h. */
691
692 gdb::optional<pending_stop>
693 windows_process_info::fetch_pending_stop (bool debug_events)
694 {
695 gdb::optional<pending_stop> result;
696 for (auto iter = pending_stops.begin ();
697 iter != pending_stops.end ();
698 ++iter)
699 {
700 if (desired_stop_thread_id == -1
701 || desired_stop_thread_id == iter->thread_id)
702 {
703 result = *iter;
704 current_event = iter->event;
705
706 DEBUG_EVENTS ("pending stop found in 0x%x (desired=0x%x)",
707 iter->thread_id, desired_stop_thread_id);
708
709 pending_stops.erase (iter);
710 break;
711 }
712 }
713
714 return result;
715 }
716
717 /* See nat/windows-nat.h. */
718
719 BOOL
720 continue_last_debug_event (DWORD continue_status, bool debug_events)
721 {
722 DEBUG_EVENTS ("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s)",
723 (unsigned) last_wait_event.dwProcessId,
724 (unsigned) last_wait_event.dwThreadId,
725 continue_status == DBG_CONTINUE ?
726 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED");
727
728 return ContinueDebugEvent (last_wait_event.dwProcessId,
729 last_wait_event.dwThreadId,
730 continue_status);
731 }
732
733 /* See nat/windows-nat.h. */
734
735 BOOL
736 wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout)
737 {
738 BOOL result = WaitForDebugEvent (event, timeout);
739 if (result)
740 last_wait_event = *event;
741 return result;
742 }
743
744 /* Define dummy functions which always return error for the rare cases where
745 these functions could not be found. */
746 template<typename... T>
747 BOOL WINAPI
748 bad (T... args)
749 {
750 return FALSE;
751 }
752
753 template<typename... T>
754 DWORD WINAPI
755 bad (T... args)
756 {
757 return 0;
758 }
759
760 static BOOL WINAPI
761 bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
762 {
763 f->nFont = 0;
764 return 1;
765 }
766
767 static COORD WINAPI
768 bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
769 {
770 COORD size;
771 size.X = 8;
772 size.Y = 12;
773 return size;
774 }
775
776 /* See windows-nat.h. */
777
778 bool
779 initialize_loadable ()
780 {
781 bool result = true;
782 HMODULE hm = NULL;
783
784 #define GPA(m, func) \
785 func = (func ## _ftype *) GetProcAddress (m, #func)
786
787 hm = LoadLibrary (TEXT ("kernel32.dll"));
788 if (hm)
789 {
790 GPA (hm, DebugActiveProcessStop);
791 GPA (hm, DebugBreakProcess);
792 GPA (hm, DebugSetProcessKillOnExit);
793 GPA (hm, GetConsoleFontSize);
794 GPA (hm, DebugActiveProcessStop);
795 GPA (hm, GetCurrentConsoleFont);
796 #ifdef __x86_64__
797 GPA (hm, Wow64SuspendThread);
798 GPA (hm, Wow64GetThreadContext);
799 GPA (hm, Wow64SetThreadContext);
800 GPA (hm, Wow64GetThreadSelectorEntry);
801 #endif
802 GPA (hm, GenerateConsoleCtrlEvent);
803 GPA (hm, GetThreadDescription);
804 }
805
806 /* Set variables to dummy versions of these processes if the function
807 wasn't found in kernel32.dll. */
808 if (!DebugBreakProcess)
809 DebugBreakProcess = bad;
810 if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
811 {
812 DebugActiveProcessStop = bad;
813 DebugSetProcessKillOnExit = bad;
814 }
815 if (!GetConsoleFontSize)
816 GetConsoleFontSize = bad_GetConsoleFontSize;
817 if (!GetCurrentConsoleFont)
818 GetCurrentConsoleFont = bad_GetCurrentConsoleFont;
819
820 /* Load optional functions used for retrieving filename information
821 associated with the currently debugged process or its dlls. */
822 hm = LoadLibrary (TEXT ("psapi.dll"));
823 if (hm)
824 {
825 GPA (hm, EnumProcessModules);
826 #ifdef __x86_64__
827 GPA (hm, EnumProcessModulesEx);
828 #endif
829 GPA (hm, GetModuleInformation);
830 GPA (hm, GetModuleFileNameExA);
831 GPA (hm, GetModuleFileNameExW);
832 }
833
834 if (!EnumProcessModules || !GetModuleInformation
835 || !GetModuleFileNameExA || !GetModuleFileNameExW)
836 {
837 /* Set variables to dummy versions of these processes if the function
838 wasn't found in psapi.dll. */
839 EnumProcessModules = bad;
840 GetModuleInformation = bad;
841 GetModuleFileNameExA = bad;
842 GetModuleFileNameExW = bad;
843
844 result = false;
845 }
846
847 hm = LoadLibrary (TEXT ("advapi32.dll"));
848 if (hm)
849 {
850 GPA (hm, OpenProcessToken);
851 GPA (hm, LookupPrivilegeValueA);
852 GPA (hm, AdjustTokenPrivileges);
853 /* Only need to set one of these since if OpenProcessToken fails nothing
854 else is needed. */
855 if (!OpenProcessToken || !LookupPrivilegeValueA
856 || !AdjustTokenPrivileges)
857 OpenProcessToken = bad;
858 }
859
860 /* On some versions of Windows, this function is only available in
861 KernelBase.dll, not kernel32.dll. */
862 if (GetThreadDescription == nullptr)
863 {
864 hm = LoadLibrary (TEXT ("KernelBase.dll"));
865 if (hm)
866 GPA (hm, GetThreadDescription);
867 }
868
869 #undef GPA
870
871 return result;
872 }
873
874 }