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