* linux-low.c (linux_kill): Handle being called with no threads.
[deliverable/binutils-gdb.git] / gdb / gdbserver / win32-i386-low.c
1 /* Low level interface to Windows debugging, for gdbserver.
2 Copyright (C) 2006
3 Free Software Foundation, Inc.
4
5 Contributed by Leo Zayas. Based on "win32-nat.c" from GDB.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
23
24 #include "server.h"
25 #include "regcache.h"
26 #include "gdb/signals.h"
27
28 #include <windows.h>
29 #include <imagehlp.h>
30 #include <psapi.h>
31 #include <sys/param.h>
32 #include <malloc.h>
33 #include <process.h>
34
35 #ifndef USE_WIN32API
36 #include <sys/cygwin.h>
37 #endif
38
39 #define LOG 0
40
41 #define OUTMSG(X) do { printf X; fflush (stdout); } while (0)
42 #if LOG
43 #define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
44 #else
45 #define OUTMSG2(X)
46 #endif
47
48 int debug_threads;
49 int using_threads = 1;
50
51 /* Globals. */
52 static HANDLE current_process_handle = NULL;
53 static DWORD current_process_id = 0;
54 static enum target_signal last_sig = TARGET_SIGNAL_0;
55
56 /* The current debug event from WaitForDebugEvent. */
57 static DEBUG_EVENT current_event;
58
59 static int debug_registers_changed = 0;
60 static int debug_registers_used = 0;
61 static unsigned dr[8];
62
63 typedef BOOL winapi_DebugActiveProcessStop (DWORD dwProcessId);
64 typedef BOOL winapi_DebugSetProcessKillOnExit (BOOL KillOnExit);
65
66 #define FLAG_TRACE_BIT 0x100
67 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
68 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
69 | CONTEXT_EXTENDED_REGISTERS
70
71 /* Thread information structure used to track extra information about
72 each thread. */
73 typedef struct thread_info_struct
74 {
75 DWORD tid;
76 HANDLE h;
77 int suspend_count;
78 CONTEXT context;
79 } thread_info;
80 static DWORD main_thread_id = 0;
81
82 /* Get the thread ID from the current selected inferior (the current
83 thread). */
84 static DWORD
85 current_inferior_tid (void)
86 {
87 thread_info *th = inferior_target_data (current_inferior);
88 return th->tid;
89 }
90
91 /* Find a thread record given a thread id. If GET_CONTEXT is set then
92 also retrieve the context for this thread. */
93 static thread_info *
94 thread_rec (DWORD id, int get_context)
95 {
96 struct thread_info *thread;
97 thread_info *th;
98
99 thread = (struct thread_info *) find_inferior_id (&all_threads, id);
100 if (thread == NULL)
101 return NULL;
102
103 th = inferior_target_data (thread);
104 if (!th->suspend_count && get_context)
105 {
106 if (get_context > 0 && id != current_event.dwThreadId)
107 th->suspend_count = SuspendThread (th->h) + 1;
108 else if (get_context < 0)
109 th->suspend_count = -1;
110
111 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
112
113 GetThreadContext (th->h, &th->context);
114
115 if (id == current_event.dwThreadId)
116 {
117 /* Copy dr values from that thread. */
118 dr[0] = th->context.Dr0;
119 dr[1] = th->context.Dr1;
120 dr[2] = th->context.Dr2;
121 dr[3] = th->context.Dr3;
122 dr[6] = th->context.Dr6;
123 dr[7] = th->context.Dr7;
124 }
125 }
126
127 return th;
128 }
129
130 /* Add a thread to the thread list. */
131 static thread_info *
132 child_add_thread (DWORD tid, HANDLE h)
133 {
134 thread_info *th;
135
136 if ((th = thread_rec (tid, FALSE)))
137 return th;
138
139 th = (thread_info *) malloc (sizeof (*th));
140 memset (th, 0, sizeof (*th));
141 th->tid = tid;
142 th->h = h;
143
144 add_thread (tid, th, (unsigned int) tid);
145 set_inferior_regcache_data ((struct thread_info *)
146 find_inferior_id (&all_threads, tid),
147 new_register_cache ());
148
149 /* Set the debug registers for the new thread if they are used. */
150 if (debug_registers_used)
151 {
152 /* Only change the value of the debug registers. */
153 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
154
155 GetThreadContext (th->h, &th->context);
156
157 th->context.Dr0 = dr[0];
158 th->context.Dr1 = dr[1];
159 th->context.Dr2 = dr[2];
160 th->context.Dr3 = dr[3];
161 /* th->context.Dr6 = dr[6];
162 FIXME: should we set dr6 also ?? */
163 th->context.Dr7 = dr[7];
164 SetThreadContext (th->h, &th->context);
165 th->context.ContextFlags = 0;
166 }
167
168 return th;
169 }
170
171 /* Delete a thread from the list of threads. */
172 static void
173 delete_thread_info (struct inferior_list_entry *thread)
174 {
175 thread_info *th = inferior_target_data ((struct thread_info *) thread);
176
177 remove_thread ((struct thread_info *) thread);
178 CloseHandle (th->h);
179 free (th);
180 }
181
182 /* Delete a thread from the list of threads. */
183 static void
184 child_delete_thread (DWORD id)
185 {
186 struct inferior_list_entry *thread;
187
188 /* If the last thread is exiting, just return. */
189 if (all_threads.head == all_threads.tail)
190 return;
191
192 thread = find_inferior_id (&all_threads, id);
193 if (thread == NULL)
194 return;
195
196 delete_thread_info (thread);
197 }
198
199 /* Transfer memory from/to the debugged process. */
200 static int
201 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
202 int write, struct target_ops *target)
203 {
204 SIZE_T done;
205 long addr = (long) memaddr;
206
207 if (write)
208 {
209 WriteProcessMemory (current_process_handle, (LPVOID) addr,
210 (LPCVOID) our, len, &done);
211 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
212 }
213 else
214 {
215 ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
216 len, &done);
217 }
218 return done;
219 }
220
221 /* Generally, what has the program done? */
222 enum target_waitkind
223 {
224 /* The program has exited. The exit status is in value.integer. */
225 TARGET_WAITKIND_EXITED,
226
227 /* The program has stopped with a signal. Which signal is in
228 value.sig. */
229 TARGET_WAITKIND_STOPPED,
230
231 /* The program is letting us know that it dynamically loaded something
232 (e.g. it called load(2) on AIX). */
233 TARGET_WAITKIND_LOADED,
234
235 /* The program has exec'ed a new executable file. The new file's
236 pathname is pointed to by value.execd_pathname. */
237
238 TARGET_WAITKIND_EXECD,
239
240 /* Nothing happened, but we stopped anyway. This perhaps should be handled
241 within target_wait, but I'm not sure target_wait should be resuming the
242 inferior. */
243 TARGET_WAITKIND_SPURIOUS,
244 };
245
246 struct target_waitstatus
247 {
248 enum target_waitkind kind;
249
250 /* Forked child pid, execd pathname, exit status or signal number. */
251 union
252 {
253 int integer;
254 enum target_signal sig;
255 int related_pid;
256 char *execd_pathname;
257 int syscall_id;
258 }
259 value;
260 };
261
262 #define NUM_REGS 41
263 #define FCS_REGNUM 27
264 #define FOP_REGNUM 31
265
266 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
267 static const int mappings[] = {
268 context_offset (Eax),
269 context_offset (Ecx),
270 context_offset (Edx),
271 context_offset (Ebx),
272 context_offset (Esp),
273 context_offset (Ebp),
274 context_offset (Esi),
275 context_offset (Edi),
276 context_offset (Eip),
277 context_offset (EFlags),
278 context_offset (SegCs),
279 context_offset (SegSs),
280 context_offset (SegDs),
281 context_offset (SegEs),
282 context_offset (SegFs),
283 context_offset (SegGs),
284 context_offset (FloatSave.RegisterArea[0 * 10]),
285 context_offset (FloatSave.RegisterArea[1 * 10]),
286 context_offset (FloatSave.RegisterArea[2 * 10]),
287 context_offset (FloatSave.RegisterArea[3 * 10]),
288 context_offset (FloatSave.RegisterArea[4 * 10]),
289 context_offset (FloatSave.RegisterArea[5 * 10]),
290 context_offset (FloatSave.RegisterArea[6 * 10]),
291 context_offset (FloatSave.RegisterArea[7 * 10]),
292 context_offset (FloatSave.ControlWord),
293 context_offset (FloatSave.StatusWord),
294 context_offset (FloatSave.TagWord),
295 context_offset (FloatSave.ErrorSelector),
296 context_offset (FloatSave.ErrorOffset),
297 context_offset (FloatSave.DataSelector),
298 context_offset (FloatSave.DataOffset),
299 context_offset (FloatSave.ErrorSelector),
300 /* XMM0-7 */
301 context_offset (ExtendedRegisters[10 * 16]),
302 context_offset (ExtendedRegisters[11 * 16]),
303 context_offset (ExtendedRegisters[12 * 16]),
304 context_offset (ExtendedRegisters[13 * 16]),
305 context_offset (ExtendedRegisters[14 * 16]),
306 context_offset (ExtendedRegisters[15 * 16]),
307 context_offset (ExtendedRegisters[16 * 16]),
308 context_offset (ExtendedRegisters[17 * 16]),
309 /* MXCSR */
310 context_offset (ExtendedRegisters[24])
311 };
312
313 #undef context_offset
314
315 /* Clear out any old thread list and reintialize it to a pristine
316 state. */
317 static void
318 child_init_thread_list (void)
319 {
320 for_each_inferior (&all_threads, delete_thread_info);
321 }
322
323 static void
324 do_initial_child_stuff (DWORD pid)
325 {
326 int i;
327
328 last_sig = TARGET_SIGNAL_0;
329
330 debug_registers_changed = 0;
331 debug_registers_used = 0;
332 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
333 dr[i] = 0;
334 memset (&current_event, 0, sizeof (current_event));
335
336 child_init_thread_list ();
337 }
338
339 /* Resume all artificially suspended threads if we are continuing
340 execution. */
341 static int
342 continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
343 {
344 struct thread_info *thread = (struct thread_info *) this_thread;
345 int thread_id = * (int *) id_ptr;
346 thread_info *th = inferior_target_data (thread);
347 int i;
348
349 if ((thread_id == -1 || thread_id == th->tid)
350 && th->suspend_count)
351 {
352 for (i = 0; i < th->suspend_count; i++)
353 (void) ResumeThread (th->h);
354 th->suspend_count = 0;
355 if (debug_registers_changed)
356 {
357 /* Only change the value of the debug registers. */
358 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
359 th->context.Dr0 = dr[0];
360 th->context.Dr1 = dr[1];
361 th->context.Dr2 = dr[2];
362 th->context.Dr3 = dr[3];
363 /* th->context.Dr6 = dr[6];
364 FIXME: should we set dr6 also ?? */
365 th->context.Dr7 = dr[7];
366 SetThreadContext (th->h, &th->context);
367 th->context.ContextFlags = 0;
368 }
369 }
370
371 return 0;
372 }
373
374 static BOOL
375 child_continue (DWORD continue_status, int thread_id)
376 {
377 BOOL res;
378
379 res = ContinueDebugEvent (current_event.dwProcessId,
380 current_event.dwThreadId, continue_status);
381 continue_status = 0;
382 if (res)
383 find_inferior (&all_threads, continue_one_thread, &thread_id);
384
385 debug_registers_changed = 0;
386 return res;
387 }
388
389 /* Fetch register(s) from gdbserver regcache data. */
390 static void
391 do_child_fetch_inferior_registers (thread_info *th, int r)
392 {
393 char *context_offset = ((char *) &th->context) + mappings[r];
394 long l;
395 if (r == FCS_REGNUM)
396 {
397 l = *((long *) context_offset) & 0xffff;
398 supply_register (r, (char *) &l);
399 }
400 else if (r == FOP_REGNUM)
401 {
402 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
403 supply_register (r, (char *) &l);
404 }
405 else
406 supply_register (r, context_offset);
407 }
408
409 /* Fetch register(s) from the current thread context. */
410 static void
411 child_fetch_inferior_registers (int r)
412 {
413 int regno;
414 thread_info *th = thread_rec (current_inferior_tid (), TRUE);
415 if (r == -1 || r == 0 || r > NUM_REGS)
416 child_fetch_inferior_registers (NUM_REGS);
417 else
418 for (regno = 0; regno < r; regno++)
419 do_child_fetch_inferior_registers (th, regno);
420 }
421
422 /* Get register from gdbserver regcache data. */
423 static void
424 do_child_store_inferior_registers (thread_info *th, int r)
425 {
426 collect_register (r, ((char *) &th->context) + mappings[r]);
427 }
428
429 /* Store a new register value into the current thread context. We don't
430 change the program's context until later, when we resume it. */
431 static void
432 child_store_inferior_registers (int r)
433 {
434 int regno;
435 thread_info *th = thread_rec (current_inferior_tid (), TRUE);
436 if (r == -1 || r == 0 || r > NUM_REGS)
437 child_store_inferior_registers (NUM_REGS);
438 else
439 for (regno = 0; regno < r; regno++)
440 do_child_store_inferior_registers (th, regno);
441 }
442
443 /* Start a new process.
444 PROGRAM is a path to the program to execute.
445 ARGS is a standard NULL-terminated array of arguments,
446 to be passed to the inferior as ``argv''.
447 Returns the new PID on success, -1 on failure. Registers the new
448 process with the process list. */
449 static int
450 win32_create_inferior (char *program, char **program_args)
451 {
452 #ifndef USE_WIN32API
453 char real_path[MAXPATHLEN];
454 char *orig_path, *new_path, *path_ptr;
455 #endif
456 char *winenv = NULL;
457 STARTUPINFO si;
458 PROCESS_INFORMATION pi;
459 BOOL ret;
460 DWORD flags;
461 char *args;
462 int argslen;
463 int argc;
464
465 if (!program)
466 error ("No executable specified, specify executable to debug.\n");
467
468 memset (&si, 0, sizeof (si));
469 si.cb = sizeof (si);
470
471 flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
472
473 #ifndef USE_WIN32API
474 orig_path = NULL;
475 path_ptr = getenv ("PATH");
476 if (path_ptr)
477 {
478 orig_path = alloca (strlen (path_ptr) + 1);
479 new_path = alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr));
480 strcpy (orig_path, path_ptr);
481 cygwin_posix_to_win32_path_list (path_ptr, new_path);
482 setenv ("PATH", new_path, 1);
483 }
484 cygwin_conv_to_win32_path (program, real_path);
485 program = real_path;
486 #endif
487
488 argslen = strlen (program) + 1;
489 for (argc = 1; program_args[argc]; argc++)
490 argslen += strlen (program_args[argc]) + 1;
491 args = alloca (argslen);
492 strcpy (args, program);
493 for (argc = 1; program_args[argc]; argc++)
494 {
495 /* FIXME: Can we do better about quoting? How does Cygwin
496 handle this? */
497 strcat (args, " ");
498 strcat (args, program_args[argc]);
499 }
500 OUTMSG2 (("Command line is %s\n", args));
501
502 flags |= CREATE_NEW_PROCESS_GROUP;
503
504 ret = CreateProcess (0, args, /* command line */
505 NULL, /* Security */
506 NULL, /* thread */
507 TRUE, /* inherit handles */
508 flags, /* start flags */
509 winenv, NULL, /* current directory */
510 &si, &pi);
511
512 #ifndef USE_WIN32API
513 if (orig_path)
514 setenv ("PATH", orig_path, 1);
515 #endif
516
517 if (!ret)
518 {
519 error ("Error creating process %s, (error %d): %s\n", args,
520 (int) GetLastError (), strerror (GetLastError ()));
521 }
522 else
523 {
524 OUTMSG2 (("Process created: %s\n", (char *) args));
525 }
526
527 CloseHandle (pi.hThread);
528
529 current_process_handle = pi.hProcess;
530 current_process_id = pi.dwProcessId;
531
532 do_initial_child_stuff (current_process_id);
533
534 return current_process_id;
535 }
536
537 /* Attach to a running process.
538 PID is the process ID to attach to, specified by the user
539 or a higher layer. */
540 static int
541 win32_attach (unsigned long pid)
542 {
543 int res = 0;
544 HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
545 winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
546 winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
547
548 DebugActiveProcessStop =
549 (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
550 "DebugActiveProcessStop");
551 DebugSetProcessKillOnExit =
552 (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
553 "DebugSetProcessKillOnExit");
554
555 res = DebugActiveProcess (pid) ? 1 : 0;
556
557 if (!res)
558 error ("Attach to process failed.");
559
560 if (DebugSetProcessKillOnExit != NULL)
561 DebugSetProcessKillOnExit (FALSE);
562
563 current_process_id = pid;
564 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
565
566 if (current_process_handle == NULL)
567 {
568 res = 0;
569 if (DebugActiveProcessStop != NULL)
570 DebugActiveProcessStop (current_process_id);
571 }
572
573 if (res)
574 do_initial_child_stuff (pid);
575
576 FreeLibrary (kernel32);
577
578 return res;
579 }
580
581 /* Kill all inferiors. */
582 static void
583 win32_kill (void)
584 {
585 if (current_process_handle == NULL)
586 return;
587
588 TerminateProcess (current_process_handle, 0);
589 for (;;)
590 {
591 if (!child_continue (DBG_CONTINUE, -1))
592 break;
593 if (!WaitForDebugEvent (&current_event, INFINITE))
594 break;
595 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
596 break;
597 }
598 }
599
600 /* Detach from all inferiors. */
601 static void
602 win32_detach (void)
603 {
604 HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
605 winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
606 winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
607
608 DebugActiveProcessStop =
609 (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
610 "DebugActiveProcessStop");
611 DebugSetProcessKillOnExit =
612 (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
613 "DebugSetProcessKillOnExit");
614
615 if (DebugSetProcessKillOnExit != NULL)
616 DebugSetProcessKillOnExit (FALSE);
617
618 if (DebugActiveProcessStop != NULL)
619 DebugActiveProcessStop (current_process_id);
620 else
621 win32_kill ();
622
623 FreeLibrary (kernel32);
624 }
625
626 /* Return 1 iff the thread with thread ID TID is alive. */
627 static int
628 win32_thread_alive (unsigned long tid)
629 {
630 int res;
631
632 /* Our thread list is reliable; don't bother to poll target
633 threads. */
634 if (find_inferior_id (&all_threads, tid) != NULL)
635 res = 1;
636 else
637 res = 0;
638 return res;
639 }
640
641 /* Resume the inferior process. RESUME_INFO describes how we want
642 to resume. */
643 static void
644 win32_resume (struct thread_resume *resume_info)
645 {
646 DWORD tid;
647 enum target_signal sig;
648 int step;
649 thread_info *th;
650 DWORD continue_status = DBG_CONTINUE;
651
652 /* This handles the very limited set of resume packets that GDB can
653 currently produce. */
654
655 if (resume_info[0].thread == -1)
656 tid = -1;
657 else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
658 tid = -1;
659 else
660 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
661 the Windows resume code do the right thing for thread switching. */
662 tid = current_event.dwThreadId;
663
664 if (resume_info[0].thread != -1)
665 {
666 sig = resume_info[0].sig;
667 step = resume_info[0].step;
668 }
669 else
670 {
671 sig = 0;
672 step = 0;
673 }
674
675 if (sig != TARGET_SIGNAL_0)
676 {
677 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
678 {
679 OUTMSG (("Cannot continue with signal %d here.\n", sig));
680 }
681 else if (sig == last_sig)
682 continue_status = DBG_EXCEPTION_NOT_HANDLED;
683 else
684 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
685 }
686
687 last_sig = TARGET_SIGNAL_0;
688
689 /* Get context for the currently selected thread. */
690 th = thread_rec (current_event.dwThreadId, FALSE);
691 if (th)
692 {
693 if (th->context.ContextFlags)
694 {
695 if (debug_registers_changed)
696 {
697 th->context.Dr0 = dr[0];
698 th->context.Dr1 = dr[1];
699 th->context.Dr2 = dr[2];
700 th->context.Dr3 = dr[3];
701 /* th->context.Dr6 = dr[6];
702 FIXME: should we set dr6 also ?? */
703 th->context.Dr7 = dr[7];
704 }
705
706 /* Move register values from the inferior into the thread
707 context structure. */
708 regcache_invalidate ();
709
710 if (step)
711 th->context.EFlags |= FLAG_TRACE_BIT;
712
713 SetThreadContext (th->h, &th->context);
714 th->context.ContextFlags = 0;
715 }
716 }
717
718 /* Allow continuing with the same signal that interrupted us.
719 Otherwise complain. */
720
721 child_continue (continue_status, tid);
722 }
723
724 static int
725 handle_exception (struct target_waitstatus *ourstatus)
726 {
727 thread_info *th;
728 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
729
730 ourstatus->kind = TARGET_WAITKIND_STOPPED;
731
732 /* Record the context of the current thread. */
733 th = thread_rec (current_event.dwThreadId, -1);
734
735 switch (code)
736 {
737 case EXCEPTION_ACCESS_VIOLATION:
738 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
739 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
740 break;
741 case STATUS_STACK_OVERFLOW:
742 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
743 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
744 break;
745 case STATUS_FLOAT_DENORMAL_OPERAND:
746 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
747 ourstatus->value.sig = TARGET_SIGNAL_FPE;
748 break;
749 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
750 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
751 ourstatus->value.sig = TARGET_SIGNAL_FPE;
752 break;
753 case STATUS_FLOAT_INEXACT_RESULT:
754 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
755 ourstatus->value.sig = TARGET_SIGNAL_FPE;
756 break;
757 case STATUS_FLOAT_INVALID_OPERATION:
758 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
759 ourstatus->value.sig = TARGET_SIGNAL_FPE;
760 break;
761 case STATUS_FLOAT_OVERFLOW:
762 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
763 ourstatus->value.sig = TARGET_SIGNAL_FPE;
764 break;
765 case STATUS_FLOAT_STACK_CHECK:
766 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
767 ourstatus->value.sig = TARGET_SIGNAL_FPE;
768 break;
769 case STATUS_FLOAT_UNDERFLOW:
770 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
771 ourstatus->value.sig = TARGET_SIGNAL_FPE;
772 break;
773 case STATUS_FLOAT_DIVIDE_BY_ZERO:
774 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
775 ourstatus->value.sig = TARGET_SIGNAL_FPE;
776 break;
777 case STATUS_INTEGER_DIVIDE_BY_ZERO:
778 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
779 ourstatus->value.sig = TARGET_SIGNAL_FPE;
780 break;
781 case STATUS_INTEGER_OVERFLOW:
782 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
783 ourstatus->value.sig = TARGET_SIGNAL_FPE;
784 break;
785 case EXCEPTION_BREAKPOINT:
786 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
787 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
788 break;
789 case DBG_CONTROL_C:
790 OUTMSG2 (("DBG_CONTROL_C"));
791 ourstatus->value.sig = TARGET_SIGNAL_INT;
792 break;
793 case DBG_CONTROL_BREAK:
794 OUTMSG2 (("DBG_CONTROL_BREAK"));
795 ourstatus->value.sig = TARGET_SIGNAL_INT;
796 break;
797 case EXCEPTION_SINGLE_STEP:
798 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
799 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
800 break;
801 case EXCEPTION_ILLEGAL_INSTRUCTION:
802 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
803 ourstatus->value.sig = TARGET_SIGNAL_ILL;
804 break;
805 case EXCEPTION_PRIV_INSTRUCTION:
806 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
807 ourstatus->value.sig = TARGET_SIGNAL_ILL;
808 break;
809 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
810 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
811 ourstatus->value.sig = TARGET_SIGNAL_ILL;
812 break;
813 default:
814 if (current_event.u.Exception.dwFirstChance)
815 return 0;
816 OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
817 current_event.u.Exception.ExceptionRecord.ExceptionCode,
818 (DWORD) current_event.u.Exception.ExceptionRecord.
819 ExceptionAddress));
820 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
821 break;
822 }
823 OUTMSG2 (("\n"));
824 last_sig = ourstatus->value.sig;
825 return 1;
826 }
827
828 /* Get the next event from the child. Return 1 if the event requires
829 handling. */
830 static int
831 get_child_debug_event (struct target_waitstatus *ourstatus)
832 {
833 BOOL debug_event;
834 DWORD continue_status, event_code;
835 thread_info *th = NULL;
836 static thread_info dummy_thread_info;
837 int retval = 0;
838
839 in:
840
841 last_sig = TARGET_SIGNAL_0;
842 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
843
844 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
845 goto out;
846
847 current_inferior =
848 (struct thread_info *) find_inferior_id (&all_threads,
849 current_event.dwThreadId);
850
851 continue_status = DBG_CONTINUE;
852 event_code = current_event.dwDebugEventCode;
853
854 switch (event_code)
855 {
856 case CREATE_THREAD_DEBUG_EVENT:
857 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
858 "for pid=%d tid=%x)\n",
859 (unsigned) current_event.dwProcessId,
860 (unsigned) current_event.dwThreadId));
861
862 /* Record the existence of this thread. */
863 th = child_add_thread (current_event.dwThreadId,
864 current_event.u.CreateThread.hThread);
865
866 retval = current_event.dwThreadId;
867 break;
868
869 case EXIT_THREAD_DEBUG_EVENT:
870 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
871 "for pid=%d tid=%x\n",
872 (unsigned) current_event.dwProcessId,
873 (unsigned) current_event.dwThreadId));
874 child_delete_thread (current_event.dwThreadId);
875 th = &dummy_thread_info;
876 break;
877
878 case CREATE_PROCESS_DEBUG_EVENT:
879 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
880 "for pid=%d tid=%x\n",
881 (unsigned) current_event.dwProcessId,
882 (unsigned) current_event.dwThreadId));
883 CloseHandle (current_event.u.CreateProcessInfo.hFile);
884
885 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
886 main_thread_id = current_event.dwThreadId;
887
888 ourstatus->kind = TARGET_WAITKIND_EXECD;
889 ourstatus->value.execd_pathname = "Main executable";
890
891 /* Add the main thread. */
892 th =
893 child_add_thread (main_thread_id,
894 current_event.u.CreateProcessInfo.hThread);
895
896 retval = ourstatus->value.related_pid = current_event.dwThreadId;
897 break;
898
899 case EXIT_PROCESS_DEBUG_EVENT:
900 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
901 "for pid=%d tid=%x\n",
902 (unsigned) current_event.dwProcessId,
903 (unsigned) current_event.dwThreadId));
904 ourstatus->kind = TARGET_WAITKIND_EXITED;
905 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
906 CloseHandle (current_process_handle);
907 current_process_handle = NULL;
908 retval = main_thread_id;
909 break;
910
911 case LOAD_DLL_DEBUG_EVENT:
912 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
913 "for pid=%d tid=%x\n",
914 (unsigned) current_event.dwProcessId,
915 (unsigned) current_event.dwThreadId));
916 CloseHandle (current_event.u.LoadDll.hFile);
917
918 ourstatus->kind = TARGET_WAITKIND_LOADED;
919 ourstatus->value.integer = 0;
920 retval = main_thread_id;
921 break;
922
923 case UNLOAD_DLL_DEBUG_EVENT:
924 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
925 "for pid=%d tid=%x\n",
926 (unsigned) current_event.dwProcessId,
927 (unsigned) current_event.dwThreadId));
928 break;
929
930 case EXCEPTION_DEBUG_EVENT:
931 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
932 "for pid=%d tid=%x\n",
933 (unsigned) current_event.dwProcessId,
934 (unsigned) current_event.dwThreadId));
935 retval = handle_exception (ourstatus);
936 break;
937
938 case OUTPUT_DEBUG_STRING_EVENT:
939 /* A message from the kernel (or Cygwin). */
940 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
941 "for pid=%d tid=%x\n",
942 (unsigned) current_event.dwProcessId,
943 (unsigned) current_event.dwThreadId));
944 break;
945
946 default:
947 OUTMSG2 (("gdbserver: kernel event unknown "
948 "for pid=%d tid=%x code=%ld\n",
949 (unsigned) current_event.dwProcessId,
950 (unsigned) current_event.dwThreadId,
951 current_event.dwDebugEventCode));
952 break;
953 }
954
955 current_inferior =
956 (struct thread_info *) find_inferior_id (&all_threads,
957 current_event.dwThreadId);
958
959 if (!retval || (event_code != EXCEPTION_DEBUG_EVENT && event_code != EXIT_PROCESS_DEBUG_EVENT))
960 {
961 child_continue (continue_status, -1);
962 goto in;
963 }
964
965 if (th == NULL)
966 thread_rec (current_event.dwThreadId, TRUE);
967
968 out:
969 return retval;
970 }
971
972 /* Wait for the inferior process to change state.
973 STATUS will be filled in with a response code to send to GDB.
974 Returns the signal which caused the process to stop. */
975 static unsigned char
976 win32_wait (char *status)
977 {
978 struct target_waitstatus our_status;
979
980 *status = 'T';
981
982 while (1)
983 {
984 get_child_debug_event (&our_status);
985
986 if (our_status.kind == TARGET_WAITKIND_EXITED)
987 {
988 OUTMSG2 (("Child exited with retcode = %x\n",
989 our_status.value.integer));
990
991 *status = 'W';
992
993 child_fetch_inferior_registers (-1);
994
995 return our_status.value.integer;
996 }
997 else if (our_status.kind == TARGET_WAITKIND_STOPPED)
998 {
999 OUTMSG2 (("Child Stopped with signal = %x \n",
1000 WSTOPSIG (our_status.value.sig)));
1001
1002 *status = 'T';
1003
1004 child_fetch_inferior_registers (-1);
1005
1006 return our_status.value.sig;
1007 }
1008 else
1009 OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
1010
1011 {
1012 struct thread_resume resume;
1013 resume.thread = -1;
1014 resume.step = 0;
1015 resume.sig = 0;
1016 resume.leave_stopped = 0;
1017 win32_resume (&resume);
1018 }
1019 }
1020 }
1021
1022 /* Fetch registers from the inferior process.
1023 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1024 static void
1025 win32_fetch_inferior_registers (int regno)
1026 {
1027 child_fetch_inferior_registers (regno);
1028 }
1029
1030 /* Store registers to the inferior process.
1031 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1032 static void
1033 win32_store_inferior_registers (int regno)
1034 {
1035 child_store_inferior_registers (regno);
1036 }
1037
1038 /* Read memory from the inferior process. This should generally be
1039 called through read_inferior_memory, which handles breakpoint shadowing.
1040 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1041 static int
1042 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1043 {
1044 return child_xfer_memory (memaddr, myaddr, len, 0, 0) != len;
1045 }
1046
1047 /* Write memory to the inferior process. This should generally be
1048 called through write_inferior_memory, which handles breakpoint shadowing.
1049 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1050 Returns 0 on success and errno on failure. */
1051 static int
1052 win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1053 int len)
1054 {
1055 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1056 }
1057
1058 static struct target_ops win32_target_ops = {
1059 win32_create_inferior,
1060 win32_attach,
1061 win32_kill,
1062 win32_detach,
1063 win32_thread_alive,
1064 win32_resume,
1065 win32_wait,
1066 win32_fetch_inferior_registers,
1067 win32_store_inferior_registers,
1068 win32_read_inferior_memory,
1069 win32_write_inferior_memory,
1070 0,
1071 0
1072 };
1073
1074 /* Initialize the Win32 backend. */
1075 void
1076 initialize_low (void)
1077 {
1078 set_target_ops (&win32_target_ops);
1079
1080 init_registers ();
1081 }
This page took 0.051486 seconds and 5 git commands to generate.