1 /* Low level interface to Windows debugging, for gdbserver.
2 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
4 Contributed by Leo Zayas. Based on "win32-nat.c" from GDB.
6 This file is part of GDB.
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 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
25 #include "gdb/signals.h"
26 #include "mem-break.h"
27 #include "win32-low.h"
33 #include <sys/param.h>
38 #include <sys/cygwin.h>
43 #define OUTMSG(X) do { printf X; fflush (stdout); } while (0)
45 #define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
47 #define OUTMSG2(X) do ; while (0)
51 #define _T(x) TEXT (x)
55 #define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
59 # define GETPROCADDRESS(DLL, PROC) \
60 ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC)))
62 # define GETPROCADDRESS(DLL, PROC) \
63 ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
66 int using_threads = 1;
69 static HANDLE current_process_handle = NULL;
70 static DWORD current_process_id = 0;
71 static enum target_signal last_sig = TARGET_SIGNAL_0;
73 /* The current debug event from WaitForDebugEvent. */
74 static DEBUG_EVENT current_event;
76 #define NUM_REGS (the_low_target.num_regs)
78 typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
79 typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
81 static DWORD main_thread_id = 0;
83 static void win32_resume (struct thread_resume *resume_info);
85 /* Get the thread ID from the current selected inferior (the current
88 current_inferior_tid (void)
90 win32_thread_info *th = inferior_target_data (current_inferior);
94 /* Find a thread record given a thread id. If GET_CONTEXT is set then
95 also retrieve the context for this thread. */
96 static win32_thread_info *
97 thread_rec (DWORD id, int get_context)
99 struct thread_info *thread;
100 win32_thread_info *th;
102 thread = (struct thread_info *) find_inferior_id (&all_threads, id);
106 th = inferior_target_data (thread);
107 if (!th->suspend_count && get_context)
109 if (id != current_event.dwThreadId)
110 th->suspend_count = SuspendThread (th->h) + 1;
112 (*the_low_target.get_thread_context) (th, ¤t_event);
118 /* Add a thread to the thread list. */
119 static win32_thread_info *
120 child_add_thread (DWORD tid, HANDLE h)
122 win32_thread_info *th;
124 if ((th = thread_rec (tid, FALSE)))
127 th = (win32_thread_info *) malloc (sizeof (*th));
128 memset (th, 0, sizeof (*th));
132 add_thread (tid, th, (unsigned int) tid);
133 set_inferior_regcache_data ((struct thread_info *)
134 find_inferior_id (&all_threads, tid),
135 new_register_cache ());
137 if (the_low_target.thread_added != NULL)
138 (*the_low_target.thread_added) (th);
143 /* Delete a thread from the list of threads. */
145 delete_thread_info (struct inferior_list_entry *thread)
147 win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
149 remove_thread ((struct thread_info *) thread);
154 /* Delete a thread from the list of threads. */
156 child_delete_thread (DWORD id)
158 struct inferior_list_entry *thread;
160 /* If the last thread is exiting, just return. */
161 if (all_threads.head == all_threads.tail)
164 thread = find_inferior_id (&all_threads, id);
168 delete_thread_info (thread);
171 /* Transfer memory from/to the debugged process. */
173 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
174 int write, struct target_ops *target)
177 long addr = (long) memaddr;
181 WriteProcessMemory (current_process_handle, (LPVOID) addr,
182 (LPCVOID) our, len, &done);
183 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
187 ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
193 /* Generally, what has the program done? */
196 /* The program has exited. The exit status is in value.integer. */
197 TARGET_WAITKIND_EXITED,
199 /* The program has stopped with a signal. Which signal is in
201 TARGET_WAITKIND_STOPPED,
203 /* The program is letting us know that it dynamically loaded something
204 (e.g. it called load(2) on AIX). */
205 TARGET_WAITKIND_LOADED,
207 /* The program has exec'ed a new executable file. The new file's
208 pathname is pointed to by value.execd_pathname. */
209 TARGET_WAITKIND_EXECD,
211 /* Nothing happened, but we stopped anyway. This perhaps should be handled
212 within target_wait, but I'm not sure target_wait should be resuming the
214 TARGET_WAITKIND_SPURIOUS,
217 struct target_waitstatus
219 enum target_waitkind kind;
221 /* Forked child pid, execd pathname, exit status or signal number. */
225 enum target_signal sig;
227 char *execd_pathname;
233 /* Clear out any old thread list and reinitialize it to a pristine
236 child_init_thread_list (void)
238 for_each_inferior (&all_threads, delete_thread_info);
242 do_initial_child_stuff (DWORD pid)
244 last_sig = TARGET_SIGNAL_0;
246 memset (¤t_event, 0, sizeof (current_event));
248 child_init_thread_list ();
250 if (the_low_target.initial_stuff != NULL)
251 (*the_low_target.initial_stuff) ();
254 /* Resume all artificially suspended threads if we are continuing
257 continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
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);
264 if ((thread_id == -1 || thread_id == th->tid)
265 && th->suspend_count)
267 if (th->context.ContextFlags)
269 (*the_low_target.set_thread_context) (th, ¤t_event);
270 th->context.ContextFlags = 0;
273 for (i = 0; i < th->suspend_count; i++)
274 (void) ResumeThread (th->h);
275 th->suspend_count = 0;
282 child_continue (DWORD continue_status, int thread_id)
286 res = ContinueDebugEvent (current_event.dwProcessId,
287 current_event.dwThreadId, continue_status);
289 find_inferior (&all_threads, continue_one_thread, &thread_id);
294 /* Fetch register(s) from the current thread context. */
296 child_fetch_inferior_registers (int r)
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);
303 for (regno = 0; regno < r; regno++)
304 (*the_low_target.fetch_inferior_register) (th, regno);
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. */
310 child_store_inferior_registers (int r)
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);
317 for (regno = 0; regno < r; regno++)
318 (*the_low_target.store_inferior_register) (th, regno);
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.
325 The string pointed to shall not be modified by the application,
326 but may be overwritten by a subsequent call to strwinerror
328 The strwinerror function does not change the current setting
332 strwinerror (DWORD error)
334 static char buf[1024];
336 DWORD lasterr = GetLastError ();
337 DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
338 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
341 0, /* Default language */
347 /* If there is an \r\n appended, zap it. */
349 && msgbuf[chars - 2] == '\r'
350 && msgbuf[chars - 1] == '\n')
356 if (chars > ((COUNTOF (buf)) - 1))
358 chars = COUNTOF (buf) - 1;
363 wcstombs (buf, msgbuf, chars + 1);
365 strncpy (buf, msgbuf, chars + 1);
370 sprintf (buf, "unknown win32 error (%ld)", error);
372 SetLastError (lasterr);
376 /* Start a new process.
377 PROGRAM is a path to the program to execute.
378 ARGS is a standard NULL-terminated array of arguments,
379 to be passed to the inferior as ``argv''.
380 Returns the new PID on success, -1 on failure. Registers the new
381 process with the process list. */
383 win32_create_inferior (char *program, char **program_args)
386 char real_path[MAXPATHLEN];
387 char *orig_path, *new_path, *path_ptr;
394 PROCESS_INFORMATION pi;
395 #ifndef __MINGW32CE__
396 STARTUPINFOA si = { sizeof (STARTUPINFOA) };
399 wchar_t *wargs, *wprogram;
403 error ("No executable specified, specify executable to debug.\n");
405 flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
409 path_ptr = getenv ("PATH");
412 orig_path = alloca (strlen (path_ptr) + 1);
413 new_path = alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr));
414 strcpy (orig_path, path_ptr);
415 cygwin_posix_to_win32_path_list (path_ptr, new_path);
416 setenv ("PATH", new_path, 1);
418 cygwin_conv_to_win32_path (program, real_path);
423 for (argc = 1; program_args[argc]; argc++)
424 argslen += strlen (program_args[argc]) + 1;
425 args = alloca (argslen);
427 for (argc = 1; program_args[argc]; argc++)
429 /* FIXME: Can we do better about quoting? How does Cygwin
432 strcat (args, program_args[argc]);
434 OUTMSG2 (("Command line is \"%s\"\n", args));
436 #ifdef CREATE_NEW_PROCESS_GROUP
437 flags |= CREATE_NEW_PROCESS_GROUP;
441 to_back_slashes (program);
442 wargs = alloca (argslen * sizeof (wchar_t));
443 mbstowcs (wargs, args, argslen);
444 wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
445 mbstowcs (wprogram, program, strlen (program) + 1);
446 ret = CreateProcessW (wprogram, /* image name */
447 wargs, /* command line */
448 NULL, /* security, not supported */
449 NULL, /* thread, not supported */
450 FALSE, /* inherit handles, not supported */
451 flags, /* start flags */
452 NULL, /* environment, not supported */
453 NULL, /* current directory, not supported */
454 NULL, /* start info, not supported */
455 &pi); /* proc info */
457 ret = CreateProcessA (program, /* image name */
458 args, /* command line */
461 TRUE, /* inherit handles */
462 flags, /* start flags */
463 winenv, /* environment */
464 NULL, /* current directory */
465 &si, /* start info */
466 &pi); /* proc info */
471 setenv ("PATH", orig_path, 1);
476 DWORD err = GetLastError ();
477 error ("Error creating process \"%s%s\", (error %d): %s\n",
478 program, args, (int) err, strwinerror (err));
482 OUTMSG2 (("Process created: %s\n", (char *) args));
486 /* On Windows CE this handle can't be closed. The OS reuses
487 it in the debug events, while the 9x/NT versions of Windows
488 probably use a DuplicateHandle'd one. */
489 CloseHandle (pi.hThread);
492 current_process_handle = pi.hProcess;
493 current_process_id = pi.dwProcessId;
495 do_initial_child_stuff (current_process_id);
497 return current_process_id;
500 /* Attach to a running process.
501 PID is the process ID to attach to, specified by the user
502 or a higher layer. */
504 win32_attach (unsigned long pid)
506 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
507 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
509 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
511 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
513 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
514 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
516 if (DebugActiveProcess (pid))
518 if (DebugSetProcessKillOnExit != NULL)
519 DebugSetProcessKillOnExit (FALSE);
521 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
523 if (current_process_handle != NULL)
525 current_process_id = pid;
526 do_initial_child_stuff (pid);
529 if (DebugActiveProcessStop != NULL)
530 DebugActiveProcessStop (current_process_id);
533 error ("Attach to process failed.");
536 /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
538 handle_output_debug_string (struct target_waitstatus *ourstatus)
540 #define READ_BUFFER_LEN 1024
542 char s[READ_BUFFER_LEN + 1] = { 0 };
543 DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
548 if (nbytes > READ_BUFFER_LEN)
549 nbytes = READ_BUFFER_LEN;
551 addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
553 if (current_event.u.DebugString.fUnicode)
555 /* The event tells us how many bytes, not chars, even
557 WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
558 if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
560 wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
564 if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
568 if (strncmp (s, "cYg", 3) != 0)
570 #undef READ_BUFFER_LEN
573 /* Kill all inferiors. */
577 win32_thread_info *current_thread;
579 if (current_process_handle == NULL)
582 TerminateProcess (current_process_handle, 0);
585 if (!child_continue (DBG_CONTINUE, -1))
587 if (!WaitForDebugEvent (¤t_event, INFINITE))
589 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
591 else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
593 struct target_waitstatus our_status = { 0 };
594 handle_output_debug_string (&our_status);
598 CloseHandle (current_process_handle);
600 current_thread = inferior_target_data (current_inferior);
601 if (current_thread && current_thread->h)
603 /* This may fail in an attached process, so don't check. */
604 (void) CloseHandle (current_thread->h);
608 /* Detach from all inferiors. */
614 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
615 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
617 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
619 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
621 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
622 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
624 if (DebugSetProcessKillOnExit == NULL
625 || DebugActiveProcessStop == NULL)
628 /* We need a new handle, since DebugActiveProcessStop
629 closes all the ones that came through the events. */
630 if ((h = OpenProcess (PROCESS_ALL_ACCESS,
632 current_process_id)) == NULL)
634 /* The process died. */
639 struct thread_resume resume;
643 resume.leave_stopped = 0;
644 win32_resume (&resume);
647 if (!DebugActiveProcessStop (current_process_id))
652 DebugSetProcessKillOnExit (FALSE);
654 current_process_handle = h;
658 /* Wait for inferiors to end. */
662 if (current_process_id == 0
663 || current_process_handle == NULL)
666 WaitForSingleObject (current_process_handle, INFINITE);
667 CloseHandle (current_process_handle);
669 current_process_handle = NULL;
670 current_process_id = 0;
673 /* Return 1 iff the thread with thread ID TID is alive. */
675 win32_thread_alive (unsigned long tid)
679 /* Our thread list is reliable; don't bother to poll target
681 if (find_inferior_id (&all_threads, tid) != NULL)
688 /* Resume the inferior process. RESUME_INFO describes how we want
691 win32_resume (struct thread_resume *resume_info)
694 enum target_signal sig;
696 win32_thread_info *th;
697 DWORD continue_status = DBG_CONTINUE;
699 /* This handles the very limited set of resume packets that GDB can
700 currently produce. */
702 if (resume_info[0].thread == -1)
704 else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
707 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
708 the Windows resume code do the right thing for thread switching. */
709 tid = current_event.dwThreadId;
711 if (resume_info[0].thread != -1)
713 sig = resume_info[0].sig;
714 step = resume_info[0].step;
722 if (sig != TARGET_SIGNAL_0)
724 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
726 OUTMSG (("Cannot continue with signal %d here.\n", sig));
728 else if (sig == last_sig)
729 continue_status = DBG_EXCEPTION_NOT_HANDLED;
731 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
734 last_sig = TARGET_SIGNAL_0;
736 /* Get context for the currently selected thread. */
737 th = thread_rec (current_event.dwThreadId, FALSE);
740 if (th->context.ContextFlags)
742 /* Move register values from the inferior into the thread
743 context structure. */
744 regcache_invalidate ();
748 if (the_low_target.single_step != NULL)
749 (*the_low_target.single_step) (th);
751 error ("Single stepping is not supported "
752 "in this configuration.\n");
755 (*the_low_target.set_thread_context) (th, ¤t_event);
756 th->context.ContextFlags = 0;
760 /* Allow continuing with the same signal that interrupted us.
761 Otherwise complain. */
763 child_continue (continue_status, tid);
767 handle_exception (struct target_waitstatus *ourstatus)
769 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
771 ourstatus->kind = TARGET_WAITKIND_STOPPED;
775 case EXCEPTION_ACCESS_VIOLATION:
776 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
777 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
779 case STATUS_STACK_OVERFLOW:
780 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
781 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
783 case STATUS_FLOAT_DENORMAL_OPERAND:
784 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
785 ourstatus->value.sig = TARGET_SIGNAL_FPE;
787 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
788 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
789 ourstatus->value.sig = TARGET_SIGNAL_FPE;
791 case STATUS_FLOAT_INEXACT_RESULT:
792 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
793 ourstatus->value.sig = TARGET_SIGNAL_FPE;
795 case STATUS_FLOAT_INVALID_OPERATION:
796 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
797 ourstatus->value.sig = TARGET_SIGNAL_FPE;
799 case STATUS_FLOAT_OVERFLOW:
800 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
801 ourstatus->value.sig = TARGET_SIGNAL_FPE;
803 case STATUS_FLOAT_STACK_CHECK:
804 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
805 ourstatus->value.sig = TARGET_SIGNAL_FPE;
807 case STATUS_FLOAT_UNDERFLOW:
808 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
809 ourstatus->value.sig = TARGET_SIGNAL_FPE;
811 case STATUS_FLOAT_DIVIDE_BY_ZERO:
812 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
813 ourstatus->value.sig = TARGET_SIGNAL_FPE;
815 case STATUS_INTEGER_DIVIDE_BY_ZERO:
816 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
817 ourstatus->value.sig = TARGET_SIGNAL_FPE;
819 case STATUS_INTEGER_OVERFLOW:
820 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
821 ourstatus->value.sig = TARGET_SIGNAL_FPE;
823 case EXCEPTION_BREAKPOINT:
824 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
825 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
827 /* Remove the initial breakpoint. */
828 check_breakpoints ((CORE_ADDR) (long) current_event
829 .u.Exception.ExceptionRecord.ExceptionAddress);
833 OUTMSG2 (("DBG_CONTROL_C"));
834 ourstatus->value.sig = TARGET_SIGNAL_INT;
836 case DBG_CONTROL_BREAK:
837 OUTMSG2 (("DBG_CONTROL_BREAK"));
838 ourstatus->value.sig = TARGET_SIGNAL_INT;
840 case EXCEPTION_SINGLE_STEP:
841 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
842 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
844 case EXCEPTION_ILLEGAL_INSTRUCTION:
845 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
846 ourstatus->value.sig = TARGET_SIGNAL_ILL;
848 case EXCEPTION_PRIV_INSTRUCTION:
849 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
850 ourstatus->value.sig = TARGET_SIGNAL_ILL;
852 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
853 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
854 ourstatus->value.sig = TARGET_SIGNAL_ILL;
857 if (current_event.u.Exception.dwFirstChance)
859 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
862 OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
863 current_event.u.Exception.ExceptionRecord.ExceptionCode,
864 (DWORD) current_event.u.Exception.ExceptionRecord.
866 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
870 last_sig = ourstatus->value.sig;
873 /* Get the next event from the child. */
875 get_child_debug_event (struct target_waitstatus *ourstatus)
879 last_sig = TARGET_SIGNAL_0;
880 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
882 if (!(debug_event = WaitForDebugEvent (¤t_event, 1000)))
886 (struct thread_info *) find_inferior_id (&all_threads,
887 current_event.dwThreadId);
889 switch (current_event.dwDebugEventCode)
891 case CREATE_THREAD_DEBUG_EVENT:
892 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
893 "for pid=%d tid=%x)\n",
894 (unsigned) current_event.dwProcessId,
895 (unsigned) current_event.dwThreadId));
897 /* Record the existence of this thread. */
898 child_add_thread (current_event.dwThreadId,
899 current_event.u.CreateThread.hThread);
902 case EXIT_THREAD_DEBUG_EVENT:
903 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
904 "for pid=%d tid=%x\n",
905 (unsigned) current_event.dwProcessId,
906 (unsigned) current_event.dwThreadId));
907 child_delete_thread (current_event.dwThreadId);
910 case CREATE_PROCESS_DEBUG_EVENT:
911 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
912 "for pid=%d tid=%x\n",
913 (unsigned) current_event.dwProcessId,
914 (unsigned) current_event.dwThreadId));
915 CloseHandle (current_event.u.CreateProcessInfo.hFile);
917 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
918 main_thread_id = current_event.dwThreadId;
920 ourstatus->kind = TARGET_WAITKIND_EXECD;
921 ourstatus->value.execd_pathname = "Main executable";
923 /* Add the main thread. */
924 child_add_thread (main_thread_id,
925 current_event.u.CreateProcessInfo.hThread);
927 ourstatus->value.related_pid = current_event.dwThreadId;
929 /* Windows CE doesn't set the initial breakpoint automatically
930 like the desktop versions of Windows do. We add it explicitly
931 here. It will be removed as soon as it is hit. */
932 set_breakpoint_at ((CORE_ADDR) (long) current_event.u
933 .CreateProcessInfo.lpStartAddress,
934 delete_breakpoint_at);
938 case EXIT_PROCESS_DEBUG_EVENT:
939 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
940 "for pid=%d tid=%x\n",
941 (unsigned) current_event.dwProcessId,
942 (unsigned) current_event.dwThreadId));
943 ourstatus->kind = TARGET_WAITKIND_EXITED;
944 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
945 CloseHandle (current_process_handle);
946 current_process_handle = NULL;
949 case LOAD_DLL_DEBUG_EVENT:
950 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
951 "for pid=%d tid=%x\n",
952 (unsigned) current_event.dwProcessId,
953 (unsigned) current_event.dwThreadId));
954 CloseHandle (current_event.u.LoadDll.hFile);
956 ourstatus->kind = TARGET_WAITKIND_LOADED;
957 ourstatus->value.integer = 0;
960 case UNLOAD_DLL_DEBUG_EVENT:
961 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
962 "for pid=%d tid=%x\n",
963 (unsigned) current_event.dwProcessId,
964 (unsigned) current_event.dwThreadId));
967 case EXCEPTION_DEBUG_EVENT:
968 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
969 "for pid=%d tid=%x\n",
970 (unsigned) current_event.dwProcessId,
971 (unsigned) current_event.dwThreadId));
972 handle_exception (ourstatus);
975 case OUTPUT_DEBUG_STRING_EVENT:
976 /* A message from the kernel (or Cygwin). */
977 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
978 "for pid=%d tid=%x\n",
979 (unsigned) current_event.dwProcessId,
980 (unsigned) current_event.dwThreadId));
981 handle_output_debug_string (ourstatus);
985 OUTMSG2 (("gdbserver: kernel event unknown "
986 "for pid=%d tid=%x code=%ld\n",
987 (unsigned) current_event.dwProcessId,
988 (unsigned) current_event.dwThreadId,
989 current_event.dwDebugEventCode));
994 (struct thread_info *) find_inferior_id (&all_threads,
995 current_event.dwThreadId);
998 /* Wait for the inferior process to change state.
999 STATUS will be filled in with a response code to send to GDB.
1000 Returns the signal which caused the process to stop. */
1001 static unsigned char
1002 win32_wait (char *status)
1004 struct target_waitstatus our_status;
1010 get_child_debug_event (&our_status);
1012 switch (our_status.kind)
1014 case TARGET_WAITKIND_EXITED:
1015 OUTMSG2 (("Child exited with retcode = %x\n",
1016 our_status.value.integer));
1020 child_fetch_inferior_registers (-1);
1022 return our_status.value.integer;
1023 case TARGET_WAITKIND_STOPPED:
1024 OUTMSG2 (("Child Stopped with signal = %d \n",
1025 our_status.value.sig));
1029 child_fetch_inferior_registers (-1);
1031 return our_status.value.sig;
1033 OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
1035 case TARGET_WAITKIND_SPURIOUS:
1036 case TARGET_WAITKIND_LOADED:
1037 case TARGET_WAITKIND_EXECD:
1038 /* do nothing, just continue */
1039 child_continue (DBG_CONTINUE, -1);
1045 /* Fetch registers from the inferior process.
1046 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1048 win32_fetch_inferior_registers (int regno)
1050 child_fetch_inferior_registers (regno);
1053 /* Store registers to the inferior process.
1054 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1056 win32_store_inferior_registers (int regno)
1058 child_store_inferior_registers (regno);
1061 /* Read memory from the inferior process. This should generally be
1062 called through read_inferior_memory, which handles breakpoint shadowing.
1063 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1065 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1067 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
1070 /* Write memory to the inferior process. This should generally be
1071 called through write_inferior_memory, which handles breakpoint shadowing.
1072 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1073 Returns 0 on success and errno on failure. */
1075 win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1078 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1082 win32_arch_string (void)
1084 return the_low_target.arch_string;
1087 static struct target_ops win32_target_ops = {
1088 win32_create_inferior,
1096 win32_fetch_inferior_registers,
1097 win32_store_inferior_registers,
1098 win32_read_inferior_memory,
1099 win32_write_inferior_memory,
1112 /* Initialize the Win32 backend. */
1114 initialize_low (void)
1116 set_target_ops (&win32_target_ops);
1117 if (the_low_target.breakpoint != NULL)
1118 set_breakpoint_data (the_low_target.breakpoint,
1119 the_low_target.breakpoint_len);