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