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