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