* win32-low.c (soft_interrupt_requested, faked_breakpoint): New
[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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
b80864fb
DJ
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
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
b80864fb
DJ
20
21#include "server.h"
22#include "regcache.h"
23#include "gdb/signals.h"
ed50f18f
PA
24#include "mem-break.h"
25#include "win32-low.h"
b80864fb
DJ
26
27#include <windows.h>
ed50f18f 28#include <winnt.h>
b80864fb 29#include <imagehlp.h>
255e7678 30#include <tlhelp32.h>
b80864fb
DJ
31#include <psapi.h>
32#include <sys/param.h>
33#include <malloc.h>
34#include <process.h>
35
36#ifndef USE_WIN32API
37#include <sys/cygwin.h>
38#endif
39
40#define LOG 0
41
42#define OUTMSG(X) do { printf X; fflush (stdout); } while (0)
43#if LOG
44#define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
45#else
ed50f18f
PA
46#define OUTMSG2(X) do ; while (0)
47#endif
48
49#ifndef _T
50#define _T(x) TEXT (x)
51#endif
52
53#ifndef COUNTOF
54#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
b80864fb
DJ
55#endif
56
bf914831
PA
57#ifdef _WIN32_WCE
58# define GETPROCADDRESS(DLL, PROC) \
59 ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC)))
60#else
61# define GETPROCADDRESS(DLL, PROC) \
62 ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
63#endif
64
b80864fb
DJ
65int using_threads = 1;
66
67/* Globals. */
68static HANDLE current_process_handle = NULL;
69static DWORD current_process_id = 0;
70static enum target_signal last_sig = TARGET_SIGNAL_0;
71
72/* The current debug event from WaitForDebugEvent. */
73static DEBUG_EVENT current_event;
74
4d5d1aaa
PA
75/* Non zero if an interrupt request is to be satisfied by suspending
76 all threads. */
77static int soft_interrupt_requested = 0;
78
79/* Non zero if the inferior is stopped in a simulated breakpoint done
80 by suspending all the threads. */
81static int faked_breakpoint = 0;
82
ed50f18f 83#define NUM_REGS (the_low_target.num_regs)
b80864fb 84
bf914831
PA
85typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
86typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
7390519e
PA
87typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
88typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
b80864fb 89
b80864fb
DJ
90static DWORD main_thread_id = 0;
91
34b34921
PA
92static void win32_resume (struct thread_resume *resume_info);
93
b80864fb
DJ
94/* Get the thread ID from the current selected inferior (the current
95 thread). */
96static DWORD
97current_inferior_tid (void)
98{
41093d81 99 win32_thread_info *th = inferior_target_data (current_inferior);
b80864fb
DJ
100 return th->tid;
101}
102
103/* Find a thread record given a thread id. If GET_CONTEXT is set then
104 also retrieve the context for this thread. */
41093d81 105static win32_thread_info *
b80864fb
DJ
106thread_rec (DWORD id, int get_context)
107{
108 struct thread_info *thread;
41093d81 109 win32_thread_info *th;
b80864fb
DJ
110
111 thread = (struct thread_info *) find_inferior_id (&all_threads, id);
112 if (thread == NULL)
113 return NULL;
114
115 th = inferior_target_data (thread);
c436e841 116 if (get_context && th->context.ContextFlags == 0)
b80864fb 117 {
c436e841
PA
118 if (!th->suspended)
119 {
120 if (SuspendThread (th->h) == (DWORD) -1)
121 {
122 DWORD err = GetLastError ();
123 OUTMSG (("warning: SuspendThread failed in thread_rec, "
124 "(error %d): %s\n", (int) err, strwinerror (err)));
125 }
126 else
127 th->suspended = 1;
128 }
b80864fb 129
34b34921 130 (*the_low_target.get_thread_context) (th, &current_event);
b80864fb
DJ
131 }
132
133 return th;
134}
135
136/* Add a thread to the thread list. */
41093d81 137static win32_thread_info *
b80864fb
DJ
138child_add_thread (DWORD tid, HANDLE h)
139{
41093d81 140 win32_thread_info *th;
b80864fb
DJ
141
142 if ((th = thread_rec (tid, FALSE)))
143 return th;
144
4d5d1aaa 145 th = calloc (1, sizeof (*th));
b80864fb
DJ
146 th->tid = tid;
147 th->h = h;
148
149 add_thread (tid, th, (unsigned int) tid);
150 set_inferior_regcache_data ((struct thread_info *)
151 find_inferior_id (&all_threads, tid),
152 new_register_cache ());
153
34b34921
PA
154 if (the_low_target.thread_added != NULL)
155 (*the_low_target.thread_added) (th);
b80864fb
DJ
156
157 return th;
158}
159
160/* Delete a thread from the list of threads. */
161static void
162delete_thread_info (struct inferior_list_entry *thread)
163{
41093d81 164 win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
b80864fb
DJ
165
166 remove_thread ((struct thread_info *) thread);
167 CloseHandle (th->h);
168 free (th);
169}
170
171/* Delete a thread from the list of threads. */
172static void
173child_delete_thread (DWORD id)
174{
175 struct inferior_list_entry *thread;
176
177 /* If the last thread is exiting, just return. */
178 if (all_threads.head == all_threads.tail)
179 return;
180
181 thread = find_inferior_id (&all_threads, id);
182 if (thread == NULL)
183 return;
184
185 delete_thread_info (thread);
186}
187
188/* Transfer memory from/to the debugged process. */
189static int
190child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
191 int write, struct target_ops *target)
192{
193 SIZE_T done;
194 long addr = (long) memaddr;
195
196 if (write)
197 {
198 WriteProcessMemory (current_process_handle, (LPVOID) addr,
199 (LPCVOID) our, len, &done);
200 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
201 }
202 else
203 {
204 ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
205 len, &done);
206 }
207 return done;
208}
209
210/* Generally, what has the program done? */
211enum target_waitkind
212{
213 /* The program has exited. The exit status is in value.integer. */
214 TARGET_WAITKIND_EXITED,
215
216 /* The program has stopped with a signal. Which signal is in
217 value.sig. */
218 TARGET_WAITKIND_STOPPED,
219
255e7678
DJ
220 /* The program is letting us know that it dynamically loaded
221 or unloaded something. */
b80864fb
DJ
222 TARGET_WAITKIND_LOADED,
223
224 /* The program has exec'ed a new executable file. The new file's
225 pathname is pointed to by value.execd_pathname. */
b80864fb
DJ
226 TARGET_WAITKIND_EXECD,
227
7390519e
PA
228 /* Nothing interesting happened, but we stopped anyway. We take the
229 chance to check if GDB requested an interrupt. */
b80864fb
DJ
230 TARGET_WAITKIND_SPURIOUS,
231};
232
233struct target_waitstatus
234{
235 enum target_waitkind kind;
236
237 /* Forked child pid, execd pathname, exit status or signal number. */
238 union
239 {
240 int integer;
241 enum target_signal sig;
242 int related_pid;
243 char *execd_pathname;
244 int syscall_id;
245 }
246 value;
247};
248
ed50f18f 249/* Clear out any old thread list and reinitialize it to a pristine
b80864fb
DJ
250 state. */
251static void
252child_init_thread_list (void)
253{
254 for_each_inferior (&all_threads, delete_thread_info);
255}
256
257static void
258do_initial_child_stuff (DWORD pid)
259{
b80864fb
DJ
260 last_sig = TARGET_SIGNAL_0;
261
b80864fb
DJ
262 memset (&current_event, 0, sizeof (current_event));
263
264 child_init_thread_list ();
ed50f18f
PA
265
266 if (the_low_target.initial_stuff != NULL)
267 (*the_low_target.initial_stuff) ();
b80864fb
DJ
268}
269
270/* Resume all artificially suspended threads if we are continuing
271 execution. */
272static int
273continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
274{
275 struct thread_info *thread = (struct thread_info *) this_thread;
276 int thread_id = * (int *) id_ptr;
41093d81 277 win32_thread_info *th = inferior_target_data (thread);
b80864fb
DJ
278
279 if ((thread_id == -1 || thread_id == th->tid)
c436e841 280 && th->suspended)
b80864fb 281 {
34b34921 282 if (th->context.ContextFlags)
b80864fb 283 {
34b34921 284 (*the_low_target.set_thread_context) (th, &current_event);
b80864fb
DJ
285 th->context.ContextFlags = 0;
286 }
34b34921 287
c436e841
PA
288 if (ResumeThread (th->h) == (DWORD) -1)
289 {
290 DWORD err = GetLastError ();
291 OUTMSG (("warning: ResumeThread failed in continue_one_thread, "
292 "(error %d): %s\n", (int) err, strwinerror (err)));
293 }
294 th->suspended = 0;
b80864fb
DJ
295 }
296
297 return 0;
298}
299
300static BOOL
301child_continue (DWORD continue_status, int thread_id)
302{
4d5d1aaa
PA
303 /* The inferior will only continue after the ContinueDebugEvent
304 call. */
305 find_inferior (&all_threads, continue_one_thread, &thread_id);
306 faked_breakpoint = 0;
b80864fb 307
4d5d1aaa
PA
308 if (!ContinueDebugEvent (current_event.dwProcessId,
309 current_event.dwThreadId,
310 continue_status))
311 return FALSE;
b80864fb 312
4d5d1aaa 313 return TRUE;
b80864fb
DJ
314}
315
b80864fb
DJ
316/* Fetch register(s) from the current thread context. */
317static void
318child_fetch_inferior_registers (int r)
319{
320 int regno;
41093d81 321 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
b80864fb
DJ
322 if (r == -1 || r == 0 || r > NUM_REGS)
323 child_fetch_inferior_registers (NUM_REGS);
324 else
325 for (regno = 0; regno < r; regno++)
34b34921 326 (*the_low_target.fetch_inferior_register) (th, regno);
b80864fb
DJ
327}
328
329/* Store a new register value into the current thread context. We don't
330 change the program's context until later, when we resume it. */
331static void
332child_store_inferior_registers (int r)
333{
334 int regno;
41093d81 335 win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
b80864fb
DJ
336 if (r == -1 || r == 0 || r > NUM_REGS)
337 child_store_inferior_registers (NUM_REGS);
338 else
339 for (regno = 0; regno < r; regno++)
34b34921 340 (*the_low_target.store_inferior_register) (th, regno);
b80864fb
DJ
341}
342
ed50f18f
PA
343/* Map the Windows error number in ERROR to a locale-dependent error
344 message string and return a pointer to it. Typically, the values
345 for ERROR come from GetLastError.
346
347 The string pointed to shall not be modified by the application,
348 but may be overwritten by a subsequent call to strwinerror
349
350 The strwinerror function does not change the current setting
351 of GetLastError. */
352
353char *
354strwinerror (DWORD error)
355{
356 static char buf[1024];
357 TCHAR *msgbuf;
358 DWORD lasterr = GetLastError ();
359 DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
360 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
361 NULL,
362 error,
363 0, /* Default language */
364 (LPVOID)&msgbuf,
365 0,
366 NULL);
367 if (chars != 0)
368 {
369 /* If there is an \r\n appended, zap it. */
370 if (chars >= 2
371 && msgbuf[chars - 2] == '\r'
372 && msgbuf[chars - 1] == '\n')
373 {
374 chars -= 2;
375 msgbuf[chars] = 0;
376 }
377
378 if (chars > ((COUNTOF (buf)) - 1))
379 {
380 chars = COUNTOF (buf) - 1;
381 msgbuf [chars] = 0;
382 }
383
384#ifdef UNICODE
385 wcstombs (buf, msgbuf, chars + 1);
386#else
387 strncpy (buf, msgbuf, chars + 1);
388#endif
389 LocalFree (msgbuf);
390 }
391 else
392 sprintf (buf, "unknown win32 error (%ld)", error);
393
394 SetLastError (lasterr);
395 return buf;
396}
397
aec18585
PA
398static BOOL
399create_process (const char *program, char *args,
400 DWORD flags, PROCESS_INFORMATION *pi)
401{
402 BOOL ret;
403
404#ifdef _WIN32_WCE
405 wchar_t *p, *wprogram, *wargs;
406 size_t argslen;
407
408 wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
409 mbstowcs (wprogram, program, strlen (program) + 1);
410
411 for (p = wprogram; *p; ++p)
412 if (L'/' == *p)
413 *p = L'\\';
414
415 argslen = strlen (args);
416 wargs = alloca ((argslen + 1) * sizeof (wchar_t));
417 mbstowcs (wargs, args, argslen + 1);
418
419 ret = CreateProcessW (wprogram, /* image name */
420 wargs, /* command line */
421 NULL, /* security, not supported */
422 NULL, /* thread, not supported */
423 FALSE, /* inherit handles, not supported */
424 flags, /* start flags */
425 NULL, /* environment, not supported */
426 NULL, /* current directory, not supported */
427 NULL, /* start info, not supported */
428 pi); /* proc info */
429#else
430 STARTUPINFOA si = { sizeof (STARTUPINFOA) };
431
432 ret = CreateProcessA (program, /* image name */
433 args, /* command line */
434 NULL, /* security */
435 NULL, /* thread */
436 TRUE, /* inherit handles */
437 flags, /* start flags */
438 NULL, /* environment */
439 NULL, /* current directory */
440 &si, /* start info */
441 pi); /* proc info */
442#endif
443
444 return ret;
445}
446
b80864fb
DJ
447/* Start a new process.
448 PROGRAM is a path to the program to execute.
449 ARGS is a standard NULL-terminated array of arguments,
450 to be passed to the inferior as ``argv''.
451 Returns the new PID on success, -1 on failure. Registers the new
452 process with the process list. */
453static int
454win32_create_inferior (char *program, char **program_args)
455{
456#ifndef USE_WIN32API
457 char real_path[MAXPATHLEN];
458 char *orig_path, *new_path, *path_ptr;
459#endif
b80864fb
DJ
460 BOOL ret;
461 DWORD flags;
462 char *args;
463 int argslen;
464 int argc;
ed50f18f 465 PROCESS_INFORMATION pi;
aec18585 466 DWORD err;
b80864fb
DJ
467
468 if (!program)
469 error ("No executable specified, specify executable to debug.\n");
470
b80864fb
DJ
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
ed50f18f 488 argslen = 1;
b80864fb
DJ
489 for (argc = 1; program_args[argc]; argc++)
490 argslen += strlen (program_args[argc]) + 1;
491 args = alloca (argslen);
ed50f18f 492 args[0] = '\0';
b80864fb
DJ
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 }
ed50f18f 500 OUTMSG2 (("Command line is \"%s\"\n", args));
b80864fb 501
ed50f18f 502#ifdef CREATE_NEW_PROCESS_GROUP
b80864fb 503 flags |= CREATE_NEW_PROCESS_GROUP;
ed50f18f 504#endif
b80864fb 505
aec18585
PA
506 ret = create_process (program, args, flags, &pi);
507 err = GetLastError ();
508 if (!ret && err == ERROR_FILE_NOT_FOUND)
509 {
510 char *exename = alloca (strlen (program) + 5);
511 strcat (strcpy (exename, program), ".exe");
512 ret = create_process (exename, args, flags, &pi);
513 err = GetLastError ();
514 }
b80864fb
DJ
515
516#ifndef USE_WIN32API
517 if (orig_path)
518 setenv ("PATH", orig_path, 1);
519#endif
520
521 if (!ret)
522 {
ed50f18f
PA
523 error ("Error creating process \"%s%s\", (error %d): %s\n",
524 program, args, (int) err, strwinerror (err));
b80864fb
DJ
525 }
526 else
527 {
528 OUTMSG2 (("Process created: %s\n", (char *) args));
529 }
530
ed50f18f
PA
531#ifndef _WIN32_WCE
532 /* On Windows CE this handle can't be closed. The OS reuses
533 it in the debug events, while the 9x/NT versions of Windows
534 probably use a DuplicateHandle'd one. */
b80864fb 535 CloseHandle (pi.hThread);
ed50f18f 536#endif
b80864fb
DJ
537
538 current_process_handle = pi.hProcess;
539 current_process_id = pi.dwProcessId;
540
541 do_initial_child_stuff (current_process_id);
542
543 return current_process_id;
544}
545
546/* Attach to a running process.
547 PID is the process ID to attach to, specified by the user
548 or a higher layer. */
549static int
550win32_attach (unsigned long pid)
551{
bf914831
PA
552 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
553 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
ed50f18f
PA
554#ifdef _WIN32_WCE
555 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
556#else
557 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
558#endif
bf914831
PA
559 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
560 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
b80864fb 561
1d5315fe
PA
562 if (DebugActiveProcess (pid))
563 {
564 if (DebugSetProcessKillOnExit != NULL)
565 DebugSetProcessKillOnExit (FALSE);
b80864fb 566
1d5315fe 567 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
b80864fb 568
1d5315fe
PA
569 if (current_process_handle != NULL)
570 {
571 current_process_id = pid;
572 do_initial_child_stuff (pid);
573 return 0;
574 }
b80864fb
DJ
575 if (DebugActiveProcessStop != NULL)
576 DebugActiveProcessStop (current_process_id);
577 }
578
1d5315fe 579 error ("Attach to process failed.");
b80864fb
DJ
580}
581
bce7165d
PA
582/* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
583static void
584handle_output_debug_string (struct target_waitstatus *ourstatus)
585{
586#define READ_BUFFER_LEN 1024
587 CORE_ADDR addr;
588 char s[READ_BUFFER_LEN + 1] = { 0 };
589 DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
590
591 if (nbytes == 0)
592 return;
593
594 if (nbytes > READ_BUFFER_LEN)
595 nbytes = READ_BUFFER_LEN;
596
597 addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
598
599 if (current_event.u.DebugString.fUnicode)
600 {
601 /* The event tells us how many bytes, not chars, even
602 in Unicode. */
603 WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
604 if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
605 return;
606 wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
607 }
608 else
609 {
610 if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
611 return;
612 }
613
614 if (strncmp (s, "cYg", 3) != 0)
45e2715e
PA
615 {
616 if (!server_waiting)
617 {
618 OUTMSG2(("%s", s));
619 return;
620 }
621
622 monitor_output (s);
623 }
bce7165d
PA
624#undef READ_BUFFER_LEN
625}
626
b80864fb
DJ
627/* Kill all inferiors. */
628static void
629win32_kill (void)
630{
ed50f18f
PA
631 win32_thread_info *current_thread;
632
9d606399
DJ
633 if (current_process_handle == NULL)
634 return;
635
b80864fb
DJ
636 TerminateProcess (current_process_handle, 0);
637 for (;;)
638 {
639 if (!child_continue (DBG_CONTINUE, -1))
640 break;
641 if (!WaitForDebugEvent (&current_event, INFINITE))
642 break;
643 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
644 break;
bce7165d
PA
645 else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
646 {
647 struct target_waitstatus our_status = { 0 };
648 handle_output_debug_string (&our_status);
649 }
b80864fb 650 }
ed50f18f
PA
651
652 CloseHandle (current_process_handle);
653
654 current_thread = inferior_target_data (current_inferior);
655 if (current_thread && current_thread->h)
656 {
657 /* This may fail in an attached process, so don't check. */
658 (void) CloseHandle (current_thread->h);
659 }
b80864fb
DJ
660}
661
662/* Detach from all inferiors. */
444d6139 663static int
b80864fb
DJ
664win32_detach (void)
665{
444d6139
PA
666 HANDLE h;
667
bf914831
PA
668 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
669 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
ed50f18f
PA
670#ifdef _WIN32_WCE
671 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
672#else
673 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
674#endif
bf914831
PA
675 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
676 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
b80864fb 677
444d6139
PA
678 if (DebugSetProcessKillOnExit == NULL
679 || DebugActiveProcessStop == NULL)
680 return -1;
b80864fb 681
444d6139
PA
682 /* We need a new handle, since DebugActiveProcessStop
683 closes all the ones that came through the events. */
684 if ((h = OpenProcess (PROCESS_ALL_ACCESS,
685 FALSE,
686 current_process_id)) == NULL)
687 {
688 /* The process died. */
689 return -1;
690 }
691
692 {
693 struct thread_resume resume;
694 resume.thread = -1;
695 resume.step = 0;
696 resume.sig = 0;
697 resume.leave_stopped = 0;
698 win32_resume (&resume);
699 }
700
701 if (!DebugActiveProcessStop (current_process_id))
702 {
703 CloseHandle (h);
704 return -1;
705 }
706 DebugSetProcessKillOnExit (FALSE);
707
708 current_process_handle = h;
709 return 0;
710}
711
712/* Wait for inferiors to end. */
713static void
714win32_join (void)
715{
716 if (current_process_id == 0
717 || current_process_handle == NULL)
718 return;
719
720 WaitForSingleObject (current_process_handle, INFINITE);
721 CloseHandle (current_process_handle);
722
723 current_process_handle = NULL;
724 current_process_id = 0;
b80864fb
DJ
725}
726
727/* Return 1 iff the thread with thread ID TID is alive. */
728static int
729win32_thread_alive (unsigned long tid)
730{
731 int res;
732
733 /* Our thread list is reliable; don't bother to poll target
734 threads. */
735 if (find_inferior_id (&all_threads, tid) != NULL)
736 res = 1;
737 else
738 res = 0;
739 return res;
740}
741
742/* Resume the inferior process. RESUME_INFO describes how we want
743 to resume. */
744static void
745win32_resume (struct thread_resume *resume_info)
746{
747 DWORD tid;
748 enum target_signal sig;
749 int step;
41093d81 750 win32_thread_info *th;
b80864fb
DJ
751 DWORD continue_status = DBG_CONTINUE;
752
753 /* This handles the very limited set of resume packets that GDB can
754 currently produce. */
755
756 if (resume_info[0].thread == -1)
757 tid = -1;
758 else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
759 tid = -1;
760 else
761 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
762 the Windows resume code do the right thing for thread switching. */
763 tid = current_event.dwThreadId;
764
765 if (resume_info[0].thread != -1)
766 {
767 sig = resume_info[0].sig;
768 step = resume_info[0].step;
769 }
770 else
771 {
772 sig = 0;
773 step = 0;
774 }
775
776 if (sig != TARGET_SIGNAL_0)
777 {
778 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
779 {
780 OUTMSG (("Cannot continue with signal %d here.\n", sig));
781 }
782 else if (sig == last_sig)
783 continue_status = DBG_EXCEPTION_NOT_HANDLED;
784 else
785 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
786 }
787
788 last_sig = TARGET_SIGNAL_0;
789
790 /* Get context for the currently selected thread. */
791 th = thread_rec (current_event.dwThreadId, FALSE);
792 if (th)
793 {
794 if (th->context.ContextFlags)
795 {
b80864fb
DJ
796 /* Move register values from the inferior into the thread
797 context structure. */
798 regcache_invalidate ();
799
800 if (step)
ed50f18f
PA
801 {
802 if (the_low_target.single_step != NULL)
803 (*the_low_target.single_step) (th);
804 else
805 error ("Single stepping is not supported "
806 "in this configuration.\n");
807 }
34b34921
PA
808
809 (*the_low_target.set_thread_context) (th, &current_event);
b80864fb
DJ
810 th->context.ContextFlags = 0;
811 }
812 }
813
814 /* Allow continuing with the same signal that interrupted us.
815 Otherwise complain. */
816
817 child_continue (continue_status, tid);
818}
819
255e7678
DJ
820static void
821win32_add_one_solib (const char *name, CORE_ADDR load_addr)
822{
823 char buf[MAX_PATH + 1];
824 char buf2[MAX_PATH + 1];
825
826#ifdef _WIN32_WCE
827 WIN32_FIND_DATA w32_fd;
828 WCHAR wname[MAX_PATH + 1];
829 mbstowcs (wname, name, MAX_PATH);
830 HANDLE h = FindFirstFile (wname, &w32_fd);
831#else
832 WIN32_FIND_DATAA w32_fd;
833 HANDLE h = FindFirstFileA (name, &w32_fd);
834#endif
835
836 if (h == INVALID_HANDLE_VALUE)
837 strcpy (buf, name);
838 else
839 {
840 FindClose (h);
841 strcpy (buf, name);
842#ifndef _WIN32_WCE
843 {
844 char cwd[MAX_PATH + 1];
845 char *p;
846 if (GetCurrentDirectoryA (MAX_PATH + 1, cwd))
847 {
848 p = strrchr (buf, '\\');
849 if (p)
850 p[1] = '\0';
851 SetCurrentDirectoryA (buf);
852 GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p);
853 SetCurrentDirectoryA (cwd);
854 }
855 }
856#endif
857 }
858
859#ifdef __CYGWIN__
860 cygwin_conv_to_posix_path (buf, buf2);
861#else
862 strcpy (buf2, buf);
863#endif
864
865 loaded_dll (buf2, load_addr);
866}
867
868static char *
869get_image_name (HANDLE h, void *address, int unicode)
870{
871 static char buf[(2 * MAX_PATH) + 1];
872 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
873 char *address_ptr;
874 int len = 0;
875 char b[2];
876 DWORD done;
877
878 /* Attempt to read the name of the dll that was detected.
879 This is documented to work only when actively debugging
880 a program. It will not work for attached processes. */
881 if (address == NULL)
882 return NULL;
883
884#ifdef _WIN32_WCE
885 /* Windows CE reports the address of the image name,
886 instead of an address of a pointer into the image name. */
887 address_ptr = address;
888#else
889 /* See if we could read the address of a string, and that the
890 address isn't null. */
891 if (!ReadProcessMemory (h, address, &address_ptr,
892 sizeof (address_ptr), &done)
893 || done != sizeof (address_ptr)
894 || !address_ptr)
895 return NULL;
896#endif
897
898 /* Find the length of the string */
899 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
900 && (b[0] != 0 || b[size - 1] != 0) && done == size)
901 continue;
902
903 if (!unicode)
904 ReadProcessMemory (h, address_ptr, buf, len, &done);
905 else
906 {
907 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
908 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
909 &done);
910
911 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
912 }
913
914 return buf;
915}
916
917typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *,
918 DWORD, LPDWORD);
919typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE,
920 LPMODULEINFO, DWORD);
921typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE,
922 LPSTR, DWORD);
923
924static winapi_EnumProcessModules win32_EnumProcessModules;
925static winapi_GetModuleInformation win32_GetModuleInformation;
926static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA;
927
928static BOOL
929load_psapi (void)
930{
931 static int psapi_loaded = 0;
932 static HMODULE dll = NULL;
933
934 if (!psapi_loaded)
935 {
936 psapi_loaded = 1;
937 dll = LoadLibrary (TEXT("psapi.dll"));
938 if (!dll)
939 return FALSE;
940 win32_EnumProcessModules =
941 GETPROCADDRESS (dll, EnumProcessModules);
942 win32_GetModuleInformation =
943 GETPROCADDRESS (dll, GetModuleInformation);
944 win32_GetModuleFileNameExA =
945 GETPROCADDRESS (dll, GetModuleFileNameExA);
946 }
947
948 return (win32_EnumProcessModules != NULL
949 && win32_GetModuleInformation != NULL
950 && win32_GetModuleFileNameExA != NULL);
951}
952
953static int
954psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
955{
956 DWORD len;
957 MODULEINFO mi;
958 size_t i;
959 HMODULE dh_buf[1];
960 HMODULE *DllHandle = dh_buf;
961 DWORD cbNeeded;
962 BOOL ok;
963
964 if (!load_psapi ())
965 goto failed;
966
967 cbNeeded = 0;
968 ok = (*win32_EnumProcessModules) (current_process_handle,
969 DllHandle,
970 sizeof (HMODULE),
971 &cbNeeded);
972
973 if (!ok || !cbNeeded)
974 goto failed;
975
976 DllHandle = (HMODULE *) alloca (cbNeeded);
977 if (!DllHandle)
978 goto failed;
979
980 ok = (*win32_EnumProcessModules) (current_process_handle,
981 DllHandle,
982 cbNeeded,
983 &cbNeeded);
984 if (!ok)
985 goto failed;
986
987 for (i = 0; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++)
988 {
989 if (!(*win32_GetModuleInformation) (current_process_handle,
990 DllHandle[i],
991 &mi,
992 sizeof (mi)))
993 {
994 DWORD err = GetLastError ();
995 error ("Can't get module info: (error %d): %s\n",
996 (int) err, strwinerror (err));
997 }
998
999 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
1000 {
1001 len = (*win32_GetModuleFileNameExA) (current_process_handle,
1002 DllHandle[i],
1003 dll_name_ret,
1004 MAX_PATH);
1005 if (len == 0)
1006 {
1007 DWORD err = GetLastError ();
1008 error ("Error getting dll name: (error %d): %s\n",
1009 (int) err, strwinerror (err));
1010 }
1011 return 1;
1012 }
1013 }
1014
1015failed:
1016 dll_name_ret[0] = '\0';
1017 return 0;
1018}
1019
1020typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD);
1021typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32);
1022typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32);
1023
1024static winapi_CreateToolhelp32Snapshot win32_CreateToolhelp32Snapshot;
1025static winapi_Module32First win32_Module32First;
1026static winapi_Module32Next win32_Module32Next;
6b3d9b83
PA
1027#ifdef _WIN32_WCE
1028typedef BOOL (WINAPI *winapi_CloseToolhelp32Snapshot) (HANDLE);
1029static winapi_CloseToolhelp32Snapshot win32_CloseToolhelp32Snapshot;
1030#endif
255e7678
DJ
1031
1032static BOOL
1033load_toolhelp (void)
1034{
1035 static int toolhelp_loaded = 0;
1036 static HMODULE dll = NULL;
1037
1038 if (!toolhelp_loaded)
1039 {
1040 toolhelp_loaded = 1;
1041#ifndef _WIN32_WCE
1042 dll = GetModuleHandle (_T("KERNEL32.DLL"));
1043#else
6b3d9b83 1044 dll = LoadLibrary (L"TOOLHELP.DLL");
255e7678
DJ
1045#endif
1046 if (!dll)
1047 return FALSE;
1048
1049 win32_CreateToolhelp32Snapshot =
1050 GETPROCADDRESS (dll, CreateToolhelp32Snapshot);
1051 win32_Module32First = GETPROCADDRESS (dll, Module32First);
1052 win32_Module32Next = GETPROCADDRESS (dll, Module32Next);
6b3d9b83
PA
1053#ifdef _WIN32_WCE
1054 win32_CloseToolhelp32Snapshot =
1055 GETPROCADDRESS (dll, CloseToolhelp32Snapshot);
1056#endif
255e7678
DJ
1057 }
1058
1059 return (win32_CreateToolhelp32Snapshot != NULL
1060 && win32_Module32First != NULL
6b3d9b83
PA
1061 && win32_Module32Next != NULL
1062#ifdef _WIN32_WCE
1063 && win32_CloseToolhelp32Snapshot != NULL
1064#endif
1065 );
255e7678
DJ
1066}
1067
1068static int
1069toolhelp_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1070{
1071 HANDLE snapshot_module;
1072 MODULEENTRY32 modEntry = { sizeof (MODULEENTRY32) };
6b3d9b83 1073 int found = 0;
255e7678
DJ
1074
1075 if (!load_toolhelp ())
1076 return 0;
1077
1078 snapshot_module = win32_CreateToolhelp32Snapshot (TH32CS_SNAPMODULE,
1079 current_event.dwProcessId);
1080 if (snapshot_module == INVALID_HANDLE_VALUE)
1081 return 0;
1082
1083 /* Ignore the first module, which is the exe. */
6b3d9b83
PA
1084 if (win32_Module32First (snapshot_module, &modEntry))
1085 while (win32_Module32Next (snapshot_module, &modEntry))
1086 if ((DWORD) modEntry.modBaseAddr == BaseAddress)
1087 {
255e7678 1088#ifdef UNICODE
6b3d9b83 1089 wcstombs (dll_name_ret, modEntry.szExePath, MAX_PATH + 1);
255e7678 1090#else
6b3d9b83 1091 strcpy (dll_name_ret, modEntry.szExePath);
255e7678 1092#endif
6b3d9b83
PA
1093 found = 1;
1094 break;
1095 }
255e7678 1096
6b3d9b83
PA
1097#ifdef _WIN32_WCE
1098 win32_CloseToolhelp32Snapshot (snapshot_module);
1099#else
255e7678 1100 CloseHandle (snapshot_module);
6b3d9b83
PA
1101#endif
1102 return found;
255e7678
DJ
1103}
1104
1105static void
1106handle_load_dll (void)
1107{
1108 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1109 char dll_buf[MAX_PATH + 1];
1110 char *dll_name = NULL;
1111 DWORD load_addr;
1112
1113 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1114
34d86ddd
PA
1115 /* Windows does not report the image name of the dlls in the debug
1116 event on attaches. We resort to iterating over the list of
1117 loaded dlls looking for a match by image base. */
1118 if (!psapi_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf))
1119 {
1120 if (!server_waiting)
1121 /* On some versions of Windows and Windows CE, we can't create
1122 toolhelp snapshots while the inferior is stopped in a
1123 LOAD_DLL_DEBUG_EVENT due to a dll load, but we can while
1124 Windows is reporting the already loaded dlls. */
1125 toolhelp_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf);
1126 }
255e7678
DJ
1127
1128 dll_name = dll_buf;
1129
1130 if (*dll_name == '\0')
1131 dll_name = get_image_name (current_process_handle,
1132 event->lpImageName, event->fUnicode);
1133 if (!dll_name)
1134 return;
1135
1136 /* The symbols in a dll are offset by 0x1000, which is the
1137 the offset from 0 of the first byte in an image - because
1138 of the file header and the section alignment. */
1139
1140 load_addr = (DWORD) event->lpBaseOfDll + 0x1000;
1141 win32_add_one_solib (dll_name, load_addr);
1142}
1143
1144static void
1145handle_unload_dll (void)
1146{
1147 CORE_ADDR load_addr =
1148 (CORE_ADDR) (DWORD) current_event.u.UnloadDll.lpBaseOfDll;
1149 load_addr += 0x1000;
1150 unloaded_dll (NULL, load_addr);
1151}
1152
34b34921 1153static void
b80864fb
DJ
1154handle_exception (struct target_waitstatus *ourstatus)
1155{
b80864fb
DJ
1156 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
1157
1158 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1159
b80864fb
DJ
1160 switch (code)
1161 {
1162 case EXCEPTION_ACCESS_VIOLATION:
1163 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
1164 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1165 break;
1166 case STATUS_STACK_OVERFLOW:
1167 OUTMSG2 (("STATUS_STACK_OVERFLOW"));
1168 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1169 break;
1170 case STATUS_FLOAT_DENORMAL_OPERAND:
1171 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
1172 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1173 break;
1174 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1175 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
1176 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1177 break;
1178 case STATUS_FLOAT_INEXACT_RESULT:
1179 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
1180 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1181 break;
1182 case STATUS_FLOAT_INVALID_OPERATION:
1183 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
1184 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1185 break;
1186 case STATUS_FLOAT_OVERFLOW:
1187 OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
1188 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1189 break;
1190 case STATUS_FLOAT_STACK_CHECK:
1191 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
1192 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1193 break;
1194 case STATUS_FLOAT_UNDERFLOW:
1195 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
1196 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1197 break;
1198 case STATUS_FLOAT_DIVIDE_BY_ZERO:
1199 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
1200 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1201 break;
1202 case STATUS_INTEGER_DIVIDE_BY_ZERO:
1203 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
1204 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1205 break;
1206 case STATUS_INTEGER_OVERFLOW:
1207 OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
1208 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1209 break;
1210 case EXCEPTION_BREAKPOINT:
1211 OUTMSG2 (("EXCEPTION_BREAKPOINT"));
1212 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
ed50f18f
PA
1213#ifdef _WIN32_WCE
1214 /* Remove the initial breakpoint. */
1215 check_breakpoints ((CORE_ADDR) (long) current_event
1216 .u.Exception.ExceptionRecord.ExceptionAddress);
1217#endif
b80864fb
DJ
1218 break;
1219 case DBG_CONTROL_C:
1220 OUTMSG2 (("DBG_CONTROL_C"));
1221 ourstatus->value.sig = TARGET_SIGNAL_INT;
1222 break;
1223 case DBG_CONTROL_BREAK:
1224 OUTMSG2 (("DBG_CONTROL_BREAK"));
1225 ourstatus->value.sig = TARGET_SIGNAL_INT;
1226 break;
1227 case EXCEPTION_SINGLE_STEP:
1228 OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
1229 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1230 break;
1231 case EXCEPTION_ILLEGAL_INSTRUCTION:
1232 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
1233 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1234 break;
1235 case EXCEPTION_PRIV_INSTRUCTION:
1236 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
1237 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1238 break;
1239 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1240 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
1241 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1242 break;
1243 default:
1244 if (current_event.u.Exception.dwFirstChance)
34b34921
PA
1245 {
1246 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1247 return;
1248 }
b80864fb
DJ
1249 OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
1250 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1251 (DWORD) current_event.u.Exception.ExceptionRecord.
1252 ExceptionAddress));
1253 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1254 break;
1255 }
1256 OUTMSG2 (("\n"));
1257 last_sig = ourstatus->value.sig;
b80864fb
DJ
1258}
1259
4d5d1aaa 1260
34b34921 1261static void
4d5d1aaa
PA
1262suspend_one_thread (struct inferior_list_entry *entry)
1263{
1264 struct thread_info *thread = (struct thread_info *) entry;
1265 win32_thread_info *th = inferior_target_data (thread);
1266
1267 if (!th->suspended)
1268 {
1269 if (SuspendThread (th->h) == (DWORD) -1)
1270 {
1271 DWORD err = GetLastError ();
1272 OUTMSG (("warning: SuspendThread failed in suspend_one_thread, "
1273 "(error %d): %s\n", (int) err, strwinerror (err)));
1274 }
1275 else
1276 th->suspended = 1;
1277 }
1278}
1279
1280static void
1281fake_breakpoint_event (void)
b80864fb 1282{
4d5d1aaa 1283 OUTMSG2(("fake_breakpoint_event\n"));
b80864fb 1284
4d5d1aaa
PA
1285 faked_breakpoint = 1;
1286
1287 memset (&current_event, 0, sizeof (current_event));
1288 current_event.dwThreadId = main_thread_id;
1289 current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
1290 current_event.u.Exception.ExceptionRecord.ExceptionCode
1291 = EXCEPTION_BREAKPOINT;
1292
1293 for_each_inferior (&all_threads, suspend_one_thread);
1294}
1295
1296/* Get the next event from the child. */
1297
1298static int
1299get_child_debug_event (struct target_waitstatus *ourstatus)
1300{
b80864fb
DJ
1301 last_sig = TARGET_SIGNAL_0;
1302 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1303
4d5d1aaa
PA
1304 /* Check if GDB sent us an interrupt request. */
1305 check_remote_input_interrupt_request ();
1306
1307 if (soft_interrupt_requested)
1308 {
1309 soft_interrupt_requested = 0;
1310 fake_breakpoint_event ();
1311 goto gotevent;
1312 }
1313
1314 /* Keep the wait time low enough for confortable remote
1315 interruption, but high enough so gdbserver doesn't become a
1316 bottleneck. */
1317 if (!WaitForDebugEvent (&current_event, 250))
1318 return 0;
1319
1320 gotevent:
b80864fb
DJ
1321
1322 current_inferior =
1323 (struct thread_info *) find_inferior_id (&all_threads,
1324 current_event.dwThreadId);
1325
34b34921 1326 switch (current_event.dwDebugEventCode)
b80864fb
DJ
1327 {
1328 case CREATE_THREAD_DEBUG_EVENT:
1329 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
1330 "for pid=%d tid=%x)\n",
1331 (unsigned) current_event.dwProcessId,
1332 (unsigned) current_event.dwThreadId));
1333
1334 /* Record the existence of this thread. */
34b34921 1335 child_add_thread (current_event.dwThreadId,
b80864fb 1336 current_event.u.CreateThread.hThread);
b80864fb
DJ
1337 break;
1338
1339 case EXIT_THREAD_DEBUG_EVENT:
1340 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
1341 "for pid=%d tid=%x\n",
1342 (unsigned) current_event.dwProcessId,
1343 (unsigned) current_event.dwThreadId));
1344 child_delete_thread (current_event.dwThreadId);
b80864fb
DJ
1345 break;
1346
1347 case CREATE_PROCESS_DEBUG_EVENT:
1348 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1349 "for pid=%d tid=%x\n",
1350 (unsigned) current_event.dwProcessId,
1351 (unsigned) current_event.dwThreadId));
1352 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1353
1354 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1355 main_thread_id = current_event.dwThreadId;
1356
1357 ourstatus->kind = TARGET_WAITKIND_EXECD;
1358 ourstatus->value.execd_pathname = "Main executable";
1359
1360 /* Add the main thread. */
34b34921
PA
1361 child_add_thread (main_thread_id,
1362 current_event.u.CreateProcessInfo.hThread);
b80864fb 1363
34b34921 1364 ourstatus->value.related_pid = current_event.dwThreadId;
ed50f18f
PA
1365#ifdef _WIN32_WCE
1366 /* Windows CE doesn't set the initial breakpoint automatically
1367 like the desktop versions of Windows do. We add it explicitly
1368 here. It will be removed as soon as it is hit. */
1369 set_breakpoint_at ((CORE_ADDR) (long) current_event.u
1370 .CreateProcessInfo.lpStartAddress,
1371 delete_breakpoint_at);
1372#endif
b80864fb
DJ
1373 break;
1374
1375 case EXIT_PROCESS_DEBUG_EVENT:
1376 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1377 "for pid=%d tid=%x\n",
1378 (unsigned) current_event.dwProcessId,
1379 (unsigned) current_event.dwThreadId));
1380 ourstatus->kind = TARGET_WAITKIND_EXITED;
1381 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1382 CloseHandle (current_process_handle);
9d606399 1383 current_process_handle = NULL;
b80864fb
DJ
1384 break;
1385
1386 case LOAD_DLL_DEBUG_EVENT:
1387 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1388 "for pid=%d tid=%x\n",
1389 (unsigned) current_event.dwProcessId,
1390 (unsigned) current_event.dwThreadId));
1391 CloseHandle (current_event.u.LoadDll.hFile);
255e7678 1392 handle_load_dll ();
b80864fb
DJ
1393
1394 ourstatus->kind = TARGET_WAITKIND_LOADED;
255e7678 1395 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
b80864fb
DJ
1396 break;
1397
1398 case UNLOAD_DLL_DEBUG_EVENT:
1399 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1400 "for pid=%d tid=%x\n",
1401 (unsigned) current_event.dwProcessId,
1402 (unsigned) current_event.dwThreadId));
255e7678
DJ
1403 handle_unload_dll ();
1404 ourstatus->kind = TARGET_WAITKIND_LOADED;
1405 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
b80864fb
DJ
1406 break;
1407
1408 case EXCEPTION_DEBUG_EVENT:
1409 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1410 "for pid=%d tid=%x\n",
1411 (unsigned) current_event.dwProcessId,
1412 (unsigned) current_event.dwThreadId));
34b34921 1413 handle_exception (ourstatus);
b80864fb
DJ
1414 break;
1415
1416 case OUTPUT_DEBUG_STRING_EVENT:
1417 /* A message from the kernel (or Cygwin). */
1418 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1419 "for pid=%d tid=%x\n",
1420 (unsigned) current_event.dwProcessId,
1421 (unsigned) current_event.dwThreadId));
bce7165d 1422 handle_output_debug_string (ourstatus);
b80864fb
DJ
1423 break;
1424
1425 default:
1426 OUTMSG2 (("gdbserver: kernel event unknown "
1427 "for pid=%d tid=%x code=%ld\n",
1428 (unsigned) current_event.dwProcessId,
1429 (unsigned) current_event.dwThreadId,
1430 current_event.dwDebugEventCode));
1431 break;
1432 }
1433
1434 current_inferior =
1435 (struct thread_info *) find_inferior_id (&all_threads,
1436 current_event.dwThreadId);
4d5d1aaa 1437 return 1;
b80864fb
DJ
1438}
1439
1440/* Wait for the inferior process to change state.
1441 STATUS will be filled in with a response code to send to GDB.
1442 Returns the signal which caused the process to stop. */
1443static unsigned char
1444win32_wait (char *status)
1445{
1446 struct target_waitstatus our_status;
1447
1448 *status = 'T';
1449
1450 while (1)
1451 {
4d5d1aaa
PA
1452 if (!get_child_debug_event (&our_status))
1453 continue;
b80864fb 1454
34b34921 1455 switch (our_status.kind)
b80864fb 1456 {
34b34921 1457 case TARGET_WAITKIND_EXITED:
b80864fb
DJ
1458 OUTMSG2 (("Child exited with retcode = %x\n",
1459 our_status.value.integer));
1460
1461 *status = 'W';
b80864fb 1462 return our_status.value.integer;
34b34921 1463 case TARGET_WAITKIND_STOPPED:
255e7678 1464 case TARGET_WAITKIND_LOADED:
f72f3e60 1465 OUTMSG2 (("Child Stopped with signal = %d \n",
ed50f18f 1466 our_status.value.sig));
b80864fb
DJ
1467
1468 *status = 'T';
1469
1470 child_fetch_inferior_registers (-1);
1471
255e7678
DJ
1472 if (our_status.kind == TARGET_WAITKIND_LOADED
1473 && !server_waiting)
1474 {
1475 /* When gdb connects, we want to be stopped at the
1476 initial breakpoint, not in some dll load event. */
1477 child_continue (DBG_CONTINUE, -1);
1478 break;
1479 }
1480
b80864fb 1481 return our_status.value.sig;
34b34921
PA
1482 default:
1483 OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
1484 /* fall-through */
1485 case TARGET_WAITKIND_SPURIOUS:
34b34921
PA
1486 case TARGET_WAITKIND_EXECD:
1487 /* do nothing, just continue */
1488 child_continue (DBG_CONTINUE, -1);
1489 break;
b80864fb 1490 }
b80864fb
DJ
1491 }
1492}
1493
1494/* Fetch registers from the inferior process.
1495 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1496static void
1497win32_fetch_inferior_registers (int regno)
1498{
1499 child_fetch_inferior_registers (regno);
1500}
1501
1502/* Store registers to the inferior process.
1503 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1504static void
1505win32_store_inferior_registers (int regno)
1506{
1507 child_store_inferior_registers (regno);
1508}
1509
1510/* Read memory from the inferior process. This should generally be
1511 called through read_inferior_memory, which handles breakpoint shadowing.
1512 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1513static int
1514win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1515{
ed50f18f 1516 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
b80864fb
DJ
1517}
1518
1519/* Write memory to the inferior process. This should generally be
1520 called through write_inferior_memory, which handles breakpoint shadowing.
1521 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1522 Returns 0 on success and errno on failure. */
1523static int
1524win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1525 int len)
1526{
1527 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1528}
1529
7390519e
PA
1530/* Send an interrupt request to the inferior process. */
1531static void
1532win32_request_interrupt (void)
1533{
1534 winapi_DebugBreakProcess DebugBreakProcess;
1535 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent;
1536
1537#ifdef _WIN32_WCE
1538 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
1539#else
1540 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1541#endif
1542
1543 GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent);
1544
1545 if (GenerateConsoleCtrlEvent != NULL
1546 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
1547 return;
1548
1549 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1550 not a process group id.
1551 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1552 breakpoint exception in the interior process. */
1553
1554 DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess);
1555
1556 if (DebugBreakProcess != NULL
1557 && DebugBreakProcess (current_process_handle))
1558 return;
1559
4d5d1aaa
PA
1560 /* Last resort, suspend all threads manually. */
1561 soft_interrupt_requested = 1;
7390519e
PA
1562}
1563
820f2bda
PA
1564static const char *
1565win32_arch_string (void)
1566{
ed50f18f 1567 return the_low_target.arch_string;
820f2bda
PA
1568}
1569
b80864fb
DJ
1570static struct target_ops win32_target_ops = {
1571 win32_create_inferior,
1572 win32_attach,
1573 win32_kill,
1574 win32_detach,
444d6139 1575 win32_join,
b80864fb
DJ
1576 win32_thread_alive,
1577 win32_resume,
1578 win32_wait,
1579 win32_fetch_inferior_registers,
1580 win32_store_inferior_registers,
1581 win32_read_inferior_memory,
1582 win32_write_inferior_memory,
820f2bda 1583 NULL,
7390519e 1584 win32_request_interrupt,
820f2bda
PA
1585 NULL,
1586 NULL,
1587 NULL,
1588 NULL,
1589 NULL,
1590 NULL,
1591 NULL,
1592 win32_arch_string
b80864fb
DJ
1593};
1594
1595/* Initialize the Win32 backend. */
1596void
1597initialize_low (void)
1598{
1599 set_target_ops (&win32_target_ops);
ed50f18f
PA
1600 if (the_low_target.breakpoint != NULL)
1601 set_breakpoint_data (the_low_target.breakpoint,
1602 the_low_target.breakpoint_len);
b80864fb
DJ
1603 init_registers ();
1604}
This page took 0.178938 seconds and 4 git commands to generate.