1 /* Target-vector operations for controlling Windows CE child processes, for GDB.
3 Copyright (C) 1999, 2000, 2001, 2004, 2006 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions, A Red Hat Company.
6 This file is part of GDB.
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.
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.
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.
26 /* We assume we're being built with and will be used for cygwin. */
30 #define SH4 /* Just to get all of the CONTEXT defines. */
34 #include "frame.h" /* required by inferior.h */
37 #include "exceptions.h"
41 #include <sys/types.h>
48 #include <cygwin/in.h>
49 #include <cygwin/socket.h>
54 #include "gdb_string.h"
55 #include "gdbthread.h"
57 #include <sys/param.h>
58 #include "wince-stub.h"
62 #include "mips-tdep.h"
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)
73 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
78 #define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
80 #define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
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"
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
92 static int connection_initialized = 0; /* True if we've initialized a
95 /* The directory where the stub and executable files are uploaded. */
96 static const char *remote_directory = "\\gdb";
98 /* The types automatic upload available. */
105 upload_when = UPLOAD_NEWER;
107 /* Valid options for 'set remoteupload'. Note that options
108 must track upload_when enum. */
129 static char *remote_upload = NULL; /* Set by set remoteupload. */
130 static int remote_add_host = 0;
132 static int win32_child_thread_alive (ptid_t);
133 void child_kill_inferior (void);
135 static int last_sig = 0; /* Set if a signal was received from
136 the 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;
147 int stepped; /* True if stepped. */
149 unsigned long step_prev;
154 static thread_info thread_head =
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
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. */
169 /* Counts of things. */
170 static int exception_count = 0;
171 static int event_count = 0;
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 */
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
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] =
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]),
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]),
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),
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),
358 context_offset (R10),
359 context_offset (R11),
360 context_offset (R12),
373 context_offset (Psr),
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.
383 regptr (LPCONTEXT c, int r)
385 static ULONG zero = 0;
390 p = (ULONG *) (((char *) c) + mappings[r]);
394 /******************** Beginning of stub interface ********************/
396 /* Stub interface description:
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
402 byte 0: command id (e.g. Create Process)
409 byte 3-n: arbitrary memory.
411 The interface is deterministic, i.e., if the stub expects a DWORD
412 then the gdb server should send a DWORD.
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.
419 The 'what' parameter is a command id as found in wince-stub.h.
421 Hopefully, the rest of the parameters are self-explanatory.
424 static int s; /* communication socket */
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
430 vstub_error (LPCSTR fmt, va_list * args)
433 vsprintf (buf, fmt, args);
438 /* The standard way to display an error message and exit. */
440 stub_error (LPCSTR fmt,...)
443 va_start (args, fmt);
444 vstub_error (fmt, args);
447 /* Standard "oh well" can't communicate error. Someday this might
448 attempt synchronization. */
450 attempt_resync (LPCSTR huh, int s)
452 stub_error ("lost synchronization with target attempting %s", huh);
455 /* Read arbitrary stuff from a socket. */
457 sockread (LPCSTR huh, int s, void *str, size_t n)
461 if (recv (s, str, n, 0) == n)
463 attempt_resync (huh, s);
467 /* Write arbitrary stuff to a socket. */
469 sockwrite (LPCSTR huh, const void *str, size_t n)
473 if (send (s, str, n, 0) == n)
475 attempt_resync (huh, s);
479 /* Output an id/dword to the host. */
481 putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
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);
489 /* Output an id/word to the host. */
491 putword (LPCSTR huh, gdb_wince_id what, WORD n)
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);
499 /* Convenience define for outputting a "gdb_wince_len" type. */
500 #define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
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
506 putmemory (LPCSTR huh, gdb_wince_id what,
507 const void *mem, gdb_wince_len len)
509 putlen (huh, what, len);
510 if (((short) len > 0) && sockwrite (huh, mem, len) != len)
511 stub_error ("error writing %s to host.", huh);
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. */
518 getdword (LPCSTR huh, gdb_wince_id what_this)
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);
527 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
528 stub_error ("error getting %s from host.", huh);
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
537 getword (LPCSTR huh, gdb_wince_id what_this)
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);
546 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
547 stub_error ("error getting %s from host.", huh);
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))
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
565 getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf,
566 gdb_wince_len * nbytes)
572 *nbytes = getlen (huh, what);
574 if ((short) *nbytes < 0)
576 SetLastError (-(short) *nbytes);
580 if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
581 stub_error ("couldn't read information from wince stub - %s", huh);
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.
591 towide (const char *s, gdb_wince_len * out_len)
594 static LPWSTR outs[8] =
595 {NULL /*, NULL, etc. */ };
601 /* First determine the length required to hold the converted string. */
602 *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s,
605 return NULL; /* The conversion failed. */
607 if (++n >= (sizeof (outs) / sizeof (outs[0])))
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).
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);
620 /******************** Emulation routines start here. ********************
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.
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.
638 create_process (LPSTR exec_file, LPSTR args, DWORD flags,
639 PROCESS_INFORMATION * pi)
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);
652 /* Emulate TerminateProcess.
653 Don't bother with the second argument since CE ignores it.
656 terminate_process (HANDLE h)
658 gdb_wince_result res;
661 puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
663 return getresult ("TerminateProcess result",
664 GDB_TERMINATEPROCESS, &res, NULL);
668 wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
672 putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
674 return getresult ("WaitForDebugEvent event",
675 GDB_WAITFORDEBUGEVENT, ev, NULL);
679 get_thread_context (HANDLE h, CONTEXT * c)
683 puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
684 putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT,
687 return getresult ("GetThreadContext context",
688 GDB_GETTHREADCONTEXT, c, NULL);
692 set_thread_context (HANDLE h, CONTEXT * c)
694 gdb_wince_result res;
697 puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
698 putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT,
701 return getresult ("SetThreadContext context",
702 GDB_SETTHREADCONTEXT, &res, NULL);
706 read_process_memory (HANDLE h, LPCVOID where,
707 LPVOID buf, gdb_wince_len len,
708 gdb_wince_len * nbytes)
712 puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
713 putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
714 putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
716 return getresult ("ReadProcessMemory buf",
717 GDB_READPROCESSMEMORY, buf, nbytes);
721 write_process_memory (HANDLE h, LPCVOID where,
722 LPCVOID buf, gdb_wince_len len,
723 gdb_wince_len * nbytes)
727 puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
728 putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
729 putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
731 return getresult ("WriteProcessMemory result",
732 GDB_WRITEPROCESSMEMORY, nbytes, NULL);
736 remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
738 gdb_wince_len nbytes;
739 if (!read_process_memory (current_process_handle,
748 remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
750 gdb_wince_len nbytes;
751 if (!write_process_memory (current_process_handle,
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.
763 thread_alive (HANDLE h)
765 gdb_wince_result res;
768 puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
769 return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
773 suspend_thread (HANDLE h)
777 puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
778 return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
782 resume_thread (HANDLE h)
786 puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
787 return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
791 continue_debug_event (DWORD pid, DWORD tid, DWORD status)
793 gdb_wince_result res;
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);
804 close_handle (HANDLE h)
806 gdb_wince_result res;
809 puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
810 return (int) getresult ("CloseHandle result",
811 GDB_CLOSEHANDLE, &res, NULL);
814 /* This is not a standard Win32 interface. This function tells the
822 (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
826 /******************** End of emulation routines. ********************/
827 /******************** End of stub interface ********************/
829 #define check_for_step(a, x) (x)
833 undoSStep (thread_info * th)
837 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
843 wince_software_single_step (enum target_signal ignore,
844 int insert_breakpoints_p)
847 /* Info on currently selected thread. */
848 thread_info *th = current_thread;
849 CORE_ADDR mips_next_pc (CORE_ADDR pc);
851 if (!insert_breakpoints_p)
858 pc = read_register (PC_REGNUM);
859 th->step_pc = mips_next_pc (pc);
861 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
865 /* Renesas SH architecture instruction encoding masks */
867 #define COND_BR_MASK 0xff00
868 #define UCOND_DBR_MASK 0xe000
869 #define UCOND_RBR_MASK 0xf0df
870 #define TRAPA_MASK 0xff00
872 #define COND_DISP 0x00ff
873 #define UCOND_DISP 0x0fff
874 #define UCOND_REG 0x0f00
876 /* Renesas SH instruction opcodes */
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
890 #define T_BIT_MASK 0x0001
893 sh_get_next_pc (CONTEXT *c)
898 unsigned short opcode;
900 instrMem = (short *) c->Fir;
902 opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));
904 if ((opcode & COND_BR_MASK) == BT_INSTR)
906 if (c->Psr & T_BIT_MASK)
908 displacement = (opcode & COND_DISP) << 1;
909 if (displacement & 0x80)
910 displacement |= 0xffffff00;
912 * Remember PC points to second instr.
913 * after PC of branch ... so add 4
915 instrMem = (short *) (c->Fir + displacement + 4);
920 else if ((opcode & COND_BR_MASK) == BF_INSTR)
922 if (c->Psr & T_BIT_MASK)
926 displacement = (opcode & COND_DISP) << 1;
927 if (displacement & 0x80)
928 displacement |= 0xffffff00;
930 * Remember PC points to second instr.
931 * after PC of branch ... so add 4
933 instrMem = (short *) (c->Fir + displacement + 4);
936 else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
938 displacement = (opcode & UCOND_DISP) << 1;
939 if (displacement & 0x0800)
940 displacement |= 0xfffff000;
943 * Remember PC points to second instr.
944 * after PC of branch ... so add 4
946 instrMem = (short *) (c->Fir + displacement + 4);
948 else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
950 reg = (char) ((opcode & UCOND_REG) >> 8);
952 instrMem = (short *) *regptr (c, reg);
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);
963 return (CORE_ADDR) instrMem;
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.
970 undoSStep (thread_info * th)
974 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
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.
985 wince_software_single_step (enum target_signal ignore,
986 int insert_breakpoints_p)
988 /* Info on currently selected thread. */
989 thread_info *th = current_thread;
991 if (!insert_breakpoints_p)
998 th->step_pc = sh_get_next_pc (&th->context);
1000 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1004 #undef check_for_step
1006 static enum target_signal
1007 check_for_step (DEBUG_EVENT *ev, enum target_signal x)
1009 thread_info *th = thread_rec (ev->dwThreadId, 1);
1012 th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
1013 return TARGET_SIGNAL_TRAP;
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.
1023 undoSStep (thread_info * th)
1027 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
1033 wince_software_single_step (enum target_signal ignore,
1034 int insert_breakpoints_p)
1037 /* Info on currently selected thread. */
1038 thread_info *th = current_thread;
1039 CORE_ADDR mips_next_pc (CORE_ADDR pc);
1041 if (!insert_breakpoints_p)
1048 pc = read_register (PC_REGNUM);
1049 th->step_pc = arm_get_next_pc (pc);
1051 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1056 /* Find a thread record given a thread id.
1057 If get_context then also retrieve the context for this thread. */
1059 static thread_info *
1060 thread_rec (DWORD id, int get_context)
1064 for (th = &thread_head; (th = th->next) != NULL;)
1067 if (!th->suspend_count && get_context)
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;
1074 th->context.ContextFlags = CONTEXT_DEBUGGER;
1075 get_thread_context (th->h, &th->context);
1082 /* Add a thread to the thread list. */
1083 static thread_info *
1084 child_add_thread (DWORD id, HANDLE h)
1088 if ((th = thread_rec (id, FALSE)))
1091 th = (thread_info *) xmalloc (sizeof (*th));
1092 memset (th, 0, sizeof (*th));
1095 th->next = thread_head.next;
1096 thread_head.next = th;
1101 /* Clear out any old thread list and reintialize it to a
1104 child_init_thread_list (void)
1106 thread_info *th = &thread_head;
1108 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
1109 init_thread_list ();
1110 while (th->next != NULL)
1112 thread_info *here = th->next;
1113 th->next = here->next;
1114 (void) close_handle (here->h);
1119 /* Delete a thread from the list of threads. */
1121 child_delete_thread (DWORD id)
1126 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
1129 for (th = &thread_head;
1130 th->next != NULL && th->next->id != id;
1134 if (th->next != NULL)
1136 thread_info *here = th->next;
1137 th->next = here->next;
1138 close_handle (here->h);
1144 check (BOOL ok, const char *file, int line)
1147 printf_filtered ("error return %s:%d was %d\n",
1148 file, line, GetLastError ());
1152 do_child_fetch_inferior_registers (int r)
1156 regcache_raw_supply (current_regcache, r,
1157 (char *) regptr (¤t_thread->context, r));
1161 for (r = 0; r < NUM_REGS; r++)
1162 do_child_fetch_inferior_registers (r);
1167 child_fetch_inferior_registers (int r)
1169 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
1170 do_child_fetch_inferior_registers (r);
1174 do_child_store_inferior_registers (int r)
1177 deprecated_read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
1180 for (r = 0; r < NUM_REGS; r++)
1181 do_child_store_inferior_registers (r);
1185 /* Store a new register value into the current thread context. */
1187 child_store_inferior_registers (int r)
1189 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
1190 do_child_store_inferior_registers (r);
1193 /* Wait for child to do something. Return pid of child, or -1 in case
1194 of error; store status through argument pointer OURSTATUS. */
1197 handle_load_dll (void *dummy)
1199 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
1200 char dll_buf[MAX_PATH + 1];
1201 char *p, *bufp, *imgp, *dll_name, *dll_basename;
1204 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1205 if (!event->lpImageName)
1209 for (bufp = dll_buf, imgp = event->lpImageName;
1210 bufp < dll_buf + sizeof (dll_buf);
1211 bufp += 16, imgp += 16)
1213 gdb_wince_len nbytes = 0;
1214 (void) read_process_memory (current_process_handle,
1215 imgp, bufp, 16, &nbytes);
1217 if (!nbytes && bufp == dll_buf)
1218 return 1; /* couldn't read it */
1219 for (p = bufp; p < bufp + nbytes; p++)
1224 if (event->fUnicode)
1235 dll_buf[len] = '\0';
1237 dll_name = alloca (len);
1242 if (!event->fUnicode)
1243 memcpy (dll_name, dll_buf, len);
1245 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf,
1246 len, dll_name, len, 0, 0);
1248 while ((p = strchr (dll_name, '\\')))
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. */
1254 if (!(dll_basename = strrchr (dll_name, '/')))
1255 dll_basename = dll_name;
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.
1263 FIXME: Is this the real reason that we need the 0x1000 ? */
1265 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
1266 printf_unfiltered ("\n");
1271 /* Handle DEBUG_STRING output from child process. */
1273 handle_output_debug_string (struct target_waitstatus *ourstatus)
1278 gdb_wince_len nbytes_read;
1279 gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;
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)
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');
1307 /* Handle target exceptions. */
1309 handle_exception (struct target_waitstatus *ourstatus)
1312 if (current_event.u.Exception.dwFirstChance)
1316 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1318 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
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;
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;
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;
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. */
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;
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 (¤t_event,
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. */
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;
1369 /* Resume all artificially suspended threads if we are continuing
1372 child_continue (DWORD continue_status, int id)
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,
1385 for (th = &thread_head; (th = th->next) != NULL;)
1386 if (((id == -1) || (id == th->id)) && th->suspend_count)
1388 for (i = 0; i < th->suspend_count; i++)
1389 (void) resume_thread (th->h);
1390 th->suspend_count = 0;
1396 /* Get the next event from the child. Return 1 if the event requires
1397 handling by WFI (or whatever).
1400 get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
1401 DWORD target_event_code, int *retval)
1405 DWORD continue_status, event_code;
1406 thread_info *th = NULL;
1407 static thread_info dummy_thread_info;
1409 if (!(debug_event = wait_for_debug_event (¤t_event, 1000)))
1416 continue_status = DBG_CONTINUE;
1419 event_code = current_event.dwDebugEventCode;
1420 breakout = event_code == target_event_code;
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);
1433 printf_unfiltered ("[New %s]\n",
1434 target_pid_to_str (current_event.dwThreadId));
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;
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;
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);
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;
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 */
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 */
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;
1498 continue_status = DBG_EXCEPTION_NOT_HANDLED;
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);
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);
1520 this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId,
1523 CHECK (child_continue (continue_status, -1));
1529 /* Wait for interesting events to occur in the target process. */
1531 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1535 int pid = PIDGET (ptid);
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. */
1544 if (get_child_debug_event (pid, ourstatus,
1545 EXCEPTION_DEBUG_EVENT, &retval))
1546 return pid_to_ptid (retval);
1551 if (deprecated_ui_loop_hook != NULL)
1552 detach = deprecated_ui_loop_hook (0);
1555 child_kill_inferior ();
1559 /* Print status information about what we're accessing. */
1562 child_files_info (struct target_ops *ignore)
1564 printf_unfiltered ("\tUsing the running image of child %s.\n",
1565 target_pid_to_str (inferior_ptid));
1569 child_open (char *arg, int from_tty)
1571 error (_("Use the \"run\" command to start a child process."));
1574 #define FACTOR (0x19db1ded53ea710LL)
1575 #define NSPERSEC 10000000
1577 /* Convert a Win32 time to "UNIX" format. */
1579 to_time_t (FILETIME * ptr)
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. */
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);
1595 /* Upload a file to the remote device depending on the user's
1596 'set remoteupload' specification. */
1598 upload_to_device (const char *to, const char *from)
1601 const char *dir = remote_directory ?: "\\gdb";
1603 static char *remotefile = NULL;
1607 const char *in_to = to;
1608 FILETIME crtime, actime, wrtime;
1613 /* Look for a path separator and only use trailing part. */
1614 while ((p = strpbrk (to, "/\\")) != NULL)
1618 error (_("no filename found to upload - %s."), in_to);
1620 len = strlen (dir) + strlen (to) + 2;
1621 remotefile = (char *) xrealloc (remotefile, len);
1622 strcpy (remotefile, dir);
1623 strcat (remotefile, "\\");
1624 strcat (remotefile, to);
1626 if (upload_when == UPLOAD_NEVER)
1627 return remotefile; /* Don't bother uploading. */
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);
1634 /* Get the time for later comparison. */
1635 if (fstat (fd, &st))
1636 st.st_mtime = (time_t) - 1;
1638 /* Always attempt to create the directory on the remote system. */
1639 wstr = towide (dir, NULL);
1640 (void) CeCreateDirectory (wstr, NULL);
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);
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."),
1653 CeGetFileTime (h, &crtime, &actime, &wrtime);
1654 utime = to_time_t (&wrtime);
1656 if (utime < st.st_mtime)
1659 strcpy (buf, ctime(&utime));
1660 printf ("%s < %s\n", buf, ctime(&st.st_mtime));
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)
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."),
1681 if (!CeCloseHandle (h))
1682 error (_("error closing remote file - %d."), CeGetLastError ());
1687 /* Initialize the connection to the remote device. */
1689 wince_initialize (void)
1694 struct sockaddr_in sin;
1695 char *stub_file_name;
1697 PROCESS_INFORMATION pi;
1699 if (!connection_initialized)
1700 switch (CeRapiInit ())
1703 connection_initialized = 1;
1707 error (_("Can't initialize connection to remote device."));
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);
1714 if (remote_add_host)
1717 hostname = strchr (args, '\0');
1718 if (gethostname (hostname, sizeof (args) - strlen (args)))
1719 error (_("couldn't get hostname of this system."));
1723 if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1724 stub_error ("Couldn't connect to host system.");
1726 /* Allow rapid reuse of the port. */
1728 (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR,
1729 (char *) &tmp, sizeof (tmp));
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. */
1737 if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
1738 error (_("couldn't bind socket"));
1741 error (_("Couldn't open socket for listening."));
1743 /* Start up the stub on the remote device. */
1744 if (!CeCreateProcess (towide (stub_file_name, NULL),
1745 towide (args, NULL),
1747 NULL, NULL, NULL, &pi))
1748 error (_("Unable to start remote stub '%s'. Windows CE error %d."),
1749 stub_file_name, CeGetLastError ());
1751 /* Wait for a connection */
1753 if ((s = accept (s0, NULL, NULL)) < 0)
1754 error (_("couldn't set up server for connection."));
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(). */
1765 child_create_inferior (char *exec_file, char *args, char **env,
1768 PROCESS_INFORMATION pi;
1769 struct target_waitstatus dummy;
1771 DWORD flags, event_code;
1772 char *exec_and_args;
1775 error (_("No executable specified, use `target exec'."));
1777 flags = DEBUG_PROCESS;
1779 wince_initialize (); /* Make sure we've got a connection. */
1781 exec_file = upload_to_device (exec_file, exec_file);
1783 while (*args == ' ')
1786 /* Allocate space for "command<sp>args" */
1789 exec_and_args = alloca (strlen (exec_file) + 1);
1790 strcpy (exec_and_args, exec_file);
1794 exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
1795 sprintf (exec_and_args, "%s %s", exec_file, args);
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 ());
1804 exception_count = 0;
1807 current_process_handle = pi.hProcess;
1808 current_event.dwProcessId = pi.dwProcessId;
1809 memset (¤t_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 ();
1820 /* Run until process and threads are loaded */
1821 while (!get_child_debug_event (PIDGET (inferior_ptid), &dummy,
1822 CREATE_PROCESS_DEBUG_EVENT, &ret))
1826 /* Chile has gone bye-bye. */
1828 child_mourn_inferior (void)
1830 (void) child_continue (DBG_CONTINUE, -1);
1831 unpush_target (&deprecated_child_ops);
1834 connection_initialized = 0;
1835 generic_mourn_inferior ();
1838 /* Move memory from child to/from gdb. */
1840 child_xfer_memory (CORE_ADDR memaddr, gdb_byte *our,
1842 struct mem_attrib *attrib,
1843 struct target_ops *target)
1849 res = remote_write_bytes (memaddr, our, len);
1851 res = remote_read_bytes (memaddr, our, len);
1856 /* Terminate the process and wait for child to tell us it has
1859 child_kill_inferior (void)
1861 CHECK (terminate_process (current_process_handle));
1865 if (!child_continue (DBG_CONTINUE, -1))
1867 if (!wait_for_debug_event (¤t_event, INFINITE))
1869 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1873 CHECK (close_handle (current_process_handle));
1874 close_handle (current_thread->h);
1875 target_mourn_inferior (); /* or just child_mourn_inferior? */
1878 /* Resume the child after an exception. */
1880 child_resume (ptid_t ptid, int step, enum target_signal sig)
1883 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1884 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1885 int pid = PIDGET (ptid);
1887 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1890 /* Get context for currently selected thread */
1891 th = thread_rec (current_event.dwThreadId, FALSE);
1893 if (th->context.ContextFlags)
1895 CHECK (set_thread_context (th->h, &th->context));
1896 th->context.ContextFlags = 0;
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",
1907 child_continue (continue_status, pid);
1911 child_prepare_to_store (void)
1913 /* Do nothing, since we can store individual regs */
1917 child_can_run (void)
1925 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1926 PIDGET (inferior_ptid)));
1929 /* Explicitly upload file to remotedir */
1932 child_load (char *file, int from_tty)
1934 upload_to_device (file, file);
1938 init_child_ops (void)
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;
1977 /* Handle 'set remoteupload' parameter. */
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);
1986 set_upload_type (char *ignore, int from_tty)
1991 if (!remote_upload || !remote_upload[0])
1993 replace_upload (UPLOAD_NEWER);
1995 printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1999 len = strlen (remote_upload);
2001 i < (sizeof (upload_options) / sizeof (upload_options[0]));
2003 if (len >= upload_options[i].abbrev &&
2004 strncasecmp (remote_upload, upload_options[i].name, len) == 0)
2010 bad_option = remote_upload;
2011 replace_upload (UPLOAD_NEWER);
2012 error (_("Unknown upload type: %s."), bad_option);
2016 _initialize_wince (void)
2018 struct cmd_list_element *set;
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: */
2027 &setlist, &showlist);
2028 remote_directory = xstrdup (remote_directory);
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);
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,
2043 NULL, /* FIXME: i18n: */
2044 &setlist, &showlist);
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,
2053 NULL, /* FIXME: i18n: */
2054 &setlist, &showlist);
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,
2060 NULL, /* FIXME: i18n: */
2061 &setlist, &showlist);
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,
2067 NULL, /* FIXME: i18n: */
2068 &setlist, &showlist);
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,
2075 NULL, /* FIXME: i18n: */
2076 &setlist, &showlist);
2078 add_target (&deprecated_child_ops);
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. */
2085 win32_child_thread_alive (ptid_t ptid)
2087 int pid = PIDGET (ptid);
2088 return thread_alive (thread_rec (pid, FALSE)->h);
2091 /* Convert pid to printable format. */
2093 cygwin_pid_to_str (int pid)
2095 static char buf[80];
2096 if (pid == current_event.dwProcessId)
2097 sprintf (buf, "process %d", pid);
2099 sprintf (buf, "thread %d.0x%x",
2100 (unsigned) current_event.dwProcessId, pid);