]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbserver/win32-low.c
* win32-low.c (create_process): New.
[thirdparty/binutils-gdb.git] / gdb / gdbserver / win32-low.c
1 /* Low level interface to Windows debugging, for gdbserver.
2 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
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
10 the Free Software Foundation; either version 3 of the License, or
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
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include "server.h"
22 #include "regcache.h"
23 #include "gdb/signals.h"
24 #include "mem-break.h"
25 #include "win32-low.h"
26
27 #include <windows.h>
28 #include <winnt.h>
29 #include <imagehlp.h>
30 #include <tlhelp32.h>
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
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]))
55 #endif
56
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
65 int using_threads = 1;
66
67 /* Globals. */
68 static HANDLE current_process_handle = NULL;
69 static DWORD current_process_id = 0;
70 static enum target_signal last_sig = TARGET_SIGNAL_0;
71
72 /* The current debug event from WaitForDebugEvent. */
73 static DEBUG_EVENT current_event;
74
75 #define NUM_REGS (the_low_target.num_regs)
76
77 typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
78 typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
79 typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
80 typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
81
82 static DWORD main_thread_id = 0;
83
84 static void win32_resume (struct thread_resume *resume_info);
85
86 /* Get the thread ID from the current selected inferior (the current
87 thread). */
88 static DWORD
89 current_inferior_tid (void)
90 {
91 win32_thread_info *th = inferior_target_data (current_inferior);
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. */
97 static win32_thread_info *
98 thread_rec (DWORD id, int get_context)
99 {
100 struct thread_info *thread;
101 win32_thread_info *th;
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 {
110 if (id != current_event.dwThreadId)
111 th->suspend_count = SuspendThread (th->h) + 1;
112
113 (*the_low_target.get_thread_context) (th, &current_event);
114 }
115
116 return th;
117 }
118
119 /* Add a thread to the thread list. */
120 static win32_thread_info *
121 child_add_thread (DWORD tid, HANDLE h)
122 {
123 win32_thread_info *th;
124
125 if ((th = thread_rec (tid, FALSE)))
126 return th;
127
128 th = (win32_thread_info *) malloc (sizeof (*th));
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
138 if (the_low_target.thread_added != NULL)
139 (*the_low_target.thread_added) (th);
140
141 return th;
142 }
143
144 /* Delete a thread from the list of threads. */
145 static void
146 delete_thread_info (struct inferior_list_entry *thread)
147 {
148 win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
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. */
156 static void
157 child_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. */
173 static int
174 child_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? */
195 enum 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
204 /* The program is letting us know that it dynamically loaded
205 or unloaded something. */
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. */
210 TARGET_WAITKIND_EXECD,
211
212 /* Nothing interesting happened, but we stopped anyway. We take the
213 chance to check if GDB requested an interrupt. */
214 TARGET_WAITKIND_SPURIOUS,
215 };
216
217 struct 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
233 /* Clear out any old thread list and reinitialize it to a pristine
234 state. */
235 static void
236 child_init_thread_list (void)
237 {
238 for_each_inferior (&all_threads, delete_thread_info);
239 }
240
241 static void
242 do_initial_child_stuff (DWORD pid)
243 {
244 last_sig = TARGET_SIGNAL_0;
245
246 memset (&current_event, 0, sizeof (current_event));
247
248 child_init_thread_list ();
249
250 if (the_low_target.initial_stuff != NULL)
251 (*the_low_target.initial_stuff) ();
252 }
253
254 /* Resume all artificially suspended threads if we are continuing
255 execution. */
256 static int
257 continue_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;
261 win32_thread_info *th = inferior_target_data (thread);
262 int i;
263
264 if ((thread_id == -1 || thread_id == th->tid)
265 && th->suspend_count)
266 {
267 if (th->context.ContextFlags)
268 {
269 (*the_low_target.set_thread_context) (th, &current_event);
270 th->context.ContextFlags = 0;
271 }
272
273 for (i = 0; i < th->suspend_count; i++)
274 (void) ResumeThread (th->h);
275 th->suspend_count = 0;
276 }
277
278 return 0;
279 }
280
281 static BOOL
282 child_continue (DWORD continue_status, int thread_id)
283 {
284 BOOL res;
285
286 res = ContinueDebugEvent (current_event.dwProcessId,
287 current_event.dwThreadId, continue_status);
288 if (res)
289 find_inferior (&all_threads, continue_one_thread, &thread_id);
290
291 return res;
292 }
293
294 /* Fetch register(s) from the current thread context. */
295 static void
296 child_fetch_inferior_registers (int r)
297 {
298 int regno;
299 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
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++)
304 (*the_low_target.fetch_inferior_register) (th, regno);
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. */
309 static void
310 child_store_inferior_registers (int r)
311 {
312 int regno;
313 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
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++)
318 (*the_low_target.store_inferior_register) (th, regno);
319 }
320
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
331 char *
332 strwinerror (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
376 static BOOL
377 create_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
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. */
431 static int
432 win32_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
438 BOOL ret;
439 DWORD flags;
440 char *args;
441 int argslen;
442 int argc;
443 PROCESS_INFORMATION pi;
444 DWORD err;
445
446 if (!program)
447 error ("No executable specified, specify executable to debug.\n");
448
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
466 argslen = 1;
467 for (argc = 1; program_args[argc]; argc++)
468 argslen += strlen (program_args[argc]) + 1;
469 args = alloca (argslen);
470 args[0] = '\0';
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 }
478 OUTMSG2 (("Command line is \"%s\"\n", args));
479
480 #ifdef CREATE_NEW_PROCESS_GROUP
481 flags |= CREATE_NEW_PROCESS_GROUP;
482 #endif
483
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 }
493
494 #ifndef USE_WIN32API
495 if (orig_path)
496 setenv ("PATH", orig_path, 1);
497 #endif
498
499 if (!ret)
500 {
501 error ("Error creating process \"%s%s\", (error %d): %s\n",
502 program, args, (int) err, strwinerror (err));
503 }
504 else
505 {
506 OUTMSG2 (("Process created: %s\n", (char *) args));
507 }
508
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. */
513 CloseHandle (pi.hThread);
514 #endif
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. */
527 static int
528 win32_attach (unsigned long pid)
529 {
530 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
531 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
532 #ifdef _WIN32_WCE
533 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
534 #else
535 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
536 #endif
537 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
538 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
539
540 if (DebugActiveProcess (pid))
541 {
542 if (DebugSetProcessKillOnExit != NULL)
543 DebugSetProcessKillOnExit (FALSE);
544
545 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
546
547 if (current_process_handle != NULL)
548 {
549 current_process_id = pid;
550 do_initial_child_stuff (pid);
551 return 0;
552 }
553 if (DebugActiveProcessStop != NULL)
554 DebugActiveProcessStop (current_process_id);
555 }
556
557 error ("Attach to process failed.");
558 }
559
560 /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
561 static void
562 handle_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)
593 {
594 if (!server_waiting)
595 {
596 OUTMSG2(("%s", s));
597 return;
598 }
599
600 monitor_output (s);
601 }
602 #undef READ_BUFFER_LEN
603 }
604
605 /* Kill all inferiors. */
606 static void
607 win32_kill (void)
608 {
609 win32_thread_info *current_thread;
610
611 if (current_process_handle == NULL)
612 return;
613
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;
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 }
628 }
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 }
638 }
639
640 /* Detach from all inferiors. */
641 static int
642 win32_detach (void)
643 {
644 HANDLE h;
645
646 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
647 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
648 #ifdef _WIN32_WCE
649 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
650 #else
651 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
652 #endif
653 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
654 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
655
656 if (DebugSetProcessKillOnExit == NULL
657 || DebugActiveProcessStop == NULL)
658 return -1;
659
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. */
691 static void
692 win32_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;
703 }
704
705 /* Return 1 iff the thread with thread ID TID is alive. */
706 static int
707 win32_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. */
722 static void
723 win32_resume (struct thread_resume *resume_info)
724 {
725 DWORD tid;
726 enum target_signal sig;
727 int step;
728 win32_thread_info *th;
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 {
774 /* Move register values from the inferior into the thread
775 context structure. */
776 regcache_invalidate ();
777
778 if (step)
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 }
786
787 (*the_low_target.set_thread_context) (th, &current_event);
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
798 static void
799 win32_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
846 static char *
847 get_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
895 typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *,
896 DWORD, LPDWORD);
897 typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE,
898 LPMODULEINFO, DWORD);
899 typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE,
900 LPSTR, DWORD);
901
902 static winapi_EnumProcessModules win32_EnumProcessModules;
903 static winapi_GetModuleInformation win32_GetModuleInformation;
904 static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA;
905
906 static BOOL
907 load_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
931 static int
932 psapi_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
993 failed:
994 dll_name_ret[0] = '\0';
995 return 0;
996 }
997
998 typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD);
999 typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32);
1000 typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32);
1001
1002 static winapi_CreateToolhelp32Snapshot win32_CreateToolhelp32Snapshot;
1003 static winapi_Module32First win32_Module32First;
1004 static winapi_Module32Next win32_Module32Next;
1005 #ifdef _WIN32_WCE
1006 typedef BOOL (WINAPI *winapi_CloseToolhelp32Snapshot) (HANDLE);
1007 static winapi_CloseToolhelp32Snapshot win32_CloseToolhelp32Snapshot;
1008 #endif
1009
1010 static BOOL
1011 load_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
1022 dll = LoadLibrary (L"TOOLHELP.DLL");
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);
1031 #ifdef _WIN32_WCE
1032 win32_CloseToolhelp32Snapshot =
1033 GETPROCADDRESS (dll, CloseToolhelp32Snapshot);
1034 #endif
1035 }
1036
1037 return (win32_CreateToolhelp32Snapshot != NULL
1038 && win32_Module32First != NULL
1039 && win32_Module32Next != NULL
1040 #ifdef _WIN32_WCE
1041 && win32_CloseToolhelp32Snapshot != NULL
1042 #endif
1043 );
1044 }
1045
1046 static int
1047 toolhelp_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1048 {
1049 HANDLE snapshot_module;
1050 MODULEENTRY32 modEntry = { sizeof (MODULEENTRY32) };
1051 int found = 0;
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. */
1062 if (win32_Module32First (snapshot_module, &modEntry))
1063 while (win32_Module32Next (snapshot_module, &modEntry))
1064 if ((DWORD) modEntry.modBaseAddr == BaseAddress)
1065 {
1066 #ifdef UNICODE
1067 wcstombs (dll_name_ret, modEntry.szExePath, MAX_PATH + 1);
1068 #else
1069 strcpy (dll_name_ret, modEntry.szExePath);
1070 #endif
1071 found = 1;
1072 break;
1073 }
1074
1075 #ifdef _WIN32_WCE
1076 win32_CloseToolhelp32Snapshot (snapshot_module);
1077 #else
1078 CloseHandle (snapshot_module);
1079 #endif
1080 return found;
1081 }
1082
1083 static void
1084 handle_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
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 }
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
1122 static void
1123 handle_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
1131 static void
1132 handle_exception (struct target_waitstatus *ourstatus)
1133 {
1134 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
1135
1136 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1137
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;
1191 #ifdef _WIN32_WCE
1192 /* Remove the initial breakpoint. */
1193 check_breakpoints ((CORE_ADDR) (long) current_event
1194 .u.Exception.ExceptionRecord.ExceptionAddress);
1195 #endif
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)
1223 {
1224 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1225 return;
1226 }
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;
1236 }
1237
1238 /* Get the next event from the child. */
1239 static void
1240 get_child_debug_event (struct target_waitstatus *ourstatus)
1241 {
1242 BOOL debug_event;
1243
1244 last_sig = TARGET_SIGNAL_0;
1245 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1246
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)))
1250 return;
1251
1252 current_inferior =
1253 (struct thread_info *) find_inferior_id (&all_threads,
1254 current_event.dwThreadId);
1255
1256 switch (current_event.dwDebugEventCode)
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. */
1265 child_add_thread (current_event.dwThreadId,
1266 current_event.u.CreateThread.hThread);
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);
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. */
1291 child_add_thread (main_thread_id,
1292 current_event.u.CreateProcessInfo.hThread);
1293
1294 ourstatus->value.related_pid = current_event.dwThreadId;
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
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);
1313 current_process_handle = NULL;
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);
1322 handle_load_dll ();
1323
1324 ourstatus->kind = TARGET_WAITKIND_LOADED;
1325 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
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));
1333 handle_unload_dll ();
1334 ourstatus->kind = TARGET_WAITKIND_LOADED;
1335 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
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));
1343 handle_exception (ourstatus);
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));
1352 handle_output_debug_string (ourstatus);
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);
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. */
1372 static unsigned char
1373 win32_wait (char *status)
1374 {
1375 struct target_waitstatus our_status;
1376
1377 *status = 'T';
1378
1379 while (1)
1380 {
1381 /* Check if GDB sent us an interrupt request. */
1382 check_remote_input_interrupt_request ();
1383
1384 get_child_debug_event (&our_status);
1385
1386 switch (our_status.kind)
1387 {
1388 case TARGET_WAITKIND_EXITED:
1389 OUTMSG2 (("Child exited with retcode = %x\n",
1390 our_status.value.integer));
1391
1392 *status = 'W';
1393
1394 child_fetch_inferior_registers (-1);
1395
1396 return our_status.value.integer;
1397 case TARGET_WAITKIND_STOPPED:
1398 case TARGET_WAITKIND_LOADED:
1399 OUTMSG2 (("Child Stopped with signal = %d \n",
1400 our_status.value.sig));
1401
1402 *status = 'T';
1403
1404 child_fetch_inferior_registers (-1);
1405
1406 if (our_status.kind == TARGET_WAITKIND_LOADED
1407 && !server_waiting)
1408 {
1409 /* When gdb connects, we want to be stopped at the
1410 initial breakpoint, not in some dll load event. */
1411 child_continue (DBG_CONTINUE, -1);
1412 break;
1413 }
1414
1415 return our_status.value.sig;
1416 default:
1417 OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
1418 /* fall-through */
1419 case TARGET_WAITKIND_SPURIOUS:
1420 case TARGET_WAITKIND_EXECD:
1421 /* do nothing, just continue */
1422 child_continue (DBG_CONTINUE, -1);
1423 break;
1424 }
1425 }
1426 }
1427
1428 /* Fetch registers from the inferior process.
1429 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1430 static void
1431 win32_fetch_inferior_registers (int regno)
1432 {
1433 child_fetch_inferior_registers (regno);
1434 }
1435
1436 /* Store registers to the inferior process.
1437 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1438 static void
1439 win32_store_inferior_registers (int regno)
1440 {
1441 child_store_inferior_registers (regno);
1442 }
1443
1444 /* Read memory from the inferior process. This should generally be
1445 called through read_inferior_memory, which handles breakpoint shadowing.
1446 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1447 static int
1448 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1449 {
1450 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
1451 }
1452
1453 /* Write memory to the inferior process. This should generally be
1454 called through write_inferior_memory, which handles breakpoint shadowing.
1455 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1456 Returns 0 on success and errno on failure. */
1457 static int
1458 win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1459 int len)
1460 {
1461 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1462 }
1463
1464 /* Send an interrupt request to the inferior process. */
1465 static void
1466 win32_request_interrupt (void)
1467 {
1468 winapi_DebugBreakProcess DebugBreakProcess;
1469 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent;
1470
1471 #ifdef _WIN32_WCE
1472 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
1473 #else
1474 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1475 #endif
1476
1477 GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent);
1478
1479 if (GenerateConsoleCtrlEvent != NULL
1480 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
1481 return;
1482
1483 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1484 not a process group id.
1485 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1486 breakpoint exception in the interior process. */
1487
1488 DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess);
1489
1490 if (DebugBreakProcess != NULL
1491 && DebugBreakProcess (current_process_handle))
1492 return;
1493
1494 OUTMSG (("Could not interrupt process.\n"));
1495 }
1496
1497 static const char *
1498 win32_arch_string (void)
1499 {
1500 return the_low_target.arch_string;
1501 }
1502
1503 static struct target_ops win32_target_ops = {
1504 win32_create_inferior,
1505 win32_attach,
1506 win32_kill,
1507 win32_detach,
1508 win32_join,
1509 win32_thread_alive,
1510 win32_resume,
1511 win32_wait,
1512 win32_fetch_inferior_registers,
1513 win32_store_inferior_registers,
1514 win32_read_inferior_memory,
1515 win32_write_inferior_memory,
1516 NULL,
1517 win32_request_interrupt,
1518 NULL,
1519 NULL,
1520 NULL,
1521 NULL,
1522 NULL,
1523 NULL,
1524 NULL,
1525 win32_arch_string
1526 };
1527
1528 /* Initialize the Win32 backend. */
1529 void
1530 initialize_low (void)
1531 {
1532 set_target_ops (&win32_target_ops);
1533 if (the_low_target.breakpoint != NULL)
1534 set_breakpoint_data (the_low_target.breakpoint,
1535 the_low_target.breakpoint_len);
1536 init_registers ();
1537 }