]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/win32-low.c
* win32-low.c (win32_wait): Don't read from the inferior when it
[thirdparty/binutils-gdb.git] / gdb / gdbserver / win32-low.c
CommitLineData
b80864fb 1/* Low level interface to Windows debugging, for gdbserver.
6aba47ca 2 Copyright (C) 2006, 2007 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"
23#include "gdb/signals.h"
ed50f18f
PA
24#include "mem-break.h"
25#include "win32-low.h"
b80864fb
DJ
26
27#include <windows.h>
ed50f18f 28#include <winnt.h>
b80864fb 29#include <imagehlp.h>
255e7678 30#include <tlhelp32.h>
b80864fb
DJ
31#include <psapi.h>
32#include <sys/param.h>
33#include <malloc.h>
34#include <process.h>
35
36#ifndef USE_WIN32API
37#include <sys/cygwin.h>
38#endif
39
40#define LOG 0
41
42#define OUTMSG(X) do { printf X; fflush (stdout); } while (0)
43#if LOG
44#define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
45#else
ed50f18f
PA
46#define OUTMSG2(X) do ; while (0)
47#endif
48
49#ifndef _T
50#define _T(x) TEXT (x)
51#endif
52
53#ifndef COUNTOF
54#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
b80864fb
DJ
55#endif
56
bf914831
PA
57#ifdef _WIN32_WCE
58# define GETPROCADDRESS(DLL, PROC) \
59 ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC)))
60#else
61# define GETPROCADDRESS(DLL, PROC) \
62 ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
63#endif
64
b80864fb
DJ
65int using_threads = 1;
66
67/* Globals. */
68static HANDLE current_process_handle = NULL;
69static DWORD current_process_id = 0;
70static enum target_signal last_sig = TARGET_SIGNAL_0;
71
72/* The current debug event from WaitForDebugEvent. */
73static DEBUG_EVENT current_event;
74
ed50f18f 75#define NUM_REGS (the_low_target.num_regs)
b80864fb 76
bf914831
PA
77typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
78typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
7390519e
PA
79typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
80typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
b80864fb 81
b80864fb
DJ
82static DWORD main_thread_id = 0;
83
34b34921
PA
84static void win32_resume (struct thread_resume *resume_info);
85
b80864fb
DJ
86/* Get the thread ID from the current selected inferior (the current
87 thread). */
88static DWORD
89current_inferior_tid (void)
90{
41093d81 91 win32_thread_info *th = inferior_target_data (current_inferior);
b80864fb
DJ
92 return th->tid;
93}
94
95/* Find a thread record given a thread id. If GET_CONTEXT is set then
96 also retrieve the context for this thread. */
41093d81 97static win32_thread_info *
b80864fb
DJ
98thread_rec (DWORD id, int get_context)
99{
100 struct thread_info *thread;
41093d81 101 win32_thread_info *th;
b80864fb
DJ
102
103 thread = (struct thread_info *) find_inferior_id (&all_threads, id);
104 if (thread == NULL)
105 return NULL;
106
107 th = inferior_target_data (thread);
108 if (!th->suspend_count && get_context)
109 {
34b34921 110 if (id != current_event.dwThreadId)
b80864fb 111 th->suspend_count = SuspendThread (th->h) + 1;
b80864fb 112
34b34921 113 (*the_low_target.get_thread_context) (th, &current_event);
b80864fb
DJ
114 }
115
116 return th;
117}
118
119/* Add a thread to the thread list. */
41093d81 120static win32_thread_info *
b80864fb
DJ
121child_add_thread (DWORD tid, HANDLE h)
122{
41093d81 123 win32_thread_info *th;
b80864fb
DJ
124
125 if ((th = thread_rec (tid, FALSE)))
126 return th;
127
41093d81 128 th = (win32_thread_info *) malloc (sizeof (*th));
b80864fb
DJ
129 memset (th, 0, sizeof (*th));
130 th->tid = tid;
131 th->h = h;
132
133 add_thread (tid, th, (unsigned int) tid);
134 set_inferior_regcache_data ((struct thread_info *)
135 find_inferior_id (&all_threads, tid),
136 new_register_cache ());
137
34b34921
PA
138 if (the_low_target.thread_added != NULL)
139 (*the_low_target.thread_added) (th);
b80864fb
DJ
140
141 return th;
142}
143
144/* Delete a thread from the list of threads. */
145static void
146delete_thread_info (struct inferior_list_entry *thread)
147{
41093d81 148 win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
b80864fb
DJ
149
150 remove_thread ((struct thread_info *) thread);
151 CloseHandle (th->h);
152 free (th);
153}
154
155/* Delete a thread from the list of threads. */
156static void
157child_delete_thread (DWORD id)
158{
159 struct inferior_list_entry *thread;
160
161 /* If the last thread is exiting, just return. */
162 if (all_threads.head == all_threads.tail)
163 return;
164
165 thread = find_inferior_id (&all_threads, id);
166 if (thread == NULL)
167 return;
168
169 delete_thread_info (thread);
170}
171
172/* Transfer memory from/to the debugged process. */
173static int
174child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
175 int write, struct target_ops *target)
176{
177 SIZE_T done;
178 long addr = (long) memaddr;
179
180 if (write)
181 {
182 WriteProcessMemory (current_process_handle, (LPVOID) addr,
183 (LPCVOID) our, len, &done);
184 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
185 }
186 else
187 {
188 ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
189 len, &done);
190 }
191 return done;
192}
193
194/* Generally, what has the program done? */
195enum target_waitkind
196{
197 /* The program has exited. The exit status is in value.integer. */
198 TARGET_WAITKIND_EXITED,
199
200 /* The program has stopped with a signal. Which signal is in
201 value.sig. */
202 TARGET_WAITKIND_STOPPED,
203
255e7678
DJ
204 /* The program is letting us know that it dynamically loaded
205 or unloaded something. */
b80864fb
DJ
206 TARGET_WAITKIND_LOADED,
207
208 /* The program has exec'ed a new executable file. The new file's
209 pathname is pointed to by value.execd_pathname. */
b80864fb
DJ
210 TARGET_WAITKIND_EXECD,
211
7390519e
PA
212 /* Nothing interesting happened, but we stopped anyway. We take the
213 chance to check if GDB requested an interrupt. */
b80864fb
DJ
214 TARGET_WAITKIND_SPURIOUS,
215};
216
217struct target_waitstatus
218{
219 enum target_waitkind kind;
220
221 /* Forked child pid, execd pathname, exit status or signal number. */
222 union
223 {
224 int integer;
225 enum target_signal sig;
226 int related_pid;
227 char *execd_pathname;
228 int syscall_id;
229 }
230 value;
231};
232
ed50f18f 233/* Clear out any old thread list and reinitialize it to a pristine
b80864fb
DJ
234 state. */
235static void
236child_init_thread_list (void)
237{
238 for_each_inferior (&all_threads, delete_thread_info);
239}
240
241static void
242do_initial_child_stuff (DWORD pid)
243{
b80864fb
DJ
244 last_sig = TARGET_SIGNAL_0;
245
b80864fb
DJ
246 memset (&current_event, 0, sizeof (current_event));
247
248 child_init_thread_list ();
ed50f18f
PA
249
250 if (the_low_target.initial_stuff != NULL)
251 (*the_low_target.initial_stuff) ();
b80864fb
DJ
252}
253
254/* Resume all artificially suspended threads if we are continuing
255 execution. */
256static int
257continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
258{
259 struct thread_info *thread = (struct thread_info *) this_thread;
260 int thread_id = * (int *) id_ptr;
41093d81 261 win32_thread_info *th = inferior_target_data (thread);
b80864fb
DJ
262 int i;
263
264 if ((thread_id == -1 || thread_id == th->tid)
265 && th->suspend_count)
266 {
34b34921 267 if (th->context.ContextFlags)
b80864fb 268 {
34b34921 269 (*the_low_target.set_thread_context) (th, &current_event);
b80864fb
DJ
270 th->context.ContextFlags = 0;
271 }
34b34921
PA
272
273 for (i = 0; i < th->suspend_count; i++)
274 (void) ResumeThread (th->h);
275 th->suspend_count = 0;
b80864fb
DJ
276 }
277
278 return 0;
279}
280
281static BOOL
282child_continue (DWORD continue_status, int thread_id)
283{
284 BOOL res;
285
286 res = ContinueDebugEvent (current_event.dwProcessId,
287 current_event.dwThreadId, continue_status);
b80864fb
DJ
288 if (res)
289 find_inferior (&all_threads, continue_one_thread, &thread_id);
290
b80864fb
DJ
291 return res;
292}
293
b80864fb
DJ
294/* Fetch register(s) from the current thread context. */
295static void
296child_fetch_inferior_registers (int r)
297{
298 int regno;
41093d81 299 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
b80864fb
DJ
300 if (r == -1 || r == 0 || r > NUM_REGS)
301 child_fetch_inferior_registers (NUM_REGS);
302 else
303 for (regno = 0; regno < r; regno++)
34b34921 304 (*the_low_target.fetch_inferior_register) (th, regno);
b80864fb
DJ
305}
306
307/* Store a new register value into the current thread context. We don't
308 change the program's context until later, when we resume it. */
309static void
310child_store_inferior_registers (int r)
311{
312 int regno;
41093d81 313 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
b80864fb
DJ
314 if (r == -1 || r == 0 || r > NUM_REGS)
315 child_store_inferior_registers (NUM_REGS);
316 else
317 for (regno = 0; regno < r; regno++)
34b34921 318 (*the_low_target.store_inferior_register) (th, regno);
b80864fb
DJ
319}
320
ed50f18f
PA
321/* Map the Windows error number in ERROR to a locale-dependent error
322 message string and return a pointer to it. Typically, the values
323 for ERROR come from GetLastError.
324
325 The string pointed to shall not be modified by the application,
326 but may be overwritten by a subsequent call to strwinerror
327
328 The strwinerror function does not change the current setting
329 of GetLastError. */
330
331char *
332strwinerror (DWORD error)
333{
334 static char buf[1024];
335 TCHAR *msgbuf;
336 DWORD lasterr = GetLastError ();
337 DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
338 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
339 NULL,
340 error,
341 0, /* Default language */
342 (LPVOID)&msgbuf,
343 0,
344 NULL);
345 if (chars != 0)
346 {
347 /* If there is an \r\n appended, zap it. */
348 if (chars >= 2
349 && msgbuf[chars - 2] == '\r'
350 && msgbuf[chars - 1] == '\n')
351 {
352 chars -= 2;
353 msgbuf[chars] = 0;
354 }
355
356 if (chars > ((COUNTOF (buf)) - 1))
357 {
358 chars = COUNTOF (buf) - 1;
359 msgbuf [chars] = 0;
360 }
361
362#ifdef UNICODE
363 wcstombs (buf, msgbuf, chars + 1);
364#else
365 strncpy (buf, msgbuf, chars + 1);
366#endif
367 LocalFree (msgbuf);
368 }
369 else
370 sprintf (buf, "unknown win32 error (%ld)", error);
371
372 SetLastError (lasterr);
373 return buf;
374}
375
aec18585
PA
376static BOOL
377create_process (const char *program, char *args,
378 DWORD flags, PROCESS_INFORMATION *pi)
379{
380 BOOL ret;
381
382#ifdef _WIN32_WCE
383 wchar_t *p, *wprogram, *wargs;
384 size_t argslen;
385
386 wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
387 mbstowcs (wprogram, program, strlen (program) + 1);
388
389 for (p = wprogram; *p; ++p)
390 if (L'/' == *p)
391 *p = L'\\';
392
393 argslen = strlen (args);
394 wargs = alloca ((argslen + 1) * sizeof (wchar_t));
395 mbstowcs (wargs, args, argslen + 1);
396
397 ret = CreateProcessW (wprogram, /* image name */
398 wargs, /* command line */
399 NULL, /* security, not supported */
400 NULL, /* thread, not supported */
401 FALSE, /* inherit handles, not supported */
402 flags, /* start flags */
403 NULL, /* environment, not supported */
404 NULL, /* current directory, not supported */
405 NULL, /* start info, not supported */
406 pi); /* proc info */
407#else
408 STARTUPINFOA si = { sizeof (STARTUPINFOA) };
409
410 ret = CreateProcessA (program, /* image name */
411 args, /* command line */
412 NULL, /* security */
413 NULL, /* thread */
414 TRUE, /* inherit handles */
415 flags, /* start flags */
416 NULL, /* environment */
417 NULL, /* current directory */
418 &si, /* start info */
419 pi); /* proc info */
420#endif
421
422 return ret;
423}
424
b80864fb
DJ
425/* Start a new process.
426 PROGRAM is a path to the program to execute.
427 ARGS is a standard NULL-terminated array of arguments,
428 to be passed to the inferior as ``argv''.
429 Returns the new PID on success, -1 on failure. Registers the new
430 process with the process list. */
431static int
432win32_create_inferior (char *program, char **program_args)
433{
434#ifndef USE_WIN32API
435 char real_path[MAXPATHLEN];
436 char *orig_path, *new_path, *path_ptr;
437#endif
b80864fb
DJ
438 BOOL ret;
439 DWORD flags;
440 char *args;
441 int argslen;
442 int argc;
ed50f18f 443 PROCESS_INFORMATION pi;
aec18585 444 DWORD err;
b80864fb
DJ
445
446 if (!program)
447 error ("No executable specified, specify executable to debug.\n");
448
b80864fb
DJ
449 flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
450
451#ifndef USE_WIN32API
452 orig_path = NULL;
453 path_ptr = getenv ("PATH");
454 if (path_ptr)
455 {
456 orig_path = alloca (strlen (path_ptr) + 1);
457 new_path = alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr));
458 strcpy (orig_path, path_ptr);
459 cygwin_posix_to_win32_path_list (path_ptr, new_path);
460 setenv ("PATH", new_path, 1);
461 }
462 cygwin_conv_to_win32_path (program, real_path);
463 program = real_path;
464#endif
465
ed50f18f 466 argslen = 1;
b80864fb
DJ
467 for (argc = 1; program_args[argc]; argc++)
468 argslen += strlen (program_args[argc]) + 1;
469 args = alloca (argslen);
ed50f18f 470 args[0] = '\0';
b80864fb
DJ
471 for (argc = 1; program_args[argc]; argc++)
472 {
473 /* FIXME: Can we do better about quoting? How does Cygwin
474 handle this? */
475 strcat (args, " ");
476 strcat (args, program_args[argc]);
477 }
ed50f18f 478 OUTMSG2 (("Command line is \"%s\"\n", args));
b80864fb 479
ed50f18f 480#ifdef CREATE_NEW_PROCESS_GROUP
b80864fb 481 flags |= CREATE_NEW_PROCESS_GROUP;
ed50f18f 482#endif
b80864fb 483
aec18585
PA
484 ret = create_process (program, args, flags, &pi);
485 err = GetLastError ();
486 if (!ret && err == ERROR_FILE_NOT_FOUND)
487 {
488 char *exename = alloca (strlen (program) + 5);
489 strcat (strcpy (exename, program), ".exe");
490 ret = create_process (exename, args, flags, &pi);
491 err = GetLastError ();
492 }
b80864fb
DJ
493
494#ifndef USE_WIN32API
495 if (orig_path)
496 setenv ("PATH", orig_path, 1);
497#endif
498
499 if (!ret)
500 {
ed50f18f
PA
501 error ("Error creating process \"%s%s\", (error %d): %s\n",
502 program, args, (int) err, strwinerror (err));
b80864fb
DJ
503 }
504 else
505 {
506 OUTMSG2 (("Process created: %s\n", (char *) args));
507 }
508
ed50f18f
PA
509#ifndef _WIN32_WCE
510 /* On Windows CE this handle can't be closed. The OS reuses
511 it in the debug events, while the 9x/NT versions of Windows
512 probably use a DuplicateHandle'd one. */
b80864fb 513 CloseHandle (pi.hThread);
ed50f18f 514#endif
b80864fb
DJ
515
516 current_process_handle = pi.hProcess;
517 current_process_id = pi.dwProcessId;
518
519 do_initial_child_stuff (current_process_id);
520
521 return current_process_id;
522}
523
524/* Attach to a running process.
525 PID is the process ID to attach to, specified by the user
526 or a higher layer. */
527static int
528win32_attach (unsigned long pid)
529{
bf914831
PA
530 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
531 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
ed50f18f
PA
532#ifdef _WIN32_WCE
533 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
534#else
535 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
536#endif
bf914831
PA
537 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
538 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
b80864fb 539
1d5315fe
PA
540 if (DebugActiveProcess (pid))
541 {
542 if (DebugSetProcessKillOnExit != NULL)
543 DebugSetProcessKillOnExit (FALSE);
b80864fb 544
1d5315fe 545 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
b80864fb 546
1d5315fe
PA
547 if (current_process_handle != NULL)
548 {
549 current_process_id = pid;
550 do_initial_child_stuff (pid);
551 return 0;
552 }
b80864fb
DJ
553 if (DebugActiveProcessStop != NULL)
554 DebugActiveProcessStop (current_process_id);
555 }
556
1d5315fe 557 error ("Attach to process failed.");
b80864fb
DJ
558}
559
bce7165d
PA
560/* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
561static void
562handle_output_debug_string (struct target_waitstatus *ourstatus)
563{
564#define READ_BUFFER_LEN 1024
565 CORE_ADDR addr;
566 char s[READ_BUFFER_LEN + 1] = { 0 };
567 DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
568
569 if (nbytes == 0)
570 return;
571
572 if (nbytes > READ_BUFFER_LEN)
573 nbytes = READ_BUFFER_LEN;
574
575 addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
576
577 if (current_event.u.DebugString.fUnicode)
578 {
579 /* The event tells us how many bytes, not chars, even
580 in Unicode. */
581 WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
582 if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
583 return;
584 wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
585 }
586 else
587 {
588 if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
589 return;
590 }
591
592 if (strncmp (s, "cYg", 3) != 0)
45e2715e
PA
593 {
594 if (!server_waiting)
595 {
596 OUTMSG2(("%s", s));
597 return;
598 }
599
600 monitor_output (s);
601 }
bce7165d
PA
602#undef READ_BUFFER_LEN
603}
604
b80864fb
DJ
605/* Kill all inferiors. */
606static void
607win32_kill (void)
608{
ed50f18f
PA
609 win32_thread_info *current_thread;
610
9d606399
DJ
611 if (current_process_handle == NULL)
612 return;
613
b80864fb
DJ
614 TerminateProcess (current_process_handle, 0);
615 for (;;)
616 {
617 if (!child_continue (DBG_CONTINUE, -1))
618 break;
619 if (!WaitForDebugEvent (&current_event, INFINITE))
620 break;
621 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
622 break;
bce7165d
PA
623 else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
624 {
625 struct target_waitstatus our_status = { 0 };
626 handle_output_debug_string (&our_status);
627 }
b80864fb 628 }
ed50f18f
PA
629
630 CloseHandle (current_process_handle);
631
632 current_thread = inferior_target_data (current_inferior);
633 if (current_thread && current_thread->h)
634 {
635 /* This may fail in an attached process, so don't check. */
636 (void) CloseHandle (current_thread->h);
637 }
b80864fb
DJ
638}
639
640/* Detach from all inferiors. */
444d6139 641static int
b80864fb
DJ
642win32_detach (void)
643{
444d6139
PA
644 HANDLE h;
645
bf914831
PA
646 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
647 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
ed50f18f
PA
648#ifdef _WIN32_WCE
649 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
650#else
651 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
652#endif
bf914831
PA
653 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
654 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
b80864fb 655
444d6139
PA
656 if (DebugSetProcessKillOnExit == NULL
657 || DebugActiveProcessStop == NULL)
658 return -1;
b80864fb 659
444d6139
PA
660 /* We need a new handle, since DebugActiveProcessStop
661 closes all the ones that came through the events. */
662 if ((h = OpenProcess (PROCESS_ALL_ACCESS,
663 FALSE,
664 current_process_id)) == NULL)
665 {
666 /* The process died. */
667 return -1;
668 }
669
670 {
671 struct thread_resume resume;
672 resume.thread = -1;
673 resume.step = 0;
674 resume.sig = 0;
675 resume.leave_stopped = 0;
676 win32_resume (&resume);
677 }
678
679 if (!DebugActiveProcessStop (current_process_id))
680 {
681 CloseHandle (h);
682 return -1;
683 }
684 DebugSetProcessKillOnExit (FALSE);
685
686 current_process_handle = h;
687 return 0;
688}
689
690/* Wait for inferiors to end. */
691static void
692win32_join (void)
693{
694 if (current_process_id == 0
695 || current_process_handle == NULL)
696 return;
697
698 WaitForSingleObject (current_process_handle, INFINITE);
699 CloseHandle (current_process_handle);
700
701 current_process_handle = NULL;
702 current_process_id = 0;
b80864fb
DJ
703}
704
705/* Return 1 iff the thread with thread ID TID is alive. */
706static int
707win32_thread_alive (unsigned long tid)
708{
709 int res;
710
711 /* Our thread list is reliable; don't bother to poll target
712 threads. */
713 if (find_inferior_id (&all_threads, tid) != NULL)
714 res = 1;
715 else
716 res = 0;
717 return res;
718}
719
720/* Resume the inferior process. RESUME_INFO describes how we want
721 to resume. */
722static void
723win32_resume (struct thread_resume *resume_info)
724{
725 DWORD tid;
726 enum target_signal sig;
727 int step;
41093d81 728 win32_thread_info *th;
b80864fb
DJ
729 DWORD continue_status = DBG_CONTINUE;
730
731 /* This handles the very limited set of resume packets that GDB can
732 currently produce. */
733
734 if (resume_info[0].thread == -1)
735 tid = -1;
736 else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
737 tid = -1;
738 else
739 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
740 the Windows resume code do the right thing for thread switching. */
741 tid = current_event.dwThreadId;
742
743 if (resume_info[0].thread != -1)
744 {
745 sig = resume_info[0].sig;
746 step = resume_info[0].step;
747 }
748 else
749 {
750 sig = 0;
751 step = 0;
752 }
753
754 if (sig != TARGET_SIGNAL_0)
755 {
756 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
757 {
758 OUTMSG (("Cannot continue with signal %d here.\n", sig));
759 }
760 else if (sig == last_sig)
761 continue_status = DBG_EXCEPTION_NOT_HANDLED;
762 else
763 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
764 }
765
766 last_sig = TARGET_SIGNAL_0;
767
768 /* Get context for the currently selected thread. */
769 th = thread_rec (current_event.dwThreadId, FALSE);
770 if (th)
771 {
772 if (th->context.ContextFlags)
773 {
b80864fb
DJ
774 /* Move register values from the inferior into the thread
775 context structure. */
776 regcache_invalidate ();
777
778 if (step)
ed50f18f
PA
779 {
780 if (the_low_target.single_step != NULL)
781 (*the_low_target.single_step) (th);
782 else
783 error ("Single stepping is not supported "
784 "in this configuration.\n");
785 }
34b34921
PA
786
787 (*the_low_target.set_thread_context) (th, &current_event);
b80864fb
DJ
788 th->context.ContextFlags = 0;
789 }
790 }
791
792 /* Allow continuing with the same signal that interrupted us.
793 Otherwise complain. */
794
795 child_continue (continue_status, tid);
796}
797
255e7678
DJ
798static void
799win32_add_one_solib (const char *name, CORE_ADDR load_addr)
800{
801 char buf[MAX_PATH + 1];
802 char buf2[MAX_PATH + 1];
803
804#ifdef _WIN32_WCE
805 WIN32_FIND_DATA w32_fd;
806 WCHAR wname[MAX_PATH + 1];
807 mbstowcs (wname, name, MAX_PATH);
808 HANDLE h = FindFirstFile (wname, &w32_fd);
809#else
810 WIN32_FIND_DATAA w32_fd;
811 HANDLE h = FindFirstFileA (name, &w32_fd);
812#endif
813
814 if (h == INVALID_HANDLE_VALUE)
815 strcpy (buf, name);
816 else
817 {
818 FindClose (h);
819 strcpy (buf, name);
820#ifndef _WIN32_WCE
821 {
822 char cwd[MAX_PATH + 1];
823 char *p;
824 if (GetCurrentDirectoryA (MAX_PATH + 1, cwd))
825 {
826 p = strrchr (buf, '\\');
827 if (p)
828 p[1] = '\0';
829 SetCurrentDirectoryA (buf);
830 GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p);
831 SetCurrentDirectoryA (cwd);
832 }
833 }
834#endif
835 }
836
837#ifdef __CYGWIN__
838 cygwin_conv_to_posix_path (buf, buf2);
839#else
840 strcpy (buf2, buf);
841#endif
842
843 loaded_dll (buf2, load_addr);
844}
845
846static char *
847get_image_name (HANDLE h, void *address, int unicode)
848{
849 static char buf[(2 * MAX_PATH) + 1];
850 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
851 char *address_ptr;
852 int len = 0;
853 char b[2];
854 DWORD done;
855
856 /* Attempt to read the name of the dll that was detected.
857 This is documented to work only when actively debugging
858 a program. It will not work for attached processes. */
859 if (address == NULL)
860 return NULL;
861
862#ifdef _WIN32_WCE
863 /* Windows CE reports the address of the image name,
864 instead of an address of a pointer into the image name. */
865 address_ptr = address;
866#else
867 /* See if we could read the address of a string, and that the
868 address isn't null. */
869 if (!ReadProcessMemory (h, address, &address_ptr,
870 sizeof (address_ptr), &done)
871 || done != sizeof (address_ptr)
872 || !address_ptr)
873 return NULL;
874#endif
875
876 /* Find the length of the string */
877 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
878 && (b[0] != 0 || b[size - 1] != 0) && done == size)
879 continue;
880
881 if (!unicode)
882 ReadProcessMemory (h, address_ptr, buf, len, &done);
883 else
884 {
885 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
886 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
887 &done);
888
889 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
890 }
891
892 return buf;
893}
894
895typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *,
896 DWORD, LPDWORD);
897typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE,
898 LPMODULEINFO, DWORD);
899typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE,
900 LPSTR, DWORD);
901
902static winapi_EnumProcessModules win32_EnumProcessModules;
903static winapi_GetModuleInformation win32_GetModuleInformation;
904static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA;
905
906static BOOL
907load_psapi (void)
908{
909 static int psapi_loaded = 0;
910 static HMODULE dll = NULL;
911
912 if (!psapi_loaded)
913 {
914 psapi_loaded = 1;
915 dll = LoadLibrary (TEXT("psapi.dll"));
916 if (!dll)
917 return FALSE;
918 win32_EnumProcessModules =
919 GETPROCADDRESS (dll, EnumProcessModules);
920 win32_GetModuleInformation =
921 GETPROCADDRESS (dll, GetModuleInformation);
922 win32_GetModuleFileNameExA =
923 GETPROCADDRESS (dll, GetModuleFileNameExA);
924 }
925
926 return (win32_EnumProcessModules != NULL
927 && win32_GetModuleInformation != NULL
928 && win32_GetModuleFileNameExA != NULL);
929}
930
931static int
932psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
933{
934 DWORD len;
935 MODULEINFO mi;
936 size_t i;
937 HMODULE dh_buf[1];
938 HMODULE *DllHandle = dh_buf;
939 DWORD cbNeeded;
940 BOOL ok;
941
942 if (!load_psapi ())
943 goto failed;
944
945 cbNeeded = 0;
946 ok = (*win32_EnumProcessModules) (current_process_handle,
947 DllHandle,
948 sizeof (HMODULE),
949 &cbNeeded);
950
951 if (!ok || !cbNeeded)
952 goto failed;
953
954 DllHandle = (HMODULE *) alloca (cbNeeded);
955 if (!DllHandle)
956 goto failed;
957
958 ok = (*win32_EnumProcessModules) (current_process_handle,
959 DllHandle,
960 cbNeeded,
961 &cbNeeded);
962 if (!ok)
963 goto failed;
964
965 for (i = 0; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++)
966 {
967 if (!(*win32_GetModuleInformation) (current_process_handle,
968 DllHandle[i],
969 &mi,
970 sizeof (mi)))
971 {
972 DWORD err = GetLastError ();
973 error ("Can't get module info: (error %d): %s\n",
974 (int) err, strwinerror (err));
975 }
976
977 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
978 {
979 len = (*win32_GetModuleFileNameExA) (current_process_handle,
980 DllHandle[i],
981 dll_name_ret,
982 MAX_PATH);
983 if (len == 0)
984 {
985 DWORD err = GetLastError ();
986 error ("Error getting dll name: (error %d): %s\n",
987 (int) err, strwinerror (err));
988 }
989 return 1;
990 }
991 }
992
993failed:
994 dll_name_ret[0] = '\0';
995 return 0;
996}
997
998typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD);
999typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32);
1000typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32);
1001
1002static winapi_CreateToolhelp32Snapshot win32_CreateToolhelp32Snapshot;
1003static winapi_Module32First win32_Module32First;
1004static winapi_Module32Next win32_Module32Next;
6b3d9b83
PA
1005#ifdef _WIN32_WCE
1006typedef BOOL (WINAPI *winapi_CloseToolhelp32Snapshot) (HANDLE);
1007static winapi_CloseToolhelp32Snapshot win32_CloseToolhelp32Snapshot;
1008#endif
255e7678
DJ
1009
1010static BOOL
1011load_toolhelp (void)
1012{
1013 static int toolhelp_loaded = 0;
1014 static HMODULE dll = NULL;
1015
1016 if (!toolhelp_loaded)
1017 {
1018 toolhelp_loaded = 1;
1019#ifndef _WIN32_WCE
1020 dll = GetModuleHandle (_T("KERNEL32.DLL"));
1021#else
6b3d9b83 1022 dll = LoadLibrary (L"TOOLHELP.DLL");
255e7678
DJ
1023#endif
1024 if (!dll)
1025 return FALSE;
1026
1027 win32_CreateToolhelp32Snapshot =
1028 GETPROCADDRESS (dll, CreateToolhelp32Snapshot);
1029 win32_Module32First = GETPROCADDRESS (dll, Module32First);
1030 win32_Module32Next = GETPROCADDRESS (dll, Module32Next);
6b3d9b83
PA
1031#ifdef _WIN32_WCE
1032 win32_CloseToolhelp32Snapshot =
1033 GETPROCADDRESS (dll, CloseToolhelp32Snapshot);
1034#endif
255e7678
DJ
1035 }
1036
1037 return (win32_CreateToolhelp32Snapshot != NULL
1038 && win32_Module32First != NULL
6b3d9b83
PA
1039 && win32_Module32Next != NULL
1040#ifdef _WIN32_WCE
1041 && win32_CloseToolhelp32Snapshot != NULL
1042#endif
1043 );
255e7678
DJ
1044}
1045
1046static int
1047toolhelp_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1048{
1049 HANDLE snapshot_module;
1050 MODULEENTRY32 modEntry = { sizeof (MODULEENTRY32) };
6b3d9b83 1051 int found = 0;
255e7678
DJ
1052
1053 if (!load_toolhelp ())
1054 return 0;
1055
1056 snapshot_module = win32_CreateToolhelp32Snapshot (TH32CS_SNAPMODULE,
1057 current_event.dwProcessId);
1058 if (snapshot_module == INVALID_HANDLE_VALUE)
1059 return 0;
1060
1061 /* Ignore the first module, which is the exe. */
6b3d9b83
PA
1062 if (win32_Module32First (snapshot_module, &modEntry))
1063 while (win32_Module32Next (snapshot_module, &modEntry))
1064 if ((DWORD) modEntry.modBaseAddr == BaseAddress)
1065 {
255e7678 1066#ifdef UNICODE
6b3d9b83 1067 wcstombs (dll_name_ret, modEntry.szExePath, MAX_PATH + 1);
255e7678 1068#else
6b3d9b83 1069 strcpy (dll_name_ret, modEntry.szExePath);
255e7678 1070#endif
6b3d9b83
PA
1071 found = 1;
1072 break;
1073 }
255e7678 1074
6b3d9b83
PA
1075#ifdef _WIN32_WCE
1076 win32_CloseToolhelp32Snapshot (snapshot_module);
1077#else
255e7678 1078 CloseHandle (snapshot_module);
6b3d9b83
PA
1079#endif
1080 return found;
255e7678
DJ
1081}
1082
1083static void
1084handle_load_dll (void)
1085{
1086 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1087 char dll_buf[MAX_PATH + 1];
1088 char *dll_name = NULL;
1089 DWORD load_addr;
1090
1091 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1092
34d86ddd
PA
1093 /* Windows does not report the image name of the dlls in the debug
1094 event on attaches. We resort to iterating over the list of
1095 loaded dlls looking for a match by image base. */
1096 if (!psapi_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf))
1097 {
1098 if (!server_waiting)
1099 /* On some versions of Windows and Windows CE, we can't create
1100 toolhelp snapshots while the inferior is stopped in a
1101 LOAD_DLL_DEBUG_EVENT due to a dll load, but we can while
1102 Windows is reporting the already loaded dlls. */
1103 toolhelp_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf);
1104 }
255e7678
DJ
1105
1106 dll_name = dll_buf;
1107
1108 if (*dll_name == '\0')
1109 dll_name = get_image_name (current_process_handle,
1110 event->lpImageName, event->fUnicode);
1111 if (!dll_name)
1112 return;
1113
1114 /* The symbols in a dll are offset by 0x1000, which is the
1115 the offset from 0 of the first byte in an image - because
1116 of the file header and the section alignment. */
1117
1118 load_addr = (DWORD) event->lpBaseOfDll + 0x1000;
1119 win32_add_one_solib (dll_name, load_addr);
1120}
1121
1122static void
1123handle_unload_dll (void)
1124{
1125 CORE_ADDR load_addr =
1126 (CORE_ADDR) (DWORD) current_event.u.UnloadDll.lpBaseOfDll;
1127 load_addr += 0x1000;
1128 unloaded_dll (NULL, load_addr);
1129}
1130
34b34921 1131static void
b80864fb
DJ
1132handle_exception (struct target_waitstatus *ourstatus)
1133{
b80864fb
DJ
1134 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
1135
1136 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1137
b80864fb
DJ
1138 switch (code)
1139 {
1140 case EXCEPTION_ACCESS_VIOLATION:
1141 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
1142 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1143 break;
1144 case STATUS_STACK_OVERFLOW:
1145 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
1146 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1147 break;
1148 case STATUS_FLOAT_DENORMAL_OPERAND:
1149 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
1150 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1151 break;
1152 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1153 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
1154 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1155 break;
1156 case STATUS_FLOAT_INEXACT_RESULT:
1157 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
1158 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1159 break;
1160 case STATUS_FLOAT_INVALID_OPERATION:
1161 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
1162 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1163 break;
1164 case STATUS_FLOAT_OVERFLOW:
1165 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
1166 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1167 break;
1168 case STATUS_FLOAT_STACK_CHECK:
1169 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
1170 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1171 break;
1172 case STATUS_FLOAT_UNDERFLOW:
1173 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
1174 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1175 break;
1176 case STATUS_FLOAT_DIVIDE_BY_ZERO:
1177 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
1178 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1179 break;
1180 case STATUS_INTEGER_DIVIDE_BY_ZERO:
1181 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
1182 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1183 break;
1184 case STATUS_INTEGER_OVERFLOW:
1185 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
1186 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1187 break;
1188 case EXCEPTION_BREAKPOINT:
1189 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
1190 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
ed50f18f
PA
1191#ifdef _WIN32_WCE
1192 /* Remove the initial breakpoint. */
1193 check_breakpoints ((CORE_ADDR) (long) current_event
1194 .u.Exception.ExceptionRecord.ExceptionAddress);
1195#endif
b80864fb
DJ
1196 break;
1197 case DBG_CONTROL_C:
1198 OUTMSG2 (("DBG_CONTROL_C"));
1199 ourstatus->value.sig = TARGET_SIGNAL_INT;
1200 break;
1201 case DBG_CONTROL_BREAK:
1202 OUTMSG2 (("DBG_CONTROL_BREAK"));
1203 ourstatus->value.sig = TARGET_SIGNAL_INT;
1204 break;
1205 case EXCEPTION_SINGLE_STEP:
1206 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
1207 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1208 break;
1209 case EXCEPTION_ILLEGAL_INSTRUCTION:
1210 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
1211 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1212 break;
1213 case EXCEPTION_PRIV_INSTRUCTION:
1214 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
1215 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1216 break;
1217 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1218 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
1219 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1220 break;
1221 default:
1222 if (current_event.u.Exception.dwFirstChance)
34b34921
PA
1223 {
1224 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1225 return;
1226 }
b80864fb
DJ
1227 OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
1228 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1229 (DWORD) current_event.u.Exception.ExceptionRecord.
1230 ExceptionAddress));
1231 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1232 break;
1233 }
1234 OUTMSG2 (("\n"));
1235 last_sig = ourstatus->value.sig;
b80864fb
DJ
1236}
1237
34b34921
PA
1238/* Get the next event from the child. */
1239static void
b80864fb
DJ
1240get_child_debug_event (struct target_waitstatus *ourstatus)
1241{
1242 BOOL debug_event;
b80864fb
DJ
1243
1244 last_sig = TARGET_SIGNAL_0;
1245 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1246
7390519e
PA
1247 /* Keep the wait time low enough for confortable remote interruption,
1248 but high enough so gdbserver doesn't become a bottleneck. */
1249 if (!(debug_event = WaitForDebugEvent (&current_event, 250)))
34b34921 1250 return;
b80864fb
DJ
1251
1252 current_inferior =
1253 (struct thread_info *) find_inferior_id (&all_threads,
1254 current_event.dwThreadId);
1255
34b34921 1256 switch (current_event.dwDebugEventCode)
b80864fb
DJ
1257 {
1258 case CREATE_THREAD_DEBUG_EVENT:
1259 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
1260 "for pid=%d tid=%x)\n",
1261 (unsigned) current_event.dwProcessId,
1262 (unsigned) current_event.dwThreadId));
1263
1264 /* Record the existence of this thread. */
34b34921 1265 child_add_thread (current_event.dwThreadId,
b80864fb 1266 current_event.u.CreateThread.hThread);
b80864fb
DJ
1267 break;
1268
1269 case EXIT_THREAD_DEBUG_EVENT:
1270 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
1271 "for pid=%d tid=%x\n",
1272 (unsigned) current_event.dwProcessId,
1273 (unsigned) current_event.dwThreadId));
1274 child_delete_thread (current_event.dwThreadId);
b80864fb
DJ
1275 break;
1276
1277 case CREATE_PROCESS_DEBUG_EVENT:
1278 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1279 "for pid=%d tid=%x\n",
1280 (unsigned) current_event.dwProcessId,
1281 (unsigned) current_event.dwThreadId));
1282 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1283
1284 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1285 main_thread_id = current_event.dwThreadId;
1286
1287 ourstatus->kind = TARGET_WAITKIND_EXECD;
1288 ourstatus->value.execd_pathname = "Main executable";
1289
1290 /* Add the main thread. */
34b34921
PA
1291 child_add_thread (main_thread_id,
1292 current_event.u.CreateProcessInfo.hThread);
b80864fb 1293
34b34921 1294 ourstatus->value.related_pid = current_event.dwThreadId;
ed50f18f
PA
1295#ifdef _WIN32_WCE
1296 /* Windows CE doesn't set the initial breakpoint automatically
1297 like the desktop versions of Windows do. We add it explicitly
1298 here. It will be removed as soon as it is hit. */
1299 set_breakpoint_at ((CORE_ADDR) (long) current_event.u
1300 .CreateProcessInfo.lpStartAddress,
1301 delete_breakpoint_at);
1302#endif
b80864fb
DJ
1303 break;
1304
1305 case EXIT_PROCESS_DEBUG_EVENT:
1306 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1307 "for pid=%d tid=%x\n",
1308 (unsigned) current_event.dwProcessId,
1309 (unsigned) current_event.dwThreadId));
1310 ourstatus->kind = TARGET_WAITKIND_EXITED;
1311 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1312 CloseHandle (current_process_handle);
9d606399 1313 current_process_handle = NULL;
b80864fb
DJ
1314 break;
1315
1316 case LOAD_DLL_DEBUG_EVENT:
1317 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1318 "for pid=%d tid=%x\n",
1319 (unsigned) current_event.dwProcessId,
1320 (unsigned) current_event.dwThreadId));
1321 CloseHandle (current_event.u.LoadDll.hFile);
255e7678 1322 handle_load_dll ();
b80864fb
DJ
1323
1324 ourstatus->kind = TARGET_WAITKIND_LOADED;
255e7678 1325 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
b80864fb
DJ
1326 break;
1327
1328 case UNLOAD_DLL_DEBUG_EVENT:
1329 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1330 "for pid=%d tid=%x\n",
1331 (unsigned) current_event.dwProcessId,
1332 (unsigned) current_event.dwThreadId));
255e7678
DJ
1333 handle_unload_dll ();
1334 ourstatus->kind = TARGET_WAITKIND_LOADED;
1335 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
b80864fb
DJ
1336 break;
1337
1338 case EXCEPTION_DEBUG_EVENT:
1339 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1340 "for pid=%d tid=%x\n",
1341 (unsigned) current_event.dwProcessId,
1342 (unsigned) current_event.dwThreadId));
34b34921 1343 handle_exception (ourstatus);
b80864fb
DJ
1344 break;
1345
1346 case OUTPUT_DEBUG_STRING_EVENT:
1347 /* A message from the kernel (or Cygwin). */
1348 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1349 "for pid=%d tid=%x\n",
1350 (unsigned) current_event.dwProcessId,
1351 (unsigned) current_event.dwThreadId));
bce7165d 1352 handle_output_debug_string (ourstatus);
b80864fb
DJ
1353 break;
1354
1355 default:
1356 OUTMSG2 (("gdbserver: kernel event unknown "
1357 "for pid=%d tid=%x code=%ld\n",
1358 (unsigned) current_event.dwProcessId,
1359 (unsigned) current_event.dwThreadId,
1360 current_event.dwDebugEventCode));
1361 break;
1362 }
1363
1364 current_inferior =
1365 (struct thread_info *) find_inferior_id (&all_threads,
1366 current_event.dwThreadId);
b80864fb
DJ
1367}
1368
1369/* Wait for the inferior process to change state.
1370 STATUS will be filled in with a response code to send to GDB.
1371 Returns the signal which caused the process to stop. */
1372static unsigned char
1373win32_wait (char *status)
1374{
1375 struct target_waitstatus our_status;
1376
1377 *status = 'T';
1378
1379 while (1)
1380 {
7390519e
PA
1381 /* Check if GDB sent us an interrupt request. */
1382 check_remote_input_interrupt_request ();
1383
b80864fb
DJ
1384 get_child_debug_event (&our_status);
1385
34b34921 1386 switch (our_status.kind)
b80864fb 1387 {
34b34921 1388 case TARGET_WAITKIND_EXITED:
b80864fb
DJ
1389 OUTMSG2 (("Child exited with retcode = %x\n",
1390 our_status.value.integer));
1391
1392 *status = 'W';
b80864fb 1393 return our_status.value.integer;
34b34921 1394 case TARGET_WAITKIND_STOPPED:
255e7678 1395 case TARGET_WAITKIND_LOADED:
f72f3e60 1396 OUTMSG2 (("Child Stopped with signal = %d \n",
ed50f18f 1397 our_status.value.sig));
b80864fb
DJ
1398
1399 *status = 'T';
1400
1401 child_fetch_inferior_registers (-1);
1402
255e7678
DJ
1403 if (our_status.kind == TARGET_WAITKIND_LOADED
1404 && !server_waiting)
1405 {
1406 /* When gdb connects, we want to be stopped at the
1407 initial breakpoint, not in some dll load event. */
1408 child_continue (DBG_CONTINUE, -1);
1409 break;
1410 }
1411
b80864fb 1412 return our_status.value.sig;
34b34921
PA
1413 default:
1414 OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
1415 /* fall-through */
1416 case TARGET_WAITKIND_SPURIOUS:
34b34921
PA
1417 case TARGET_WAITKIND_EXECD:
1418 /* do nothing, just continue */
1419 child_continue (DBG_CONTINUE, -1);
1420 break;
b80864fb 1421 }
b80864fb
DJ
1422 }
1423}
1424
1425/* Fetch registers from the inferior process.
1426 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1427static void
1428win32_fetch_inferior_registers (int regno)
1429{
1430 child_fetch_inferior_registers (regno);
1431}
1432
1433/* Store registers to the inferior process.
1434 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1435static void
1436win32_store_inferior_registers (int regno)
1437{
1438 child_store_inferior_registers (regno);
1439}
1440
1441/* Read memory from the inferior process. This should generally be
1442 called through read_inferior_memory, which handles breakpoint shadowing.
1443 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1444static int
1445win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1446{
ed50f18f 1447 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
b80864fb
DJ
1448}
1449
1450/* Write memory to the inferior process. This should generally be
1451 called through write_inferior_memory, which handles breakpoint shadowing.
1452 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1453 Returns 0 on success and errno on failure. */
1454static int
1455win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1456 int len)
1457{
1458 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1459}
1460
7390519e
PA
1461/* Send an interrupt request to the inferior process. */
1462static void
1463win32_request_interrupt (void)
1464{
1465 winapi_DebugBreakProcess DebugBreakProcess;
1466 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent;
1467
1468#ifdef _WIN32_WCE
1469 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
1470#else
1471 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1472#endif
1473
1474 GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent);
1475
1476 if (GenerateConsoleCtrlEvent != NULL
1477 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
1478 return;
1479
1480 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1481 not a process group id.
1482 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1483 breakpoint exception in the interior process. */
1484
1485 DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess);
1486
1487 if (DebugBreakProcess != NULL
1488 && DebugBreakProcess (current_process_handle))
1489 return;
1490
1491 OUTMSG (("Could not interrupt process.\n"));
1492}
1493
820f2bda
PA
1494static const char *
1495win32_arch_string (void)
1496{
ed50f18f 1497 return the_low_target.arch_string;
820f2bda
PA
1498}
1499
b80864fb
DJ
1500static struct target_ops win32_target_ops = {
1501 win32_create_inferior,
1502 win32_attach,
1503 win32_kill,
1504 win32_detach,
444d6139 1505 win32_join,
b80864fb
DJ
1506 win32_thread_alive,
1507 win32_resume,
1508 win32_wait,
1509 win32_fetch_inferior_registers,
1510 win32_store_inferior_registers,
1511 win32_read_inferior_memory,
1512 win32_write_inferior_memory,
820f2bda 1513 NULL,
7390519e 1514 win32_request_interrupt,
820f2bda
PA
1515 NULL,
1516 NULL,
1517 NULL,
1518 NULL,
1519 NULL,
1520 NULL,
1521 NULL,
1522 win32_arch_string
b80864fb
DJ
1523};
1524
1525/* Initialize the Win32 backend. */
1526void
1527initialize_low (void)
1528{
1529 set_target_ops (&win32_target_ops);
ed50f18f
PA
1530 if (the_low_target.breakpoint != NULL)
1531 set_breakpoint_data (the_low_target.breakpoint,
1532 the_low_target.breakpoint_len);
b80864fb
DJ
1533 init_registers ();
1534}