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