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