* externalize a function
[binutils-gdb.git] / gdb / wince.c
blob83112d9db0808abce49ca6f308f681289c8012a3
1 /* Target-vector operations for controlling Windows CE child processes, for GDB.
2 Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions, A Red Hat Company.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
23 /* by Christopher Faylor (cgf@cygnus.com) */
25 /* We assume we're being built with and will be used for cygwin. */
27 #ifdef SHx
28 #undef SH4
29 #define SH4 /* Just to get all of the CONTEXT defines. */
30 #endif
32 #include "defs.h"
33 #include "frame.h" /* required by inferior.h */
34 #include "inferior.h"
35 #include "target.h"
36 #include "gdbcore.h"
37 #include "command.h"
38 #include <signal.h>
39 #include <sys/types.h>
40 #include <fcntl.h>
41 #include <stdlib.h>
43 #include <windows.h>
44 #include <rapi.h>
45 #include <netdb.h>
46 #include <cygwin/in.h>
47 #include <cygwin/socket.h>
49 #include "buildsym.h"
50 #include "symfile.h"
51 #include "objfiles.h"
52 #include "gdb_string.h"
53 #include "gdbthread.h"
54 #include "gdbcmd.h"
55 #include <sys/param.h>
56 #include "wince-stub.h"
57 #include <time.h>
58 #include "regcache.h"
60 /* The ui's event loop. */
61 extern int (*ui_loop_hook) (int signo);
63 /* If we're not using the old Cygwin header file set, define the
64 following which never should have been in the generic Win32 API
65 headers in the first place since they were our own invention... */
66 #ifndef _GNU_H_WINDOWS_H
67 #define FLAG_TRACE_BIT 0x100
68 #ifdef CONTEXT_FLOATING_POINT
69 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
70 #else
71 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
72 #endif
73 #endif
75 #ifdef SH4
76 #define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
77 #else
78 #define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
79 #endif
80 /* The string sent by cygwin when it processes a signal.
81 FIXME: This should be in a cygwin include file. */
82 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
84 #define CHECK(x) check (x, __FILE__,__LINE__)
85 #define DEBUG_EXEC(x) if (debug_exec) printf x
86 #define DEBUG_EVENTS(x) if (debug_events) printf x
87 #define DEBUG_MEM(x) if (debug_memory) printf x
88 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
90 static int connection_initialized = 0; /* True if we've initialized a RAPI session. */
92 /* The directory where the stub and executable files are uploaded. */
93 static const char *remote_directory = "\\gdb";
95 /* The types automatic upload available. */
96 static enum
98 UPLOAD_ALWAYS = 0,
99 UPLOAD_NEWER = 1,
100 UPLOAD_NEVER = 2
102 upload_when = UPLOAD_NEWER;
104 /* Valid options for 'set remoteupload'. Note that options
105 must track upload_when enum. */
106 static struct opts
108 const char *name;
109 int abbrev;
111 upload_options[3] =
114 "always", 1
118 "newer", 3
122 "never", 3
126 static char *remote_upload = NULL; /* Set by set remoteupload */
127 static int remote_add_host = 0;
129 /* Forward declaration */
130 extern struct target_ops child_ops;
132 static int win32_child_thread_alive (int);
133 void child_kill_inferior (void);
135 static int last_sig = 0; /* Set if a signal was received from the
136 debugged process */
138 /* Thread information structure used to track information that is
139 not available in gdb's thread structure. */
140 typedef struct thread_info_struct
142 struct thread_info_struct *next;
143 DWORD id;
144 HANDLE h;
145 char *name;
146 int suspend_count;
147 int stepped; /* True if stepped. */
148 CORE_ADDR step_pc;
149 unsigned long step_prev;
150 CONTEXT context;
152 thread_info;
154 static thread_info thread_head =
155 {NULL};
156 static thread_info * thread_rec (DWORD id, int get_context);
158 /* The process and thread handles for the above context. */
160 static DEBUG_EVENT current_event; /* The current debug event from
161 WaitForDebugEvent */
162 static HANDLE current_process_handle; /* Currently executing process */
163 static thread_info *current_thread; /* Info on currently selected thread */
164 static thread_info *this_thread; /* Info on thread returned by wait_for_debug_event */
165 static DWORD main_thread_id; /* Thread ID of the main thread */
167 /* Counts of things. */
168 static int exception_count = 0;
169 static int event_count = 0;
171 /* User options. */
172 static int debug_exec = 0; /* show execution */
173 static int debug_events = 0; /* show events from kernel */
174 static int debug_memory = 0; /* show target memory accesses */
175 static int debug_exceptions = 0; /* show target exceptions */
177 /* An array of offset mappings into a Win32 Context structure.
178 This is a one-to-one mapping which is indexed by gdb's register
179 numbers. It retrieves an offset into the context structure where
180 the 4 byte register is located.
181 An offset value of -1 indicates that Win32 does not provide this
182 register in it's CONTEXT structure. regptr will return zero for this
183 register.
185 This is used by the regptr function. */
186 #define context_offset(x) ((int)&(((PCONTEXT)NULL)->x))
187 static const int mappings[NUM_REGS + 1] =
189 #ifdef __i386__
190 context_offset (Eax),
191 context_offset (Ecx),
192 context_offset (Edx),
193 context_offset (Ebx),
194 context_offset (Esp),
195 context_offset (Ebp),
196 context_offset (Esi),
197 context_offset (Edi),
198 context_offset (Eip),
199 context_offset (EFlags),
200 context_offset (SegCs),
201 context_offset (SegSs),
202 context_offset (SegDs),
203 context_offset (SegEs),
204 context_offset (SegFs),
205 context_offset (SegGs),
206 context_offset (FloatSave.RegisterArea[0 * 10]),
207 context_offset (FloatSave.RegisterArea[1 * 10]),
208 context_offset (FloatSave.RegisterArea[2 * 10]),
209 context_offset (FloatSave.RegisterArea[3 * 10]),
210 context_offset (FloatSave.RegisterArea[4 * 10]),
211 context_offset (FloatSave.RegisterArea[5 * 10]),
212 context_offset (FloatSave.RegisterArea[6 * 10]),
213 context_offset (FloatSave.RegisterArea[7 * 10]),
214 #elif defined(SHx)
215 context_offset (R0),
216 context_offset (R1),
217 context_offset (R2),
218 context_offset (R3),
219 context_offset (R4),
220 context_offset (R5),
221 context_offset (R6),
222 context_offset (R7),
223 context_offset (R8),
224 context_offset (R9),
225 context_offset (R10),
226 context_offset (R11),
227 context_offset (R12),
228 context_offset (R13),
229 context_offset (R14),
230 context_offset (R15),
231 context_offset (Fir),
232 context_offset (PR), /* Procedure Register */
233 context_offset (GBR), /* Global Base Register */
234 context_offset (MACH), /* Accumulate */
235 context_offset (MACL), /* Multiply */
236 context_offset (Psr),
237 context_offset (Fpul),
238 context_offset (Fpscr),
239 context_offset (FRegs[0]),
240 context_offset (FRegs[1]),
241 context_offset (FRegs[2]),
242 context_offset (FRegs[3]),
243 context_offset (FRegs[4]),
244 context_offset (FRegs[5]),
245 context_offset (FRegs[6]),
246 context_offset (FRegs[7]),
247 context_offset (FRegs[8]),
248 context_offset (FRegs[9]),
249 context_offset (FRegs[10]),
250 context_offset (FRegs[11]),
251 context_offset (FRegs[12]),
252 context_offset (FRegs[13]),
253 context_offset (FRegs[14]),
254 context_offset (FRegs[15]),
255 context_offset (xFRegs[0]),
256 context_offset (xFRegs[1]),
257 context_offset (xFRegs[2]),
258 context_offset (xFRegs[3]),
259 context_offset (xFRegs[4]),
260 context_offset (xFRegs[5]),
261 context_offset (xFRegs[6]),
262 context_offset (xFRegs[7]),
263 context_offset (xFRegs[8]),
264 context_offset (xFRegs[9]),
265 context_offset (xFRegs[10]),
266 context_offset (xFRegs[11]),
267 context_offset (xFRegs[12]),
268 context_offset (xFRegs[13]),
269 context_offset (xFRegs[14]),
270 context_offset (xFRegs[15]),
271 #elif defined(MIPS)
272 context_offset (IntZero),
273 context_offset (IntAt),
274 context_offset (IntV0),
275 context_offset (IntV1),
276 context_offset (IntA0),
277 context_offset (IntA1),
278 context_offset (IntA2),
279 context_offset (IntA3),
280 context_offset (IntT0),
281 context_offset (IntT1),
282 context_offset (IntT2),
283 context_offset (IntT3),
284 context_offset (IntT4),
285 context_offset (IntT5),
286 context_offset (IntT6),
287 context_offset (IntT7),
288 context_offset (IntS0),
289 context_offset (IntS1),
290 context_offset (IntS2),
291 context_offset (IntS3),
292 context_offset (IntS4),
293 context_offset (IntS5),
294 context_offset (IntS6),
295 context_offset (IntS7),
296 context_offset (IntT8),
297 context_offset (IntT9),
298 context_offset (IntK0),
299 context_offset (IntK1),
300 context_offset (IntGp),
301 context_offset (IntSp),
302 context_offset (IntS8),
303 context_offset (IntRa),
304 context_offset (Psr),
305 context_offset (IntLo),
306 context_offset (IntHi),
307 -1, /* bad */
308 -1, /* cause */
309 context_offset (Fir),
310 context_offset (FltF0),
311 context_offset (FltF1),
312 context_offset (FltF2),
313 context_offset (FltF3),
314 context_offset (FltF4),
315 context_offset (FltF5),
316 context_offset (FltF6),
317 context_offset (FltF7),
318 context_offset (FltF8),
319 context_offset (FltF9),
320 context_offset (FltF10),
321 context_offset (FltF11),
322 context_offset (FltF12),
323 context_offset (FltF13),
324 context_offset (FltF14),
325 context_offset (FltF15),
326 context_offset (FltF16),
327 context_offset (FltF17),
328 context_offset (FltF18),
329 context_offset (FltF19),
330 context_offset (FltF20),
331 context_offset (FltF21),
332 context_offset (FltF22),
333 context_offset (FltF23),
334 context_offset (FltF24),
335 context_offset (FltF25),
336 context_offset (FltF26),
337 context_offset (FltF27),
338 context_offset (FltF28),
339 context_offset (FltF29),
340 context_offset (FltF30),
341 context_offset (FltF31),
342 context_offset (Fsr),
343 context_offset (Fir),
344 -1, /* fp */
345 #elif defined(ARM)
346 context_offset (R0),
347 context_offset (R1),
348 context_offset (R2),
349 context_offset (R3),
350 context_offset (R4),
351 context_offset (R5),
352 context_offset (R6),
353 context_offset (R7),
354 context_offset (R8),
355 context_offset (R9),
356 context_offset (R10),
357 context_offset (R11),
358 context_offset (R12),
359 context_offset (Sp),
360 context_offset (Lr),
361 context_offset (Pc),
371 context_offset (Psr),
372 #endif
376 /* Return a pointer into a CONTEXT field indexed by gdb register number.
377 Return a pointer to an address pointing to zero if there is no
378 corresponding CONTEXT field for the given register number.
380 static ULONG *
381 regptr (LPCONTEXT c, int r)
383 static ULONG zero = 0;
384 ULONG *p;
385 if (mappings[r] < 0)
386 p = &zero;
387 else
388 p = (ULONG *) (((char *) c) + mappings[r]);
389 return p;
392 /******************** Beginning of stub interface ********************/
394 /* Stub interface description:
396 The Windows CE stub implements a crude RPC. The hand-held device
397 connects to gdb using port 7000. gdb and the stub then communicate
398 using packets where:
400 byte 0: command id (e.g. Create Process)
402 byte 1-4: DWORD
404 byte 1-2: WORD
406 byte 1-2: length
407 byte 3-n: arbitrary memory.
409 The interface is deterministic, i.e., if the stub expects a DWORD then
410 the gdb server should send a DWORD.
413 /* Note: In the functions below, the `huh' parameter is a string passed from the
414 function containing a descriptive string concerning the current operation.
415 This is used for error reporting.
417 The 'what' parameter is a command id as found in wince-stub.h.
419 Hopefully, the rest of the parameters are self-explanatory.
422 static int s; /* communication socket */
424 /* v-style interface for handling varying argyment list error messages.
425 Displays the error message in a dialog box and exits when user clicks
426 on OK. */
427 static void
428 vstub_error (LPCSTR fmt, va_list * args)
430 char buf[4096];
431 vsprintf (buf, fmt, args);
432 s = -1;
433 error ("%s", buf);
436 /* The standard way to display an error message and exit. */
437 static void
438 stub_error (LPCSTR fmt,...)
440 va_list args;
441 va_start (args, fmt);
442 vstub_error (fmt, args);
445 /* Standard "oh well" can't communicate error. Someday this might attempt
446 synchronization. */
447 static void
448 attempt_resync (LPCSTR huh, int s)
450 stub_error ("lost synchronization with target attempting %s", huh);
453 /* Read arbitrary stuff from a socket. */
454 static int
455 sockread (LPCSTR huh, int s, void *str, size_t n)
457 for (;;)
459 if (recv (s, str, n, 0) == n)
460 return n;
461 attempt_resync (huh, s);
465 /* Write arbitrary stuff to a socket. */
466 static int
467 sockwrite (LPCSTR huh, const void *str, size_t n)
469 for (;;)
471 if (send (s, str, n, 0) == n)
472 return n;
473 attempt_resync (huh, s);
477 /* Output an id/dword to the host */
478 static void
479 putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
481 if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
482 stub_error ("error writing record id to host for %s", huh);
483 if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
484 stub_error ("error writing %s to host.", huh);
487 /* Output an id/word to the host */
488 static void
489 putword (LPCSTR huh, gdb_wince_id what, WORD n)
491 if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
492 stub_error ("error writing record id to host for %s", huh);
493 if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
494 stub_error ("error writing %s host.", huh);
497 /* Convenience define for outputting a "gdb_wince_len" type. */
498 #define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
500 /* Put an arbitrary block of memory to the gdb host. This comes in
501 two chunks an id/dword representing the length and the stream of memory
502 itself. */
503 static void
504 putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
506 putlen (huh, what, len);
507 if (((short) len > 0) && sockwrite (huh, mem, len) != len)
508 stub_error ("error writing %s to host.", huh);
511 /* Output the result of an operation to the host. If res != 0, sends a block of
512 memory starting at mem of len bytes. If res == 0, sends -GetLastError () and
513 avoids sending the mem. */
514 static DWORD
515 getdword (LPCSTR huh, gdb_wince_id what_this)
517 DWORD n;
518 gdb_wince_id what;
520 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
521 stub_error ("error getting record type from host - %s.", huh);
522 while (what_this != what);
524 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
525 stub_error ("error getting %s from host.", huh);
527 return n;
530 /* Get a an ID (possibly) and a WORD from the host gdb.
531 Don't bother with the id if the main loop has already
532 read it. */
533 static WORD
534 getword (LPCSTR huh, gdb_wince_id what_this)
536 WORD n;
537 gdb_wince_id what;
539 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
540 stub_error ("error getting record type from host - %s.", huh);
541 while (what_this != what);
543 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
544 stub_error ("error getting %s from host.", huh);
546 return n;
549 /* Handy defines for getting/putting various types of values. */
550 #define gethandle(huh, what) (HANDLE) getdword ((huh), (what))
551 #define getpvoid(huh, what) (LPVOID) getdword ((huh), (what))
552 #define getlen(huh, what) (gdb_wince_len) getword ((huh), (what))
553 #define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h))
554 #define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p))
556 /* Retrieve the result of an operation from the stub. If nbytes < 0) then nbytes
557 is actually an error and nothing else follows. Use SetLastError to remember this.
558 if nbytes > 0, retrieve a block of *nbytes into buf.
561 getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
563 gdb_wince_len dummy;
564 if (nbytes == NULL)
565 nbytes = &dummy;
567 *nbytes = getlen (huh, what);
569 if ((short) *nbytes < 0)
571 SetLastError (-(short) *nbytes);
572 return 0;
575 if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
576 stub_error ("couldn't read information from wince stub - %s", huh);
578 return 1;
581 /* Convert "narrow" string to "wide". Manipulates a buffer ring of 8
582 buffers which hold the translated string. This is an arbitrary limit
583 but it is approximately double the current needs of this module.
585 LPWSTR
586 towide (const char *s, gdb_wince_len * out_len)
588 static int n = -1;
589 static LPWSTR outs[8] =
590 {NULL /*, NULL, etc. */ };
591 gdb_wince_len dummy;
593 if (!out_len)
594 out_len = &dummy;
596 /* First determine the length required to hold the converted string. */
597 *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
598 if (!*out_len)
599 return NULL; /* The conversion failed */
601 if (++n >= (sizeof (outs) / sizeof (outs[0])))
602 n = 0; /* wrap */
604 /* Allocate space for the converted string, reusing any previously allocated
605 space, if applicable. Note that if outs[n] is NULL, xrealloc will act as
606 a malloc (under cygwin, at least).
608 outs[n] = (LPWSTR) xrealloc (outs[n], *out_len);
609 memset (outs[n], 0, *out_len);
610 (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len);
611 return outs[n];
614 /******************** Emulation routines start here. ********************
616 The functions below are modelled after their Win32 counterparts. They are named
617 similarly to Win32 and take exactly the same arguments except where otherwise noted.
618 They communicate with the stub on the hand-held device by sending their arguments
619 over the socket and waiting for results from the socket.
621 There is one universal change. In cases where a length is expected to be returned
622 in a DWORD, we use a gdb_wince_len type instead. Currently this is an unsigned short
623 which is smaller than the standard Win32 DWORD. This is done to minimize unnecessary
624 traffic since the connection to Windows CE can be slow. To change this, modify the
625 typedef in wince-stub.h and change the putlen/getlen macros in this file and in
626 the stub.
629 static int
630 create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
632 gdb_wince_len len;
633 LPWSTR buf;
635 buf = towide (exec_file, &len);
636 putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len);
637 buf = towide (args, &len);
638 putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len);
639 putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags);
640 return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL);
643 /* Emulate TerminateProcess. Don't bother with the second argument since CE
644 ignores it.
646 static int
647 terminate_process (HANDLE h)
649 gdb_wince_result res;
650 if (s < 0)
651 return 1;
652 puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
653 return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
656 static int
657 wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
659 if (s < 0)
660 return 1;
661 putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
662 return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
665 static int
666 get_thread_context (HANDLE h, CONTEXT * c)
668 if (s < 0)
669 return 1;
670 puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
671 putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
672 return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
675 static int
676 set_thread_context (HANDLE h, CONTEXT * c)
678 gdb_wince_result res;
679 if (s < 0)
680 return 1;
681 puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
682 putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c));
683 return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL);
686 static int
687 read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
689 if (s < 0)
690 return 1;
691 puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
692 putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
693 putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
695 return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
698 static int
699 write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
701 if (s < 0)
702 return 1;
703 puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
704 putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
705 putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
707 return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
710 static int
711 remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
713 gdb_wince_len nbytes;
714 if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
715 (LPVOID) myaddr, len, &nbytes))
716 return -1;
717 return nbytes;
720 static int
721 remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
723 gdb_wince_len nbytes;
724 if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
725 (LPCVOID) myaddr, len, &nbytes))
726 return -1;
727 return nbytes;
730 /* This is not a standard Win32 function. It instructs the stub to return TRUE
731 if the thread referenced by HANDLE h is alive.
733 static int
734 thread_alive (HANDLE h)
736 gdb_wince_result res;
737 if (s < 0)
738 return 1;
739 puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
740 return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
743 static int
744 suspend_thread (HANDLE h)
746 if (s < 0)
747 return 1;
748 puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
749 return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
752 static int
753 resume_thread (HANDLE h)
755 if (s < 0)
756 return 1;
757 puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
758 return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
761 static int
762 continue_debug_event (DWORD pid, DWORD tid, DWORD status)
764 gdb_wince_result res;
765 if (s < 0)
766 return 0;
767 putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid);
768 putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid);
769 putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status);
770 return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL);
773 static int
774 close_handle (HANDLE h)
776 gdb_wince_result res;
777 if (s < 0)
778 return 1;
779 puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
780 return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
783 /* This is not a standard Win32 interface. This function tells the stub
784 to terminate.
786 static void
787 stop_stub (void)
789 if (s < 0)
790 return;
791 (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
792 s = -1;
795 /******************** End of emulation routines. ********************/
796 /******************** End of stub interface ********************/
798 #define check_for_step(a, x) (x)
800 #ifdef MIPS
801 static void
802 undoSStep (thread_info * th)
804 if (th->stepped)
806 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
807 th->stepped = 0;
811 void
812 wince_software_single_step (enum target_signal ignore,
813 int insert_breakpoints_p)
815 unsigned long pc;
816 thread_info *th = current_thread; /* Info on currently selected thread */
817 CORE_ADDR mips_next_pc (CORE_ADDR pc);
819 if (!insert_breakpoints_p)
821 undoSStep (th);
822 return;
825 th->stepped = 1;
826 pc = read_register (PC_REGNUM);
827 th->step_pc = mips_next_pc (pc);
828 th->step_prev = 0;
829 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
830 return;
832 #elif SHx
833 /* Hitachi SH architecture instruction encoding masks */
835 #define COND_BR_MASK 0xff00
836 #define UCOND_DBR_MASK 0xe000
837 #define UCOND_RBR_MASK 0xf0df
838 #define TRAPA_MASK 0xff00
840 #define COND_DISP 0x00ff
841 #define UCOND_DISP 0x0fff
842 #define UCOND_REG 0x0f00
844 /* Hitachi SH instruction opcodes */
846 #define BF_INSTR 0x8b00
847 #define BT_INSTR 0x8900
848 #define BRA_INSTR 0xa000
849 #define BSR_INSTR 0xb000
850 #define JMP_INSTR 0x402b
851 #define JSR_INSTR 0x400b
852 #define RTS_INSTR 0x000b
853 #define RTE_INSTR 0x002b
854 #define TRAPA_INSTR 0xc300
855 #define SSTEP_INSTR 0xc3ff
858 #define T_BIT_MASK 0x0001
860 static CORE_ADDR
861 sh_get_next_pc (CONTEXT *c)
863 short *instrMem;
864 int displacement;
865 int reg;
866 unsigned short opcode;
868 instrMem = (short *) c->Fir;
870 opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));
872 if ((opcode & COND_BR_MASK) == BT_INSTR)
874 if (c->Psr & T_BIT_MASK)
876 displacement = (opcode & COND_DISP) << 1;
877 if (displacement & 0x80)
878 displacement |= 0xffffff00;
880 * Remember PC points to second instr.
881 * after PC of branch ... so add 4
883 instrMem = (short *) (c->Fir + displacement + 4);
885 else
886 instrMem += 1;
888 else if ((opcode & COND_BR_MASK) == BF_INSTR)
890 if (c->Psr & T_BIT_MASK)
891 instrMem += 1;
892 else
894 displacement = (opcode & COND_DISP) << 1;
895 if (displacement & 0x80)
896 displacement |= 0xffffff00;
898 * Remember PC points to second instr.
899 * after PC of branch ... so add 4
901 instrMem = (short *) (c->Fir + displacement + 4);
904 else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
906 displacement = (opcode & UCOND_DISP) << 1;
907 if (displacement & 0x0800)
908 displacement |= 0xfffff000;
911 * Remember PC points to second instr.
912 * after PC of branch ... so add 4
914 instrMem = (short *) (c->Fir + displacement + 4);
916 else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
918 reg = (char) ((opcode & UCOND_REG) >> 8);
920 instrMem = (short *) *regptr (c, reg);
922 else if (opcode == RTS_INSTR)
923 instrMem = (short *) c->PR;
924 else if (opcode == RTE_INSTR)
925 instrMem = (short *) *regptr (c, 15);
926 else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
927 instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
928 else
929 instrMem += 1;
931 return (CORE_ADDR) instrMem;
933 /* Single step (in a painstaking fashion) by inspecting the current
934 instruction and setting a breakpoint on the "next" instruction
935 which would be executed. This code hails from sh-stub.c.
937 static void
938 undoSStep (thread_info * th)
940 if (th->stepped)
942 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
943 th->stepped = 0;
945 return;
948 /* Single step (in a painstaking fashion) by inspecting the current
949 instruction and setting a breakpoint on the "next" instruction
950 which would be executed. This code hails from sh-stub.c.
952 void
953 wince_software_single_step (enum target_signal ignore,
954 int insert_breakpoints_p)
956 thread_info *th = current_thread; /* Info on currently selected thread */
958 if (!insert_breakpoints_p)
960 undoSStep (th);
961 return;
964 th->stepped = 1;
965 th->step_pc = sh_get_next_pc (&th->context);
966 th->step_prev = 0;
967 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
968 return;
970 #elif defined (ARM)
971 #undef check_for_step
973 static enum target_signal
974 check_for_step (DEBUG_EVENT *ev, enum target_signal x)
976 thread_info *th = thread_rec (ev->dwThreadId, 1);
978 if (th->stepped &&
979 th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
980 return TARGET_SIGNAL_TRAP;
981 else
982 return x;
985 /* Single step (in a painstaking fashion) by inspecting the current
986 instruction and setting a breakpoint on the "next" instruction
987 which would be executed. This code hails from sh-stub.c.
989 static void
990 undoSStep (thread_info * th)
992 if (th->stepped)
994 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
995 th->stepped = 0;
999 void
1000 wince_software_single_step (enum target_signal ignore,
1001 int insert_breakpoints_p)
1003 unsigned long pc;
1004 thread_info *th = current_thread; /* Info on currently selected thread */
1005 CORE_ADDR mips_next_pc (CORE_ADDR pc);
1007 if (!insert_breakpoints_p)
1009 undoSStep (th);
1010 return;
1013 th->stepped = 1;
1014 pc = read_register (PC_REGNUM);
1015 th->step_pc = arm_get_next_pc (pc);
1016 th->step_prev = 0;
1017 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1018 return;
1020 #endif
1022 /* Find a thread record given a thread id.
1023 If get_context then also retrieve the context for this
1024 thread. */
1025 static thread_info *
1026 thread_rec (DWORD id, int get_context)
1028 thread_info *th;
1030 for (th = &thread_head; (th = th->next) != NULL;)
1031 if (th->id == id)
1033 if (!th->suspend_count && get_context)
1035 if (get_context > 0 && th != this_thread)
1036 th->suspend_count = suspend_thread (th->h) + 1;
1037 else if (get_context < 0)
1038 th->suspend_count = -1;
1040 th->context.ContextFlags = CONTEXT_DEBUGGER;
1041 get_thread_context (th->h, &th->context);
1043 return th;
1046 return NULL;
1049 /* Add a thread to the thread list */
1050 static thread_info *
1051 child_add_thread (DWORD id, HANDLE h)
1053 thread_info *th;
1055 if ((th = thread_rec (id, FALSE)))
1056 return th;
1058 th = (thread_info *) xmalloc (sizeof (*th));
1059 memset (th, 0, sizeof (*th));
1060 th->id = id;
1061 th->h = h;
1062 th->next = thread_head.next;
1063 thread_head.next = th;
1064 add_thread (id);
1065 return th;
1068 /* Clear out any old thread list and reintialize it to a
1069 pristine state. */
1070 static void
1071 child_init_thread_list (void)
1073 thread_info *th = &thread_head;
1075 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
1076 init_thread_list ();
1077 while (th->next != NULL)
1079 thread_info *here = th->next;
1080 th->next = here->next;
1081 (void) close_handle (here->h);
1082 xfree (here);
1086 /* Delete a thread from the list of threads */
1087 static void
1088 child_delete_thread (DWORD id)
1090 thread_info *th;
1092 if (info_verbose)
1093 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
1094 delete_thread (id);
1096 for (th = &thread_head;
1097 th->next != NULL && th->next->id != id;
1098 th = th->next)
1099 continue;
1101 if (th->next != NULL)
1103 thread_info *here = th->next;
1104 th->next = here->next;
1105 close_handle (here->h);
1106 xfree (here);
1110 static void
1111 check (BOOL ok, const char *file, int line)
1113 if (!ok)
1114 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
1117 static void
1118 do_child_fetch_inferior_registers (int r)
1120 if (r >= 0)
1122 supply_register (r, (char *) regptr (&current_thread->context, r));
1124 else
1126 for (r = 0; r < NUM_REGS; r++)
1127 do_child_fetch_inferior_registers (r);
1131 static void
1132 child_fetch_inferior_registers (int r)
1134 current_thread = thread_rec (inferior_pid, TRUE);
1135 do_child_fetch_inferior_registers (r);
1138 static void
1139 do_child_store_inferior_registers (int r)
1141 if (r >= 0)
1142 read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
1143 else
1145 for (r = 0; r < NUM_REGS; r++)
1146 do_child_store_inferior_registers (r);
1150 /* Store a new register value into the current thread context */
1151 static void
1152 child_store_inferior_registers (int r)
1154 current_thread = thread_rec (inferior_pid, TRUE);
1155 do_child_store_inferior_registers (r);
1158 /* Wait for child to do something. Return pid of child, or -1 in case
1159 of error; store status through argument pointer OURSTATUS. */
1161 static int
1162 handle_load_dll (void *dummy)
1164 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1165 char dll_buf[MAX_PATH + 1];
1166 char *p, *bufp, *imgp, *dll_name, *dll_basename;
1167 int len;
1169 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1170 if (!event->lpImageName)
1171 return 1;
1173 len = 0;
1174 for (bufp = dll_buf, imgp = event->lpImageName;
1175 bufp < dll_buf + sizeof (dll_buf);
1176 bufp += 16, imgp += 16)
1178 gdb_wince_len nbytes = 0;
1179 (void) read_process_memory (current_process_handle,
1180 imgp, bufp, 16, &nbytes);
1182 if (!nbytes && bufp == dll_buf)
1183 return 1; /* couldn't read it */
1184 for (p = bufp; p < bufp + nbytes; p++)
1186 len++;
1187 if (*p == '\0')
1188 goto out;
1189 if (event->fUnicode)
1190 p++;
1192 if (!nbytes)
1193 break;
1196 out:
1197 if (!len)
1198 return 1;
1199 #if 0
1200 dll_buf[len] = '\0';
1201 #endif
1202 dll_name = alloca (len);
1204 if (!dll_name)
1205 return 1;
1207 if (!event->fUnicode)
1208 memcpy (dll_name, dll_buf, len);
1209 else
1210 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len,
1211 dll_name, len, 0, 0);
1213 while ((p = strchr (dll_name, '\\')))
1214 *p = '/';
1216 /* FIXME!! It would be nice to define one symbol which pointed to the
1217 front of the dll if we can't find any symbols. */
1219 if (!(dll_basename = strrchr (dll_name, '/')))
1220 dll_basename = dll_name;
1221 else
1222 dll_basename++;
1224 /* The symbols in a dll are offset by 0x1000, which is the
1225 the offset from 0 of the first byte in an image - because
1226 of the file header and the section alignment.
1228 FIXME: Is this the real reason that we need the 0x1000 ? */
1230 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
1231 printf_unfiltered ("\n");
1233 return 1;
1236 /* Handle DEBUG_STRING output from child process. */
1237 static void
1238 handle_output_debug_string (struct target_waitstatus *ourstatus)
1240 char p[256];
1241 char s[255];
1242 char *q;
1243 gdb_wince_len nbytes_read;
1244 gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;
1246 if (nbytes > 255)
1247 nbytes = 255;
1249 memset (p, 0, sizeof (p));
1250 if (!read_process_memory (current_process_handle,
1251 current_event.u.DebugString.lpDebugStringData,
1252 &p, nbytes, &nbytes_read)
1253 || !*p)
1254 return;
1256 memset (s, 0, sizeof (s));
1257 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) p, (int) nbytes_read, s,
1258 sizeof (s) - 1, NULL, NULL);
1259 q = strchr (s, '\n');
1260 if (q != NULL)
1262 *q = '\0';
1263 if (*--q = '\r')
1264 *q = '\0';
1267 warning (s);
1269 return;
1272 /* Handle target exceptions. */
1273 static int
1274 handle_exception (struct target_waitstatus *ourstatus)
1276 #if 0
1277 if (current_event.u.Exception.dwFirstChance)
1278 return 0;
1279 #endif
1281 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1283 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
1285 case EXCEPTION_ACCESS_VIOLATION:
1286 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
1287 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1288 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1289 break;
1290 case STATUS_STACK_OVERFLOW:
1291 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
1292 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1293 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1294 break;
1295 case EXCEPTION_BREAKPOINT:
1296 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
1297 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1298 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1299 break;
1300 case DBG_CONTROL_C:
1301 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
1302 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1303 ourstatus->value.sig = TARGET_SIGNAL_INT;
1304 /* User typed CTRL-C. Continue with this status */
1305 last_sig = SIGINT; /* FIXME - should check pass state */
1306 break;
1307 case EXCEPTION_SINGLE_STEP:
1308 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
1309 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1310 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1311 break;
1312 case EXCEPTION_ILLEGAL_INSTRUCTION:
1313 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
1314 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1315 ourstatus->value.sig = check_for_step (&current_event, TARGET_SIGNAL_ILL);
1316 break;
1317 default:
1318 /* This may be a structured exception handling exception. In
1319 that case, we want to let the program try to handle it, and
1320 only break if we see the exception a second time. */
1322 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
1323 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1324 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1325 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1326 break;
1328 exception_count++;
1329 return 1;
1332 /* Resume all artificially suspended threads if we are continuing
1333 execution */
1334 static BOOL
1335 child_continue (DWORD continue_status, int id)
1337 int i;
1338 thread_info *th;
1339 BOOL res;
1341 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
1342 (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId));
1343 res = continue_debug_event (current_event.dwProcessId,
1344 current_event.dwThreadId,
1345 continue_status);
1346 if (res)
1347 for (th = &thread_head; (th = th->next) != NULL;)
1348 if (((id == -1) || (id == th->id)) && th->suspend_count)
1350 for (i = 0; i < th->suspend_count; i++)
1351 (void) resume_thread (th->h);
1352 th->suspend_count = 0;
1355 return res;
1358 /* Get the next event from the child. Return 1 if the event requires
1359 handling by WFI (or whatever).
1361 static int
1362 get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
1363 DWORD target_event_code, int *retval)
1365 int breakout = 0;
1366 BOOL debug_event;
1367 DWORD continue_status, event_code;
1368 thread_info *th = NULL;
1369 static thread_info dummy_thread_info;
1371 if (!(debug_event = wait_for_debug_event (&current_event, 1000)))
1373 *retval = 0;
1374 goto out;
1377 event_count++;
1378 continue_status = DBG_CONTINUE;
1379 *retval = 0;
1381 event_code = current_event.dwDebugEventCode;
1382 breakout = event_code == target_event_code;
1384 switch (event_code)
1386 case CREATE_THREAD_DEBUG_EVENT:
1387 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1388 (unsigned) current_event.dwProcessId,
1389 (unsigned) current_event.dwThreadId,
1390 "CREATE_THREAD_DEBUG_EVENT"));
1391 /* Record the existence of this thread */
1392 th = child_add_thread (current_event.dwThreadId,
1393 current_event.u.CreateThread.hThread);
1394 if (info_verbose)
1395 printf_unfiltered ("[New %s]\n",
1396 target_pid_to_str (current_event.dwThreadId));
1397 break;
1399 case EXIT_THREAD_DEBUG_EVENT:
1400 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1401 (unsigned) current_event.dwProcessId,
1402 (unsigned) current_event.dwThreadId,
1403 "EXIT_THREAD_DEBUG_EVENT"));
1404 child_delete_thread (current_event.dwThreadId);
1405 th = &dummy_thread_info;
1406 break;
1408 case CREATE_PROCESS_DEBUG_EVENT:
1409 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1410 (unsigned) current_event.dwProcessId,
1411 (unsigned) current_event.dwThreadId,
1412 "CREATE_PROCESS_DEBUG_EVENT"));
1413 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1415 main_thread_id = inferior_pid = current_event.dwThreadId;
1416 /* Add the main thread */
1417 th = child_add_thread (inferior_pid,
1418 current_event.u.CreateProcessInfo.hThread);
1419 break;
1421 case EXIT_PROCESS_DEBUG_EVENT:
1422 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1423 (unsigned) current_event.dwProcessId,
1424 (unsigned) current_event.dwThreadId,
1425 "EXIT_PROCESS_DEBUG_EVENT"));
1426 ourstatus->kind = TARGET_WAITKIND_EXITED;
1427 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1428 close_handle (current_process_handle);
1429 *retval = current_event.dwProcessId;
1430 breakout = 1;
1431 break;
1433 case LOAD_DLL_DEBUG_EVENT:
1434 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1435 (unsigned) current_event.dwProcessId,
1436 (unsigned) current_event.dwThreadId,
1437 "LOAD_DLL_DEBUG_EVENT"));
1438 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1439 registers_changed (); /* mark all regs invalid */
1440 break;
1442 case UNLOAD_DLL_DEBUG_EVENT:
1443 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1444 (unsigned) current_event.dwProcessId,
1445 (unsigned) current_event.dwThreadId,
1446 "UNLOAD_DLL_DEBUG_EVENT"));
1447 break; /* FIXME: don't know what to do here */
1449 case EXCEPTION_DEBUG_EVENT:
1450 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1451 (unsigned) current_event.dwProcessId,
1452 (unsigned) current_event.dwThreadId,
1453 "EXCEPTION_DEBUG_EVENT"));
1454 if (handle_exception (ourstatus))
1455 *retval = current_event.dwThreadId;
1456 else
1458 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1459 breakout = 0;
1461 break;
1463 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1464 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1465 (unsigned) current_event.dwProcessId,
1466 (unsigned) current_event.dwThreadId,
1467 "OUTPUT_DEBUG_STRING_EVENT"));
1468 handle_output_debug_string ( ourstatus);
1469 break;
1470 default:
1471 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
1472 current_event.dwProcessId,
1473 current_event.dwThreadId);
1474 printf_unfiltered (" unknown event code %d\n",
1475 current_event.dwDebugEventCode);
1476 break;
1479 if (breakout)
1480 this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1481 else
1482 CHECK (child_continue (continue_status, -1));
1484 out:
1485 return breakout;
1488 /* Wait for interesting events to occur in the target process. */
1489 static int
1490 child_wait (int pid, struct target_waitstatus *ourstatus)
1492 DWORD event_code;
1493 int retval;
1495 /* We loop when we get a non-standard exception rather than return
1496 with a SPURIOUS because resume can try and step or modify things,
1497 which needs a current_thread->h. But some of these exceptions mark
1498 the birth or death of threads, which mean that the current thread
1499 isn't necessarily what you think it is. */
1501 while (1)
1502 if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
1503 return retval;
1504 else
1506 int detach = 0;
1508 if (ui_loop_hook != NULL)
1509 detach = ui_loop_hook (0);
1511 if (detach)
1512 child_kill_inferior ();
1516 /* Print status information about what we're accessing. */
1518 static void
1519 child_files_info (struct target_ops *ignore)
1521 printf_unfiltered ("\tUsing the running image of child %s.\n",
1522 target_pid_to_str (inferior_pid));
1525 /* ARGSUSED */
1526 static void
1527 child_open (char *arg, int from_tty)
1529 error ("Use the \"run\" command to start a child process.");
1532 #define FACTOR (0x19db1ded53ea710LL)
1533 #define NSPERSEC 10000000
1535 /* Convert a Win32 time to "UNIX" format. */
1536 long
1537 to_time_t (FILETIME * ptr)
1539 /* A file time is the number of 100ns since jan 1 1601
1540 stuffed into two long words.
1541 A time_t is the number of seconds since jan 1 1970. */
1543 long rem;
1544 long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime);
1545 x -= FACTOR; /* number of 100ns between 1601 and 1970 */
1546 rem = x % ((long long) NSPERSEC);
1547 rem += (NSPERSEC / 2);
1548 x /= (long long) NSPERSEC; /* number of 100ns in a second */
1549 x += (long long) (rem / NSPERSEC);
1550 return x;
1553 /* Upload a file to the remote device depending on the user's
1554 'set remoteupload' specification. */
1555 char *
1556 upload_to_device (const char *to, const char *from)
1558 HANDLE h;
1559 const char *dir = remote_directory ?: "\\gdb";
1560 int len;
1561 static char *remotefile = NULL;
1562 LPWSTR wstr;
1563 char *p;
1564 DWORD err;
1565 const char *in_to = to;
1566 FILETIME crtime, actime, wrtime;
1567 time_t utime;
1568 struct stat st;
1569 int fd;
1571 /* Look for a path separator and only use trailing part. */
1572 while ((p = strpbrk (to, "/\\")) != NULL)
1573 to = p + 1;
1575 if (!*to)
1576 error ("no filename found to upload - %s.", in_to);
1578 len = strlen (dir) + strlen (to) + 2;
1579 remotefile = (char *) xrealloc (remotefile, len);
1580 strcpy (remotefile, dir);
1581 strcat (remotefile, "\\");
1582 strcat (remotefile, to);
1584 if (upload_when == UPLOAD_NEVER)
1585 return remotefile; /* Don't bother uploading. */
1587 /* Open the source. */
1588 if ((fd = openp (getenv ("PATH"), TRUE, (char *) from, O_RDONLY, 0, NULL)) < 0)
1589 error ("couldn't open %s", from);
1591 /* Get the time for later comparison. */
1592 if (fstat (fd, &st))
1593 st.st_mtime = (time_t) - 1;
1595 /* Always attempt to create the directory on the remote system. */
1596 wstr = towide (dir, NULL);
1597 (void) CeCreateDirectory (wstr, NULL);
1599 /* Attempt to open the remote file, creating it if it doesn't exist. */
1600 wstr = towide (remotefile, NULL);
1601 h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1602 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1604 /* Some kind of problem? */
1605 err = CeGetLastError ();
1606 if (h == NULL || h == INVALID_HANDLE_VALUE)
1607 error ("error opening file \"%s\". Windows error %d.",
1608 remotefile, err);
1610 CeGetFileTime (h, &crtime, &actime, &wrtime);
1611 utime = to_time_t (&wrtime);
1612 #if 0
1613 if (utime < st.st_mtime)
1615 char buf[80];
1616 strcpy (buf, ctime(&utime));
1617 printf ("%s < %s\n", buf, ctime(&st.st_mtime));
1619 #endif
1620 /* See if we need to upload the file. */
1621 if (upload_when == UPLOAD_ALWAYS ||
1622 err != ERROR_ALREADY_EXISTS ||
1623 !CeGetFileTime (h, &crtime, &actime, &wrtime) ||
1624 to_time_t (&wrtime) < st.st_mtime)
1626 DWORD nbytes;
1627 char buf[4096];
1628 int n;
1630 /* Upload the file. */
1631 while ((n = read (fd, buf, sizeof (buf))) > 0)
1632 if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL))
1633 error ("error writing to remote device - %d.",
1634 CeGetLastError ());
1637 close (fd);
1638 if (!CeCloseHandle (h))
1639 error ("error closing remote file - %d.", CeGetLastError ());
1641 return remotefile;
1644 /* Initialize the connection to the remote device. */
1645 static void
1646 wince_initialize (void)
1648 int tmp;
1649 char args[256];
1650 char *hostname;
1651 struct sockaddr_in sin;
1652 char *stub_file_name;
1653 int s0;
1654 PROCESS_INFORMATION pi;
1656 if (!connection_initialized)
1657 switch (CeRapiInit ())
1659 case 0:
1660 connection_initialized = 1;
1661 break;
1662 default:
1663 CeRapiUninit ();
1664 error ("Can't initialize connection to remote device.\n");
1665 break;
1668 /* Upload the stub to the handheld device. */
1669 stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB);
1670 strcpy (args, stub_file_name);
1672 if (remote_add_host)
1674 strcat (args, " ");
1675 hostname = strchr (args, '\0');
1676 if (gethostname (hostname, sizeof (args) - strlen (args)))
1677 error ("couldn't get hostname of this system.");
1680 /* Get a socket. */
1681 if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1682 stub_error ("Couldn't connect to host system.");
1684 /* Allow rapid reuse of the port. */
1685 tmp = 1;
1686 (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1689 /* Set up the information for connecting to the host gdb process. */
1690 memset (&sin, 0, sizeof (sin));
1691 sin.sin_family = AF_INET;
1692 sin.sin_port = htons (7000); /* FIXME: This should be configurable */
1694 if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
1695 error ("couldn't bind socket");
1697 if (listen (s0, 1))
1698 error ("Couldn't open socket for listening.\n");
1700 /* Start up the stub on the remote device. */
1701 if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL),
1702 NULL, NULL, 0, 0, NULL, NULL, NULL, &pi))
1703 error ("Unable to start remote stub '%s'. Windows CE error %d.",
1704 stub_file_name, CeGetLastError ());
1706 /* Wait for a connection */
1708 if ((s = accept (s0, NULL, NULL)) < 0)
1709 error ("couldn't set up server for connection.");
1711 close (s0);
1714 /* Start an inferior win32 child process and sets inferior_pid to its pid.
1715 EXEC_FILE is the file to run.
1716 ALLARGS is a string containing the arguments to the program.
1717 ENV is the environment vector to pass. Errors reported with error(). */
1718 static void
1719 child_create_inferior (char *exec_file, char *args, char **env)
1721 PROCESS_INFORMATION pi;
1722 struct target_waitstatus dummy;
1723 int ret;
1724 DWORD flags, event_code;
1725 char *exec_and_args;
1727 if (!exec_file)
1728 error ("No executable specified, use `target exec'.\n");
1730 flags = DEBUG_PROCESS;
1732 wince_initialize (); /* Make sure we've got a connection. */
1734 exec_file = upload_to_device (exec_file, exec_file);
1736 while (*args == ' ')
1737 args++;
1739 /* Allocate space for "command<sp>args" */
1740 if (*args == '\0')
1742 exec_and_args = alloca (strlen (exec_file) + 1);
1743 strcpy (exec_and_args, exec_file);
1745 else
1747 exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
1748 sprintf (exec_and_args, "%s %s", exec_file, args);
1751 memset (&pi, 0, sizeof (pi));
1752 /* Execute the process */
1753 if (!create_process (exec_file, exec_and_args, flags, &pi))
1754 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1756 exception_count = 0;
1757 event_count = 0;
1759 current_process_handle = pi.hProcess;
1760 current_event.dwProcessId = pi.dwProcessId;
1761 memset (&current_event, 0, sizeof (current_event));
1762 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1763 push_target (&child_ops);
1764 child_init_thread_list ();
1765 child_add_thread (pi.dwThreadId, pi.hThread);
1766 init_wait_for_inferior ();
1767 clear_proceed_status ();
1768 target_terminal_init ();
1769 target_terminal_inferior ();
1771 /* Run until process and threads are loaded */
1772 while (!get_child_debug_event (inferior_pid, &dummy,
1773 CREATE_PROCESS_DEBUG_EVENT, &ret))
1774 continue;
1776 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
1779 /* Chile has gone bye-bye. */
1780 static void
1781 child_mourn_inferior (void)
1783 (void) child_continue (DBG_CONTINUE, -1);
1784 unpush_target (&child_ops);
1785 stop_stub ();
1786 CeRapiUninit ();
1787 connection_initialized = 0;
1788 generic_mourn_inferior ();
1791 /* Move memory from child to/from gdb. */
1793 child_xfer_memory (CORE_ADDR memaddr, char *our, int len, int write,
1794 struct mem_attrib *attrib,
1795 struct target_ops *target)
1797 if (len <= 0)
1798 return 0;
1800 if (write)
1801 res = remote_write_bytes (memaddr, our, len);
1802 else
1803 res = remote_read_bytes (memaddr, our, len);
1805 return res;
1808 /* Terminate the process and wait for child to tell us it has completed. */
1809 void
1810 child_kill_inferior (void)
1812 CHECK (terminate_process (current_process_handle));
1814 for (;;)
1816 if (!child_continue (DBG_CONTINUE, -1))
1817 break;
1818 if (!wait_for_debug_event (&current_event, INFINITE))
1819 break;
1820 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1821 break;
1824 CHECK (close_handle (current_process_handle));
1825 close_handle (current_thread->h);
1826 target_mourn_inferior (); /* or just child_mourn_inferior? */
1829 /* Resume the child after an exception. */
1830 void
1831 child_resume (int pid, int step, enum target_signal sig)
1833 thread_info *th;
1834 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1835 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1837 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1838 pid, step, sig));
1840 /* Get context for currently selected thread */
1841 th = thread_rec (current_event.dwThreadId, FALSE);
1843 if (th->context.ContextFlags)
1845 CHECK (set_thread_context (th->h, &th->context));
1846 th->context.ContextFlags = 0;
1849 /* Allow continuing with the same signal that interrupted us.
1850 Otherwise complain. */
1851 if (sig && sig != last_sig)
1852 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
1854 last_sig = 0;
1855 child_continue (continue_status, pid);
1858 static void
1859 child_prepare_to_store (void)
1861 /* Do nothing, since we can store individual regs */
1864 static int
1865 child_can_run (void)
1867 return 1;
1870 static void
1871 child_close (void)
1873 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1876 /* Explicitly upload file to remotedir */
1878 static void
1879 child_load (char *file, int from_tty)
1881 upload_to_device (file, file);
1884 struct target_ops child_ops;
1886 static void
1887 init_child_ops (void)
1889 memset (&child_ops, 0, sizeof (child_ops));
1890 child_ops.to_shortname = (char *) "child";
1891 child_ops.to_longname = (char *) "Windows CE process";
1892 child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command).";
1893 child_ops.to_open = child_open;
1894 child_ops.to_close = child_close;
1895 child_ops.to_resume = child_resume;
1896 child_ops.to_wait = child_wait;
1897 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1898 child_ops.to_store_registers = child_store_inferior_registers;
1899 child_ops.to_prepare_to_store = child_prepare_to_store;
1900 child_ops.to_xfer_memory = child_xfer_memory;
1901 child_ops.to_files_info = child_files_info;
1902 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1903 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1904 child_ops.to_terminal_init = terminal_init_inferior;
1905 child_ops.to_terminal_inferior = terminal_inferior;
1906 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1907 child_ops.to_terminal_ours = terminal_ours;
1908 child_ops.to_terminal_info = child_terminal_info;
1909 child_ops.to_kill = child_kill_inferior;
1910 child_ops.to_load = child_load;
1911 child_ops.to_create_inferior = child_create_inferior;
1912 child_ops.to_mourn_inferior = child_mourn_inferior;
1913 child_ops.to_can_run = child_can_run;
1914 child_ops.to_thread_alive = win32_child_thread_alive;
1915 child_ops.to_stratum = process_stratum;
1916 child_ops.to_has_all_memory = 1;
1917 child_ops.to_has_memory = 1;
1918 child_ops.to_has_stack = 1;
1919 child_ops.to_has_registers = 1;
1920 child_ops.to_has_execution = 1;
1921 child_ops.to_sections = 0;
1922 child_ops.to_sections_end = 0;
1923 child_ops.to_magic = OPS_MAGIC;
1927 /* Handle 'set remoteupload' parameter. */
1929 #define replace_upload(what) \
1930 upload_when = what; \
1931 remote_upload = xrealloc (remote_upload, strlen (upload_options[upload_when].name) + 1); \
1932 strcpy (remote_upload, upload_options[upload_when].name);
1934 static void
1935 set_upload_type (char *ignore, int from_tty)
1937 int i, len;
1938 char *bad_option;
1940 if (!remote_upload || !remote_upload[0])
1942 replace_upload (UPLOAD_NEWER);
1943 if (from_tty)
1944 printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1945 return;
1948 len = strlen (remote_upload);
1949 for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++)
1950 if (len >= upload_options[i].abbrev &&
1951 strncasecmp (remote_upload, upload_options[i].name, len) == 0)
1953 replace_upload (i);
1954 return;
1957 bad_option = remote_upload;
1958 replace_upload (UPLOAD_NEWER);
1959 error ("Unknown upload type: %s.", bad_option);
1962 void
1963 _initialize_inftarg (void)
1965 struct cmd_list_element *set;
1966 init_child_ops ();
1968 add_show_from_set
1969 (add_set_cmd ((char *) "remotedirectory", no_class,
1970 var_string_noescape, (char *) &remote_directory,
1971 (char *) "Set directory for remote upload.\n",
1972 &setlist),
1973 &showlist);
1974 remote_directory = xstrdup (remote_directory);
1976 set = add_set_cmd ((char *) "remoteupload", no_class,
1977 var_string_noescape, (char *) &remote_upload,
1978 (char *) "Set how to upload executables to remote device.\n",
1979 &setlist);
1980 add_show_from_set (set, &showlist);
1981 set->function.cfunc = set_upload_type;
1982 set_upload_type (NULL, 0);
1984 add_show_from_set
1985 (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
1986 (char *) &debug_exec,
1987 (char *) "Set whether to display execution in child process.",
1988 &setlist),
1989 &showlist);
1991 add_show_from_set
1992 (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
1993 (char *) &remote_add_host,
1994 (char *) "Set whether to add this host to remote stub arguments for\n
1995 debugging over a network.", &setlist),
1996 &showlist);
1998 add_show_from_set
1999 (add_set_cmd ((char *) "debugevents", class_support, var_boolean,
2000 (char *) &debug_events,
2001 (char *) "Set whether to display kernel events in child process.",
2002 &setlist),
2003 &showlist);
2005 add_show_from_set
2006 (add_set_cmd ((char *) "debugmemory", class_support, var_boolean,
2007 (char *) &debug_memory,
2008 (char *) "Set whether to display memory accesses in child process.",
2009 &setlist),
2010 &showlist);
2012 add_show_from_set
2013 (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean,
2014 (char *) &debug_exceptions,
2015 (char *) "Set whether to display kernel exceptions in child process.",
2016 &setlist),
2017 &showlist);
2019 add_target (&child_ops);
2022 /* Determine if the thread referenced by "pid" is alive
2023 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2024 it means that the pid has died. Otherwise it is assumed to be alive. */
2025 static int
2026 win32_child_thread_alive (int pid)
2028 return thread_alive (thread_rec (pid, FALSE)->h);
2031 /* Convert pid to printable format. */
2032 char *
2033 cygwin_pid_to_str (int pid)
2035 static char buf[80];
2036 if (pid == current_event.dwProcessId)
2037 sprintf (buf, "process %d", pid);
2038 else
2039 sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);
2040 return buf;