* win32-low.c (win32_wait): Don't use WSTOPSIG.
[deliverable/binutils-gdb.git] / gdb / gdbserver / win32-low.c
1 /* Low level interface to Windows debugging, for gdbserver.
2 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
3
4 Contributed by Leo Zayas. Based on "win32-nat.c" from GDB.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 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 int using_threads = 1;
59
60 /* Globals. */
61 static HANDLE current_process_handle = NULL;
62 static DWORD current_process_id = 0;
63 static enum target_signal last_sig = TARGET_SIGNAL_0;
64
65 /* The current debug event from WaitForDebugEvent. */
66 static DEBUG_EVENT current_event;
67
68 static int debug_registers_changed = 0;
69 static int debug_registers_used = 0;
70
71 #define NUM_REGS (the_low_target.num_regs)
72
73 typedef BOOL winapi_DebugActiveProcessStop (DWORD dwProcessId);
74 typedef BOOL winapi_DebugSetProcessKillOnExit (BOOL KillOnExit);
75
76 #ifndef CONTEXT_EXTENDED_REGISTERS
77 #define CONTEXT_EXTENDED_REGISTERS 0
78 #endif
79
80 #ifndef CONTEXT_FLOATING_POINT
81 #define CONTEXT_FLOATING_POINT 0
82 #endif
83
84 #ifndef CONTEXT_DEBUG_REGISTERS
85 #define CONTEXT_DEBUG_REGISTERS 0
86 #endif
87
88 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
89 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
90 | CONTEXT_EXTENDED_REGISTERS
91
92 static DWORD main_thread_id = 0;
93
94 /* Get the thread ID from the current selected inferior (the current
95 thread). */
96 static DWORD
97 current_inferior_tid (void)
98 {
99 win32_thread_info *th = inferior_target_data (current_inferior);
100 return th->tid;
101 }
102
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)
107 {
108 struct thread_info *thread;
109 win32_thread_info *th;
110
111 thread = (struct thread_info *) find_inferior_id (&all_threads, id);
112 if (thread == NULL)
113 return NULL;
114
115 th = inferior_target_data (thread);
116 if (!th->suspend_count && get_context)
117 {
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;
122
123 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
124
125 GetThreadContext (th->h, &th->context);
126
127 if (id == current_event.dwThreadId)
128 {
129 /* Copy dr values from that thread. */
130 if (the_low_target.store_debug_registers != NULL)
131 (*the_low_target.store_debug_registers) (th);
132 }
133 }
134
135 return th;
136 }
137
138 /* Add a thread to the thread list. */
139 static win32_thread_info *
140 child_add_thread (DWORD tid, HANDLE h)
141 {
142 win32_thread_info *th;
143
144 if ((th = thread_rec (tid, FALSE)))
145 return th;
146
147 th = (win32_thread_info *) malloc (sizeof (*th));
148 memset (th, 0, sizeof (*th));
149 th->tid = tid;
150 th->h = h;
151
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 ());
156
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)
160 {
161 /* Only change the value of the debug registers. */
162 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
163
164 GetThreadContext (th->h, &th->context);
165
166 (*the_low_target.load_debug_registers) (th);
167
168 SetThreadContext (th->h, &th->context);
169 th->context.ContextFlags = 0;
170 }
171
172 return th;
173 }
174
175 /* Delete a thread from the list of threads. */
176 static void
177 delete_thread_info (struct inferior_list_entry *thread)
178 {
179 win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
180
181 remove_thread ((struct thread_info *) thread);
182 CloseHandle (th->h);
183 free (th);
184 }
185
186 /* Delete a thread from the list of threads. */
187 static void
188 child_delete_thread (DWORD id)
189 {
190 struct inferior_list_entry *thread;
191
192 /* If the last thread is exiting, just return. */
193 if (all_threads.head == all_threads.tail)
194 return;
195
196 thread = find_inferior_id (&all_threads, id);
197 if (thread == NULL)
198 return;
199
200 delete_thread_info (thread);
201 }
202
203 /* Transfer memory from/to the debugged process. */
204 static int
205 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
206 int write, struct target_ops *target)
207 {
208 SIZE_T done;
209 long addr = (long) memaddr;
210
211 if (write)
212 {
213 WriteProcessMemory (current_process_handle, (LPVOID) addr,
214 (LPCVOID) our, len, &done);
215 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
216 }
217 else
218 {
219 ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
220 len, &done);
221 }
222 return done;
223 }
224
225 /* Generally, what has the program done? */
226 enum target_waitkind
227 {
228 /* The program has exited. The exit status is in value.integer. */
229 TARGET_WAITKIND_EXITED,
230
231 /* The program has stopped with a signal. Which signal is in
232 value.sig. */
233 TARGET_WAITKIND_STOPPED,
234
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,
238
239 /* The program has exec'ed a new executable file. The new file's
240 pathname is pointed to by value.execd_pathname. */
241
242 TARGET_WAITKIND_EXECD,
243
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
246 inferior. */
247 TARGET_WAITKIND_SPURIOUS,
248 };
249
250 struct target_waitstatus
251 {
252 enum target_waitkind kind;
253
254 /* Forked child pid, execd pathname, exit status or signal number. */
255 union
256 {
257 int integer;
258 enum target_signal sig;
259 int related_pid;
260 char *execd_pathname;
261 int syscall_id;
262 }
263 value;
264 };
265
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. */
269 char *
270 regptr (CONTEXT* c, int r)
271 {
272 if (the_low_target.regmap[r] < 0)
273 {
274 static ULONG zero;
275 /* Always force value to zero, in case the user tried to write
276 to this register before. */
277 zero = 0;
278 return (char *) &zero;
279 }
280 else
281 return (char *) c + the_low_target.regmap[r];
282 }
283
284
285 /* Clear out any old thread list and reinitialize it to a pristine
286 state. */
287 static void
288 child_init_thread_list (void)
289 {
290 for_each_inferior (&all_threads, delete_thread_info);
291 }
292
293 static void
294 do_initial_child_stuff (DWORD pid)
295 {
296 last_sig = TARGET_SIGNAL_0;
297
298 debug_registers_changed = 0;
299 debug_registers_used = 0;
300
301 memset (&current_event, 0, sizeof (current_event));
302
303 child_init_thread_list ();
304
305 if (the_low_target.initial_stuff != NULL)
306 (*the_low_target.initial_stuff) ();
307 }
308
309 /* Resume all artificially suspended threads if we are continuing
310 execution. */
311 static int
312 continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
313 {
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);
317 int i;
318
319 if ((thread_id == -1 || thread_id == th->tid)
320 && th->suspend_count)
321 {
322 for (i = 0; i < th->suspend_count; i++)
323 (void) ResumeThread (th->h);
324 th->suspend_count = 0;
325 if (debug_registers_changed)
326 {
327 /* Only change the value of the debug registers. */
328 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
329
330 if (the_low_target.load_debug_registers != NULL)
331 the_low_target.load_debug_registers (th);
332
333 SetThreadContext (th->h, &th->context);
334 th->context.ContextFlags = 0;
335 }
336 }
337
338 return 0;
339 }
340
341 static BOOL
342 child_continue (DWORD continue_status, int thread_id)
343 {
344 BOOL res;
345
346 res = ContinueDebugEvent (current_event.dwProcessId,
347 current_event.dwThreadId, continue_status);
348 continue_status = 0;
349 if (res)
350 find_inferior (&all_threads, continue_one_thread, &thread_id);
351
352 debug_registers_changed = 0;
353 return res;
354 }
355
356 /* Fetch register(s) from the current thread context. */
357 static void
358 child_fetch_inferior_registers (int r)
359 {
360 int regno;
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);
364 else
365 for (regno = 0; regno < r; regno++)
366 (*the_low_target.fetch_inferior_registers) (th, regno);
367 }
368
369 /* Get register from gdbserver regcache data. */
370 static void
371 do_child_store_inferior_registers (win32_thread_info *th, int r)
372 {
373 collect_register (r, regptr (&th->context, r));
374 }
375
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. */
378 static void
379 child_store_inferior_registers (int r)
380 {
381 int regno;
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);
385 else
386 for (regno = 0; regno < r; regno++)
387 do_child_store_inferior_registers (th, regno);
388 }
389
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.
393
394 The string pointed to shall not be modified by the application,
395 but may be overwritten by a subsequent call to strwinerror
396
397 The strwinerror function does not change the current setting
398 of GetLastError. */
399
400 char *
401 strwinerror (DWORD error)
402 {
403 static char buf[1024];
404 TCHAR *msgbuf;
405 DWORD lasterr = GetLastError ();
406 DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
407 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
408 NULL,
409 error,
410 0, /* Default language */
411 (LPVOID)&msgbuf,
412 0,
413 NULL);
414 if (chars != 0)
415 {
416 /* If there is an \r\n appended, zap it. */
417 if (chars >= 2
418 && msgbuf[chars - 2] == '\r'
419 && msgbuf[chars - 1] == '\n')
420 {
421 chars -= 2;
422 msgbuf[chars] = 0;
423 }
424
425 if (chars > ((COUNTOF (buf)) - 1))
426 {
427 chars = COUNTOF (buf) - 1;
428 msgbuf [chars] = 0;
429 }
430
431 #ifdef UNICODE
432 wcstombs (buf, msgbuf, chars + 1);
433 #else
434 strncpy (buf, msgbuf, chars + 1);
435 #endif
436 LocalFree (msgbuf);
437 }
438 else
439 sprintf (buf, "unknown win32 error (%ld)", error);
440
441 SetLastError (lasterr);
442 return buf;
443 }
444
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. */
451 static int
452 win32_create_inferior (char *program, char **program_args)
453 {
454 #ifndef USE_WIN32API
455 char real_path[MAXPATHLEN];
456 char *orig_path, *new_path, *path_ptr;
457 #endif
458 BOOL ret;
459 DWORD flags;
460 char *args;
461 int argslen;
462 int argc;
463 PROCESS_INFORMATION pi;
464 #ifndef __MINGW32CE__
465 STARTUPINFO si = { sizeof (STARTUPINFO) };
466 char *winenv = NULL;
467 #else
468 wchar_t *wargs, *wprogram;
469 #endif
470
471 if (!program)
472 error ("No executable specified, specify executable to debug.\n");
473
474 flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
475
476 #ifndef USE_WIN32API
477 orig_path = NULL;
478 path_ptr = getenv ("PATH");
479 if (path_ptr)
480 {
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);
486 }
487 cygwin_conv_to_win32_path (program, real_path);
488 program = real_path;
489 #endif
490
491 argslen = 1;
492 for (argc = 1; program_args[argc]; argc++)
493 argslen += strlen (program_args[argc]) + 1;
494 args = alloca (argslen);
495 args[0] = '\0';
496 for (argc = 1; program_args[argc]; argc++)
497 {
498 /* FIXME: Can we do better about quoting? How does Cygwin
499 handle this? */
500 strcat (args, " ");
501 strcat (args, program_args[argc]);
502 }
503 OUTMSG2 (("Command line is \"%s\"\n", args));
504
505 #ifdef CREATE_NEW_PROCESS_GROUP
506 flags |= CREATE_NEW_PROCESS_GROUP;
507 #endif
508
509 #ifdef __MINGW32CE__
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 */
525 #else
526 ret = CreateProcess (program, /* image name */
527 args, /* command line */
528 NULL, /* security */
529 NULL, /* thread */
530 TRUE, /* inherit handles */
531 flags, /* start flags */
532 winenv, /* environment */
533 NULL, /* current directory */
534 &si, /* start info */
535 &pi); /* proc info */
536 #endif
537
538 #ifndef USE_WIN32API
539 if (orig_path)
540 setenv ("PATH", orig_path, 1);
541 #endif
542
543 if (!ret)
544 {
545 DWORD err = GetLastError ();
546 error ("Error creating process \"%s%s\", (error %d): %s\n",
547 program, args, (int) err, strwinerror (err));
548 }
549 else
550 {
551 OUTMSG2 (("Process created: %s\n", (char *) args));
552 }
553
554 #ifndef _WIN32_WCE
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);
559 #endif
560
561 current_process_handle = pi.hProcess;
562 current_process_id = pi.dwProcessId;
563
564 do_initial_child_stuff (current_process_id);
565
566 return current_process_id;
567 }
568
569 /* Attach to a running process.
570 PID is the process ID to attach to, specified by the user
571 or a higher layer. */
572 static int
573 win32_attach (unsigned long pid)
574 {
575 int res = 0;
576 winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
577
578 winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
579 #ifdef _WIN32_WCE
580 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
581 #else
582 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
583 #endif
584 DebugActiveProcessStop = (winapi_DebugActiveProcessStop *)
585 GetProcAddress (dll, _T("DebugActiveProcessStop"));
586 DebugSetProcessKillOnExit = (winapi_DebugSetProcessKillOnExit *)
587 GetProcAddress (dll, _T("DebugSetProcessKillOnExit"));
588
589 res = DebugActiveProcess (pid) ? 1 : 0;
590
591 if (!res)
592 error ("Attach to process failed.");
593
594 if (DebugSetProcessKillOnExit != NULL)
595 DebugSetProcessKillOnExit (FALSE);
596
597 current_process_id = pid;
598 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
599
600 if (current_process_handle == NULL)
601 {
602 res = 0;
603 if (DebugActiveProcessStop != NULL)
604 DebugActiveProcessStop (current_process_id);
605 }
606
607 if (res)
608 do_initial_child_stuff (pid);
609
610 return res;
611 }
612
613 /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
614 static void
615 handle_output_debug_string (struct target_waitstatus *ourstatus)
616 {
617 #define READ_BUFFER_LEN 1024
618 CORE_ADDR addr;
619 char s[READ_BUFFER_LEN + 1] = { 0 };
620 DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
621
622 if (nbytes == 0)
623 return;
624
625 if (nbytes > READ_BUFFER_LEN)
626 nbytes = READ_BUFFER_LEN;
627
628 addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
629
630 if (current_event.u.DebugString.fUnicode)
631 {
632 /* The event tells us how many bytes, not chars, even
633 in Unicode. */
634 WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
635 if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
636 return;
637 wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
638 }
639 else
640 {
641 if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
642 return;
643 }
644
645 if (strncmp (s, "cYg", 3) != 0)
646 monitor_output (s);
647 #undef READ_BUFFER_LEN
648 }
649
650 /* Kill all inferiors. */
651 static void
652 win32_kill (void)
653 {
654 win32_thread_info *current_thread;
655
656 if (current_process_handle == NULL)
657 return;
658
659 TerminateProcess (current_process_handle, 0);
660 for (;;)
661 {
662 if (!child_continue (DBG_CONTINUE, -1))
663 break;
664 if (!WaitForDebugEvent (&current_event, INFINITE))
665 break;
666 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
667 break;
668 else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
669 {
670 struct target_waitstatus our_status = { 0 };
671 handle_output_debug_string (&our_status);
672 }
673 }
674
675 CloseHandle (current_process_handle);
676
677 current_thread = inferior_target_data (current_inferior);
678 if (current_thread && current_thread->h)
679 {
680 /* This may fail in an attached process, so don't check. */
681 (void) CloseHandle (current_thread->h);
682 }
683 }
684
685 /* Detach from all inferiors. */
686 static void
687 win32_detach (void)
688 {
689 winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
690 winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
691 #ifdef _WIN32_WCE
692 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
693 #else
694 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
695 #endif
696 DebugActiveProcessStop = (winapi_DebugActiveProcessStop *)
697 GetProcAddress (dll, _T("DebugActiveProcessStop"));
698 DebugSetProcessKillOnExit = (winapi_DebugSetProcessKillOnExit *)
699 GetProcAddress (dll, _T("DebugSetProcessKillOnExit"));
700
701 if (DebugSetProcessKillOnExit != NULL)
702 DebugSetProcessKillOnExit (FALSE);
703
704 if (DebugActiveProcessStop != NULL)
705 DebugActiveProcessStop (current_process_id);
706 else
707 win32_kill ();
708 }
709
710 /* Return 1 iff the thread with thread ID TID is alive. */
711 static int
712 win32_thread_alive (unsigned long tid)
713 {
714 int res;
715
716 /* Our thread list is reliable; don't bother to poll target
717 threads. */
718 if (find_inferior_id (&all_threads, tid) != NULL)
719 res = 1;
720 else
721 res = 0;
722 return res;
723 }
724
725 /* Resume the inferior process. RESUME_INFO describes how we want
726 to resume. */
727 static void
728 win32_resume (struct thread_resume *resume_info)
729 {
730 DWORD tid;
731 enum target_signal sig;
732 int step;
733 win32_thread_info *th;
734 DWORD continue_status = DBG_CONTINUE;
735
736 /* This handles the very limited set of resume packets that GDB can
737 currently produce. */
738
739 if (resume_info[0].thread == -1)
740 tid = -1;
741 else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
742 tid = -1;
743 else
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;
747
748 if (resume_info[0].thread != -1)
749 {
750 sig = resume_info[0].sig;
751 step = resume_info[0].step;
752 }
753 else
754 {
755 sig = 0;
756 step = 0;
757 }
758
759 if (sig != TARGET_SIGNAL_0)
760 {
761 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
762 {
763 OUTMSG (("Cannot continue with signal %d here.\n", sig));
764 }
765 else if (sig == last_sig)
766 continue_status = DBG_EXCEPTION_NOT_HANDLED;
767 else
768 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
769 }
770
771 last_sig = TARGET_SIGNAL_0;
772
773 /* Get context for the currently selected thread. */
774 th = thread_rec (current_event.dwThreadId, FALSE);
775 if (th)
776 {
777 if (th->context.ContextFlags)
778 {
779 if (debug_registers_changed)
780 if (the_low_target.load_debug_registers != NULL)
781 (*the_low_target.load_debug_registers) (th);
782
783 /* Move register values from the inferior into the thread
784 context structure. */
785 regcache_invalidate ();
786
787 if (step)
788 {
789 if (the_low_target.single_step != NULL)
790 (*the_low_target.single_step) (th);
791 else
792 error ("Single stepping is not supported "
793 "in this configuration.\n");
794 }
795 SetThreadContext (th->h, &th->context);
796 th->context.ContextFlags = 0;
797 }
798 }
799
800 /* Allow continuing with the same signal that interrupted us.
801 Otherwise complain. */
802
803 child_continue (continue_status, tid);
804 }
805
806 static int
807 handle_exception (struct target_waitstatus *ourstatus)
808 {
809 win32_thread_info *th;
810 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
811
812 ourstatus->kind = TARGET_WAITKIND_STOPPED;
813
814 /* Record the context of the current thread. */
815 th = thread_rec (current_event.dwThreadId, -1);
816
817 switch (code)
818 {
819 case EXCEPTION_ACCESS_VIOLATION:
820 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
821 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
822 break;
823 case STATUS_STACK_OVERFLOW:
824 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
825 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
826 break;
827 case STATUS_FLOAT_DENORMAL_OPERAND:
828 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
829 ourstatus->value.sig = TARGET_SIGNAL_FPE;
830 break;
831 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
832 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
833 ourstatus->value.sig = TARGET_SIGNAL_FPE;
834 break;
835 case STATUS_FLOAT_INEXACT_RESULT:
836 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
837 ourstatus->value.sig = TARGET_SIGNAL_FPE;
838 break;
839 case STATUS_FLOAT_INVALID_OPERATION:
840 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
841 ourstatus->value.sig = TARGET_SIGNAL_FPE;
842 break;
843 case STATUS_FLOAT_OVERFLOW:
844 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
845 ourstatus->value.sig = TARGET_SIGNAL_FPE;
846 break;
847 case STATUS_FLOAT_STACK_CHECK:
848 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
849 ourstatus->value.sig = TARGET_SIGNAL_FPE;
850 break;
851 case STATUS_FLOAT_UNDERFLOW:
852 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
853 ourstatus->value.sig = TARGET_SIGNAL_FPE;
854 break;
855 case STATUS_FLOAT_DIVIDE_BY_ZERO:
856 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
857 ourstatus->value.sig = TARGET_SIGNAL_FPE;
858 break;
859 case STATUS_INTEGER_DIVIDE_BY_ZERO:
860 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
861 ourstatus->value.sig = TARGET_SIGNAL_FPE;
862 break;
863 case STATUS_INTEGER_OVERFLOW:
864 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
865 ourstatus->value.sig = TARGET_SIGNAL_FPE;
866 break;
867 case EXCEPTION_BREAKPOINT:
868 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
869 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
870 #ifdef _WIN32_WCE
871 /* Remove the initial breakpoint. */
872 check_breakpoints ((CORE_ADDR) (long) current_event
873 .u.Exception.ExceptionRecord.ExceptionAddress);
874 #endif
875 break;
876 case DBG_CONTROL_C:
877 OUTMSG2 (("DBG_CONTROL_C"));
878 ourstatus->value.sig = TARGET_SIGNAL_INT;
879 break;
880 case DBG_CONTROL_BREAK:
881 OUTMSG2 (("DBG_CONTROL_BREAK"));
882 ourstatus->value.sig = TARGET_SIGNAL_INT;
883 break;
884 case EXCEPTION_SINGLE_STEP:
885 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
886 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
887 break;
888 case EXCEPTION_ILLEGAL_INSTRUCTION:
889 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
890 ourstatus->value.sig = TARGET_SIGNAL_ILL;
891 break;
892 case EXCEPTION_PRIV_INSTRUCTION:
893 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
894 ourstatus->value.sig = TARGET_SIGNAL_ILL;
895 break;
896 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
897 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
898 ourstatus->value.sig = TARGET_SIGNAL_ILL;
899 break;
900 default:
901 if (current_event.u.Exception.dwFirstChance)
902 return 0;
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.
906 ExceptionAddress));
907 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
908 break;
909 }
910 OUTMSG2 (("\n"));
911 last_sig = ourstatus->value.sig;
912 return 1;
913 }
914
915 /* Get the next event from the child. Return 1 if the event requires
916 handling. */
917 static int
918 get_child_debug_event (struct target_waitstatus *ourstatus)
919 {
920 BOOL debug_event;
921 DWORD continue_status, event_code;
922 win32_thread_info *th = NULL;
923 static win32_thread_info dummy_thread_info;
924 int retval = 0;
925
926 in:
927
928 last_sig = TARGET_SIGNAL_0;
929 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
930
931 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
932 goto out;
933
934 current_inferior =
935 (struct thread_info *) find_inferior_id (&all_threads,
936 current_event.dwThreadId);
937
938 continue_status = DBG_CONTINUE;
939 event_code = current_event.dwDebugEventCode;
940
941 switch (event_code)
942 {
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));
948
949 /* Record the existence of this thread. */
950 th = child_add_thread (current_event.dwThreadId,
951 current_event.u.CreateThread.hThread);
952
953 retval = current_event.dwThreadId;
954 break;
955
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;
963 break;
964
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);
971
972 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
973 main_thread_id = current_event.dwThreadId;
974
975 ourstatus->kind = TARGET_WAITKIND_EXECD;
976 ourstatus->value.execd_pathname = "Main executable";
977
978 /* Add the main thread. */
979 th =
980 child_add_thread (main_thread_id,
981 current_event.u.CreateProcessInfo.hThread);
982
983 retval = ourstatus->value.related_pid = current_event.dwThreadId;
984 #ifdef _WIN32_WCE
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);
991 #endif
992 break;
993
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;
1004 break;
1005
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);
1012
1013 ourstatus->kind = TARGET_WAITKIND_LOADED;
1014 ourstatus->value.integer = 0;
1015 retval = main_thread_id;
1016 break;
1017
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));
1023 break;
1024
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);
1031 break;
1032
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);
1040 break;
1041
1042 default:
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));
1048 break;
1049 }
1050
1051 current_inferior =
1052 (struct thread_info *) find_inferior_id (&all_threads,
1053 current_event.dwThreadId);
1054
1055 if (!retval || (event_code != EXCEPTION_DEBUG_EVENT && event_code != EXIT_PROCESS_DEBUG_EVENT))
1056 {
1057 child_continue (continue_status, -1);
1058 goto in;
1059 }
1060
1061 if (th == NULL)
1062 thread_rec (current_event.dwThreadId, TRUE);
1063
1064 out:
1065 return retval;
1066 }
1067
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)
1073 {
1074 struct target_waitstatus our_status;
1075
1076 *status = 'T';
1077
1078 while (1)
1079 {
1080 get_child_debug_event (&our_status);
1081
1082 if (our_status.kind == TARGET_WAITKIND_EXITED)
1083 {
1084 OUTMSG2 (("Child exited with retcode = %x\n",
1085 our_status.value.integer));
1086
1087 *status = 'W';
1088
1089 child_fetch_inferior_registers (-1);
1090
1091 return our_status.value.integer;
1092 }
1093 else if (our_status.kind == TARGET_WAITKIND_STOPPED)
1094 {
1095 OUTMSG2 (("Child Stopped with signal = %d \n",
1096 our_status.value.sig));
1097
1098 *status = 'T';
1099
1100 child_fetch_inferior_registers (-1);
1101
1102 return our_status.value.sig;
1103 }
1104 else
1105 OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
1106
1107 {
1108 struct thread_resume resume;
1109 resume.thread = -1;
1110 resume.step = 0;
1111 resume.sig = 0;
1112 resume.leave_stopped = 0;
1113 win32_resume (&resume);
1114 }
1115 }
1116 }
1117
1118 /* Fetch registers from the inferior process.
1119 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1120 static void
1121 win32_fetch_inferior_registers (int regno)
1122 {
1123 child_fetch_inferior_registers (regno);
1124 }
1125
1126 /* Store registers to the inferior process.
1127 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1128 static void
1129 win32_store_inferior_registers (int regno)
1130 {
1131 child_store_inferior_registers (regno);
1132 }
1133
1134 /* Read memory from the inferior process. This should generally be
1135 called through read_inferior_memory, which handles breakpoint shadowing.
1136 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1137 static int
1138 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1139 {
1140 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
1141 }
1142
1143 /* Write memory to the inferior process. This should generally be
1144 called through write_inferior_memory, which handles breakpoint shadowing.
1145 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1146 Returns 0 on success and errno on failure. */
1147 static int
1148 win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1149 int len)
1150 {
1151 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1152 }
1153
1154 static const char *
1155 win32_arch_string (void)
1156 {
1157 return the_low_target.arch_string;
1158 }
1159
1160 static struct target_ops win32_target_ops = {
1161 win32_create_inferior,
1162 win32_attach,
1163 win32_kill,
1164 win32_detach,
1165 win32_thread_alive,
1166 win32_resume,
1167 win32_wait,
1168 win32_fetch_inferior_registers,
1169 win32_store_inferior_registers,
1170 win32_read_inferior_memory,
1171 win32_write_inferior_memory,
1172 NULL,
1173 NULL,
1174 NULL,
1175 NULL,
1176 NULL,
1177 NULL,
1178 NULL,
1179 NULL,
1180 NULL,
1181 win32_arch_string
1182 };
1183
1184 /* Initialize the Win32 backend. */
1185 void
1186 initialize_low (void)
1187 {
1188 set_target_ops (&win32_target_ops);
1189 if (the_low_target.breakpoint != NULL)
1190 set_breakpoint_data (the_low_target.breakpoint,
1191 the_low_target.breakpoint_len);
1192 init_registers ();
1193 }
This page took 0.073618 seconds and 4 git commands to generate.