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