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 static int debug_registers_changed
= 0;
77 static int debug_registers_used
= 0;
79 #define NUM_REGS (the_low_target.num_regs)
81 typedef BOOL
WINAPI (*winapi_DebugActiveProcessStop
) (DWORD dwProcessId
);
82 typedef BOOL
WINAPI (*winapi_DebugSetProcessKillOnExit
) (BOOL KillOnExit
);
84 #ifndef CONTEXT_EXTENDED_REGISTERS
85 #define CONTEXT_EXTENDED_REGISTERS 0
88 #ifndef CONTEXT_FLOATING_POINT
89 #define CONTEXT_FLOATING_POINT 0
92 #ifndef CONTEXT_DEBUG_REGISTERS
93 #define CONTEXT_DEBUG_REGISTERS 0
96 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
97 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
98 | CONTEXT_EXTENDED_REGISTERS
100 static DWORD main_thread_id
= 0;
102 /* Get the thread ID from the current selected inferior (the current
105 current_inferior_tid (void)
107 win32_thread_info
*th
= inferior_target_data (current_inferior
);
111 /* Find a thread record given a thread id. If GET_CONTEXT is set then
112 also retrieve the context for this thread. */
113 static win32_thread_info
*
114 thread_rec (DWORD id
, int get_context
)
116 struct thread_info
*thread
;
117 win32_thread_info
*th
;
119 thread
= (struct thread_info
*) find_inferior_id (&all_threads
, id
);
123 th
= inferior_target_data (thread
);
124 if (!th
->suspend_count
&& get_context
)
126 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
127 th
->suspend_count
= SuspendThread (th
->h
) + 1;
128 else if (get_context
< 0)
129 th
->suspend_count
= -1;
131 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
133 GetThreadContext (th
->h
, &th
->context
);
135 if (id
== current_event
.dwThreadId
)
137 /* Copy dr values from that thread. */
138 if (the_low_target
.store_debug_registers
!= NULL
)
139 (*the_low_target
.store_debug_registers
) (th
);
146 /* Add a thread to the thread list. */
147 static win32_thread_info
*
148 child_add_thread (DWORD tid
, HANDLE h
)
150 win32_thread_info
*th
;
152 if ((th
= thread_rec (tid
, FALSE
)))
155 th
= (win32_thread_info
*) malloc (sizeof (*th
));
156 memset (th
, 0, sizeof (*th
));
160 add_thread (tid
, th
, (unsigned int) tid
);
161 set_inferior_regcache_data ((struct thread_info
*)
162 find_inferior_id (&all_threads
, tid
),
163 new_register_cache ());
165 /* Set the debug registers for the new thread if they are used. */
166 if (debug_registers_used
167 && the_low_target
.load_debug_registers
!= NULL
)
169 /* Only change the value of the debug registers. */
170 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
172 GetThreadContext (th
->h
, &th
->context
);
174 (*the_low_target
.load_debug_registers
) (th
);
176 SetThreadContext (th
->h
, &th
->context
);
177 th
->context
.ContextFlags
= 0;
183 /* Delete a thread from the list of threads. */
185 delete_thread_info (struct inferior_list_entry
*thread
)
187 win32_thread_info
*th
= inferior_target_data ((struct thread_info
*) thread
);
189 remove_thread ((struct thread_info
*) thread
);
194 /* Delete a thread from the list of threads. */
196 child_delete_thread (DWORD id
)
198 struct inferior_list_entry
*thread
;
200 /* If the last thread is exiting, just return. */
201 if (all_threads
.head
== all_threads
.tail
)
204 thread
= find_inferior_id (&all_threads
, id
);
208 delete_thread_info (thread
);
211 /* Transfer memory from/to the debugged process. */
213 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
214 int write
, struct target_ops
*target
)
217 long addr
= (long) memaddr
;
221 WriteProcessMemory (current_process_handle
, (LPVOID
) addr
,
222 (LPCVOID
) our
, len
, &done
);
223 FlushInstructionCache (current_process_handle
, (LPCVOID
) addr
, len
);
227 ReadProcessMemory (current_process_handle
, (LPCVOID
) addr
, (LPVOID
) our
,
233 /* Generally, what has the program done? */
236 /* The program has exited. The exit status is in value.integer. */
237 TARGET_WAITKIND_EXITED
,
239 /* The program has stopped with a signal. Which signal is in
241 TARGET_WAITKIND_STOPPED
,
243 /* The program is letting us know that it dynamically loaded something
244 (e.g. it called load(2) on AIX). */
245 TARGET_WAITKIND_LOADED
,
247 /* The program has exec'ed a new executable file. The new file's
248 pathname is pointed to by value.execd_pathname. */
250 TARGET_WAITKIND_EXECD
,
252 /* Nothing happened, but we stopped anyway. This perhaps should be handled
253 within target_wait, but I'm not sure target_wait should be resuming the
255 TARGET_WAITKIND_SPURIOUS
,
258 struct target_waitstatus
260 enum target_waitkind kind
;
262 /* Forked child pid, execd pathname, exit status or signal number. */
266 enum target_signal sig
;
268 char *execd_pathname
;
274 /* Return a pointer into a CONTEXT field indexed by gdb register number.
275 Return a pointer to an dummy register holding zero if there is no
276 corresponding CONTEXT field for the given register number. */
278 regptr (CONTEXT
* c
, int r
)
280 if (the_low_target
.regmap
[r
] < 0)
283 /* Always force value to zero, in case the user tried to write
284 to this register before. */
286 return (char *) &zero
;
289 return (char *) c
+ the_low_target
.regmap
[r
];
293 /* Clear out any old thread list and reinitialize it to a pristine
296 child_init_thread_list (void)
298 for_each_inferior (&all_threads
, delete_thread_info
);
302 do_initial_child_stuff (DWORD pid
)
304 last_sig
= TARGET_SIGNAL_0
;
306 debug_registers_changed
= 0;
307 debug_registers_used
= 0;
309 memset (¤t_event
, 0, sizeof (current_event
));
311 child_init_thread_list ();
313 if (the_low_target
.initial_stuff
!= NULL
)
314 (*the_low_target
.initial_stuff
) ();
317 /* Resume all artificially suspended threads if we are continuing
320 continue_one_thread (struct inferior_list_entry
*this_thread
, void *id_ptr
)
322 struct thread_info
*thread
= (struct thread_info
*) this_thread
;
323 int thread_id
= * (int *) id_ptr
;
324 win32_thread_info
*th
= inferior_target_data (thread
);
327 if ((thread_id
== -1 || thread_id
== th
->tid
)
328 && th
->suspend_count
)
330 for (i
= 0; i
< th
->suspend_count
; i
++)
331 (void) ResumeThread (th
->h
);
332 th
->suspend_count
= 0;
333 if (debug_registers_changed
)
335 /* Only change the value of the debug registers. */
336 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
338 if (the_low_target
.load_debug_registers
!= NULL
)
339 the_low_target
.load_debug_registers (th
);
341 SetThreadContext (th
->h
, &th
->context
);
342 th
->context
.ContextFlags
= 0;
350 child_continue (DWORD continue_status
, int thread_id
)
354 res
= ContinueDebugEvent (current_event
.dwProcessId
,
355 current_event
.dwThreadId
, continue_status
);
358 find_inferior (&all_threads
, continue_one_thread
, &thread_id
);
360 debug_registers_changed
= 0;
364 /* Fetch register(s) from the current thread context. */
366 child_fetch_inferior_registers (int r
)
369 win32_thread_info
*th
= thread_rec (current_inferior_tid (), TRUE
);
370 if (r
== -1 || r
== 0 || r
> NUM_REGS
)
371 child_fetch_inferior_registers (NUM_REGS
);
373 for (regno
= 0; regno
< r
; regno
++)
374 (*the_low_target
.fetch_inferior_registers
) (th
, regno
);
377 /* Get register from gdbserver regcache data. */
379 do_child_store_inferior_registers (win32_thread_info
*th
, int r
)
381 collect_register (r
, regptr (&th
->context
, r
));
384 /* Store a new register value into the current thread context. We don't
385 change the program's context until later, when we resume it. */
387 child_store_inferior_registers (int r
)
390 win32_thread_info
*th
= thread_rec (current_inferior_tid (), TRUE
);
391 if (r
== -1 || r
== 0 || r
> NUM_REGS
)
392 child_store_inferior_registers (NUM_REGS
);
394 for (regno
= 0; regno
< r
; regno
++)
395 do_child_store_inferior_registers (th
, regno
);
398 /* Map the Windows error number in ERROR to a locale-dependent error
399 message string and return a pointer to it. Typically, the values
400 for ERROR come from GetLastError.
402 The string pointed to shall not be modified by the application,
403 but may be overwritten by a subsequent call to strwinerror
405 The strwinerror function does not change the current setting
409 strwinerror (DWORD error
)
411 static char buf
[1024];
413 DWORD lasterr
= GetLastError ();
414 DWORD chars
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
415 | FORMAT_MESSAGE_ALLOCATE_BUFFER
,
418 0, /* Default language */
424 /* If there is an \r\n appended, zap it. */
426 && msgbuf
[chars
- 2] == '\r'
427 && msgbuf
[chars
- 1] == '\n')
433 if (chars
> ((COUNTOF (buf
)) - 1))
435 chars
= COUNTOF (buf
) - 1;
440 wcstombs (buf
, msgbuf
, chars
+ 1);
442 strncpy (buf
, msgbuf
, chars
+ 1);
447 sprintf (buf
, "unknown win32 error (%ld)", error
);
449 SetLastError (lasterr
);
453 /* Start a new process.
454 PROGRAM is a path to the program to execute.
455 ARGS is a standard NULL-terminated array of arguments,
456 to be passed to the inferior as ``argv''.
457 Returns the new PID on success, -1 on failure. Registers the new
458 process with the process list. */
460 win32_create_inferior (char *program
, char **program_args
)
463 char real_path
[MAXPATHLEN
];
464 char *orig_path
, *new_path
, *path_ptr
;
471 PROCESS_INFORMATION pi
;
472 #ifndef __MINGW32CE__
473 STARTUPINFOA si
= { sizeof (STARTUPINFOA
) };
476 wchar_t *wargs
, *wprogram
;
480 error ("No executable specified, specify executable to debug.\n");
482 flags
= DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
;
486 path_ptr
= getenv ("PATH");
489 orig_path
= alloca (strlen (path_ptr
) + 1);
490 new_path
= alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr
));
491 strcpy (orig_path
, path_ptr
);
492 cygwin_posix_to_win32_path_list (path_ptr
, new_path
);
493 setenv ("PATH", new_path
, 1);
495 cygwin_conv_to_win32_path (program
, real_path
);
500 for (argc
= 1; program_args
[argc
]; argc
++)
501 argslen
+= strlen (program_args
[argc
]) + 1;
502 args
= alloca (argslen
);
504 for (argc
= 1; program_args
[argc
]; argc
++)
506 /* FIXME: Can we do better about quoting? How does Cygwin
509 strcat (args
, program_args
[argc
]);
511 OUTMSG2 (("Command line is \"%s\"\n", args
));
513 #ifdef CREATE_NEW_PROCESS_GROUP
514 flags
|= CREATE_NEW_PROCESS_GROUP
;
518 to_back_slashes (program
);
519 wargs
= alloca (argslen
* sizeof (wchar_t));
520 mbstowcs (wargs
, args
, argslen
);
521 wprogram
= alloca ((strlen (program
) + 1) * sizeof (wchar_t));
522 mbstowcs (wprogram
, program
, strlen (program
) + 1);
523 ret
= CreateProcessW (wprogram
, /* image name */
524 wargs
, /* command line */
525 NULL
, /* security, not supported */
526 NULL
, /* thread, not supported */
527 FALSE
, /* inherit handles, not supported */
528 flags
, /* start flags */
529 NULL
, /* environment, not supported */
530 NULL
, /* current directory, not supported */
531 NULL
, /* start info, not supported */
532 &pi
); /* proc info */
534 ret
= CreateProcessA (program
, /* image name */
535 args
, /* command line */
538 TRUE
, /* inherit handles */
539 flags
, /* start flags */
540 winenv
, /* environment */
541 NULL
, /* current directory */
542 &si
, /* start info */
543 &pi
); /* proc info */
548 setenv ("PATH", orig_path
, 1);
553 DWORD err
= GetLastError ();
554 error ("Error creating process \"%s%s\", (error %d): %s\n",
555 program
, args
, (int) err
, strwinerror (err
));
559 OUTMSG2 (("Process created: %s\n", (char *) args
));
563 /* On Windows CE this handle can't be closed. The OS reuses
564 it in the debug events, while the 9x/NT versions of Windows
565 probably use a DuplicateHandle'd one. */
566 CloseHandle (pi
.hThread
);
569 current_process_handle
= pi
.hProcess
;
570 current_process_id
= pi
.dwProcessId
;
572 do_initial_child_stuff (current_process_id
);
574 return current_process_id
;
577 /* Attach to a running process.
578 PID is the process ID to attach to, specified by the user
579 or a higher layer. */
581 win32_attach (unsigned long pid
)
583 winapi_DebugActiveProcessStop DebugActiveProcessStop
= NULL
;
584 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit
= NULL
;
586 HMODULE dll
= GetModuleHandle (_T("COREDLL.DLL"));
588 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
590 DebugActiveProcessStop
= GETPROCADDRESS (dll
, DebugActiveProcessStop
);
591 DebugSetProcessKillOnExit
= GETPROCADDRESS (dll
, DebugSetProcessKillOnExit
);
593 if (DebugActiveProcess (pid
))
595 if (DebugSetProcessKillOnExit
!= NULL
)
596 DebugSetProcessKillOnExit (FALSE
);
598 current_process_handle
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
, pid
);
600 if (current_process_handle
!= NULL
)
602 current_process_id
= pid
;
603 do_initial_child_stuff (pid
);
606 if (DebugActiveProcessStop
!= NULL
)
607 DebugActiveProcessStop (current_process_id
);
610 error ("Attach to process failed.");
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. */
691 winapi_DebugActiveProcessStop DebugActiveProcessStop
= NULL
;
692 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit
= NULL
;
694 HMODULE dll
= GetModuleHandle (_T("COREDLL.DLL"));
696 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
698 DebugActiveProcessStop
= GETPROCADDRESS (dll
, DebugActiveProcessStop
);
699 DebugSetProcessKillOnExit
= GETPROCADDRESS (dll
, DebugSetProcessKillOnExit
);
701 if (DebugSetProcessKillOnExit
== NULL
702 || DebugActiveProcessStop
== NULL
)
705 /* We need a new handle, since DebugActiveProcessStop
706 closes all the ones that came through the events. */
707 if ((h
= OpenProcess (PROCESS_ALL_ACCESS
,
709 current_process_id
)) == NULL
)
711 /* The process died. */
716 struct thread_resume resume
;
720 resume
.leave_stopped
= 0;
721 win32_resume (&resume
);
724 if (!DebugActiveProcessStop (current_process_id
))
729 DebugSetProcessKillOnExit (FALSE
);
731 current_process_handle
= h
;
735 /* Wait for inferiors to end. */
739 if (current_process_id
== 0
740 || current_process_handle
== NULL
)
743 WaitForSingleObject (current_process_handle
, INFINITE
);
744 CloseHandle (current_process_handle
);
746 current_process_handle
= NULL
;
747 current_process_id
= 0;
750 /* Return 1 iff the thread with thread ID TID is alive. */
752 win32_thread_alive (unsigned long tid
)
756 /* Our thread list is reliable; don't bother to poll target
758 if (find_inferior_id (&all_threads
, tid
) != NULL
)
765 /* Resume the inferior process. RESUME_INFO describes how we want
768 win32_resume (struct thread_resume
*resume_info
)
771 enum target_signal sig
;
773 win32_thread_info
*th
;
774 DWORD continue_status
= DBG_CONTINUE
;
776 /* This handles the very limited set of resume packets that GDB can
777 currently produce. */
779 if (resume_info
[0].thread
== -1)
781 else if (resume_info
[1].thread
== -1 && !resume_info
[1].leave_stopped
)
784 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
785 the Windows resume code do the right thing for thread switching. */
786 tid
= current_event
.dwThreadId
;
788 if (resume_info
[0].thread
!= -1)
790 sig
= resume_info
[0].sig
;
791 step
= resume_info
[0].step
;
799 if (sig
!= TARGET_SIGNAL_0
)
801 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
803 OUTMSG (("Cannot continue with signal %d here.\n", sig
));
805 else if (sig
== last_sig
)
806 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
808 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig
));
811 last_sig
= TARGET_SIGNAL_0
;
813 /* Get context for the currently selected thread. */
814 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
817 if (th
->context
.ContextFlags
)
819 if (debug_registers_changed
)
820 if (the_low_target
.load_debug_registers
!= NULL
)
821 (*the_low_target
.load_debug_registers
) (th
);
823 /* Move register values from the inferior into the thread
824 context structure. */
825 regcache_invalidate ();
829 if (the_low_target
.single_step
!= NULL
)
830 (*the_low_target
.single_step
) (th
);
832 error ("Single stepping is not supported "
833 "in this configuration.\n");
835 SetThreadContext (th
->h
, &th
->context
);
836 th
->context
.ContextFlags
= 0;
840 /* Allow continuing with the same signal that interrupted us.
841 Otherwise complain. */
843 child_continue (continue_status
, tid
);
847 handle_exception (struct target_waitstatus
*ourstatus
)
849 win32_thread_info
*th
;
850 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
852 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
854 /* Record the context of the current thread. */
855 th
= thread_rec (current_event
.dwThreadId
, -1);
859 case EXCEPTION_ACCESS_VIOLATION
:
860 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
861 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
863 case STATUS_STACK_OVERFLOW
:
864 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
865 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
867 case STATUS_FLOAT_DENORMAL_OPERAND
:
868 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
869 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
871 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
872 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
873 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
875 case STATUS_FLOAT_INEXACT_RESULT
:
876 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
877 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
879 case STATUS_FLOAT_INVALID_OPERATION
:
880 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
881 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
883 case STATUS_FLOAT_OVERFLOW
:
884 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
885 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
887 case STATUS_FLOAT_STACK_CHECK
:
888 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
889 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
891 case STATUS_FLOAT_UNDERFLOW
:
892 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
893 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
895 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
896 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
897 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
899 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
900 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
901 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
903 case STATUS_INTEGER_OVERFLOW
:
904 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
905 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
907 case EXCEPTION_BREAKPOINT
:
908 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
909 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
911 /* Remove the initial breakpoint. */
912 check_breakpoints ((CORE_ADDR
) (long) current_event
913 .u
.Exception
.ExceptionRecord
.ExceptionAddress
);
917 OUTMSG2 (("DBG_CONTROL_C"));
918 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
920 case DBG_CONTROL_BREAK
:
921 OUTMSG2 (("DBG_CONTROL_BREAK"));
922 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
924 case EXCEPTION_SINGLE_STEP
:
925 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
926 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
928 case EXCEPTION_ILLEGAL_INSTRUCTION
:
929 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
930 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
932 case EXCEPTION_PRIV_INSTRUCTION
:
933 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
934 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
936 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
937 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
938 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
941 if (current_event
.u
.Exception
.dwFirstChance
)
943 OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
944 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
945 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.
947 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
951 last_sig
= ourstatus
->value
.sig
;
955 /* Get the next event from the child. Return 1 if the event requires
958 get_child_debug_event (struct target_waitstatus
*ourstatus
)
961 DWORD continue_status
, event_code
;
962 win32_thread_info
*th
= NULL
;
963 static win32_thread_info dummy_thread_info
;
968 last_sig
= TARGET_SIGNAL_0
;
969 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
971 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
975 (struct thread_info
*) find_inferior_id (&all_threads
,
976 current_event
.dwThreadId
);
978 continue_status
= DBG_CONTINUE
;
979 event_code
= current_event
.dwDebugEventCode
;
983 case CREATE_THREAD_DEBUG_EVENT
:
984 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
985 "for pid=%d tid=%x)\n",
986 (unsigned) current_event
.dwProcessId
,
987 (unsigned) current_event
.dwThreadId
));
989 /* Record the existence of this thread. */
990 th
= child_add_thread (current_event
.dwThreadId
,
991 current_event
.u
.CreateThread
.hThread
);
993 retval
= current_event
.dwThreadId
;
996 case EXIT_THREAD_DEBUG_EVENT
:
997 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
998 "for pid=%d tid=%x\n",
999 (unsigned) current_event
.dwProcessId
,
1000 (unsigned) current_event
.dwThreadId
));
1001 child_delete_thread (current_event
.dwThreadId
);
1002 th
= &dummy_thread_info
;
1005 case CREATE_PROCESS_DEBUG_EVENT
:
1006 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1007 "for pid=%d tid=%x\n",
1008 (unsigned) current_event
.dwProcessId
,
1009 (unsigned) current_event
.dwThreadId
));
1010 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1012 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1013 main_thread_id
= current_event
.dwThreadId
;
1015 ourstatus
->kind
= TARGET_WAITKIND_EXECD
;
1016 ourstatus
->value
.execd_pathname
= "Main executable";
1018 /* Add the main thread. */
1020 child_add_thread (main_thread_id
,
1021 current_event
.u
.CreateProcessInfo
.hThread
);
1023 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1025 /* Windows CE doesn't set the initial breakpoint automatically
1026 like the desktop versions of Windows do. We add it explicitly
1027 here. It will be removed as soon as it is hit. */
1028 set_breakpoint_at ((CORE_ADDR
) (long) current_event
.u
1029 .CreateProcessInfo
.lpStartAddress
,
1030 delete_breakpoint_at
);
1034 case EXIT_PROCESS_DEBUG_EVENT
:
1035 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1036 "for pid=%d tid=%x\n",
1037 (unsigned) current_event
.dwProcessId
,
1038 (unsigned) current_event
.dwThreadId
));
1039 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1040 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1041 CloseHandle (current_process_handle
);
1042 current_process_handle
= NULL
;
1043 retval
= main_thread_id
;
1046 case LOAD_DLL_DEBUG_EVENT
:
1047 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1048 "for pid=%d tid=%x\n",
1049 (unsigned) current_event
.dwProcessId
,
1050 (unsigned) current_event
.dwThreadId
));
1051 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1053 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1054 ourstatus
->value
.integer
= 0;
1055 retval
= main_thread_id
;
1058 case UNLOAD_DLL_DEBUG_EVENT
:
1059 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1060 "for pid=%d tid=%x\n",
1061 (unsigned) current_event
.dwProcessId
,
1062 (unsigned) current_event
.dwThreadId
));
1065 case EXCEPTION_DEBUG_EVENT
:
1066 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1067 "for pid=%d tid=%x\n",
1068 (unsigned) current_event
.dwProcessId
,
1069 (unsigned) current_event
.dwThreadId
));
1070 retval
= handle_exception (ourstatus
);
1073 case OUTPUT_DEBUG_STRING_EVENT
:
1074 /* A message from the kernel (or Cygwin). */
1075 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1076 "for pid=%d tid=%x\n",
1077 (unsigned) current_event
.dwProcessId
,
1078 (unsigned) current_event
.dwThreadId
));
1079 handle_output_debug_string (ourstatus
);
1083 OUTMSG2 (("gdbserver: kernel event unknown "
1084 "for pid=%d tid=%x code=%ld\n",
1085 (unsigned) current_event
.dwProcessId
,
1086 (unsigned) current_event
.dwThreadId
,
1087 current_event
.dwDebugEventCode
));
1092 (struct thread_info
*) find_inferior_id (&all_threads
,
1093 current_event
.dwThreadId
);
1095 if (!retval
|| (event_code
!= EXCEPTION_DEBUG_EVENT
&& event_code
!= EXIT_PROCESS_DEBUG_EVENT
))
1097 child_continue (continue_status
, -1);
1102 thread_rec (current_event
.dwThreadId
, TRUE
);
1108 /* Wait for the inferior process to change state.
1109 STATUS will be filled in with a response code to send to GDB.
1110 Returns the signal which caused the process to stop. */
1111 static unsigned char
1112 win32_wait (char *status
)
1114 struct target_waitstatus our_status
;
1120 get_child_debug_event (&our_status
);
1122 if (our_status
.kind
== TARGET_WAITKIND_EXITED
)
1124 OUTMSG2 (("Child exited with retcode = %x\n",
1125 our_status
.value
.integer
));
1129 child_fetch_inferior_registers (-1);
1131 return our_status
.value
.integer
;
1133 else if (our_status
.kind
== TARGET_WAITKIND_STOPPED
)
1135 OUTMSG2 (("Child Stopped with signal = %d \n",
1136 our_status
.value
.sig
));
1140 child_fetch_inferior_registers (-1);
1142 return our_status
.value
.sig
;
1145 OUTMSG (("Ignoring unknown internal event, %d\n", our_status
.kind
));
1148 struct thread_resume resume
;
1152 resume
.leave_stopped
= 0;
1153 win32_resume (&resume
);
1158 /* Fetch registers from the inferior process.
1159 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1161 win32_fetch_inferior_registers (int regno
)
1163 child_fetch_inferior_registers (regno
);
1166 /* Store registers to the inferior process.
1167 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1169 win32_store_inferior_registers (int regno
)
1171 child_store_inferior_registers (regno
);
1174 /* Read memory from the inferior process. This should generally be
1175 called through read_inferior_memory, which handles breakpoint shadowing.
1176 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1178 win32_read_inferior_memory (CORE_ADDR memaddr
, unsigned char *myaddr
, int len
)
1180 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 0, 0) != len
;
1183 /* Write memory to the inferior process. This should generally be
1184 called through write_inferior_memory, which handles breakpoint shadowing.
1185 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1186 Returns 0 on success and errno on failure. */
1188 win32_write_inferior_memory (CORE_ADDR memaddr
, const unsigned char *myaddr
,
1191 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 1, 0) != len
;
1195 win32_arch_string (void)
1197 return the_low_target
.arch_string
;
1200 static struct target_ops win32_target_ops
= {
1201 win32_create_inferior
,
1209 win32_fetch_inferior_registers
,
1210 win32_store_inferior_registers
,
1211 win32_read_inferior_memory
,
1212 win32_write_inferior_memory
,
1225 /* Initialize the Win32 backend. */
1227 initialize_low (void)
1229 set_target_ops (&win32_target_ops
);
1230 if (the_low_target
.breakpoint
!= NULL
)
1231 set_breakpoint_data (the_low_target
.breakpoint
,
1232 the_low_target
.breakpoint_len
);