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