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]))
58 int using_threads
= 1;
61 static HANDLE current_process_handle
= NULL
;
62 static DWORD current_process_id
= 0;
63 static enum target_signal last_sig
= TARGET_SIGNAL_0
;
65 /* The current debug event from WaitForDebugEvent. */
66 static DEBUG_EVENT current_event
;
68 static int debug_registers_changed
= 0;
69 static int debug_registers_used
= 0;
71 #define NUM_REGS (the_low_target.num_regs)
73 typedef BOOL
winapi_DebugActiveProcessStop (DWORD dwProcessId
);
74 typedef BOOL
winapi_DebugSetProcessKillOnExit (BOOL KillOnExit
);
76 #ifndef CONTEXT_EXTENDED_REGISTERS
77 #define CONTEXT_EXTENDED_REGISTERS 0
80 #ifndef CONTEXT_FLOATING_POINT
81 #define CONTEXT_FLOATING_POINT 0
84 #ifndef CONTEXT_DEBUG_REGISTERS
85 #define CONTEXT_DEBUG_REGISTERS 0
88 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
89 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
90 | CONTEXT_EXTENDED_REGISTERS
92 static DWORD main_thread_id
= 0;
94 /* Get the thread ID from the current selected inferior (the current
97 current_inferior_tid (void)
99 win32_thread_info
*th
= inferior_target_data (current_inferior
);
103 /* Find a thread record given a thread id. If GET_CONTEXT is set then
104 also retrieve the context for this thread. */
105 static win32_thread_info
*
106 thread_rec (DWORD id
, int get_context
)
108 struct thread_info
*thread
;
109 win32_thread_info
*th
;
111 thread
= (struct thread_info
*) find_inferior_id (&all_threads
, id
);
115 th
= inferior_target_data (thread
);
116 if (!th
->suspend_count
&& get_context
)
118 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
119 th
->suspend_count
= SuspendThread (th
->h
) + 1;
120 else if (get_context
< 0)
121 th
->suspend_count
= -1;
123 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
125 GetThreadContext (th
->h
, &th
->context
);
127 if (id
== current_event
.dwThreadId
)
129 /* Copy dr values from that thread. */
130 if (the_low_target
.store_debug_registers
!= NULL
)
131 (*the_low_target
.store_debug_registers
) (th
);
138 /* Add a thread to the thread list. */
139 static win32_thread_info
*
140 child_add_thread (DWORD tid
, HANDLE h
)
142 win32_thread_info
*th
;
144 if ((th
= thread_rec (tid
, FALSE
)))
147 th
= (win32_thread_info
*) malloc (sizeof (*th
));
148 memset (th
, 0, sizeof (*th
));
152 add_thread (tid
, th
, (unsigned int) tid
);
153 set_inferior_regcache_data ((struct thread_info
*)
154 find_inferior_id (&all_threads
, tid
),
155 new_register_cache ());
157 /* Set the debug registers for the new thread if they are used. */
158 if (debug_registers_used
159 && the_low_target
.load_debug_registers
!= NULL
)
161 /* Only change the value of the debug registers. */
162 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
164 GetThreadContext (th
->h
, &th
->context
);
166 (*the_low_target
.load_debug_registers
) (th
);
168 SetThreadContext (th
->h
, &th
->context
);
169 th
->context
.ContextFlags
= 0;
175 /* Delete a thread from the list of threads. */
177 delete_thread_info (struct inferior_list_entry
*thread
)
179 win32_thread_info
*th
= inferior_target_data ((struct thread_info
*) thread
);
181 remove_thread ((struct thread_info
*) thread
);
186 /* Delete a thread from the list of threads. */
188 child_delete_thread (DWORD id
)
190 struct inferior_list_entry
*thread
;
192 /* If the last thread is exiting, just return. */
193 if (all_threads
.head
== all_threads
.tail
)
196 thread
= find_inferior_id (&all_threads
, id
);
200 delete_thread_info (thread
);
203 /* Transfer memory from/to the debugged process. */
205 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
206 int write
, struct target_ops
*target
)
209 long addr
= (long) memaddr
;
213 WriteProcessMemory (current_process_handle
, (LPVOID
) addr
,
214 (LPCVOID
) our
, len
, &done
);
215 FlushInstructionCache (current_process_handle
, (LPCVOID
) addr
, len
);
219 ReadProcessMemory (current_process_handle
, (LPCVOID
) addr
, (LPVOID
) our
,
225 /* Generally, what has the program done? */
228 /* The program has exited. The exit status is in value.integer. */
229 TARGET_WAITKIND_EXITED
,
231 /* The program has stopped with a signal. Which signal is in
233 TARGET_WAITKIND_STOPPED
,
235 /* The program is letting us know that it dynamically loaded something
236 (e.g. it called load(2) on AIX). */
237 TARGET_WAITKIND_LOADED
,
239 /* The program has exec'ed a new executable file. The new file's
240 pathname is pointed to by value.execd_pathname. */
242 TARGET_WAITKIND_EXECD
,
244 /* Nothing happened, but we stopped anyway. This perhaps should be handled
245 within target_wait, but I'm not sure target_wait should be resuming the
247 TARGET_WAITKIND_SPURIOUS
,
250 struct target_waitstatus
252 enum target_waitkind kind
;
254 /* Forked child pid, execd pathname, exit status or signal number. */
258 enum target_signal sig
;
260 char *execd_pathname
;
266 /* Return a pointer into a CONTEXT field indexed by gdb register number.
267 Return a pointer to an dummy register holding zero if there is no
268 corresponding CONTEXT field for the given register number. */
270 regptr (CONTEXT
* c
, int r
)
272 if (the_low_target
.regmap
[r
] < 0)
275 /* Always force value to zero, in case the user tried to write
276 to this register before. */
278 return (char *) &zero
;
281 return (char *) c
+ the_low_target
.regmap
[r
];
285 /* Clear out any old thread list and reinitialize it to a pristine
288 child_init_thread_list (void)
290 for_each_inferior (&all_threads
, delete_thread_info
);
294 do_initial_child_stuff (DWORD pid
)
296 last_sig
= TARGET_SIGNAL_0
;
298 debug_registers_changed
= 0;
299 debug_registers_used
= 0;
301 memset (¤t_event
, 0, sizeof (current_event
));
303 child_init_thread_list ();
305 if (the_low_target
.initial_stuff
!= NULL
)
306 (*the_low_target
.initial_stuff
) ();
309 /* Resume all artificially suspended threads if we are continuing
312 continue_one_thread (struct inferior_list_entry
*this_thread
, void *id_ptr
)
314 struct thread_info
*thread
= (struct thread_info
*) this_thread
;
315 int thread_id
= * (int *) id_ptr
;
316 win32_thread_info
*th
= inferior_target_data (thread
);
319 if ((thread_id
== -1 || thread_id
== th
->tid
)
320 && th
->suspend_count
)
322 for (i
= 0; i
< th
->suspend_count
; i
++)
323 (void) ResumeThread (th
->h
);
324 th
->suspend_count
= 0;
325 if (debug_registers_changed
)
327 /* Only change the value of the debug registers. */
328 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
330 if (the_low_target
.load_debug_registers
!= NULL
)
331 the_low_target
.load_debug_registers (th
);
333 SetThreadContext (th
->h
, &th
->context
);
334 th
->context
.ContextFlags
= 0;
342 child_continue (DWORD continue_status
, int thread_id
)
346 res
= ContinueDebugEvent (current_event
.dwProcessId
,
347 current_event
.dwThreadId
, continue_status
);
350 find_inferior (&all_threads
, continue_one_thread
, &thread_id
);
352 debug_registers_changed
= 0;
356 /* Fetch register(s) from the current thread context. */
358 child_fetch_inferior_registers (int r
)
361 win32_thread_info
*th
= thread_rec (current_inferior_tid (), TRUE
);
362 if (r
== -1 || r
== 0 || r
> NUM_REGS
)
363 child_fetch_inferior_registers (NUM_REGS
);
365 for (regno
= 0; regno
< r
; regno
++)
366 (*the_low_target
.fetch_inferior_registers
) (th
, regno
);
369 /* Get register from gdbserver regcache data. */
371 do_child_store_inferior_registers (win32_thread_info
*th
, int r
)
373 collect_register (r
, regptr (&th
->context
, r
));
376 /* Store a new register value into the current thread context. We don't
377 change the program's context until later, when we resume it. */
379 child_store_inferior_registers (int r
)
382 win32_thread_info
*th
= thread_rec (current_inferior_tid (), TRUE
);
383 if (r
== -1 || r
== 0 || r
> NUM_REGS
)
384 child_store_inferior_registers (NUM_REGS
);
386 for (regno
= 0; regno
< r
; regno
++)
387 do_child_store_inferior_registers (th
, regno
);
390 /* Map the Windows error number in ERROR to a locale-dependent error
391 message string and return a pointer to it. Typically, the values
392 for ERROR come from GetLastError.
394 The string pointed to shall not be modified by the application,
395 but may be overwritten by a subsequent call to strwinerror
397 The strwinerror function does not change the current setting
401 strwinerror (DWORD error
)
403 static char buf
[1024];
405 DWORD lasterr
= GetLastError ();
406 DWORD chars
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
407 | FORMAT_MESSAGE_ALLOCATE_BUFFER
,
410 0, /* Default language */
416 /* If there is an \r\n appended, zap it. */
418 && msgbuf
[chars
- 2] == '\r'
419 && msgbuf
[chars
- 1] == '\n')
425 if (chars
> ((COUNTOF (buf
)) - 1))
427 chars
= COUNTOF (buf
) - 1;
432 wcstombs (buf
, msgbuf
, chars
+ 1);
434 strncpy (buf
, msgbuf
, chars
+ 1);
439 sprintf (buf
, "unknown win32 error (%ld)", error
);
441 SetLastError (lasterr
);
445 /* Start a new process.
446 PROGRAM is a path to the program to execute.
447 ARGS is a standard NULL-terminated array of arguments,
448 to be passed to the inferior as ``argv''.
449 Returns the new PID on success, -1 on failure. Registers the new
450 process with the process list. */
452 win32_create_inferior (char *program
, char **program_args
)
455 char real_path
[MAXPATHLEN
];
456 char *orig_path
, *new_path
, *path_ptr
;
463 PROCESS_INFORMATION pi
;
464 #ifndef __MINGW32CE__
465 STARTUPINFO si
= { sizeof (STARTUPINFO
) };
468 wchar_t *wargs
, *wprogram
;
472 error ("No executable specified, specify executable to debug.\n");
474 flags
= DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
;
478 path_ptr
= getenv ("PATH");
481 orig_path
= alloca (strlen (path_ptr
) + 1);
482 new_path
= alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr
));
483 strcpy (orig_path
, path_ptr
);
484 cygwin_posix_to_win32_path_list (path_ptr
, new_path
);
485 setenv ("PATH", new_path
, 1);
487 cygwin_conv_to_win32_path (program
, real_path
);
492 for (argc
= 1; program_args
[argc
]; argc
++)
493 argslen
+= strlen (program_args
[argc
]) + 1;
494 args
= alloca (argslen
);
496 for (argc
= 1; program_args
[argc
]; argc
++)
498 /* FIXME: Can we do better about quoting? How does Cygwin
501 strcat (args
, program_args
[argc
]);
503 OUTMSG2 (("Command line is \"%s\"\n", args
));
505 #ifdef CREATE_NEW_PROCESS_GROUP
506 flags
|= CREATE_NEW_PROCESS_GROUP
;
510 to_back_slashes (program
);
511 wargs
= alloca (argslen
* sizeof (wchar_t));
512 mbstowcs (wargs
, args
, argslen
);
513 wprogram
= alloca ((strlen (program
) + 1) * sizeof (wchar_t));
514 mbstowcs (wprogram
, program
, strlen (program
) + 1);
515 ret
= CreateProcessW (wprogram
, /* image name */
516 wargs
, /* command line */
517 NULL
, /* security, not supported */
518 NULL
, /* thread, not supported */
519 FALSE
, /* inherit handles, not supported */
520 flags
, /* start flags */
521 NULL
, /* environment, not supported */
522 NULL
, /* current directory, not supported */
523 NULL
, /* start info, not supported */
524 &pi
); /* proc info */
526 ret
= CreateProcess (program
, /* image name */
527 args
, /* command line */
530 TRUE
, /* inherit handles */
531 flags
, /* start flags */
532 winenv
, /* environment */
533 NULL
, /* current directory */
534 &si
, /* start info */
535 &pi
); /* proc info */
540 setenv ("PATH", orig_path
, 1);
545 DWORD err
= GetLastError ();
546 error ("Error creating process \"%s%s\", (error %d): %s\n",
547 program
, args
, (int) err
, strwinerror (err
));
551 OUTMSG2 (("Process created: %s\n", (char *) args
));
555 /* On Windows CE this handle can't be closed. The OS reuses
556 it in the debug events, while the 9x/NT versions of Windows
557 probably use a DuplicateHandle'd one. */
558 CloseHandle (pi
.hThread
);
561 current_process_handle
= pi
.hProcess
;
562 current_process_id
= pi
.dwProcessId
;
564 do_initial_child_stuff (current_process_id
);
566 return current_process_id
;
569 /* Attach to a running process.
570 PID is the process ID to attach to, specified by the user
571 or a higher layer. */
573 win32_attach (unsigned long pid
)
576 winapi_DebugActiveProcessStop
*DebugActiveProcessStop
= NULL
;
578 winapi_DebugSetProcessKillOnExit
*DebugSetProcessKillOnExit
= NULL
;
580 HMODULE dll
= GetModuleHandle (_T("COREDLL.DLL"));
582 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
584 DebugActiveProcessStop
= (winapi_DebugActiveProcessStop
*)
585 GetProcAddress (dll
, _T("DebugActiveProcessStop"));
586 DebugSetProcessKillOnExit
= (winapi_DebugSetProcessKillOnExit
*)
587 GetProcAddress (dll
, _T("DebugSetProcessKillOnExit"));
589 res
= DebugActiveProcess (pid
) ? 1 : 0;
592 error ("Attach to process failed.");
594 if (DebugSetProcessKillOnExit
!= NULL
)
595 DebugSetProcessKillOnExit (FALSE
);
597 current_process_id
= pid
;
598 current_process_handle
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
, pid
);
600 if (current_process_handle
== NULL
)
603 if (DebugActiveProcessStop
!= NULL
)
604 DebugActiveProcessStop (current_process_id
);
608 do_initial_child_stuff (pid
);
613 /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
615 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
617 #define READ_BUFFER_LEN 1024
619 char s
[READ_BUFFER_LEN
+ 1] = { 0 };
620 DWORD nbytes
= current_event
.u
.DebugString
.nDebugStringLength
;
625 if (nbytes
> READ_BUFFER_LEN
)
626 nbytes
= READ_BUFFER_LEN
;
628 addr
= (CORE_ADDR
) (size_t) current_event
.u
.DebugString
.lpDebugStringData
;
630 if (current_event
.u
.DebugString
.fUnicode
)
632 /* The event tells us how many bytes, not chars, even
634 WCHAR buffer
[(READ_BUFFER_LEN
+ 1) / sizeof (WCHAR
)] = { 0 };
635 if (read_inferior_memory (addr
, (unsigned char *) buffer
, nbytes
) != 0)
637 wcstombs (s
, buffer
, (nbytes
+ 1) / sizeof (WCHAR
));
641 if (read_inferior_memory (addr
, (unsigned char *) s
, nbytes
) != 0)
645 if (strncmp (s
, "cYg", 3) != 0)
647 #undef READ_BUFFER_LEN
650 /* Kill all inferiors. */
654 win32_thread_info
*current_thread
;
656 if (current_process_handle
== NULL
)
659 TerminateProcess (current_process_handle
, 0);
662 if (!child_continue (DBG_CONTINUE
, -1))
664 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
666 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
668 else if (current_event
.dwDebugEventCode
== OUTPUT_DEBUG_STRING_EVENT
)
670 struct target_waitstatus our_status
= { 0 };
671 handle_output_debug_string (&our_status
);
675 CloseHandle (current_process_handle
);
677 current_thread
= inferior_target_data (current_inferior
);
678 if (current_thread
&& current_thread
->h
)
680 /* This may fail in an attached process, so don't check. */
681 (void) CloseHandle (current_thread
->h
);
685 /* Detach from all inferiors. */
689 winapi_DebugActiveProcessStop
*DebugActiveProcessStop
= NULL
;
690 winapi_DebugSetProcessKillOnExit
*DebugSetProcessKillOnExit
= NULL
;
692 HMODULE dll
= GetModuleHandle (_T("COREDLL.DLL"));
694 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
696 DebugActiveProcessStop
= (winapi_DebugActiveProcessStop
*)
697 GetProcAddress (dll
, _T("DebugActiveProcessStop"));
698 DebugSetProcessKillOnExit
= (winapi_DebugSetProcessKillOnExit
*)
699 GetProcAddress (dll
, _T("DebugSetProcessKillOnExit"));
701 if (DebugSetProcessKillOnExit
!= NULL
)
702 DebugSetProcessKillOnExit (FALSE
);
704 if (DebugActiveProcessStop
!= NULL
)
705 DebugActiveProcessStop (current_process_id
);
710 /* Return 1 iff the thread with thread ID TID is alive. */
712 win32_thread_alive (unsigned long tid
)
716 /* Our thread list is reliable; don't bother to poll target
718 if (find_inferior_id (&all_threads
, tid
) != NULL
)
725 /* Resume the inferior process. RESUME_INFO describes how we want
728 win32_resume (struct thread_resume
*resume_info
)
731 enum target_signal sig
;
733 win32_thread_info
*th
;
734 DWORD continue_status
= DBG_CONTINUE
;
736 /* This handles the very limited set of resume packets that GDB can
737 currently produce. */
739 if (resume_info
[0].thread
== -1)
741 else if (resume_info
[1].thread
== -1 && !resume_info
[1].leave_stopped
)
744 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
745 the Windows resume code do the right thing for thread switching. */
746 tid
= current_event
.dwThreadId
;
748 if (resume_info
[0].thread
!= -1)
750 sig
= resume_info
[0].sig
;
751 step
= resume_info
[0].step
;
759 if (sig
!= TARGET_SIGNAL_0
)
761 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
763 OUTMSG (("Cannot continue with signal %d here.\n", sig
));
765 else if (sig
== last_sig
)
766 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
768 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig
));
771 last_sig
= TARGET_SIGNAL_0
;
773 /* Get context for the currently selected thread. */
774 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
777 if (th
->context
.ContextFlags
)
779 if (debug_registers_changed
)
780 if (the_low_target
.load_debug_registers
!= NULL
)
781 (*the_low_target
.load_debug_registers
) (th
);
783 /* Move register values from the inferior into the thread
784 context structure. */
785 regcache_invalidate ();
789 if (the_low_target
.single_step
!= NULL
)
790 (*the_low_target
.single_step
) (th
);
792 error ("Single stepping is not supported "
793 "in this configuration.\n");
795 SetThreadContext (th
->h
, &th
->context
);
796 th
->context
.ContextFlags
= 0;
800 /* Allow continuing with the same signal that interrupted us.
801 Otherwise complain. */
803 child_continue (continue_status
, tid
);
807 handle_exception (struct target_waitstatus
*ourstatus
)
809 win32_thread_info
*th
;
810 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
812 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
814 /* Record the context of the current thread. */
815 th
= thread_rec (current_event
.dwThreadId
, -1);
819 case EXCEPTION_ACCESS_VIOLATION
:
820 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
821 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
823 case STATUS_STACK_OVERFLOW
:
824 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
825 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
827 case STATUS_FLOAT_DENORMAL_OPERAND
:
828 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
829 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
831 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
832 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
833 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
835 case STATUS_FLOAT_INEXACT_RESULT
:
836 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
837 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
839 case STATUS_FLOAT_INVALID_OPERATION
:
840 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
841 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
843 case STATUS_FLOAT_OVERFLOW
:
844 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
845 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
847 case STATUS_FLOAT_STACK_CHECK
:
848 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
849 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
851 case STATUS_FLOAT_UNDERFLOW
:
852 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
853 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
855 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
856 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
857 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
859 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
860 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
861 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
863 case STATUS_INTEGER_OVERFLOW
:
864 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
865 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
867 case EXCEPTION_BREAKPOINT
:
868 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
869 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
871 /* Remove the initial breakpoint. */
872 check_breakpoints ((CORE_ADDR
) (long) current_event
873 .u
.Exception
.ExceptionRecord
.ExceptionAddress
);
877 OUTMSG2 (("DBG_CONTROL_C"));
878 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
880 case DBG_CONTROL_BREAK
:
881 OUTMSG2 (("DBG_CONTROL_BREAK"));
882 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
884 case EXCEPTION_SINGLE_STEP
:
885 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
886 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
888 case EXCEPTION_ILLEGAL_INSTRUCTION
:
889 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
890 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
892 case EXCEPTION_PRIV_INSTRUCTION
:
893 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
894 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
896 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
897 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
898 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
901 if (current_event
.u
.Exception
.dwFirstChance
)
903 OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
904 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
905 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.
907 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
911 last_sig
= ourstatus
->value
.sig
;
915 /* Get the next event from the child. Return 1 if the event requires
918 get_child_debug_event (struct target_waitstatus
*ourstatus
)
921 DWORD continue_status
, event_code
;
922 win32_thread_info
*th
= NULL
;
923 static win32_thread_info dummy_thread_info
;
928 last_sig
= TARGET_SIGNAL_0
;
929 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
931 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
935 (struct thread_info
*) find_inferior_id (&all_threads
,
936 current_event
.dwThreadId
);
938 continue_status
= DBG_CONTINUE
;
939 event_code
= current_event
.dwDebugEventCode
;
943 case CREATE_THREAD_DEBUG_EVENT
:
944 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
945 "for pid=%d tid=%x)\n",
946 (unsigned) current_event
.dwProcessId
,
947 (unsigned) current_event
.dwThreadId
));
949 /* Record the existence of this thread. */
950 th
= child_add_thread (current_event
.dwThreadId
,
951 current_event
.u
.CreateThread
.hThread
);
953 retval
= current_event
.dwThreadId
;
956 case EXIT_THREAD_DEBUG_EVENT
:
957 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
958 "for pid=%d tid=%x\n",
959 (unsigned) current_event
.dwProcessId
,
960 (unsigned) current_event
.dwThreadId
));
961 child_delete_thread (current_event
.dwThreadId
);
962 th
= &dummy_thread_info
;
965 case CREATE_PROCESS_DEBUG_EVENT
:
966 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
967 "for pid=%d tid=%x\n",
968 (unsigned) current_event
.dwProcessId
,
969 (unsigned) current_event
.dwThreadId
));
970 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
972 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
973 main_thread_id
= current_event
.dwThreadId
;
975 ourstatus
->kind
= TARGET_WAITKIND_EXECD
;
976 ourstatus
->value
.execd_pathname
= "Main executable";
978 /* Add the main thread. */
980 child_add_thread (main_thread_id
,
981 current_event
.u
.CreateProcessInfo
.hThread
);
983 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
985 /* Windows CE doesn't set the initial breakpoint automatically
986 like the desktop versions of Windows do. We add it explicitly
987 here. It will be removed as soon as it is hit. */
988 set_breakpoint_at ((CORE_ADDR
) (long) current_event
.u
989 .CreateProcessInfo
.lpStartAddress
,
990 delete_breakpoint_at
);
994 case EXIT_PROCESS_DEBUG_EVENT
:
995 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
996 "for pid=%d tid=%x\n",
997 (unsigned) current_event
.dwProcessId
,
998 (unsigned) current_event
.dwThreadId
));
999 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1000 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1001 CloseHandle (current_process_handle
);
1002 current_process_handle
= NULL
;
1003 retval
= main_thread_id
;
1006 case LOAD_DLL_DEBUG_EVENT
:
1007 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1008 "for pid=%d tid=%x\n",
1009 (unsigned) current_event
.dwProcessId
,
1010 (unsigned) current_event
.dwThreadId
));
1011 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1013 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1014 ourstatus
->value
.integer
= 0;
1015 retval
= main_thread_id
;
1018 case UNLOAD_DLL_DEBUG_EVENT
:
1019 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1020 "for pid=%d tid=%x\n",
1021 (unsigned) current_event
.dwProcessId
,
1022 (unsigned) current_event
.dwThreadId
));
1025 case EXCEPTION_DEBUG_EVENT
:
1026 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1027 "for pid=%d tid=%x\n",
1028 (unsigned) current_event
.dwProcessId
,
1029 (unsigned) current_event
.dwThreadId
));
1030 retval
= handle_exception (ourstatus
);
1033 case OUTPUT_DEBUG_STRING_EVENT
:
1034 /* A message from the kernel (or Cygwin). */
1035 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1036 "for pid=%d tid=%x\n",
1037 (unsigned) current_event
.dwProcessId
,
1038 (unsigned) current_event
.dwThreadId
));
1039 handle_output_debug_string (ourstatus
);
1043 OUTMSG2 (("gdbserver: kernel event unknown "
1044 "for pid=%d tid=%x code=%ld\n",
1045 (unsigned) current_event
.dwProcessId
,
1046 (unsigned) current_event
.dwThreadId
,
1047 current_event
.dwDebugEventCode
));
1052 (struct thread_info
*) find_inferior_id (&all_threads
,
1053 current_event
.dwThreadId
);
1055 if (!retval
|| (event_code
!= EXCEPTION_DEBUG_EVENT
&& event_code
!= EXIT_PROCESS_DEBUG_EVENT
))
1057 child_continue (continue_status
, -1);
1062 thread_rec (current_event
.dwThreadId
, TRUE
);
1068 /* Wait for the inferior process to change state.
1069 STATUS will be filled in with a response code to send to GDB.
1070 Returns the signal which caused the process to stop. */
1071 static unsigned char
1072 win32_wait (char *status
)
1074 struct target_waitstatus our_status
;
1080 get_child_debug_event (&our_status
);
1082 if (our_status
.kind
== TARGET_WAITKIND_EXITED
)
1084 OUTMSG2 (("Child exited with retcode = %x\n",
1085 our_status
.value
.integer
));
1089 child_fetch_inferior_registers (-1);
1091 return our_status
.value
.integer
;
1093 else if (our_status
.kind
== TARGET_WAITKIND_STOPPED
)
1095 #ifndef __MINGW32CE__
1096 OUTMSG2 (("Child Stopped with signal = %x \n",
1097 WSTOPSIG (our_status
.value
.sig
)));
1099 OUTMSG2 (("Child Stopped with signal = %x \n",
1100 our_status
.value
.sig
));
1105 child_fetch_inferior_registers (-1);
1107 return our_status
.value
.sig
;
1110 OUTMSG (("Ignoring unknown internal event, %d\n", our_status
.kind
));
1113 struct thread_resume resume
;
1117 resume
.leave_stopped
= 0;
1118 win32_resume (&resume
);
1123 /* Fetch registers from the inferior process.
1124 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1126 win32_fetch_inferior_registers (int regno
)
1128 child_fetch_inferior_registers (regno
);
1131 /* Store registers to the inferior process.
1132 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1134 win32_store_inferior_registers (int regno
)
1136 child_store_inferior_registers (regno
);
1139 /* Read memory from the inferior process. This should generally be
1140 called through read_inferior_memory, which handles breakpoint shadowing.
1141 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1143 win32_read_inferior_memory (CORE_ADDR memaddr
, unsigned char *myaddr
, int len
)
1145 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 0, 0) != len
;
1148 /* Write memory to the inferior process. This should generally be
1149 called through write_inferior_memory, which handles breakpoint shadowing.
1150 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1151 Returns 0 on success and errno on failure. */
1153 win32_write_inferior_memory (CORE_ADDR memaddr
, const unsigned char *myaddr
,
1156 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 1, 0) != len
;
1160 win32_arch_string (void)
1162 return the_low_target
.arch_string
;
1165 static struct target_ops win32_target_ops
= {
1166 win32_create_inferior
,
1173 win32_fetch_inferior_registers
,
1174 win32_store_inferior_registers
,
1175 win32_read_inferior_memory
,
1176 win32_write_inferior_memory
,
1189 /* Initialize the Win32 backend. */
1191 initialize_low (void)
1193 set_target_ops (&win32_target_ops
);
1194 if (the_low_target
.breakpoint
!= NULL
)
1195 set_breakpoint_data (the_low_target
.breakpoint
,
1196 the_low_target
.breakpoint_len
);