]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdbserver/win32-low.cc
Make target_wait options use enum flags
[thirdparty/binutils-gdb.git] / gdbserver / win32-low.cc
CommitLineData
b80864fb 1/* Low level interface to Windows debugging, for gdbserver.
b811d2c2 2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
b80864fb
DJ
3
4 Contributed by Leo Zayas. Based on "win32-nat.c" from GDB.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
b80864fb
DJ
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
b80864fb
DJ
20
21#include "server.h"
22#include "regcache.h"
59a016f0 23#include "gdb/fileio.h"
ed50f18f
PA
24#include "mem-break.h"
25#include "win32-low.h"
623b6bdf 26#include "gdbthread.h"
799cdc37 27#include "dll.h"
533b0600 28#include "hostio.h"
b80864fb 29#include <windows.h>
ed50f18f 30#include <winnt.h>
b80864fb 31#include <imagehlp.h>
255e7678 32#include <tlhelp32.h>
b80864fb 33#include <psapi.h>
b80864fb 34#include <process.h>
268a13a5
TT
35#include "gdbsupport/gdb_tilde_expand.h"
36#include "gdbsupport/common-inferior.h"
559e7e50 37#include "gdbsupport/gdb_wait.h"
b80864fb 38
4834dad0
TT
39using namespace windows_nat;
40
b80864fb
DJ
41#ifndef USE_WIN32API
42#include <sys/cygwin.h>
43#endif
44
10357975
PA
45#define OUTMSG(X) do { printf X; fflush (stderr); } while (0)
46
47#define OUTMSG2(X) \
48 do \
49 { \
50 if (debug_threads) \
51 { \
52 printf X; \
53 fflush (stderr); \
54 } \
55 } while (0)
ed50f18f
PA
56
57#ifndef _T
58#define _T(x) TEXT (x)
59#endif
60
61#ifndef COUNTOF
62#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
b80864fb
DJ
63#endif
64
bf914831
PA
65#ifdef _WIN32_WCE
66# define GETPROCADDRESS(DLL, PROC) \
67 ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC)))
68#else
69# define GETPROCADDRESS(DLL, PROC) \
70 ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
71#endif
72
b80864fb
DJ
73int using_threads = 1;
74
75/* Globals. */
d97903b2 76static int attaching = 0;
b80864fb 77
4210d83e
PA
78/* A status that hasn't been reported to the core yet, and so
79 win32_wait should return it next, instead of fetching the next
80 debug event off the win32 API. */
81static struct target_waitstatus cached_status;
82
4d5d1aaa
PA
83/* Non zero if an interrupt request is to be satisfied by suspending
84 all threads. */
85static int soft_interrupt_requested = 0;
86
87/* Non zero if the inferior is stopped in a simulated breakpoint done
88 by suspending all the threads. */
89static int faked_breakpoint = 0;
90
6479bf85
HD
91/* True if current_process_handle needs to be closed. */
92static bool open_process_used = false;
93
7d186bc0
HD
94#ifdef __x86_64__
95bool wow64_process = false;
96#endif
97
3aee8918 98const struct target_desc *win32_tdesc;
7d186bc0
HD
99#ifdef __x86_64__
100const struct target_desc *wow64_win32_tdesc;
101#endif
3aee8918 102
7d186bc0 103#define NUM_REGS (the_low_target.num_regs ())
b80864fb 104
7a9a7487
MG
105typedef BOOL (WINAPI *winapi_DebugActiveProcessStop) (DWORD dwProcessId);
106typedef BOOL (WINAPI *winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
107typedef BOOL (WINAPI *winapi_DebugBreakProcess) (HANDLE);
108typedef BOOL (WINAPI *winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
b80864fb 109
7d186bc0
HD
110#ifdef __x86_64__
111typedef BOOL (WINAPI *winapi_Wow64SetThreadContext) (HANDLE,
112 const WOW64_CONTEXT *);
113
114winapi_Wow64GetThreadContext win32_Wow64GetThreadContext;
115static winapi_Wow64SetThreadContext win32_Wow64SetThreadContext;
116#endif
117
379a5e2d 118#ifndef _WIN32_WCE
f25b3fc3 119static void win32_add_all_dlls (void);
379a5e2d 120#endif
34b34921 121
b80864fb
DJ
122/* Get the thread ID from the current selected inferior (the current
123 thread). */
95954743 124static ptid_t
0bfdf32f 125current_thread_ptid (void)
b80864fb 126{
80894984 127 return current_ptid;
95954743
PA
128}
129
130/* The current debug event from WaitForDebugEvent. */
131static ptid_t
132debug_event_ptid (DEBUG_EVENT *event)
133{
fd79271b 134 return ptid_t (event->dwProcessId, event->dwThreadId, 0);
b80864fb
DJ
135}
136
9c6c8194
PA
137/* Get the thread context of the thread associated with TH. */
138
139static void
e56f8ccb 140win32_get_thread_context (windows_thread_info *th)
9c6c8194 141{
7d186bc0
HD
142#ifdef __x86_64__
143 if (wow64_process)
144 memset (&th->wow64_context, 0, sizeof (WOW64_CONTEXT));
145 else
146#endif
147 memset (&th->context, 0, sizeof (CONTEXT));
a2abc7de 148 (*the_low_target.get_thread_context) (th);
9c6c8194
PA
149#ifdef _WIN32_WCE
150 memcpy (&th->base_context, &th->context, sizeof (CONTEXT));
151#endif
152}
153
154/* Set the thread context of the thread associated with TH. */
155
156static void
e56f8ccb 157win32_set_thread_context (windows_thread_info *th)
9c6c8194
PA
158{
159#ifdef _WIN32_WCE
160 /* Calling SuspendThread on a thread that is running kernel code
161 will report that the suspending was successful, but in fact, that
162 will often not be true. In those cases, the context returned by
163 GetThreadContext will not be correct by the time the thread
164 stops, hence we can't set that context back into the thread when
30baf67b 165 resuming - it will most likely crash the inferior.
9c6c8194
PA
166 Unfortunately, there is no way to know when the thread will
167 really stop. To work around it, we'll only write the context
168 back to the thread when either the user or GDB explicitly change
169 it between stopping and resuming. */
170 if (memcmp (&th->context, &th->base_context, sizeof (CONTEXT)) != 0)
171#endif
7d186bc0
HD
172 {
173#ifdef __x86_64__
174 if (wow64_process)
175 win32_Wow64SetThreadContext (th->h, &th->wow64_context);
176 else
177#endif
178 SetThreadContext (th->h, &th->context);
179 }
9c6c8194
PA
180}
181
a2abc7de
PA
182/* Set the thread context of the thread associated with TH. */
183
184static void
e56f8ccb 185win32_prepare_to_resume (windows_thread_info *th)
b80864fb 186{
a2abc7de
PA
187 if (the_low_target.prepare_to_resume != NULL)
188 (*the_low_target.prepare_to_resume) (th);
189}
b80864fb 190
a2abc7de 191/* See win32-low.h. */
b80864fb 192
a2abc7de 193void
e56f8ccb 194win32_require_context (windows_thread_info *th)
a2abc7de 195{
7d186bc0
HD
196 DWORD context_flags;
197#ifdef __x86_64__
198 if (wow64_process)
199 context_flags = th->wow64_context.ContextFlags;
200 else
201#endif
202 context_flags = th->context.ContextFlags;
203 if (context_flags == 0)
b80864fb 204 {
98a03287 205 th->suspend ();
9c6c8194 206 win32_get_thread_context (th);
b80864fb 207 }
a2abc7de
PA
208}
209
28688adf
TT
210/* See nat/windows-nat.h. */
211
212windows_thread_info *
213windows_nat::thread_rec (ptid_t ptid, thread_disposition_type disposition)
a2abc7de 214{
8dc7b443 215 thread_info *thread = find_thread_ptid (ptid);
a2abc7de
PA
216 if (thread == NULL)
217 return NULL;
218
e56f8ccb 219 windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
28688adf 220 if (disposition != DONT_INVALIDATE_CONTEXT)
a2abc7de 221 win32_require_context (th);
b80864fb
DJ
222 return th;
223}
224
225/* Add a thread to the thread list. */
e56f8ccb 226static windows_thread_info *
711e434b 227child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb)
b80864fb 228{
e56f8ccb 229 windows_thread_info *th;
fd79271b 230 ptid_t ptid = ptid_t (pid, tid, 0);
b80864fb 231
28688adf 232 if ((th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT)))
b80864fb
DJ
233 return th;
234
7d186bc0
HD
235 CORE_ADDR base = (CORE_ADDR) (uintptr_t) tlb;
236#ifdef __x86_64__
237 /* For WOW64 processes, this is actually the pointer to the 64bit TIB,
238 and the 32bit TIB is exactly 2 pages after it. */
239 if (wow64_process)
240 base += 2 * 4096; /* page size = 4096 */
241#endif
242 th = new windows_thread_info (tid, h, base);
b80864fb 243
95954743 244 add_thread (ptid, th);
b80864fb 245
34b34921
PA
246 if (the_low_target.thread_added != NULL)
247 (*the_low_target.thread_added) (th);
b80864fb
DJ
248
249 return th;
250}
251
252/* Delete a thread from the list of threads. */
253static void
9c80ecd6 254delete_thread_info (thread_info *thread)
b80864fb 255{
e56f8ccb 256 windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
b80864fb 257
c3de4d92 258 remove_thread (thread);
e9534bd2 259 delete th;
b80864fb
DJ
260}
261
262/* Delete a thread from the list of threads. */
263static void
95954743 264child_delete_thread (DWORD pid, DWORD tid)
b80864fb 265{
b80864fb 266 /* If the last thread is exiting, just return. */
9c80ecd6 267 if (all_threads.size () == 1)
b80864fb
DJ
268 return;
269
8dc7b443 270 thread_info *thread = find_thread_ptid (ptid_t (pid, tid));
b80864fb
DJ
271 if (thread == NULL)
272 return;
273
274 delete_thread_info (thread);
275}
276
aa5ca48f
DE
277/* These watchpoint related wrapper functions simply pass on the function call
278 if the low target has registered a corresponding function. */
279
a2b2297a
TBA
280bool
281win32_process_target::supports_z_point_type (char z_type)
802e8e6d 282{
523d4f80
TT
283 return (z_type == Z_PACKET_SW_BP
284 || (the_low_target.supports_z_point_type != NULL
285 && the_low_target.supports_z_point_type (z_type)));
802e8e6d
PA
286}
287
7e0bde70
TBA
288int
289win32_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
290 int size, raw_breakpoint *bp)
aa5ca48f 291{
523d4f80
TT
292 if (type == raw_bkpt_type_sw)
293 return insert_memory_breakpoint (bp);
294 else if (the_low_target.insert_point != NULL)
802e8e6d 295 return the_low_target.insert_point (type, addr, size, bp);
aa5ca48f
DE
296 else
297 /* Unsupported (see target.h). */
298 return 1;
299}
300
7e0bde70
TBA
301int
302win32_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
303 int size, raw_breakpoint *bp)
aa5ca48f 304{
523d4f80
TT
305 if (type == raw_bkpt_type_sw)
306 return remove_memory_breakpoint (bp);
307 else if (the_low_target.remove_point != NULL)
802e8e6d 308 return the_low_target.remove_point (type, addr, size, bp);
aa5ca48f
DE
309 else
310 /* Unsupported (see target.h). */
311 return 1;
312}
313
6eeb5c55
TBA
314bool
315win32_process_target::stopped_by_watchpoint ()
aa5ca48f
DE
316{
317 if (the_low_target.stopped_by_watchpoint != NULL)
318 return the_low_target.stopped_by_watchpoint ();
319 else
6eeb5c55 320 return false;
aa5ca48f
DE
321}
322
6eeb5c55
TBA
323CORE_ADDR
324win32_process_target::stopped_data_address ()
aa5ca48f
DE
325{
326 if (the_low_target.stopped_data_address != NULL)
327 return the_low_target.stopped_data_address ();
328 else
329 return 0;
330}
331
332
b80864fb
DJ
333/* Transfer memory from/to the debugged process. */
334static int
335child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
5b6d1e4f 336 int write, process_stratum_target *target)
b80864fb 337{
cee83bcb
PM
338 BOOL success;
339 SIZE_T done = 0;
340 DWORD lasterror = 0;
e8f0053d 341 uintptr_t addr = (uintptr_t) memaddr;
b80864fb
DJ
342
343 if (write)
344 {
cee83bcb
PM
345 success = WriteProcessMemory (current_process_handle, (LPVOID) addr,
346 (LPCVOID) our, len, &done);
347 if (!success)
348 lasterror = GetLastError ();
b80864fb
DJ
349 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
350 }
351 else
352 {
cee83bcb
PM
353 success = ReadProcessMemory (current_process_handle, (LPCVOID) addr,
354 (LPVOID) our, len, &done);
355 if (!success)
356 lasterror = GetLastError ();
b80864fb 357 }
cee83bcb
PM
358 if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0)
359 return done;
360 else
361 return success ? done : -1;
b80864fb
DJ
362}
363
ed50f18f 364/* Clear out any old thread list and reinitialize it to a pristine
b80864fb
DJ
365 state. */
366static void
367child_init_thread_list (void)
368{
f0045347 369 for_each_thread (delete_thread_info);
b80864fb
DJ
370}
371
f25b3fc3
JB
372/* Zero during the child initialization phase, and nonzero otherwise. */
373
374static int child_initialization_done = 0;
375
b80864fb 376static void
95954743 377do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
b80864fb 378{
3aee8918
PA
379 struct process_info *proc;
380
a493e3e2 381 last_sig = GDB_SIGNAL_0;
b80864fb 382
5ac588cf
PA
383 current_process_handle = proch;
384 current_process_id = pid;
385 main_thread_id = 0;
386
387 soft_interrupt_requested = 0;
388 faked_breakpoint = 0;
6479bf85 389 open_process_used = true;
5ac588cf 390
b80864fb
DJ
391 memset (&current_event, 0, sizeof (current_event));
392
7d186bc0
HD
393#ifdef __x86_64__
394 BOOL wow64;
395 if (!IsWow64Process (proch, &wow64))
396 {
397 DWORD err = GetLastError ();
398 error ("Check if WOW64 process failed (error %d): %s\n",
399 (int) err, strwinerror (err));
400 }
401 wow64_process = wow64;
402
403 if (wow64_process
404 && (win32_Wow64GetThreadContext == nullptr
405 || win32_Wow64SetThreadContext == nullptr))
406 error ("WOW64 debugging is not supported on this system.\n");
407
408 ignore_first_breakpoint = !attached && wow64_process;
409#endif
410
3aee8918 411 proc = add_process (pid, attached);
7d186bc0
HD
412#ifdef __x86_64__
413 if (wow64_process)
414 proc->tdesc = wow64_win32_tdesc;
415 else
416#endif
417 proc->tdesc = win32_tdesc;
b80864fb 418 child_init_thread_list ();
f25b3fc3 419 child_initialization_done = 0;
ed50f18f
PA
420
421 if (the_low_target.initial_stuff != NULL)
422 (*the_low_target.initial_stuff) ();
4210d83e
PA
423
424 cached_status.kind = TARGET_WAITKIND_IGNORE;
425
426 /* Flush all currently pending debug events (thread and dll list) up
427 to the initial breakpoint. */
428 while (1)
429 {
430 struct target_waitstatus status;
431
52405d85 432 the_target->wait (minus_one_ptid, &status, 0);
4210d83e
PA
433
434 /* Note win32_wait doesn't return thread events. */
435 if (status.kind != TARGET_WAITKIND_LOADED)
436 {
437 cached_status = status;
438 break;
439 }
440
441 {
442 struct thread_resume resume;
443
444 resume.thread = minus_one_ptid;
445 resume.kind = resume_continue;
446 resume.sig = 0;
447
52405d85 448 the_target->resume (&resume, 1);
4210d83e
PA
449 }
450 }
379a5e2d
JB
451
452#ifndef _WIN32_WCE
f25b3fc3
JB
453 /* Now that the inferior has been started and all DLLs have been mapped,
454 we can iterate over all DLLs and load them in.
455
456 We avoid doing it any earlier because, on certain versions of Windows,
457 LOAD_DLL_DEBUG_EVENTs are sometimes not complete. In particular,
458 we have seen on Windows 8.1 that the ntdll.dll load event does not
459 include the DLL name, preventing us from creating an associated SO.
460 A possible explanation is that ntdll.dll might be mapped before
461 the SO info gets created by the Windows system -- ntdll.dll is
462 the first DLL to be reported via LOAD_DLL_DEBUG_EVENT and other DLLs
463 do not seem to suffer from that problem.
464
465 Rather than try to work around this sort of issue, it is much
466 simpler to just ignore DLL load/unload events during the startup
467 phase, and then process them all in one batch now. */
468 win32_add_all_dlls ();
379a5e2d 469#endif
f25b3fc3
JB
470
471 child_initialization_done = 1;
b80864fb
DJ
472}
473
474/* Resume all artificially suspended threads if we are continuing
475 execution. */
2bee2b6c
SM
476static void
477continue_one_thread (thread_info *thread, int thread_id)
b80864fb 478{
e56f8ccb 479 windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
b80864fb 480
a2abc7de 481 if (thread_id == -1 || thread_id == th->tid)
b80864fb 482 {
a2abc7de 483 win32_prepare_to_resume (th);
34b34921 484
a2abc7de 485 if (th->suspended)
c436e841 486 {
7d186bc0
HD
487 DWORD *context_flags;
488#ifdef __x86_64__
489 if (wow64_process)
490 context_flags = &th->wow64_context.ContextFlags;
491 else
492#endif
493 context_flags = &th->context.ContextFlags;
494 if (*context_flags)
a2abc7de
PA
495 {
496 win32_set_thread_context (th);
7d186bc0 497 *context_flags = 0;
a2abc7de
PA
498 }
499
98a03287 500 th->resume ();
c436e841 501 }
b80864fb 502 }
b80864fb
DJ
503}
504
505static BOOL
506child_continue (DWORD continue_status, int thread_id)
507{
360ad8b3
TT
508 desired_stop_thread_id = thread_id;
509 if (matching_pending_stop (debug_threads))
510 return TRUE;
511
4d5d1aaa
PA
512 /* The inferior will only continue after the ContinueDebugEvent
513 call. */
2bee2b6c
SM
514 for_each_thread ([&] (thread_info *thread)
515 {
516 continue_one_thread (thread, thread_id);
517 });
4d5d1aaa 518 faked_breakpoint = 0;
b80864fb 519
e758e19c 520 return continue_last_debug_event (continue_status, debug_threads);
b80864fb
DJ
521}
522
b80864fb
DJ
523/* Fetch register(s) from the current thread context. */
524static void
442ea881 525child_fetch_inferior_registers (struct regcache *regcache, int r)
b80864fb
DJ
526{
527 int regno;
28688adf
TT
528 windows_thread_info *th = thread_rec (current_thread_ptid (),
529 INVALIDATE_CONTEXT);
4463ce24 530 if (r == -1 || r > NUM_REGS)
442ea881 531 child_fetch_inferior_registers (regcache, NUM_REGS);
b80864fb
DJ
532 else
533 for (regno = 0; regno < r; regno++)
442ea881 534 (*the_low_target.fetch_inferior_register) (regcache, th, regno);
b80864fb
DJ
535}
536
537/* Store a new register value into the current thread context. We don't
538 change the program's context until later, when we resume it. */
539static void
442ea881 540child_store_inferior_registers (struct regcache *regcache, int r)
b80864fb
DJ
541{
542 int regno;
28688adf
TT
543 windows_thread_info *th = thread_rec (current_thread_ptid (),
544 INVALIDATE_CONTEXT);
b80864fb 545 if (r == -1 || r == 0 || r > NUM_REGS)
442ea881 546 child_store_inferior_registers (regcache, NUM_REGS);
b80864fb
DJ
547 else
548 for (regno = 0; regno < r; regno++)
442ea881 549 (*the_low_target.store_inferior_register) (regcache, th, regno);
b80864fb
DJ
550}
551
ed50f18f
PA
552/* Map the Windows error number in ERROR to a locale-dependent error
553 message string and return a pointer to it. Typically, the values
554 for ERROR come from GetLastError.
555
556 The string pointed to shall not be modified by the application,
557 but may be overwritten by a subsequent call to strwinerror
558
559 The strwinerror function does not change the current setting
560 of GetLastError. */
561
562char *
563strwinerror (DWORD error)
564{
565 static char buf[1024];
566 TCHAR *msgbuf;
567 DWORD lasterr = GetLastError ();
568 DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
569 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
570 NULL,
571 error,
572 0, /* Default language */
c3de4d92 573 (LPTSTR) &msgbuf,
ed50f18f
PA
574 0,
575 NULL);
576 if (chars != 0)
577 {
578 /* If there is an \r\n appended, zap it. */
579 if (chars >= 2
580 && msgbuf[chars - 2] == '\r'
581 && msgbuf[chars - 1] == '\n')
582 {
583 chars -= 2;
584 msgbuf[chars] = 0;
585 }
586
587 if (chars > ((COUNTOF (buf)) - 1))
588 {
589 chars = COUNTOF (buf) - 1;
590 msgbuf [chars] = 0;
591 }
592
593#ifdef UNICODE
594 wcstombs (buf, msgbuf, chars + 1);
595#else
596 strncpy (buf, msgbuf, chars + 1);
597#endif
598 LocalFree (msgbuf);
599 }
600 else
dfe07582 601 sprintf (buf, "unknown win32 error (%u)", (unsigned) error);
ed50f18f
PA
602
603 SetLastError (lasterr);
604 return buf;
605}
606
aec18585
PA
607static BOOL
608create_process (const char *program, char *args,
609 DWORD flags, PROCESS_INFORMATION *pi)
610{
bc3b087d 611 const char *inferior_cwd = get_inferior_cwd ();
aec18585 612 BOOL ret;
a9b34532
EZ
613 size_t argslen, proglen;
614
615 proglen = strlen (program) + 1;
616 argslen = strlen (args) + proglen;
aec18585
PA
617
618#ifdef _WIN32_WCE
bc3b087d 619 wchar_t *p, *wprogram, *wargs, *wcwd = NULL;
aec18585 620
a9b34532
EZ
621 wprogram = (wchar_t *) alloca (proglen * sizeof (wchar_t));
622 mbstowcs (wprogram, program, proglen);
aec18585
PA
623
624 for (p = wprogram; *p; ++p)
625 if (L'/' == *p)
626 *p = L'\\';
627
aec18585 628 wargs = alloca ((argslen + 1) * sizeof (wchar_t));
a9b34532
EZ
629 wcscpy (wargs, wprogram);
630 wcscat (wargs, L" ");
631 mbstowcs (wargs + proglen, args, argslen + 1 - proglen);
aec18585 632
bc3b087d
SDJ
633 if (inferior_cwd != NULL)
634 {
906994d9 635 std::string expanded_infcwd = gdb_tilde_expand (inferior_cwd);
bc3b087d
SDJ
636 std::replace (expanded_infcwd.begin (), expanded_infcwd.end (),
637 '/', '\\');
638 wcwd = alloca ((expanded_infcwd.size () + 1) * sizeof (wchar_t));
639 if (mbstowcs (wcwd, expanded_infcwd.c_str (),
640 expanded_infcwd.size () + 1) == NULL)
641 {
642 error (_("\
643Could not convert the expanded inferior cwd to wide-char."));
644 }
645 }
646
aec18585 647 ret = CreateProcessW (wprogram, /* image name */
1b3f6016
PA
648 wargs, /* command line */
649 NULL, /* security, not supported */
650 NULL, /* thread, not supported */
651 FALSE, /* inherit handles, not supported */
652 flags, /* start flags */
653 NULL, /* environment, not supported */
bc3b087d 654 wcwd, /* current directory */
1b3f6016
PA
655 NULL, /* start info, not supported */
656 pi); /* proc info */
aec18585
PA
657#else
658 STARTUPINFOA si = { sizeof (STARTUPINFOA) };
a9b34532
EZ
659 char *program_and_args = (char *) alloca (argslen + 1);
660
661 strcpy (program_and_args, program);
662 strcat (program_and_args, " ");
663 strcat (program_and_args, args);
664 ret = CreateProcessA (program, /* image name */
665 program_and_args, /* command line */
666 NULL, /* security */
667 NULL, /* thread */
668 TRUE, /* inherit handles */
669 flags, /* start flags */
670 NULL, /* environment */
906994d9
JB
671 /* current directory */
672 (inferior_cwd == NULL
673 ? NULL
674 : gdb_tilde_expand (inferior_cwd).c_str()),
a9b34532
EZ
675 &si, /* start info */
676 pi); /* proc info */
aec18585
PA
677#endif
678
679 return ret;
680}
681
b80864fb 682/* Start a new process.
2090129c
SDJ
683 PROGRAM is the program name.
684 PROGRAM_ARGS is the vector containing the inferior's args.
b80864fb
DJ
685 Returns the new PID on success, -1 on failure. Registers the new
686 process with the process list. */
15295543
TBA
687int
688win32_process_target::create_inferior (const char *program,
689 const std::vector<char *> &program_args)
b80864fb 690{
6341380d 691 client_state &cs = get_client_state ();
b80864fb 692#ifndef USE_WIN32API
d8d2a3ee 693 char real_path[PATH_MAX];
b80864fb
DJ
694 char *orig_path, *new_path, *path_ptr;
695#endif
b80864fb
DJ
696 BOOL ret;
697 DWORD flags;
ed50f18f 698 PROCESS_INFORMATION pi;
aec18585 699 DWORD err;
bea571eb 700 std::string str_program_args = construct_inferior_arguments (program_args);
2090129c 701 char *args = (char *) str_program_args.c_str ();
b80864fb 702
d97903b2
PA
703 /* win32_wait needs to know we're not attaching. */
704 attaching = 0;
705
b80864fb
DJ
706 if (!program)
707 error ("No executable specified, specify executable to debug.\n");
708
b80864fb
DJ
709 flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
710
711#ifndef USE_WIN32API
712 orig_path = NULL;
713 path_ptr = getenv ("PATH");
714 if (path_ptr)
715 {
81239425 716 int size = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, NULL, 0);
0ae534d2
JT
717 orig_path = (char *) alloca (strlen (path_ptr) + 1);
718 new_path = (char *) alloca (size);
b80864fb 719 strcpy (orig_path, path_ptr);
81239425 720 cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, new_path, size);
b80864fb 721 setenv ("PATH", new_path, 1);
81239425 722 }
d8d2a3ee 723 cygwin_conv_path (CCP_POSIX_TO_WIN_A, program, real_path, PATH_MAX);
b80864fb
DJ
724 program = real_path;
725#endif
726
a9b34532 727 OUTMSG2 (("Command line is \"%s %s\"\n", program, args));
b80864fb 728
ed50f18f 729#ifdef CREATE_NEW_PROCESS_GROUP
b80864fb 730 flags |= CREATE_NEW_PROCESS_GROUP;
ed50f18f 731#endif
b80864fb 732
aec18585
PA
733 ret = create_process (program, args, flags, &pi);
734 err = GetLastError ();
735 if (!ret && err == ERROR_FILE_NOT_FOUND)
736 {
c3de4d92 737 char *exename = (char *) alloca (strlen (program) + 5);
aec18585
PA
738 strcat (strcpy (exename, program), ".exe");
739 ret = create_process (exename, args, flags, &pi);
740 err = GetLastError ();
741 }
b80864fb
DJ
742
743#ifndef USE_WIN32API
744 if (orig_path)
745 setenv ("PATH", orig_path, 1);
746#endif
747
748 if (!ret)
749 {
a9b34532 750 error ("Error creating process \"%s %s\", (error %d): %s\n",
ed50f18f 751 program, args, (int) err, strwinerror (err));
b80864fb
DJ
752 }
753 else
754 {
a9b34532 755 OUTMSG2 (("Process created: %s %s\n", program, (char *) args));
b80864fb
DJ
756 }
757
ed50f18f
PA
758#ifndef _WIN32_WCE
759 /* On Windows CE this handle can't be closed. The OS reuses
760 it in the debug events, while the 9x/NT versions of Windows
761 probably use a DuplicateHandle'd one. */
b80864fb 762 CloseHandle (pi.hThread);
ed50f18f 763#endif
b80864fb 764
95954743 765 do_initial_child_stuff (pi.hProcess, pi.dwProcessId, 0);
b80864fb 766
7dbac825
JB
767 /* Wait till we are at 1st instruction in program, return new pid
768 (assuming success). */
6532e7e3 769 cs.last_ptid = wait (ptid_t (current_process_id), &cs.last_status, 0);
7dbac825 770
052793ad
HD
771 /* Necessary for handle_v_kill. */
772 signal_pid = current_process_id;
773
b80864fb
DJ
774 return current_process_id;
775}
776
777/* Attach to a running process.
778 PID is the process ID to attach to, specified by the user
779 or a higher layer. */
ef03dad8
TBA
780int
781win32_process_target::attach (unsigned long pid)
b80864fb 782{
5ca906e6 783 HANDLE h;
bf914831 784 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
5ca906e6 785 DWORD err;
ed50f18f
PA
786#ifdef _WIN32_WCE
787 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
788#else
789 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
790#endif
bf914831 791 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
b80864fb 792
5ca906e6
PA
793 h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
794 if (h != NULL)
1d5315fe 795 {
5ca906e6
PA
796 if (DebugActiveProcess (pid))
797 {
798 if (DebugSetProcessKillOnExit != NULL)
799 DebugSetProcessKillOnExit (FALSE);
800
d97903b2 801 /* win32_wait needs to know we're attaching. */
1b3f6016 802 attaching = 1;
95954743 803 do_initial_child_stuff (h, pid, 1);
5ca906e6
PA
804 return 0;
805 }
806
807 CloseHandle (h);
b80864fb
DJ
808 }
809
5ca906e6
PA
810 err = GetLastError ();
811 error ("Attach to process failed (error %d): %s\n",
812 (int) err, strwinerror (err));
b80864fb
DJ
813}
814
d41b524f
TT
815/* See nat/windows-nat.h. */
816
817int
818windows_nat::handle_output_debug_string (struct target_waitstatus *ourstatus)
bce7165d
PA
819{
820#define READ_BUFFER_LEN 1024
821 CORE_ADDR addr;
822 char s[READ_BUFFER_LEN + 1] = { 0 };
823 DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
824
825 if (nbytes == 0)
d41b524f 826 return 0;
bce7165d
PA
827
828 if (nbytes > READ_BUFFER_LEN)
829 nbytes = READ_BUFFER_LEN;
830
831 addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
832
833 if (current_event.u.DebugString.fUnicode)
834 {
835 /* The event tells us how many bytes, not chars, even
1b3f6016 836 in Unicode. */
bce7165d
PA
837 WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
838 if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
d41b524f 839 return 0;
bce7165d
PA
840 wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
841 }
842 else
843 {
844 if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
d41b524f 845 return 0;
bce7165d
PA
846 }
847
61012eef 848 if (!startswith (s, "cYg"))
45e2715e
PA
849 {
850 if (!server_waiting)
851 {
852 OUTMSG2(("%s", s));
d41b524f 853 return 0;
45e2715e
PA
854 }
855
856 monitor_output (s);
857 }
bce7165d 858#undef READ_BUFFER_LEN
d41b524f
TT
859
860 return 0;
bce7165d
PA
861}
862
5ac588cf
PA
863static void
864win32_clear_inferiors (void)
865{
6479bf85
HD
866 if (open_process_used)
867 {
868 CloseHandle (current_process_handle);
869 open_process_used = false;
870 }
5ac588cf 871
f0045347 872 for_each_thread (delete_thread_info);
7928d571 873 siginfo_er.ExceptionCode = 0;
5ac588cf
PA
874 clear_inferiors ();
875}
876
a780ef4f
PA
877/* Implementation of target_ops::kill. */
878
c6885a57
TBA
879int
880win32_process_target::kill (process_info *process)
b80864fb
DJ
881{
882 TerminateProcess (current_process_handle, 0);
883 for (;;)
884 {
885 if (!child_continue (DBG_CONTINUE, -1))
886 break;
2c1d95e8 887 if (!wait_for_debug_event (&current_event, INFINITE))
b80864fb
DJ
888 break;
889 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
890 break;
bce7165d 891 else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
d41b524f 892 handle_output_debug_string (nullptr);
b80864fb 893 }
ed50f18f 894
5ac588cf 895 win32_clear_inferiors ();
95954743 896
95954743
PA
897 remove_process (process);
898 return 0;
b80864fb
DJ
899}
900
ef2ddb33
PA
901/* Implementation of target_ops::detach. */
902
9061c9cf
TBA
903int
904win32_process_target::detach (process_info *process)
b80864fb 905{
bf914831
PA
906 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
907 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
ed50f18f
PA
908#ifdef _WIN32_WCE
909 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
910#else
911 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
912#endif
bf914831
PA
913 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
914 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
b80864fb 915
444d6139
PA
916 if (DebugSetProcessKillOnExit == NULL
917 || DebugActiveProcessStop == NULL)
918 return -1;
b80864fb 919
444d6139
PA
920 {
921 struct thread_resume resume;
95954743 922 resume.thread = minus_one_ptid;
bd99dc85 923 resume.kind = resume_continue;
444d6139 924 resume.sig = 0;
0e4d7e35 925 this->resume (&resume, 1);
444d6139
PA
926 }
927
928 if (!DebugActiveProcessStop (current_process_id))
5ac588cf
PA
929 return -1;
930
444d6139 931 DebugSetProcessKillOnExit (FALSE);
95954743 932 remove_process (process);
444d6139 933
5ac588cf 934 win32_clear_inferiors ();
444d6139
PA
935 return 0;
936}
937
8adb37b9
TBA
938void
939win32_process_target::mourn (struct process_info *process)
505106cd
PA
940{
941 remove_process (process);
942}
943
ef2ddb33
PA
944/* Implementation of target_ops::join. */
945
95a49a39
TBA
946void
947win32_process_target::join (int pid)
444d6139 948{
d105de22 949 HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
5ac588cf
PA
950 if (h != NULL)
951 {
952 WaitForSingleObject (h, INFINITE);
953 CloseHandle (h);
954 }
b80864fb
DJ
955}
956
13d3d99b
TBA
957/* Return true iff the thread with thread ID TID is alive. */
958bool
959win32_process_target::thread_alive (ptid_t ptid)
b80864fb 960{
b80864fb
DJ
961 /* Our thread list is reliable; don't bother to poll target
962 threads. */
8dc7b443 963 return find_thread_ptid (ptid) != NULL;
b80864fb
DJ
964}
965
966/* Resume the inferior process. RESUME_INFO describes how we want
967 to resume. */
0e4d7e35
TBA
968void
969win32_process_target::resume (thread_resume *resume_info, size_t n)
b80864fb
DJ
970{
971 DWORD tid;
2ea28649 972 enum gdb_signal sig;
b80864fb 973 int step;
e56f8ccb 974 windows_thread_info *th;
b80864fb 975 DWORD continue_status = DBG_CONTINUE;
95954743 976 ptid_t ptid;
b80864fb
DJ
977
978 /* This handles the very limited set of resume packets that GDB can
979 currently produce. */
980
d7e15655 981 if (n == 1 && resume_info[0].thread == minus_one_ptid)
b80864fb 982 tid = -1;
2bd7c093 983 else if (n > 1)
b80864fb
DJ
984 tid = -1;
985 else
986 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
987 the Windows resume code do the right thing for thread switching. */
988 tid = current_event.dwThreadId;
989
d7e15655 990 if (resume_info[0].thread != minus_one_ptid)
b80864fb 991 {
ce7715e2 992 sig = gdb_signal_from_host (resume_info[0].sig);
bd99dc85 993 step = resume_info[0].kind == resume_step;
b80864fb
DJ
994 }
995 else
996 {
ce7715e2 997 sig = GDB_SIGNAL_0;
b80864fb
DJ
998 step = 0;
999 }
1000
a493e3e2 1001 if (sig != GDB_SIGNAL_0)
b80864fb
DJ
1002 {
1003 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1004 {
ce7715e2
PA
1005 OUTMSG (("Cannot continue with signal %s here.\n",
1006 gdb_signal_to_string (sig)));
b80864fb
DJ
1007 }
1008 else if (sig == last_sig)
1009 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1010 else
ce7715e2
PA
1011 OUTMSG (("Can only continue with received signal %s.\n",
1012 gdb_signal_to_string (last_sig)));
b80864fb
DJ
1013 }
1014
a493e3e2 1015 last_sig = GDB_SIGNAL_0;
b80864fb
DJ
1016
1017 /* Get context for the currently selected thread. */
95954743 1018 ptid = debug_event_ptid (&current_event);
28688adf 1019 th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
b80864fb
DJ
1020 if (th)
1021 {
a2abc7de
PA
1022 win32_prepare_to_resume (th);
1023
7d186bc0
HD
1024 DWORD *context_flags;
1025#ifdef __x86_64__
1026 if (wow64_process)
1027 context_flags = &th->wow64_context.ContextFlags;
1028 else
1029#endif
1030 context_flags = &th->context.ContextFlags;
1031 if (*context_flags)
b80864fb 1032 {
b80864fb
DJ
1033 /* Move register values from the inferior into the thread
1034 context structure. */
1035 regcache_invalidate ();
1036
1037 if (step)
ed50f18f
PA
1038 {
1039 if (the_low_target.single_step != NULL)
1040 (*the_low_target.single_step) (th);
1041 else
1042 error ("Single stepping is not supported "
1043 "in this configuration.\n");
1044 }
34b34921 1045
9c6c8194 1046 win32_set_thread_context (th);
7d186bc0 1047 *context_flags = 0;
b80864fb
DJ
1048 }
1049 }
1050
1051 /* Allow continuing with the same signal that interrupted us.
1052 Otherwise complain. */
1053
1054 child_continue (continue_status, tid);
1055}
1056
255e7678
DJ
1057static void
1058win32_add_one_solib (const char *name, CORE_ADDR load_addr)
1059{
1060 char buf[MAX_PATH + 1];
1061 char buf2[MAX_PATH + 1];
1062
1063#ifdef _WIN32_WCE
1064 WIN32_FIND_DATA w32_fd;
1065 WCHAR wname[MAX_PATH + 1];
1066 mbstowcs (wname, name, MAX_PATH);
1067 HANDLE h = FindFirstFile (wname, &w32_fd);
1068#else
1069 WIN32_FIND_DATAA w32_fd;
1070 HANDLE h = FindFirstFileA (name, &w32_fd);
1071#endif
1072
850a0f76
JB
1073 /* The symbols in a dll are offset by 0x1000, which is the
1074 offset from 0 of the first byte in an image - because
1075 of the file header and the section alignment. */
1076 load_addr += 0x1000;
1077
255e7678
DJ
1078 if (h == INVALID_HANDLE_VALUE)
1079 strcpy (buf, name);
1080 else
1081 {
1082 FindClose (h);
1083 strcpy (buf, name);
1084#ifndef _WIN32_WCE
1085 {
1086 char cwd[MAX_PATH + 1];
1087 char *p;
1088 if (GetCurrentDirectoryA (MAX_PATH + 1, cwd))
1089 {
1090 p = strrchr (buf, '\\');
1091 if (p)
1092 p[1] = '\0';
1093 SetCurrentDirectoryA (buf);
1094 GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p);
1095 SetCurrentDirectoryA (cwd);
1096 }
1097 }
1098#endif
1099 }
1100
cf6e3471
PA
1101#ifndef _WIN32_WCE
1102 if (strcasecmp (buf, "ntdll.dll") == 0)
1103 {
1104 GetSystemDirectoryA (buf, sizeof (buf));
1105 strcat (buf, "\\ntdll.dll");
1106 }
1107#endif
1108
255e7678 1109#ifdef __CYGWIN__
81239425 1110 cygwin_conv_path (CCP_WIN_A_TO_POSIX, buf, buf2, sizeof (buf2));
255e7678
DJ
1111#else
1112 strcpy (buf2, buf);
1113#endif
1114
1115 loaded_dll (buf2, load_addr);
1116}
1117
255e7678
DJ
1118typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *,
1119 DWORD, LPDWORD);
7d186bc0
HD
1120#ifdef __x86_64__
1121typedef BOOL (WINAPI *winapi_EnumProcessModulesEx) (HANDLE, HMODULE *, DWORD,
1122 LPDWORD, DWORD);
1123#endif
255e7678
DJ
1124typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE,
1125 LPMODULEINFO, DWORD);
1126typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE,
1127 LPSTR, DWORD);
1128
1129static winapi_EnumProcessModules win32_EnumProcessModules;
7d186bc0
HD
1130#ifdef __x86_64__
1131static winapi_EnumProcessModulesEx win32_EnumProcessModulesEx;
1132#endif
255e7678
DJ
1133static winapi_GetModuleInformation win32_GetModuleInformation;
1134static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA;
1135
1136static BOOL
1137load_psapi (void)
1138{
1139 static int psapi_loaded = 0;
1140 static HMODULE dll = NULL;
1141
1142 if (!psapi_loaded)
1143 {
1144 psapi_loaded = 1;
1145 dll = LoadLibrary (TEXT("psapi.dll"));
1146 if (!dll)
1147 return FALSE;
1148 win32_EnumProcessModules =
1149 GETPROCADDRESS (dll, EnumProcessModules);
7d186bc0
HD
1150#ifdef __x86_64__
1151 win32_EnumProcessModulesEx =
1152 GETPROCADDRESS (dll, EnumProcessModulesEx);
1153#endif
255e7678
DJ
1154 win32_GetModuleInformation =
1155 GETPROCADDRESS (dll, GetModuleInformation);
1156 win32_GetModuleFileNameExA =
1157 GETPROCADDRESS (dll, GetModuleFileNameExA);
1158 }
1159
7d186bc0
HD
1160#ifdef __x86_64__
1161 if (wow64_process && win32_EnumProcessModulesEx == nullptr)
1162 return FALSE;
1163#endif
1164
255e7678
DJ
1165 return (win32_EnumProcessModules != NULL
1166 && win32_GetModuleInformation != NULL
1167 && win32_GetModuleFileNameExA != NULL);
1168}
1169
379a5e2d 1170#ifndef _WIN32_WCE
649ebbca 1171
f25b3fc3
JB
1172/* Iterate over all DLLs currently mapped by our inferior, and
1173 add them to our list of solibs. */
379a5e2d
JB
1174
1175static void
f25b3fc3 1176win32_add_all_dlls (void)
379a5e2d 1177{
379a5e2d
JB
1178 size_t i;
1179 HMODULE dh_buf[1];
1180 HMODULE *DllHandle = dh_buf;
1181 DWORD cbNeeded;
1182 BOOL ok;
1183
379a5e2d
JB
1184 if (!load_psapi ())
1185 return;
1186
1187 cbNeeded = 0;
7d186bc0
HD
1188#ifdef __x86_64__
1189 if (wow64_process)
1190 ok = (*win32_EnumProcessModulesEx) (current_process_handle,
1191 DllHandle,
1192 sizeof (HMODULE),
1193 &cbNeeded,
1194 LIST_MODULES_32BIT);
1195 else
1196#endif
1197 ok = (*win32_EnumProcessModules) (current_process_handle,
1198 DllHandle,
1199 sizeof (HMODULE),
1200 &cbNeeded);
379a5e2d
JB
1201
1202 if (!ok || !cbNeeded)
1203 return;
1204
1205 DllHandle = (HMODULE *) alloca (cbNeeded);
1206 if (!DllHandle)
1207 return;
1208
7d186bc0
HD
1209#ifdef __x86_64__
1210 if (wow64_process)
1211 ok = (*win32_EnumProcessModulesEx) (current_process_handle,
1212 DllHandle,
1213 cbNeeded,
1214 &cbNeeded,
1215 LIST_MODULES_32BIT);
1216 else
1217#endif
1218 ok = (*win32_EnumProcessModules) (current_process_handle,
1219 DllHandle,
1220 cbNeeded,
1221 &cbNeeded);
379a5e2d
JB
1222 if (!ok)
1223 return;
1224
7d186bc0
HD
1225 char system_dir[MAX_PATH];
1226 char syswow_dir[MAX_PATH];
1227 size_t system_dir_len = 0;
1228 bool convert_syswow_dir = false;
1229#ifdef __x86_64__
1230 if (wow64_process)
1231#endif
1232 {
1233 /* This fails on 32bit Windows because it has no SysWOW64 directory,
1234 and in this case a path conversion isn't necessary. */
1235 UINT len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
1236 if (len > 0)
1237 {
1238 /* Check that we have passed a large enough buffer. */
1239 gdb_assert (len < sizeof (syswow_dir));
1240
1241 len = GetSystemDirectoryA (system_dir, sizeof (system_dir));
1242 /* Error check. */
1243 gdb_assert (len != 0);
1244 /* Check that we have passed a large enough buffer. */
1245 gdb_assert (len < sizeof (system_dir));
1246
1247 strcat (system_dir, "\\");
1248 strcat (syswow_dir, "\\");
1249 system_dir_len = strlen (system_dir);
1250
1251 convert_syswow_dir = true;
1252 }
1253
1254 }
1255
f25b3fc3 1256 for (i = 1; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++)
379a5e2d
JB
1257 {
1258 MODULEINFO mi;
1259 char dll_name[MAX_PATH];
1260
1261 if (!(*win32_GetModuleInformation) (current_process_handle,
1262 DllHandle[i],
1263 &mi,
1264 sizeof (mi)))
1265 continue;
1266 if ((*win32_GetModuleFileNameExA) (current_process_handle,
1267 DllHandle[i],
1268 dll_name,
1269 MAX_PATH) == 0)
1270 continue;
7d186bc0
HD
1271
1272 const char *name = dll_name;
1273 /* Convert the DLL path of 32bit processes returned by
1274 GetModuleFileNameEx from the 64bit system directory to the
1275 32bit syswow64 directory if necessary. */
1276 std::string syswow_dll_path;
1277 if (convert_syswow_dir
1278 && strncasecmp (dll_name, system_dir, system_dir_len) == 0
1279 && strchr (dll_name + system_dir_len, '\\') == nullptr)
1280 {
1281 syswow_dll_path = syswow_dir;
1282 syswow_dll_path += dll_name + system_dir_len;
1283 name = syswow_dll_path.c_str();
1284 }
1285
1286 win32_add_one_solib (name, (CORE_ADDR) (uintptr_t) mi.lpBaseOfDll);
379a5e2d
JB
1287 }
1288}
1289#endif
1290
255e7678
DJ
1291typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD);
1292typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32);
1293typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32);
1294
a816ba18 1295/* See nat/windows-nat.h. */
255e7678 1296
a816ba18
TT
1297void
1298windows_nat::handle_load_dll ()
255e7678
DJ
1299{
1300 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
9d8679cc 1301 const char *dll_name;
255e7678 1302
d763de10
JB
1303 dll_name = get_image_name (current_process_handle,
1304 event->lpImageName, event->fUnicode);
255e7678
DJ
1305 if (!dll_name)
1306 return;
1307
850a0f76 1308 win32_add_one_solib (dll_name, (CORE_ADDR) (uintptr_t) event->lpBaseOfDll);
255e7678
DJ
1309}
1310
a816ba18 1311/* See nat/windows-nat.h. */
f25b3fc3 1312
a816ba18
TT
1313void
1314windows_nat::handle_unload_dll ()
255e7678
DJ
1315{
1316 CORE_ADDR load_addr =
e8f0053d 1317 (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll;
850a0f76
JB
1318
1319 /* The symbols in a dll are offset by 0x1000, which is the
1320 offset from 0 of the first byte in an image - because
1321 of the file header and the section alignment. */
255e7678
DJ
1322 load_addr += 0x1000;
1323 unloaded_dll (NULL, load_addr);
1324}
1325
34b34921 1326static void
9c80ecd6 1327suspend_one_thread (thread_info *thread)
4d5d1aaa 1328{
e56f8ccb 1329 windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
4d5d1aaa 1330
98a03287 1331 th->suspend ();
4d5d1aaa
PA
1332}
1333
1334static void
1335fake_breakpoint_event (void)
b80864fb 1336{
4d5d1aaa 1337 OUTMSG2(("fake_breakpoint_event\n"));
b80864fb 1338
4d5d1aaa
PA
1339 faked_breakpoint = 1;
1340
1341 memset (&current_event, 0, sizeof (current_event));
1342 current_event.dwThreadId = main_thread_id;
1343 current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
1344 current_event.u.Exception.ExceptionRecord.ExceptionCode
1345 = EXCEPTION_BREAKPOINT;
1346
f0045347 1347 for_each_thread (suspend_one_thread);
4d5d1aaa
PA
1348}
1349
b65d95c5
DJ
1350#ifdef _WIN32_WCE
1351static int
1352auto_delete_breakpoint (CORE_ADDR stop_pc)
1353{
1354 return 1;
1355}
1356#endif
1357
8d30e395
TT
1358/* See nat/windows-nat.h. */
1359
1360bool
1361windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
1362{
1363 return false;
1364}
1365
a010605f
TT
1366/* See nat/windows-nat.h. */
1367
1368bool
1369windows_nat::handle_access_violation (const EXCEPTION_RECORD *rec)
1370{
1371 return false;
1372}
1373
523d4f80
TT
1374/* A helper function that will, if needed, set
1375 'stopped_at_software_breakpoint' on the thread and adjust the
1376 PC. */
1377
1378static void
1379maybe_adjust_pc ()
1380{
1381 struct regcache *regcache = get_thread_regcache (current_thread, 1);
1382 child_fetch_inferior_registers (regcache, -1);
1383
1384 windows_thread_info *th = thread_rec (current_thread_ptid (),
1385 DONT_INVALIDATE_CONTEXT);
1386 th->stopped_at_software_breakpoint = false;
1387
1388 if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
7d186bc0
HD
1389 && ((current_event.u.Exception.ExceptionRecord.ExceptionCode
1390 == EXCEPTION_BREAKPOINT)
1391 || (current_event.u.Exception.ExceptionRecord.ExceptionCode
1392 == STATUS_WX86_BREAKPOINT))
523d4f80
TT
1393 && child_initialization_done)
1394 {
1395 th->stopped_at_software_breakpoint = true;
1396 CORE_ADDR pc = regcache_read_pc (regcache);
1397 CORE_ADDR sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break;
1398 regcache_write_pc (regcache, sw_breakpoint_pc);
1399 }
1400}
1401
4d5d1aaa
PA
1402/* Get the next event from the child. */
1403
1404static int
8d30e395
TT
1405get_child_debug_event (DWORD *continue_status,
1406 struct target_waitstatus *ourstatus)
4d5d1aaa 1407{
95954743
PA
1408 ptid_t ptid;
1409
a493e3e2 1410 last_sig = GDB_SIGNAL_0;
b80864fb 1411 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
8d30e395 1412 *continue_status = DBG_CONTINUE;
b80864fb 1413
4d5d1aaa
PA
1414 /* Check if GDB sent us an interrupt request. */
1415 check_remote_input_interrupt_request ();
1416
1417 if (soft_interrupt_requested)
1418 {
1419 soft_interrupt_requested = 0;
1420 fake_breakpoint_event ();
1421 goto gotevent;
1422 }
1423
d97903b2 1424 attaching = 0;
84b300de
SM
1425 {
1426 gdb::optional<pending_stop> stop = fetch_pending_stop (debug_threads);
1427 if (stop.has_value ())
1428 {
1429 *ourstatus = stop->status;
1430 current_event = stop->event;
1431 ptid = debug_event_ptid (&current_event);
1432 current_thread = find_thread_ptid (ptid);
1433 return 1;
1434 }
360ad8b3 1435
84b300de
SM
1436 /* Keep the wait time low enough for comfortable remote
1437 interruption, but high enough so gdbserver doesn't become a
1438 bottleneck. */
1439 if (!wait_for_debug_event (&current_event, 250))
1440 {
1441 DWORD e = GetLastError();
912cf4ba 1442
84b300de
SM
1443 if (e == ERROR_PIPE_NOT_CONNECTED)
1444 {
1445 /* This will happen if the loader fails to succesfully
1446 load the application, e.g., if the main executable
1447 tries to pull in a non-existing export from a
1448 DLL. */
1449 ourstatus->kind = TARGET_WAITKIND_EXITED;
1450 ourstatus->value.integer = 1;
1451 return 1;
1452 }
912cf4ba 1453
84b300de
SM
1454 return 0;
1455 }
1456 }
4d5d1aaa
PA
1457
1458 gotevent:
b80864fb 1459
34b34921 1460 switch (current_event.dwDebugEventCode)
b80864fb
DJ
1461 {
1462 case CREATE_THREAD_DEBUG_EVENT:
1463 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
dfe07582 1464 "for pid=%u tid=%x)\n",
b80864fb
DJ
1465 (unsigned) current_event.dwProcessId,
1466 (unsigned) current_event.dwThreadId));
1467
1468 /* Record the existence of this thread. */
95954743
PA
1469 child_add_thread (current_event.dwProcessId,
1470 current_event.dwThreadId,
711e434b
PM
1471 current_event.u.CreateThread.hThread,
1472 current_event.u.CreateThread.lpThreadLocalBase);
b80864fb
DJ
1473 break;
1474
1475 case EXIT_THREAD_DEBUG_EVENT:
1476 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
dfe07582 1477 "for pid=%u tid=%x\n",
b80864fb
DJ
1478 (unsigned) current_event.dwProcessId,
1479 (unsigned) current_event.dwThreadId));
95954743
PA
1480 child_delete_thread (current_event.dwProcessId,
1481 current_event.dwThreadId);
aeeb81d1 1482
9c80ecd6 1483 current_thread = get_first_thread ();
aeeb81d1 1484 return 1;
b80864fb
DJ
1485
1486 case CREATE_PROCESS_DEBUG_EVENT:
1487 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
dfe07582 1488 "for pid=%u tid=%x\n",
b80864fb
DJ
1489 (unsigned) current_event.dwProcessId,
1490 (unsigned) current_event.dwThreadId));
1491 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1492
6479bf85
HD
1493 if (open_process_used)
1494 {
1495 CloseHandle (current_process_handle);
1496 open_process_used = false;
1497 }
1498
b80864fb
DJ
1499 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1500 main_thread_id = current_event.dwThreadId;
1501
b80864fb 1502 /* Add the main thread. */
95954743
PA
1503 child_add_thread (current_event.dwProcessId,
1504 main_thread_id,
711e434b
PM
1505 current_event.u.CreateProcessInfo.hThread,
1506 current_event.u.CreateProcessInfo.lpThreadLocalBase);
b80864fb
DJ
1507 break;
1508
1509 case EXIT_PROCESS_DEBUG_EVENT:
1510 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
dfe07582 1511 "for pid=%u tid=%x\n",
b80864fb
DJ
1512 (unsigned) current_event.dwProcessId,
1513 (unsigned) current_event.dwThreadId));
559e7e50
EZ
1514 {
1515 DWORD exit_status = current_event.u.ExitProcess.dwExitCode;
1516 /* If the exit status looks like a fatal exception, but we
1517 don't recognize the exception's code, make the original
1518 exit status value available, to avoid losing information. */
1519 int exit_signal
1520 = WIFSIGNALED (exit_status) ? WTERMSIG (exit_status) : -1;
1521 if (exit_signal == -1)
1522 {
1523 ourstatus->kind = TARGET_WAITKIND_EXITED;
1524 ourstatus->value.integer = exit_status;
1525 }
1526 else
1527 {
1528 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
1529 ourstatus->value.sig = gdb_signal_from_host (exit_signal);
1530 }
1531 }
360ad8b3 1532 child_continue (DBG_CONTINUE, desired_stop_thread_id);
b80864fb
DJ
1533 break;
1534
1535 case LOAD_DLL_DEBUG_EVENT:
1536 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
dfe07582 1537 "for pid=%u tid=%x\n",
b80864fb
DJ
1538 (unsigned) current_event.dwProcessId,
1539 (unsigned) current_event.dwThreadId));
1540 CloseHandle (current_event.u.LoadDll.hFile);
f25b3fc3
JB
1541 if (! child_initialization_done)
1542 break;
255e7678 1543 handle_load_dll ();
b80864fb
DJ
1544
1545 ourstatus->kind = TARGET_WAITKIND_LOADED;
a493e3e2 1546 ourstatus->value.sig = GDB_SIGNAL_TRAP;
b80864fb
DJ
1547 break;
1548
1549 case UNLOAD_DLL_DEBUG_EVENT:
1550 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
dfe07582 1551 "for pid=%u tid=%x\n",
b80864fb
DJ
1552 (unsigned) current_event.dwProcessId,
1553 (unsigned) current_event.dwThreadId));
f25b3fc3
JB
1554 if (! child_initialization_done)
1555 break;
255e7678
DJ
1556 handle_unload_dll ();
1557 ourstatus->kind = TARGET_WAITKIND_LOADED;
a493e3e2 1558 ourstatus->value.sig = GDB_SIGNAL_TRAP;
b80864fb
DJ
1559 break;
1560
1561 case EXCEPTION_DEBUG_EVENT:
1562 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
dfe07582 1563 "for pid=%u tid=%x\n",
b80864fb
DJ
1564 (unsigned) current_event.dwProcessId,
1565 (unsigned) current_event.dwThreadId));
8d30e395
TT
1566 if (handle_exception (ourstatus, debug_threads)
1567 == HANDLE_EXCEPTION_UNHANDLED)
1568 *continue_status = DBG_EXCEPTION_NOT_HANDLED;
b80864fb
DJ
1569 break;
1570
1571 case OUTPUT_DEBUG_STRING_EVENT:
1572 /* A message from the kernel (or Cygwin). */
1573 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
dfe07582 1574 "for pid=%u tid=%x\n",
b80864fb
DJ
1575 (unsigned) current_event.dwProcessId,
1576 (unsigned) current_event.dwThreadId));
d41b524f 1577 handle_output_debug_string (nullptr);
b80864fb
DJ
1578 break;
1579
1580 default:
1581 OUTMSG2 (("gdbserver: kernel event unknown "
dfe07582 1582 "for pid=%u tid=%x code=%x\n",
b80864fb
DJ
1583 (unsigned) current_event.dwProcessId,
1584 (unsigned) current_event.dwThreadId,
dfe07582 1585 (unsigned) current_event.dwDebugEventCode));
b80864fb
DJ
1586 break;
1587 }
1588
aeeb81d1 1589 ptid = debug_event_ptid (&current_event);
360ad8b3
TT
1590
1591 if (desired_stop_thread_id != -1 && desired_stop_thread_id != ptid.lwp ())
1592 {
1593 /* Pending stop. See the comment by the definition of
1594 "pending_stops" for details on why this is needed. */
1595 OUTMSG2 (("get_windows_debug_event - "
e2275c6e 1596 "unexpected stop in 0x%lx (expecting 0x%x)\n",
360ad8b3
TT
1597 ptid.lwp (), desired_stop_thread_id));
1598 maybe_adjust_pc ();
1599 pending_stops.push_back ({(DWORD) ptid.lwp (), *ourstatus, current_event});
1600 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1601 }
1602 else
1603 current_thread = find_thread_ptid (ptid);
1604
4d5d1aaa 1605 return 1;
b80864fb
DJ
1606}
1607
1608/* Wait for the inferior process to change state.
1609 STATUS will be filled in with a response code to send to GDB.
1610 Returns the signal which caused the process to stop. */
6532e7e3
TBA
1611ptid_t
1612win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
b60cea74 1613 target_wait_flags options)
b80864fb 1614{
4210d83e
PA
1615 if (cached_status.kind != TARGET_WAITKIND_IGNORE)
1616 {
1617 /* The core always does a wait after creating the inferior, and
1618 do_initial_child_stuff already ran the inferior to the
1619 initial breakpoint (or an exit, if creating the process
1620 fails). Report it now. */
1621 *ourstatus = cached_status;
1622 cached_status.kind = TARGET_WAITKIND_IGNORE;
1623 return debug_event_ptid (&current_event);
1624 }
1625
b80864fb
DJ
1626 while (1)
1627 {
8d30e395
TT
1628 DWORD continue_status;
1629 if (!get_child_debug_event (&continue_status, ourstatus))
4d5d1aaa 1630 continue;
b80864fb 1631
5b1c542e 1632 switch (ourstatus->kind)
b80864fb 1633 {
34b34921 1634 case TARGET_WAITKIND_EXITED:
b80864fb 1635 OUTMSG2 (("Child exited with retcode = %x\n",
5b1c542e 1636 ourstatus->value.integer));
5ac588cf 1637 win32_clear_inferiors ();
f2907e49 1638 return ptid_t (current_event.dwProcessId);
34b34921 1639 case TARGET_WAITKIND_STOPPED:
559e7e50 1640 case TARGET_WAITKIND_SIGNALLED:
1b3f6016 1641 case TARGET_WAITKIND_LOADED:
523d4f80
TT
1642 {
1643 OUTMSG2 (("Child Stopped with signal = %d \n",
1644 ourstatus->value.sig));
1645 maybe_adjust_pc ();
1646 return debug_event_ptid (&current_event);
1647 }
1b3f6016 1648 default:
5b1c542e 1649 OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind));
1b3f6016
PA
1650 /* fall-through */
1651 case TARGET_WAITKIND_SPURIOUS:
34b34921 1652 /* do nothing, just continue */
360ad8b3 1653 child_continue (continue_status, desired_stop_thread_id);
34b34921 1654 break;
b80864fb 1655 }
b80864fb
DJ
1656 }
1657}
1658
1659/* Fetch registers from the inferior process.
1660 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
a5a4d4cd
TBA
1661void
1662win32_process_target::fetch_registers (regcache *regcache, int regno)
b80864fb 1663{
442ea881 1664 child_fetch_inferior_registers (regcache, regno);
b80864fb
DJ
1665}
1666
1667/* Store registers to the inferior process.
1668 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
a5a4d4cd
TBA
1669void
1670win32_process_target::store_registers (regcache *regcache, int regno)
b80864fb 1671{
442ea881 1672 child_store_inferior_registers (regcache, regno);
b80864fb
DJ
1673}
1674
1675/* Read memory from the inferior process. This should generally be
1676 called through read_inferior_memory, which handles breakpoint shadowing.
1677 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
e2558df3
TBA
1678int
1679win32_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
1680 int len)
b80864fb 1681{
ed50f18f 1682 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
b80864fb
DJ
1683}
1684
1685/* Write memory to the inferior process. This should generally be
1686 called through write_inferior_memory, which handles breakpoint shadowing.
1687 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1688 Returns 0 on success and errno on failure. */
e2558df3
TBA
1689int
1690win32_process_target::write_memory (CORE_ADDR memaddr,
1691 const unsigned char *myaddr, int len)
b80864fb
DJ
1692{
1693 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1694}
1695
7390519e 1696/* Send an interrupt request to the inferior process. */
eb497a2a
TBA
1697void
1698win32_process_target::request_interrupt ()
7390519e
PA
1699{
1700 winapi_DebugBreakProcess DebugBreakProcess;
1701 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent;
1702
1703#ifdef _WIN32_WCE
1704 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
1705#else
1706 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1707#endif
1708
1709 GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent);
1710
1711 if (GenerateConsoleCtrlEvent != NULL
1712 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
1713 return;
1714
1715 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1716 not a process group id.
1717 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1718 breakpoint exception in the interior process. */
1719
1720 DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess);
1721
1722 if (DebugBreakProcess != NULL
1723 && DebugBreakProcess (current_process_handle))
1724 return;
1725
4d5d1aaa
PA
1726 /* Last resort, suspend all threads manually. */
1727 soft_interrupt_requested = 1;
7390519e
PA
1728}
1729
22aa6223
TBA
1730bool
1731win32_process_target::supports_hardware_single_step ()
1732{
1733 return true;
1734}
1735
59a016f0
PA
1736#ifdef _WIN32_WCE
1737int
1738win32_error_to_fileio_error (DWORD err)
1739{
1740 switch (err)
1741 {
1742 case ERROR_BAD_PATHNAME:
1743 case ERROR_FILE_NOT_FOUND:
1744 case ERROR_INVALID_NAME:
1745 case ERROR_PATH_NOT_FOUND:
1746 return FILEIO_ENOENT;
1747 case ERROR_CRC:
1748 case ERROR_IO_DEVICE:
1749 case ERROR_OPEN_FAILED:
1750 return FILEIO_EIO;
1751 case ERROR_INVALID_HANDLE:
1752 return FILEIO_EBADF;
1753 case ERROR_ACCESS_DENIED:
1754 case ERROR_SHARING_VIOLATION:
1755 return FILEIO_EACCES;
1756 case ERROR_NOACCESS:
1757 return FILEIO_EFAULT;
1758 case ERROR_BUSY:
1759 return FILEIO_EBUSY;
1760 case ERROR_ALREADY_EXISTS:
1761 case ERROR_FILE_EXISTS:
1762 return FILEIO_EEXIST;
1763 case ERROR_BAD_DEVICE:
1764 return FILEIO_ENODEV;
1765 case ERROR_DIRECTORY:
1766 return FILEIO_ENOTDIR;
1767 case ERROR_FILENAME_EXCED_RANGE:
1768 case ERROR_INVALID_DATA:
1769 case ERROR_INVALID_PARAMETER:
1770 case ERROR_NEGATIVE_SEEK:
1771 return FILEIO_EINVAL;
1772 case ERROR_TOO_MANY_OPEN_FILES:
1773 return FILEIO_EMFILE;
1774 case ERROR_HANDLE_DISK_FULL:
1775 case ERROR_DISK_FULL:
1776 return FILEIO_ENOSPC;
1777 case ERROR_WRITE_PROTECT:
1778 return FILEIO_EROFS;
1779 case ERROR_NOT_SUPPORTED:
1780 return FILEIO_ENOSYS;
1781 }
1782
1783 return FILEIO_EUNKNOWN;
1784}
1785
ea06bbaa
TBA
1786void
1787win32_process_target::hostio_last_error (char *buf)
59a016f0
PA
1788{
1789 DWORD winerr = GetLastError ();
1790 int fileio_err = win32_error_to_fileio_error (winerr);
1791 sprintf (buf, "F-1,%x", fileio_err);
1792}
1793#endif
1794
d7abedf7
TBA
1795bool
1796win32_process_target::supports_qxfer_siginfo ()
1797{
1798 return true;
1799}
1800
7928d571
HD
1801/* Write Windows signal info. */
1802
d7abedf7
TBA
1803int
1804win32_process_target::qxfer_siginfo (const char *annex,
1805 unsigned char *readbuf,
1806 unsigned const char *writebuf,
1807 CORE_ADDR offset, int len)
7928d571
HD
1808{
1809 if (siginfo_er.ExceptionCode == 0)
1810 return -1;
1811
1812 if (readbuf == nullptr)
1813 return -1;
1814
7d186bc0
HD
1815 char *buf = (char *) &siginfo_er;
1816 size_t bufsize = sizeof (siginfo_er);
1817
1818#ifdef __x86_64__
1819 EXCEPTION_RECORD32 er32;
1820 if (wow64_process)
1821 {
1822 buf = (char *) &er32;
1823 bufsize = sizeof (er32);
1824
1825 er32.ExceptionCode = siginfo_er.ExceptionCode;
1826 er32.ExceptionFlags = siginfo_er.ExceptionFlags;
1827 er32.ExceptionRecord = (uintptr_t) siginfo_er.ExceptionRecord;
1828 er32.ExceptionAddress = (uintptr_t) siginfo_er.ExceptionAddress;
1829 er32.NumberParameters = siginfo_er.NumberParameters;
1830 int i;
1831 for (i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; i++)
1832 er32.ExceptionInformation[i] = siginfo_er.ExceptionInformation[i];
1833 }
1834#endif
1835
1836 if (offset > bufsize)
7928d571
HD
1837 return -1;
1838
7d186bc0
HD
1839 if (offset + len > bufsize)
1840 len = bufsize - offset;
7928d571 1841
7d186bc0 1842 memcpy (readbuf, buf + offset, len);
7928d571
HD
1843
1844 return len;
1845}
1846
4e2e869c
TBA
1847bool
1848win32_process_target::supports_get_tib_address ()
1849{
1850 return true;
1851}
1852
711e434b
PM
1853/* Write Windows OS Thread Information Block address. */
1854
4e2e869c
TBA
1855int
1856win32_process_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
711e434b 1857{
e56f8ccb 1858 windows_thread_info *th;
28688adf 1859 th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
711e434b
PM
1860 if (th == NULL)
1861 return 0;
1862 if (addr != NULL)
1863 *addr = th->thread_local_base;
1864 return 1;
1865}
1866
fb78e89c
AT
1867/* Implementation of the target_ops method "sw_breakpoint_from_kind". */
1868
d367006f
TBA
1869const gdb_byte *
1870win32_process_target::sw_breakpoint_from_kind (int kind, int *size)
fb78e89c
AT
1871{
1872 *size = the_low_target.breakpoint_len;
1873 return the_low_target.breakpoint;
1874}
1875
523d4f80
TT
1876bool
1877win32_process_target::stopped_by_sw_breakpoint ()
1878{
1879 windows_thread_info *th = thread_rec (current_thread_ptid (),
1880 DONT_INVALIDATE_CONTEXT);
1881 return th == nullptr ? false : th->stopped_at_software_breakpoint;
1882}
1883
1884bool
1885win32_process_target::supports_stopped_by_sw_breakpoint ()
1886{
1887 return true;
1888}
1889
d6225aff
TT
1890CORE_ADDR
1891win32_process_target::read_pc (struct regcache *regcache)
1892{
1893 return (*the_low_target.get_pc) (regcache);
1894}
1895
1896void
1897win32_process_target::write_pc (struct regcache *regcache, CORE_ADDR pc)
1898{
1899 return (*the_low_target.set_pc) (regcache, pc);
1900}
1901
5ef9273d
TBA
1902/* The win32 target ops object. */
1903
1904static win32_process_target the_win32_target;
1905
b80864fb
DJ
1906/* Initialize the Win32 backend. */
1907void
1908initialize_low (void)
1909{
52405d85 1910 set_target_ops (&the_win32_target);
d05b4ac3 1911 the_low_target.arch_setup ();
7d186bc0
HD
1912
1913#ifdef __x86_64__
1914 /* These functions are loaded dynamically, because they are not available
1915 on Windows XP. */
1916 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1917 win32_Wow64GetThreadContext = GETPROCADDRESS (dll, Wow64GetThreadContext);
1918 win32_Wow64SetThreadContext = GETPROCADDRESS (dll, Wow64SetThreadContext);
1919#endif
b80864fb 1920}