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