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