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