* solib-target.c (library_list_start_segment): Cast address to
[deliverable/binutils-gdb.git] / gdb / gdbserver / win32-low.c
... / ...
CommitLineData
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 2 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, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23#include "server.h"
24#include "regcache.h"
25#include "gdb/signals.h"
26#include "mem-break.h"
27#include "win32-low.h"
28
29#include <windows.h>
30#include <winnt.h>
31#include <imagehlp.h>
32#include <psapi.h>
33#include <sys/param.h>
34#include <malloc.h>
35#include <process.h>
36
37#ifndef USE_WIN32API
38#include <sys/cygwin.h>
39#endif
40
41#define LOG 0
42
43#define OUTMSG(X) do { printf X; fflush (stdout); } while (0)
44#if LOG
45#define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
46#else
47#define OUTMSG2(X) do ; while (0)
48#endif
49
50#ifndef _T
51#define _T(x) TEXT (x)
52#endif
53
54#ifndef COUNTOF
55#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
56#endif
57
58#ifdef _WIN32_WCE
59# define GETPROCADDRESS(DLL, PROC) \
60 ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC)))
61#else
62# define GETPROCADDRESS(DLL, PROC) \
63 ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
64#endif
65
66int using_threads = 1;
67
68/* Globals. */
69static HANDLE current_process_handle = NULL;
70static DWORD current_process_id = 0;
71static enum target_signal last_sig = TARGET_SIGNAL_0;
72
73/* The current debug event from WaitForDebugEvent. */
74static DEBUG_EVENT current_event;
75
76#define NUM_REGS (the_low_target.num_regs)
77
78typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
79typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
80typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
81typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
82
83static DWORD main_thread_id = 0;
84
85static void win32_resume (struct thread_resume *resume_info);
86
87/* Get the thread ID from the current selected inferior (the current
88 thread). */
89static DWORD
90current_inferior_tid (void)
91{
92 win32_thread_info *th = inferior_target_data (current_inferior);
93 return th->tid;
94}
95
96/* Find a thread record given a thread id. If GET_CONTEXT is set then
97 also retrieve the context for this thread. */
98static win32_thread_info *
99thread_rec (DWORD id, int get_context)
100{
101 struct thread_info *thread;
102 win32_thread_info *th;
103
104 thread = (struct thread_info *) find_inferior_id (&all_threads, id);
105 if (thread == NULL)
106 return NULL;
107
108 th = inferior_target_data (thread);
109 if (!th->suspend_count && get_context)
110 {
111 if (id != current_event.dwThreadId)
112 th->suspend_count = SuspendThread (th->h) + 1;
113
114 (*the_low_target.get_thread_context) (th, &current_event);
115 }
116
117 return th;
118}
119
120/* Add a thread to the thread list. */
121static win32_thread_info *
122child_add_thread (DWORD tid, HANDLE h)
123{
124 win32_thread_info *th;
125
126 if ((th = thread_rec (tid, FALSE)))
127 return th;
128
129 th = (win32_thread_info *) malloc (sizeof (*th));
130 memset (th, 0, sizeof (*th));
131 th->tid = tid;
132 th->h = h;
133
134 add_thread (tid, th, (unsigned int) tid);
135 set_inferior_regcache_data ((struct thread_info *)
136 find_inferior_id (&all_threads, tid),
137 new_register_cache ());
138
139 if (the_low_target.thread_added != NULL)
140 (*the_low_target.thread_added) (th);
141
142 return th;
143}
144
145/* Delete a thread from the list of threads. */
146static void
147delete_thread_info (struct inferior_list_entry *thread)
148{
149 win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
150
151 remove_thread ((struct thread_info *) thread);
152 CloseHandle (th->h);
153 free (th);
154}
155
156/* Delete a thread from the list of threads. */
157static void
158child_delete_thread (DWORD id)
159{
160 struct inferior_list_entry *thread;
161
162 /* If the last thread is exiting, just return. */
163 if (all_threads.head == all_threads.tail)
164 return;
165
166 thread = find_inferior_id (&all_threads, id);
167 if (thread == NULL)
168 return;
169
170 delete_thread_info (thread);
171}
172
173/* Transfer memory from/to the debugged process. */
174static int
175child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
176 int write, struct target_ops *target)
177{
178 SIZE_T done;
179 long addr = (long) memaddr;
180
181 if (write)
182 {
183 WriteProcessMemory (current_process_handle, (LPVOID) addr,
184 (LPCVOID) our, len, &done);
185 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
186 }
187 else
188 {
189 ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
190 len, &done);
191 }
192 return done;
193}
194
195/* Generally, what has the program done? */
196enum target_waitkind
197{
198 /* The program has exited. The exit status is in value.integer. */
199 TARGET_WAITKIND_EXITED,
200
201 /* The program has stopped with a signal. Which signal is in
202 value.sig. */
203 TARGET_WAITKIND_STOPPED,
204
205 /* The program is letting us know that it dynamically loaded something
206 (e.g. it called load(2) on AIX). */
207 TARGET_WAITKIND_LOADED,
208
209 /* The program has exec'ed a new executable file. The new file's
210 pathname is pointed to by value.execd_pathname. */
211 TARGET_WAITKIND_EXECD,
212
213 /* Nothing interesting happened, but we stopped anyway. We take the
214 chance to check if GDB requested an interrupt. */
215 TARGET_WAITKIND_SPURIOUS,
216};
217
218struct target_waitstatus
219{
220 enum target_waitkind kind;
221
222 /* Forked child pid, execd pathname, exit status or signal number. */
223 union
224 {
225 int integer;
226 enum target_signal sig;
227 int related_pid;
228 char *execd_pathname;
229 int syscall_id;
230 }
231 value;
232};
233
234/* Clear out any old thread list and reinitialize it to a pristine
235 state. */
236static void
237child_init_thread_list (void)
238{
239 for_each_inferior (&all_threads, delete_thread_info);
240}
241
242static void
243do_initial_child_stuff (DWORD pid)
244{
245 last_sig = TARGET_SIGNAL_0;
246
247 memset (&current_event, 0, sizeof (current_event));
248
249 child_init_thread_list ();
250
251 if (the_low_target.initial_stuff != NULL)
252 (*the_low_target.initial_stuff) ();
253}
254
255/* Resume all artificially suspended threads if we are continuing
256 execution. */
257static int
258continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
259{
260 struct thread_info *thread = (struct thread_info *) this_thread;
261 int thread_id = * (int *) id_ptr;
262 win32_thread_info *th = inferior_target_data (thread);
263 int i;
264
265 if ((thread_id == -1 || thread_id == th->tid)
266 && th->suspend_count)
267 {
268 if (th->context.ContextFlags)
269 {
270 (*the_low_target.set_thread_context) (th, &current_event);
271 th->context.ContextFlags = 0;
272 }
273
274 for (i = 0; i < th->suspend_count; i++)
275 (void) ResumeThread (th->h);
276 th->suspend_count = 0;
277 }
278
279 return 0;
280}
281
282static BOOL
283child_continue (DWORD continue_status, int thread_id)
284{
285 BOOL res;
286
287 res = ContinueDebugEvent (current_event.dwProcessId,
288 current_event.dwThreadId, continue_status);
289 if (res)
290 find_inferior (&all_threads, continue_one_thread, &thread_id);
291
292 return res;
293}
294
295/* Fetch register(s) from the current thread context. */
296static void
297child_fetch_inferior_registers (int r)
298{
299 int regno;
300 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
301 if (r == -1 || r == 0 || r > NUM_REGS)
302 child_fetch_inferior_registers (NUM_REGS);
303 else
304 for (regno = 0; regno < r; regno++)
305 (*the_low_target.fetch_inferior_register) (th, regno);
306}
307
308/* Store a new register value into the current thread context. We don't
309 change the program's context until later, when we resume it. */
310static void
311child_store_inferior_registers (int r)
312{
313 int regno;
314 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
315 if (r == -1 || r == 0 || r > NUM_REGS)
316 child_store_inferior_registers (NUM_REGS);
317 else
318 for (regno = 0; regno < r; regno++)
319 (*the_low_target.store_inferior_register) (th, regno);
320}
321
322/* Map the Windows error number in ERROR to a locale-dependent error
323 message string and return a pointer to it. Typically, the values
324 for ERROR come from GetLastError.
325
326 The string pointed to shall not be modified by the application,
327 but may be overwritten by a subsequent call to strwinerror
328
329 The strwinerror function does not change the current setting
330 of GetLastError. */
331
332char *
333strwinerror (DWORD error)
334{
335 static char buf[1024];
336 TCHAR *msgbuf;
337 DWORD lasterr = GetLastError ();
338 DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
339 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
340 NULL,
341 error,
342 0, /* Default language */
343 (LPVOID)&msgbuf,
344 0,
345 NULL);
346 if (chars != 0)
347 {
348 /* If there is an \r\n appended, zap it. */
349 if (chars >= 2
350 && msgbuf[chars - 2] == '\r'
351 && msgbuf[chars - 1] == '\n')
352 {
353 chars -= 2;
354 msgbuf[chars] = 0;
355 }
356
357 if (chars > ((COUNTOF (buf)) - 1))
358 {
359 chars = COUNTOF (buf) - 1;
360 msgbuf [chars] = 0;
361 }
362
363#ifdef UNICODE
364 wcstombs (buf, msgbuf, chars + 1);
365#else
366 strncpy (buf, msgbuf, chars + 1);
367#endif
368 LocalFree (msgbuf);
369 }
370 else
371 sprintf (buf, "unknown win32 error (%ld)", error);
372
373 SetLastError (lasterr);
374 return buf;
375}
376
377/* Start a new process.
378 PROGRAM is a path to the program to execute.
379 ARGS is a standard NULL-terminated array of arguments,
380 to be passed to the inferior as ``argv''.
381 Returns the new PID on success, -1 on failure. Registers the new
382 process with the process list. */
383static int
384win32_create_inferior (char *program, char **program_args)
385{
386#ifndef USE_WIN32API
387 char real_path[MAXPATHLEN];
388 char *orig_path, *new_path, *path_ptr;
389#endif
390 BOOL ret;
391 DWORD flags;
392 char *args;
393 int argslen;
394 int argc;
395 PROCESS_INFORMATION pi;
396#ifndef __MINGW32CE__
397 STARTUPINFOA si = { sizeof (STARTUPINFOA) };
398 char *winenv = NULL;
399#else
400 wchar_t *wargs, *wprogram;
401#endif
402
403 if (!program)
404 error ("No executable specified, specify executable to debug.\n");
405
406 flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
407
408#ifndef USE_WIN32API
409 orig_path = NULL;
410 path_ptr = getenv ("PATH");
411 if (path_ptr)
412 {
413 orig_path = alloca (strlen (path_ptr) + 1);
414 new_path = alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr));
415 strcpy (orig_path, path_ptr);
416 cygwin_posix_to_win32_path_list (path_ptr, new_path);
417 setenv ("PATH", new_path, 1);
418 }
419 cygwin_conv_to_win32_path (program, real_path);
420 program = real_path;
421#endif
422
423 argslen = 1;
424 for (argc = 1; program_args[argc]; argc++)
425 argslen += strlen (program_args[argc]) + 1;
426 args = alloca (argslen);
427 args[0] = '\0';
428 for (argc = 1; program_args[argc]; argc++)
429 {
430 /* FIXME: Can we do better about quoting? How does Cygwin
431 handle this? */
432 strcat (args, " ");
433 strcat (args, program_args[argc]);
434 }
435 OUTMSG2 (("Command line is \"%s\"\n", args));
436
437#ifdef CREATE_NEW_PROCESS_GROUP
438 flags |= CREATE_NEW_PROCESS_GROUP;
439#endif
440
441#ifdef __MINGW32CE__
442 to_back_slashes (program);
443 wargs = alloca (argslen * sizeof (wchar_t));
444 mbstowcs (wargs, args, argslen);
445 wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
446 mbstowcs (wprogram, program, strlen (program) + 1);
447 ret = CreateProcessW (wprogram, /* image name */
448 wargs, /* command line */
449 NULL, /* security, not supported */
450 NULL, /* thread, not supported */
451 FALSE, /* inherit handles, not supported */
452 flags, /* start flags */
453 NULL, /* environment, not supported */
454 NULL, /* current directory, not supported */
455 NULL, /* start info, not supported */
456 &pi); /* proc info */
457#else
458 ret = CreateProcessA (program, /* image name */
459 args, /* command line */
460 NULL, /* security */
461 NULL, /* thread */
462 TRUE, /* inherit handles */
463 flags, /* start flags */
464 winenv, /* environment */
465 NULL, /* current directory */
466 &si, /* start info */
467 &pi); /* proc info */
468#endif
469
470#ifndef USE_WIN32API
471 if (orig_path)
472 setenv ("PATH", orig_path, 1);
473#endif
474
475 if (!ret)
476 {
477 DWORD err = GetLastError ();
478 error ("Error creating process \"%s%s\", (error %d): %s\n",
479 program, args, (int) err, strwinerror (err));
480 }
481 else
482 {
483 OUTMSG2 (("Process created: %s\n", (char *) args));
484 }
485
486#ifndef _WIN32_WCE
487 /* On Windows CE this handle can't be closed. The OS reuses
488 it in the debug events, while the 9x/NT versions of Windows
489 probably use a DuplicateHandle'd one. */
490 CloseHandle (pi.hThread);
491#endif
492
493 current_process_handle = pi.hProcess;
494 current_process_id = pi.dwProcessId;
495
496 do_initial_child_stuff (current_process_id);
497
498 return current_process_id;
499}
500
501/* Attach to a running process.
502 PID is the process ID to attach to, specified by the user
503 or a higher layer. */
504static int
505win32_attach (unsigned long pid)
506{
507 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
508 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
509#ifdef _WIN32_WCE
510 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
511#else
512 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
513#endif
514 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
515 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
516
517 if (DebugActiveProcess (pid))
518 {
519 if (DebugSetProcessKillOnExit != NULL)
520 DebugSetProcessKillOnExit (FALSE);
521
522 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
523
524 if (current_process_handle != NULL)
525 {
526 current_process_id = pid;
527 do_initial_child_stuff (pid);
528 return 0;
529 }
530 if (DebugActiveProcessStop != NULL)
531 DebugActiveProcessStop (current_process_id);
532 }
533
534 error ("Attach to process failed.");
535}
536
537/* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
538static void
539handle_output_debug_string (struct target_waitstatus *ourstatus)
540{
541#define READ_BUFFER_LEN 1024
542 CORE_ADDR addr;
543 char s[READ_BUFFER_LEN + 1] = { 0 };
544 DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
545
546 if (nbytes == 0)
547 return;
548
549 if (nbytes > READ_BUFFER_LEN)
550 nbytes = READ_BUFFER_LEN;
551
552 addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
553
554 if (current_event.u.DebugString.fUnicode)
555 {
556 /* The event tells us how many bytes, not chars, even
557 in Unicode. */
558 WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
559 if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
560 return;
561 wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
562 }
563 else
564 {
565 if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
566 return;
567 }
568
569 if (strncmp (s, "cYg", 3) != 0)
570 monitor_output (s);
571#undef READ_BUFFER_LEN
572}
573
574/* Kill all inferiors. */
575static void
576win32_kill (void)
577{
578 win32_thread_info *current_thread;
579
580 if (current_process_handle == NULL)
581 return;
582
583 TerminateProcess (current_process_handle, 0);
584 for (;;)
585 {
586 if (!child_continue (DBG_CONTINUE, -1))
587 break;
588 if (!WaitForDebugEvent (&current_event, INFINITE))
589 break;
590 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
591 break;
592 else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
593 {
594 struct target_waitstatus our_status = { 0 };
595 handle_output_debug_string (&our_status);
596 }
597 }
598
599 CloseHandle (current_process_handle);
600
601 current_thread = inferior_target_data (current_inferior);
602 if (current_thread && current_thread->h)
603 {
604 /* This may fail in an attached process, so don't check. */
605 (void) CloseHandle (current_thread->h);
606 }
607}
608
609/* Detach from all inferiors. */
610static int
611win32_detach (void)
612{
613 HANDLE h;
614
615 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
616 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
617#ifdef _WIN32_WCE
618 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
619#else
620 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
621#endif
622 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
623 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
624
625 if (DebugSetProcessKillOnExit == NULL
626 || DebugActiveProcessStop == NULL)
627 return -1;
628
629 /* We need a new handle, since DebugActiveProcessStop
630 closes all the ones that came through the events. */
631 if ((h = OpenProcess (PROCESS_ALL_ACCESS,
632 FALSE,
633 current_process_id)) == NULL)
634 {
635 /* The process died. */
636 return -1;
637 }
638
639 {
640 struct thread_resume resume;
641 resume.thread = -1;
642 resume.step = 0;
643 resume.sig = 0;
644 resume.leave_stopped = 0;
645 win32_resume (&resume);
646 }
647
648 if (!DebugActiveProcessStop (current_process_id))
649 {
650 CloseHandle (h);
651 return -1;
652 }
653 DebugSetProcessKillOnExit (FALSE);
654
655 current_process_handle = h;
656 return 0;
657}
658
659/* Wait for inferiors to end. */
660static void
661win32_join (void)
662{
663 if (current_process_id == 0
664 || current_process_handle == NULL)
665 return;
666
667 WaitForSingleObject (current_process_handle, INFINITE);
668 CloseHandle (current_process_handle);
669
670 current_process_handle = NULL;
671 current_process_id = 0;
672}
673
674/* Return 1 iff the thread with thread ID TID is alive. */
675static int
676win32_thread_alive (unsigned long tid)
677{
678 int res;
679
680 /* Our thread list is reliable; don't bother to poll target
681 threads. */
682 if (find_inferior_id (&all_threads, tid) != NULL)
683 res = 1;
684 else
685 res = 0;
686 return res;
687}
688
689/* Resume the inferior process. RESUME_INFO describes how we want
690 to resume. */
691static void
692win32_resume (struct thread_resume *resume_info)
693{
694 DWORD tid;
695 enum target_signal sig;
696 int step;
697 win32_thread_info *th;
698 DWORD continue_status = DBG_CONTINUE;
699
700 /* This handles the very limited set of resume packets that GDB can
701 currently produce. */
702
703 if (resume_info[0].thread == -1)
704 tid = -1;
705 else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
706 tid = -1;
707 else
708 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
709 the Windows resume code do the right thing for thread switching. */
710 tid = current_event.dwThreadId;
711
712 if (resume_info[0].thread != -1)
713 {
714 sig = resume_info[0].sig;
715 step = resume_info[0].step;
716 }
717 else
718 {
719 sig = 0;
720 step = 0;
721 }
722
723 if (sig != TARGET_SIGNAL_0)
724 {
725 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
726 {
727 OUTMSG (("Cannot continue with signal %d here.\n", sig));
728 }
729 else if (sig == last_sig)
730 continue_status = DBG_EXCEPTION_NOT_HANDLED;
731 else
732 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
733 }
734
735 last_sig = TARGET_SIGNAL_0;
736
737 /* Get context for the currently selected thread. */
738 th = thread_rec (current_event.dwThreadId, FALSE);
739 if (th)
740 {
741 if (th->context.ContextFlags)
742 {
743 /* Move register values from the inferior into the thread
744 context structure. */
745 regcache_invalidate ();
746
747 if (step)
748 {
749 if (the_low_target.single_step != NULL)
750 (*the_low_target.single_step) (th);
751 else
752 error ("Single stepping is not supported "
753 "in this configuration.\n");
754 }
755
756 (*the_low_target.set_thread_context) (th, &current_event);
757 th->context.ContextFlags = 0;
758 }
759 }
760
761 /* Allow continuing with the same signal that interrupted us.
762 Otherwise complain. */
763
764 child_continue (continue_status, tid);
765}
766
767static void
768handle_exception (struct target_waitstatus *ourstatus)
769{
770 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
771
772 ourstatus->kind = TARGET_WAITKIND_STOPPED;
773
774 switch (code)
775 {
776 case EXCEPTION_ACCESS_VIOLATION:
777 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
778 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
779 break;
780 case STATUS_STACK_OVERFLOW:
781 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
782 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
783 break;
784 case STATUS_FLOAT_DENORMAL_OPERAND:
785 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
786 ourstatus->value.sig = TARGET_SIGNAL_FPE;
787 break;
788 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
789 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
790 ourstatus->value.sig = TARGET_SIGNAL_FPE;
791 break;
792 case STATUS_FLOAT_INEXACT_RESULT:
793 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
794 ourstatus->value.sig = TARGET_SIGNAL_FPE;
795 break;
796 case STATUS_FLOAT_INVALID_OPERATION:
797 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
798 ourstatus->value.sig = TARGET_SIGNAL_FPE;
799 break;
800 case STATUS_FLOAT_OVERFLOW:
801 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
802 ourstatus->value.sig = TARGET_SIGNAL_FPE;
803 break;
804 case STATUS_FLOAT_STACK_CHECK:
805 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
806 ourstatus->value.sig = TARGET_SIGNAL_FPE;
807 break;
808 case STATUS_FLOAT_UNDERFLOW:
809 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
810 ourstatus->value.sig = TARGET_SIGNAL_FPE;
811 break;
812 case STATUS_FLOAT_DIVIDE_BY_ZERO:
813 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
814 ourstatus->value.sig = TARGET_SIGNAL_FPE;
815 break;
816 case STATUS_INTEGER_DIVIDE_BY_ZERO:
817 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
818 ourstatus->value.sig = TARGET_SIGNAL_FPE;
819 break;
820 case STATUS_INTEGER_OVERFLOW:
821 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
822 ourstatus->value.sig = TARGET_SIGNAL_FPE;
823 break;
824 case EXCEPTION_BREAKPOINT:
825 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
826 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
827#ifdef _WIN32_WCE
828 /* Remove the initial breakpoint. */
829 check_breakpoints ((CORE_ADDR) (long) current_event
830 .u.Exception.ExceptionRecord.ExceptionAddress);
831#endif
832 break;
833 case DBG_CONTROL_C:
834 OUTMSG2 (("DBG_CONTROL_C"));
835 ourstatus->value.sig = TARGET_SIGNAL_INT;
836 break;
837 case DBG_CONTROL_BREAK:
838 OUTMSG2 (("DBG_CONTROL_BREAK"));
839 ourstatus->value.sig = TARGET_SIGNAL_INT;
840 break;
841 case EXCEPTION_SINGLE_STEP:
842 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
843 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
844 break;
845 case EXCEPTION_ILLEGAL_INSTRUCTION:
846 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
847 ourstatus->value.sig = TARGET_SIGNAL_ILL;
848 break;
849 case EXCEPTION_PRIV_INSTRUCTION:
850 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
851 ourstatus->value.sig = TARGET_SIGNAL_ILL;
852 break;
853 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
854 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
855 ourstatus->value.sig = TARGET_SIGNAL_ILL;
856 break;
857 default:
858 if (current_event.u.Exception.dwFirstChance)
859 {
860 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
861 return;
862 }
863 OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
864 current_event.u.Exception.ExceptionRecord.ExceptionCode,
865 (DWORD) current_event.u.Exception.ExceptionRecord.
866 ExceptionAddress));
867 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
868 break;
869 }
870 OUTMSG2 (("\n"));
871 last_sig = ourstatus->value.sig;
872}
873
874/* Get the next event from the child. */
875static void
876get_child_debug_event (struct target_waitstatus *ourstatus)
877{
878 BOOL debug_event;
879
880 last_sig = TARGET_SIGNAL_0;
881 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
882
883 /* Keep the wait time low enough for confortable remote interruption,
884 but high enough so gdbserver doesn't become a bottleneck. */
885 if (!(debug_event = WaitForDebugEvent (&current_event, 250)))
886 return;
887
888 current_inferior =
889 (struct thread_info *) find_inferior_id (&all_threads,
890 current_event.dwThreadId);
891
892 switch (current_event.dwDebugEventCode)
893 {
894 case CREATE_THREAD_DEBUG_EVENT:
895 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
896 "for pid=%d tid=%x)\n",
897 (unsigned) current_event.dwProcessId,
898 (unsigned) current_event.dwThreadId));
899
900 /* Record the existence of this thread. */
901 child_add_thread (current_event.dwThreadId,
902 current_event.u.CreateThread.hThread);
903 break;
904
905 case EXIT_THREAD_DEBUG_EVENT:
906 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
907 "for pid=%d tid=%x\n",
908 (unsigned) current_event.dwProcessId,
909 (unsigned) current_event.dwThreadId));
910 child_delete_thread (current_event.dwThreadId);
911 break;
912
913 case CREATE_PROCESS_DEBUG_EVENT:
914 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
915 "for pid=%d tid=%x\n",
916 (unsigned) current_event.dwProcessId,
917 (unsigned) current_event.dwThreadId));
918 CloseHandle (current_event.u.CreateProcessInfo.hFile);
919
920 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
921 main_thread_id = current_event.dwThreadId;
922
923 ourstatus->kind = TARGET_WAITKIND_EXECD;
924 ourstatus->value.execd_pathname = "Main executable";
925
926 /* Add the main thread. */
927 child_add_thread (main_thread_id,
928 current_event.u.CreateProcessInfo.hThread);
929
930 ourstatus->value.related_pid = current_event.dwThreadId;
931#ifdef _WIN32_WCE
932 /* Windows CE doesn't set the initial breakpoint automatically
933 like the desktop versions of Windows do. We add it explicitly
934 here. It will be removed as soon as it is hit. */
935 set_breakpoint_at ((CORE_ADDR) (long) current_event.u
936 .CreateProcessInfo.lpStartAddress,
937 delete_breakpoint_at);
938#endif
939 break;
940
941 case EXIT_PROCESS_DEBUG_EVENT:
942 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
943 "for pid=%d tid=%x\n",
944 (unsigned) current_event.dwProcessId,
945 (unsigned) current_event.dwThreadId));
946 ourstatus->kind = TARGET_WAITKIND_EXITED;
947 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
948 CloseHandle (current_process_handle);
949 current_process_handle = NULL;
950 break;
951
952 case LOAD_DLL_DEBUG_EVENT:
953 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
954 "for pid=%d tid=%x\n",
955 (unsigned) current_event.dwProcessId,
956 (unsigned) current_event.dwThreadId));
957 CloseHandle (current_event.u.LoadDll.hFile);
958
959 ourstatus->kind = TARGET_WAITKIND_LOADED;
960 ourstatus->value.integer = 0;
961 break;
962
963 case UNLOAD_DLL_DEBUG_EVENT:
964 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
965 "for pid=%d tid=%x\n",
966 (unsigned) current_event.dwProcessId,
967 (unsigned) current_event.dwThreadId));
968 break;
969
970 case EXCEPTION_DEBUG_EVENT:
971 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
972 "for pid=%d tid=%x\n",
973 (unsigned) current_event.dwProcessId,
974 (unsigned) current_event.dwThreadId));
975 handle_exception (ourstatus);
976 break;
977
978 case OUTPUT_DEBUG_STRING_EVENT:
979 /* A message from the kernel (or Cygwin). */
980 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
981 "for pid=%d tid=%x\n",
982 (unsigned) current_event.dwProcessId,
983 (unsigned) current_event.dwThreadId));
984 handle_output_debug_string (ourstatus);
985 break;
986
987 default:
988 OUTMSG2 (("gdbserver: kernel event unknown "
989 "for pid=%d tid=%x code=%ld\n",
990 (unsigned) current_event.dwProcessId,
991 (unsigned) current_event.dwThreadId,
992 current_event.dwDebugEventCode));
993 break;
994 }
995
996 current_inferior =
997 (struct thread_info *) find_inferior_id (&all_threads,
998 current_event.dwThreadId);
999}
1000
1001/* Wait for the inferior process to change state.
1002 STATUS will be filled in with a response code to send to GDB.
1003 Returns the signal which caused the process to stop. */
1004static unsigned char
1005win32_wait (char *status)
1006{
1007 struct target_waitstatus our_status;
1008
1009 *status = 'T';
1010
1011 while (1)
1012 {
1013 /* Check if GDB sent us an interrupt request. */
1014 check_remote_input_interrupt_request ();
1015
1016 get_child_debug_event (&our_status);
1017
1018 switch (our_status.kind)
1019 {
1020 case TARGET_WAITKIND_EXITED:
1021 OUTMSG2 (("Child exited with retcode = %x\n",
1022 our_status.value.integer));
1023
1024 *status = 'W';
1025
1026 child_fetch_inferior_registers (-1);
1027
1028 return our_status.value.integer;
1029 case TARGET_WAITKIND_STOPPED:
1030 OUTMSG2 (("Child Stopped with signal = %d \n",
1031 our_status.value.sig));
1032
1033 *status = 'T';
1034
1035 child_fetch_inferior_registers (-1);
1036
1037 return our_status.value.sig;
1038 default:
1039 OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
1040 /* fall-through */
1041 case TARGET_WAITKIND_SPURIOUS:
1042 case TARGET_WAITKIND_LOADED:
1043 case TARGET_WAITKIND_EXECD:
1044 /* do nothing, just continue */
1045 child_continue (DBG_CONTINUE, -1);
1046 break;
1047 }
1048 }
1049}
1050
1051/* Fetch registers from the inferior process.
1052 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1053static void
1054win32_fetch_inferior_registers (int regno)
1055{
1056 child_fetch_inferior_registers (regno);
1057}
1058
1059/* Store registers to the inferior process.
1060 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1061static void
1062win32_store_inferior_registers (int regno)
1063{
1064 child_store_inferior_registers (regno);
1065}
1066
1067/* Read memory from the inferior process. This should generally be
1068 called through read_inferior_memory, which handles breakpoint shadowing.
1069 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1070static int
1071win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1072{
1073 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
1074}
1075
1076/* Write memory to the inferior process. This should generally be
1077 called through write_inferior_memory, which handles breakpoint shadowing.
1078 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1079 Returns 0 on success and errno on failure. */
1080static int
1081win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1082 int len)
1083{
1084 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1085}
1086
1087/* Send an interrupt request to the inferior process. */
1088static void
1089win32_request_interrupt (void)
1090{
1091 winapi_DebugBreakProcess DebugBreakProcess;
1092 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent;
1093
1094#ifdef _WIN32_WCE
1095 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
1096#else
1097 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1098#endif
1099
1100 GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent);
1101
1102 if (GenerateConsoleCtrlEvent != NULL
1103 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
1104 return;
1105
1106 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1107 not a process group id.
1108 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1109 breakpoint exception in the interior process. */
1110
1111 DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess);
1112
1113 if (DebugBreakProcess != NULL
1114 && DebugBreakProcess (current_process_handle))
1115 return;
1116
1117 OUTMSG (("Could not interrupt process.\n"));
1118}
1119
1120static const char *
1121win32_arch_string (void)
1122{
1123 return the_low_target.arch_string;
1124}
1125
1126static struct target_ops win32_target_ops = {
1127 win32_create_inferior,
1128 win32_attach,
1129 win32_kill,
1130 win32_detach,
1131 win32_join,
1132 win32_thread_alive,
1133 win32_resume,
1134 win32_wait,
1135 win32_fetch_inferior_registers,
1136 win32_store_inferior_registers,
1137 win32_read_inferior_memory,
1138 win32_write_inferior_memory,
1139 NULL,
1140 win32_request_interrupt,
1141 NULL,
1142 NULL,
1143 NULL,
1144 NULL,
1145 NULL,
1146 NULL,
1147 NULL,
1148 win32_arch_string
1149};
1150
1151/* Initialize the Win32 backend. */
1152void
1153initialize_low (void)
1154{
1155 set_target_ops (&win32_target_ops);
1156 if (the_low_target.breakpoint != NULL)
1157 set_breakpoint_data (the_low_target.breakpoint,
1158 the_low_target.breakpoint_len);
1159 init_registers ();
1160}
This page took 0.027413 seconds and 4 git commands to generate.