1 /* Target-vector operations for controlling Windows CE child processes, for GDB.
2 Copyright 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions, A Red Hat Company.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
25 /* We assume we're being built with and will be used for cygwin. */
29 #define SH4 /* Just to get all of the CONTEXT defines. */
33 #include "frame.h" /* required by inferior.h */
39 #include <sys/types.h>
46 #include <cygwin/in.h>
47 #include <cygwin/socket.h>
52 #include "gdb_string.h"
53 #include "gdbthread.h"
55 #include <sys/param.h>
56 #include "wince-stub.h"
60 /* The ui's event loop. */
61 extern int (*ui_loop_hook) PARAMS ((int signo));
63 /* If we're not using the old Cygwin header file set, define the
64 following which never should have been in the generic Win32 API
65 headers in the first place since they were our own invention... */
66 #ifndef _GNU_H_WINDOWS_H
67 #define FLAG_TRACE_BIT 0x100
68 #ifdef CONTEXT_FLOATING_POINT
69 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
71 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
76 #define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
78 #define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
80 /* The string sent by cygwin when it processes a signal.
81 FIXME: This should be in a cygwin include file. */
82 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
84 #define CHECK(x) check (x, __FILE__,__LINE__)
85 #define DEBUG_EXEC(x) if (debug_exec) printf x
86 #define DEBUG_EVENTS(x) if (debug_events) printf x
87 #define DEBUG_MEM(x) if (debug_memory) printf x
88 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
90 static int connection_initialized = 0; /* True if we've initialized a RAPI session. */
92 static DCACHE *remote_dcache;
94 /* The directory where the stub and executable files are uploaded. */
95 static const char *remote_directory = "\\gdb";
97 /* The types automatic upload available. */
104 upload_when = UPLOAD_NEWER;
106 /* Valid options for 'set remoteupload'. Note that options
107 must track upload_when enum. */
128 static char *remote_upload = NULL; /* Set by set remoteupload */
129 static int remote_add_host = 0;
131 /* Forward declaration */
132 extern struct target_ops child_ops;
134 static int win32_child_thread_alive (int);
135 void child_kill_inferior (void);
137 static int last_sig = 0; /* Set if a signal was received from the
140 /* Thread information structure used to track information that is
141 not available in gdb's thread structure. */
142 typedef struct thread_info_struct
144 struct thread_info_struct *next;
149 int stepped; /* True if stepped. */
151 unsigned long step_prev;
156 static thread_info thread_head =
158 static thread_info * thread_rec (DWORD id, int get_context);
160 /* The process and thread handles for the above context. */
162 static DEBUG_EVENT current_event; /* The current debug event from
164 static HANDLE current_process_handle; /* Currently executing process */
165 static thread_info *current_thread; /* Info on currently selected thread */
166 static thread_info *this_thread; /* Info on thread returned by 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 then
412 the gdb server should send a DWORD.
415 /* Note: In the functions below, the `huh' parameter is a string passed from the
416 function containing a descriptive string concerning the current operation.
417 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 attempt
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 memory
506 putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
508 putlen (huh, what, len);
509 if (((short) len > 0) && sockwrite (huh, mem, len) != len)
510 stub_error ("error writing %s to host.", huh);
513 /* Output the result of an operation to the host. If res != 0, sends a block of
514 memory starting at mem of len bytes. If res == 0, sends -GetLastError () and
515 avoids sending the mem. */
517 getdword (LPCSTR huh, gdb_wince_id what_this)
522 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
523 stub_error ("error getting record type from host - %s.", huh);
524 while (what_this != what);
526 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
527 stub_error ("error getting %s from host.", huh);
532 /* Get a an ID (possibly) and a WORD from the host gdb.
533 Don't bother with the id if the main loop has already
536 getword (LPCSTR huh, gdb_wince_id what_this)
541 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
542 stub_error ("error getting record type from host - %s.", huh);
543 while (what_this != what);
545 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
546 stub_error ("error getting %s from host.", huh);
551 /* Handy defines for getting/putting various types of values. */
552 #define gethandle(huh, what) (HANDLE) getdword ((huh), (what))
553 #define getpvoid(huh, what) (LPVOID) getdword ((huh), (what))
554 #define getlen(huh, what) (gdb_wince_len) getword ((huh), (what))
555 #define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h))
556 #define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p))
558 /* Retrieve the result of an operation from the stub. If nbytes < 0) then nbytes
559 is actually an error and nothing else follows. Use SetLastError to remember this.
560 if nbytes > 0, retrieve a block of *nbytes into buf.
563 getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
569 *nbytes = getlen (huh, what);
571 if ((short) *nbytes < 0)
573 SetLastError (-(short) *nbytes);
577 if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
578 stub_error ("couldn't read information from wince stub - %s", huh);
583 /* Convert "narrow" string to "wide". Manipulates a buffer ring of 8
584 buffers which hold the translated string. This is an arbitrary limit
585 but it is approximately double the current needs of this module.
588 towide (const char *s, gdb_wince_len * out_len)
591 static LPWSTR outs[8] =
592 {NULL /*, NULL, etc. */ };
598 /* First determine the length required to hold the converted string. */
599 *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
601 return NULL; /* The conversion failed */
603 if (++n >= (sizeof (outs) / sizeof (outs[0])))
606 /* Allocate space for the converted string, reusing any previously allocated
607 space, if applicable. Note that if outs[n] is NULL, realloc will act as
608 a malloc (under cygwin, at least).
610 outs[n] = (LPWSTR) realloc (outs[n], *out_len);
611 memset (outs[n], 0, *out_len);
612 (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len);
616 /******************** Emulation routines start here. ********************
618 The functions below are modelled after their Win32 counterparts. They are named
619 similarly to Win32 and take exactly the same arguments except where otherwise noted.
620 They communicate with the stub on the hand-held device by sending their arguments
621 over the socket and waiting for results from the socket.
623 There is one universal change. In cases where a length is expected to be returned
624 in a DWORD, we use a gdb_wince_len type instead. Currently this is an unsigned short
625 which is smaller than the standard Win32 DWORD. This is done to minimize unnecessary
626 traffic since the connection to Windows CE can be slow. To change this, modify the
627 typedef in wince-stub.h and change the putlen/getlen macros in this file and in
632 create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
637 buf = towide (exec_file, &len);
638 putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len);
639 buf = towide (args, &len);
640 putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len);
641 putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags);
642 return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL);
645 /* Emulate TerminateProcess. Don't bother with the second argument since CE
649 terminate_process (HANDLE h)
651 gdb_wince_result res;
654 puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
655 return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
659 wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
663 putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
664 return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
668 get_thread_context (HANDLE h, CONTEXT * c)
672 puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
673 putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
674 return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
678 set_thread_context (HANDLE h, CONTEXT * c)
680 gdb_wince_result res;
683 puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
684 putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c));
685 return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL);
689 read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
693 puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
694 putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
695 putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
697 return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
701 write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
705 puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
706 putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
707 putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
709 return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
713 remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
715 gdb_wince_len nbytes;
716 if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
717 (LPVOID) myaddr, len, &nbytes))
723 remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
725 gdb_wince_len nbytes;
726 if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
727 (LPCVOID) myaddr, len, &nbytes))
732 /* This is not a standard Win32 function. It instructs the stub to return TRUE
733 if the thread referenced by HANDLE h is alive.
736 thread_alive (HANDLE h)
738 gdb_wince_result res;
741 puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
742 return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
746 suspend_thread (HANDLE h)
750 puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
751 return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
755 resume_thread (HANDLE h)
759 puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
760 return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
764 continue_debug_event (DWORD pid, DWORD tid, DWORD status)
766 gdb_wince_result res;
769 putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid);
770 putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid);
771 putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status);
772 return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL);
776 close_handle (HANDLE h)
778 gdb_wince_result res;
781 puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
782 return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
785 /* This is not a standard Win32 interface. This function tells the stub
793 (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
797 /******************** End of emulation routines. ********************/
798 /******************** End of stub interface ********************/
800 #define check_for_step(a, x) (x)
804 undoSStep (thread_info * th)
808 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
814 wince_software_single_step (unsigned int ignore, int insert_breakpoints_p)
817 thread_info *th = current_thread; /* Info on currently selected thread */
818 CORE_ADDR mips_next_pc (CORE_ADDR pc);
820 if (!insert_breakpoints_p)
827 pc = read_register (PC_REGNUM);
828 th->step_pc = mips_next_pc (pc);
830 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
834 /* Hitachi SH architecture instruction encoding masks */
836 #define COND_BR_MASK 0xff00
837 #define UCOND_DBR_MASK 0xe000
838 #define UCOND_RBR_MASK 0xf0df
839 #define TRAPA_MASK 0xff00
841 #define COND_DISP 0x00ff
842 #define UCOND_DISP 0x0fff
843 #define UCOND_REG 0x0f00
845 /* Hitachi SH instruction opcodes */
847 #define BF_INSTR 0x8b00
848 #define BT_INSTR 0x8900
849 #define BRA_INSTR 0xa000
850 #define BSR_INSTR 0xb000
851 #define JMP_INSTR 0x402b
852 #define JSR_INSTR 0x400b
853 #define RTS_INSTR 0x000b
854 #define RTE_INSTR 0x002b
855 #define TRAPA_INSTR 0xc300
856 #define SSTEP_INSTR 0xc3ff
859 #define T_BIT_MASK 0x0001
862 sh_get_next_pc (CONTEXT *c)
867 unsigned short opcode;
869 instrMem = (short *) c->Fir;
871 opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));
873 if ((opcode & COND_BR_MASK) == BT_INSTR)
875 if (c->Psr & T_BIT_MASK)
877 displacement = (opcode & COND_DISP) << 1;
878 if (displacement & 0x80)
879 displacement |= 0xffffff00;
881 * Remember PC points to second instr.
882 * after PC of branch ... so add 4
884 instrMem = (short *) (c->Fir + displacement + 4);
889 else if ((opcode & COND_BR_MASK) == BF_INSTR)
891 if (c->Psr & T_BIT_MASK)
895 displacement = (opcode & COND_DISP) << 1;
896 if (displacement & 0x80)
897 displacement |= 0xffffff00;
899 * Remember PC points to second instr.
900 * after PC of branch ... so add 4
902 instrMem = (short *) (c->Fir + displacement + 4);
905 else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
907 displacement = (opcode & UCOND_DISP) << 1;
908 if (displacement & 0x0800)
909 displacement |= 0xfffff000;
912 * Remember PC points to second instr.
913 * after PC of branch ... so add 4
915 instrMem = (short *) (c->Fir + displacement + 4);
917 else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
919 reg = (char) ((opcode & UCOND_REG) >> 8);
921 instrMem = (short *) *regptr (c, reg);
923 else if (opcode == RTS_INSTR)
924 instrMem = (short *) c->PR;
925 else if (opcode == RTE_INSTR)
926 instrMem = (short *) *regptr (c, 15);
927 else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
928 instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
932 return (CORE_ADDR) instrMem;
934 /* Single step (in a painstaking fashion) by inspecting the current
935 instruction and setting a breakpoint on the "next" instruction
936 which would be executed. This code hails from sh-stub.c.
939 undoSStep (thread_info * th)
943 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
949 /* Single step (in a painstaking fashion) by inspecting the current
950 instruction and setting a breakpoint on the "next" instruction
951 which would be executed. This code hails from sh-stub.c.
954 wince_software_single_step (unsigned int ignore, int insert_breakpoints_p)
956 thread_info *th = current_thread; /* Info on currently selected thread */
958 if (!insert_breakpoints_p)
965 th->step_pc = sh_get_next_pc (&th->context);
967 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
971 #undef check_for_step
973 static enum target_signal
974 check_for_step (DEBUG_EVENT *ev, enum target_signal x)
976 thread_info *th = thread_rec (ev->dwThreadId, 1);
979 th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
980 return TARGET_SIGNAL_TRAP;
985 /* Single step (in a painstaking fashion) by inspecting the current
986 instruction and setting a breakpoint on the "next" instruction
987 which would be executed. This code hails from sh-stub.c.
990 undoSStep (thread_info * th)
994 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
1000 wince_software_single_step (unsigned int ignore, int insert_breakpoints_p)
1003 thread_info *th = current_thread; /* Info on currently selected thread */
1004 CORE_ADDR mips_next_pc (CORE_ADDR pc);
1006 if (!insert_breakpoints_p)
1013 pc = read_register (PC_REGNUM);
1014 th->step_pc = arm_get_next_pc (pc);
1016 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1021 /* Find a thread record given a thread id.
1022 If get_context then also retrieve the context for this
1024 static thread_info *
1025 thread_rec (DWORD id, int get_context)
1029 for (th = &thread_head; (th = th->next) != NULL;)
1032 if (!th->suspend_count && get_context)
1034 if (get_context > 0 && th != this_thread)
1035 th->suspend_count = suspend_thread (th->h) + 1;
1036 else if (get_context < 0)
1037 th->suspend_count = -1;
1039 th->context.ContextFlags = CONTEXT_DEBUGGER;
1040 get_thread_context (th->h, &th->context);
1048 /* Add a thread to the thread list */
1049 static thread_info *
1050 child_add_thread (DWORD id, HANDLE h)
1054 if ((th = thread_rec (id, FALSE)))
1057 th = (thread_info *) xmalloc (sizeof (*th));
1058 memset (th, 0, sizeof (*th));
1061 th->next = thread_head.next;
1062 thread_head.next = th;
1067 /* Clear out any old thread list and reintialize it to a
1070 child_init_thread_list ()
1072 thread_info *th = &thread_head;
1074 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
1075 init_thread_list ();
1076 while (th->next != NULL)
1078 thread_info *here = th->next;
1079 th->next = here->next;
1080 (void) close_handle (here->h);
1085 /* Delete a thread from the list of threads */
1087 child_delete_thread (DWORD id)
1092 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
1095 for (th = &thread_head;
1096 th->next != NULL && th->next->id != id;
1100 if (th->next != NULL)
1102 thread_info *here = th->next;
1103 th->next = here->next;
1104 close_handle (here->h);
1110 check (BOOL ok, const char *file, int line)
1113 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
1117 do_child_fetch_inferior_registers (int r)
1121 supply_register (r, (char *) regptr (¤t_thread->context, r));
1125 for (r = 0; r < NUM_REGS; r++)
1126 do_child_fetch_inferior_registers (r);
1131 child_fetch_inferior_registers (int r)
1133 current_thread = thread_rec (inferior_pid, TRUE);
1134 do_child_fetch_inferior_registers (r);
1138 do_child_store_inferior_registers (int r)
1141 read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
1144 for (r = 0; r < NUM_REGS; r++)
1145 do_child_store_inferior_registers (r);
1149 /* Store a new register value into the current thread context */
1151 child_store_inferior_registers (int r)
1153 current_thread = thread_rec (inferior_pid, TRUE);
1154 do_child_store_inferior_registers (r);
1157 /* Wait for child to do something. Return pid of child, or -1 in case
1158 of error; store status through argument pointer OURSTATUS. */
1161 handle_load_dll (PTR dummy)
1163 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
1164 char dll_buf[MAX_PATH + 1];
1165 char *p, *bufp, *imgp, *dll_name, *dll_basename;
1168 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1169 if (!event->lpImageName)
1173 for (bufp = dll_buf, imgp = event->lpImageName;
1174 bufp < dll_buf + sizeof (dll_buf);
1175 bufp += 16, imgp += 16)
1177 gdb_wince_len nbytes = 0;
1178 (void) read_process_memory (current_process_handle,
1179 imgp, bufp, 16, &nbytes);
1181 if (!nbytes && bufp == dll_buf)
1182 return 1; /* couldn't read it */
1183 for (p = bufp; p < bufp + nbytes; p++)
1188 if (event->fUnicode)
1199 dll_buf[len] = '\0';
1201 dll_name = alloca (len);
1206 if (!event->fUnicode)
1207 memcpy (dll_name, dll_buf, len);
1209 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len,
1210 dll_name, len, 0, 0);
1212 while ((p = strchr (dll_name, '\\')))
1215 /* FIXME!! It would be nice to define one symbol which pointed to the
1216 front of the dll if we can't find any symbols. */
1218 if (!(dll_basename = strrchr (dll_name, '/')))
1219 dll_basename = dll_name;
1223 /* The symbols in a dll are offset by 0x1000, which is the
1224 the offset from 0 of the first byte in an image - because
1225 of the file header and the section alignment.
1227 FIXME: Is this the real reason that we need the 0x1000 ? */
1229 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
1230 printf_unfiltered ("\n");
1235 /* Handle DEBUG_STRING output from child process. */
1237 handle_output_debug_string (struct target_waitstatus *ourstatus)
1242 gdb_wince_len nbytes_read;
1243 gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;
1248 memset (p, 0, sizeof (p));
1249 if (!read_process_memory (current_process_handle,
1250 current_event.u.DebugString.lpDebugStringData,
1251 &p, nbytes, &nbytes_read)
1255 memset (s, 0, sizeof (s));
1256 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) p, (int) nbytes_read, s,
1257 sizeof (s) - 1, NULL, NULL);
1258 q = strchr (s, '\n');
1271 /* Handle target exceptions. */
1273 handle_exception (struct target_waitstatus *ourstatus)
1276 if (current_event.u.Exception.dwFirstChance)
1280 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1282 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
1284 case EXCEPTION_ACCESS_VIOLATION:
1285 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
1286 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1287 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1289 case STATUS_STACK_OVERFLOW:
1290 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
1291 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1292 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1294 case EXCEPTION_BREAKPOINT:
1295 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
1296 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1297 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1300 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
1301 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1302 ourstatus->value.sig = TARGET_SIGNAL_INT;
1303 /* User typed CTRL-C. Continue with this status */
1304 last_sig = SIGINT; /* FIXME - should check pass state */
1306 case EXCEPTION_SINGLE_STEP:
1307 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
1308 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1309 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1311 case EXCEPTION_ILLEGAL_INSTRUCTION:
1312 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
1313 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1314 ourstatus->value.sig = check_for_step (¤t_event, TARGET_SIGNAL_ILL);
1317 /* This may be a structured exception handling exception. In
1318 that case, we want to let the program try to handle it, and
1319 only break if we see the exception a second time. */
1321 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
1322 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1323 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1324 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1331 /* Resume all artificially suspended threads if we are continuing
1334 child_continue (DWORD continue_status, int id)
1340 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
1341 (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId));
1342 res = continue_debug_event (current_event.dwProcessId,
1343 current_event.dwThreadId,
1346 for (th = &thread_head; (th = th->next) != NULL;)
1347 if (((id == -1) || (id == th->id)) && th->suspend_count)
1349 for (i = 0; i < th->suspend_count; i++)
1350 (void) resume_thread (th->h);
1351 th->suspend_count = 0;
1357 /* Get the next event from the child. Return 1 if the event requires
1358 handling by WFI (or whatever).
1361 get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
1362 DWORD target_event_code, int *retval)
1366 DWORD continue_status, event_code;
1367 thread_info *th = NULL;
1368 static thread_info dummy_thread_info;
1370 if (!(debug_event = wait_for_debug_event (¤t_event, 1000)))
1377 continue_status = DBG_CONTINUE;
1380 event_code = current_event.dwDebugEventCode;
1381 breakout = event_code == target_event_code;
1385 case CREATE_THREAD_DEBUG_EVENT:
1386 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1387 (unsigned) current_event.dwProcessId,
1388 (unsigned) current_event.dwThreadId,
1389 "CREATE_THREAD_DEBUG_EVENT"));
1390 /* Record the existence of this thread */
1391 th = child_add_thread (current_event.dwThreadId,
1392 current_event.u.CreateThread.hThread);
1394 printf_unfiltered ("[New %s]\n",
1395 target_pid_to_str (current_event.dwThreadId));
1398 case EXIT_THREAD_DEBUG_EVENT:
1399 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1400 (unsigned) current_event.dwProcessId,
1401 (unsigned) current_event.dwThreadId,
1402 "EXIT_THREAD_DEBUG_EVENT"));
1403 child_delete_thread (current_event.dwThreadId);
1404 th = &dummy_thread_info;
1407 case CREATE_PROCESS_DEBUG_EVENT:
1408 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1409 (unsigned) current_event.dwProcessId,
1410 (unsigned) current_event.dwThreadId,
1411 "CREATE_PROCESS_DEBUG_EVENT"));
1412 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1414 main_thread_id = inferior_pid = current_event.dwThreadId;
1415 /* Add the main thread */
1416 th = child_add_thread (inferior_pid,
1417 current_event.u.CreateProcessInfo.hThread);
1420 case EXIT_PROCESS_DEBUG_EVENT:
1421 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1422 (unsigned) current_event.dwProcessId,
1423 (unsigned) current_event.dwThreadId,
1424 "EXIT_PROCESS_DEBUG_EVENT"));
1425 ourstatus->kind = TARGET_WAITKIND_EXITED;
1426 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1427 close_handle (current_process_handle);
1428 *retval = current_event.dwProcessId;
1432 case LOAD_DLL_DEBUG_EVENT:
1433 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1434 (unsigned) current_event.dwProcessId,
1435 (unsigned) current_event.dwThreadId,
1436 "LOAD_DLL_DEBUG_EVENT"));
1437 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1438 registers_changed (); /* mark all regs invalid */
1441 case UNLOAD_DLL_DEBUG_EVENT:
1442 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1443 (unsigned) current_event.dwProcessId,
1444 (unsigned) current_event.dwThreadId,
1445 "UNLOAD_DLL_DEBUG_EVENT"));
1446 break; /* FIXME: don't know what to do here */
1448 case EXCEPTION_DEBUG_EVENT:
1449 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1450 (unsigned) current_event.dwProcessId,
1451 (unsigned) current_event.dwThreadId,
1452 "EXCEPTION_DEBUG_EVENT"));
1453 if (handle_exception (ourstatus))
1454 *retval = current_event.dwThreadId;
1457 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1462 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1463 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1464 (unsigned) current_event.dwProcessId,
1465 (unsigned) current_event.dwThreadId,
1466 "OUTPUT_DEBUG_STRING_EVENT"));
1467 handle_output_debug_string ( ourstatus);
1470 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
1471 current_event.dwProcessId,
1472 current_event.dwThreadId);
1473 printf_unfiltered (" unknown event code %d\n",
1474 current_event.dwDebugEventCode);
1479 this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1481 CHECK (child_continue (continue_status, -1));
1487 /* Wait for interesting events to occur in the target process. */
1489 child_wait (int pid, struct target_waitstatus *ourstatus)
1494 /* We loop when we get a non-standard exception rather than return
1495 with a SPURIOUS because resume can try and step or modify things,
1496 which needs a current_thread->h. But some of these exceptions mark
1497 the birth or death of threads, which mean that the current thread
1498 isn't necessarily what you think it is. */
1501 if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
1507 if (ui_loop_hook != NULL)
1508 detach = ui_loop_hook (0);
1511 child_kill_inferior ();
1515 /* Print status information about what we're accessing. */
1518 child_files_info (ignore)
1519 struct target_ops *ignore;
1521 printf_unfiltered ("\tUsing the running image of child %s.\n",
1522 target_pid_to_str (inferior_pid));
1527 child_open (arg, from_tty)
1531 error ("Use the \"run\" command to start a child process.");
1534 #define FACTOR (0x19db1ded53ea710LL)
1535 #define NSPERSEC 10000000
1537 /* Convert a Win32 time to "UNIX" format. */
1539 to_time_t (FILETIME * ptr)
1541 /* A file time is the number of 100ns since jan 1 1601
1542 stuffed into two long words.
1543 A time_t is the number of seconds since jan 1 1970. */
1546 long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime);
1547 x -= FACTOR; /* number of 100ns between 1601 and 1970 */
1548 rem = x % ((long long) NSPERSEC);
1549 rem += (NSPERSEC / 2);
1550 x /= (long long) NSPERSEC; /* number of 100ns in a second */
1551 x += (long long) (rem / NSPERSEC);
1555 /* Upload a file to the remote device depending on the user's
1556 'set remoteupload' specification. */
1558 upload_to_device (const char *to, const char *from)
1561 const char *dir = remote_directory ?: "\\gdb";
1563 static char *remotefile = NULL;
1567 const char *in_to = to;
1568 FILETIME crtime, actime, wrtime;
1573 /* Look for a path separator and only use trailing part. */
1574 while ((p = strpbrk (to, "/\\")) != NULL)
1578 error ("no filename found to upload - %s.", in_to);
1580 len = strlen (dir) + strlen (to) + 2;
1581 remotefile = (char *) realloc (remotefile, len);
1582 strcpy (remotefile, dir);
1583 strcat (remotefile, "\\");
1584 strcat (remotefile, to);
1586 if (upload_when == UPLOAD_NEVER)
1587 return remotefile; /* Don't bother uploading. */
1589 /* Open the source. */
1590 if ((fd = openp (getenv ("PATH"), TRUE, (char *) from, O_RDONLY, 0, NULL)) < 0)
1591 error ("couldn't open %s", from);
1593 /* Get the time for later comparison. */
1594 if (fstat (fd, &st))
1595 st.st_mtime = (time_t) - 1;
1597 /* Always attempt to create the directory on the remote system. */
1598 wstr = towide (dir, NULL);
1599 (void) CeCreateDirectory (wstr, NULL);
1601 /* Attempt to open the remote file, creating it if it doesn't exist. */
1602 wstr = towide (remotefile, NULL);
1603 h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1604 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1606 /* Some kind of problem? */
1607 err = CeGetLastError ();
1608 if (h == NULL || h == INVALID_HANDLE_VALUE)
1609 error ("error opening file \"%s\". Windows error %d.",
1612 CeGetFileTime (h, &crtime, &actime, &wrtime);
1613 utime = to_time_t (&wrtime);
1615 if (utime < st.st_mtime)
1618 strcpy (buf, ctime(&utime));
1619 printf ("%s < %s\n", buf, ctime(&st.st_mtime));
1622 /* See if we need to upload the file. */
1623 if (upload_when == UPLOAD_ALWAYS ||
1624 err != ERROR_ALREADY_EXISTS ||
1625 !CeGetFileTime (h, &crtime, &actime, &wrtime) ||
1626 to_time_t (&wrtime) < st.st_mtime)
1632 /* Upload the file. */
1633 while ((n = read (fd, buf, sizeof (buf))) > 0)
1634 if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL))
1635 error ("error writing to remote device - %d.",
1640 if (!CeCloseHandle (h))
1641 error ("error closing remote file - %d.", CeGetLastError ());
1646 /* Initialize the connection to the remote device. */
1653 struct sockaddr_in sin;
1654 char *stub_file_name;
1656 PROCESS_INFORMATION pi;
1658 if (!connection_initialized)
1659 switch (CeRapiInit ())
1662 connection_initialized = 1;
1666 error ("Can't initialize connection to remote device.\n");
1670 /* Upload the stub to the handheld device. */
1671 stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB);
1672 strcpy (args, stub_file_name);
1674 if (remote_add_host)
1677 hostname = strchr (args, '\0');
1678 if (gethostname (hostname, sizeof (args) - strlen (args)))
1679 error ("couldn't get hostname of this system.");
1683 if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1684 stub_error ("Couldn't connect to host system.");
1686 /* Allow rapid reuse of the port. */
1688 (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1691 /* Set up the information for connecting to the host gdb process. */
1692 memset (&sin, 0, sizeof (sin));
1693 sin.sin_family = AF_INET;
1694 sin.sin_port = htons (7000); /* FIXME: This should be configurable */
1696 if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
1697 error ("couldn't bind socket");
1700 error ("Couldn't open socket for listening.\n");
1702 /* Start up the stub on the remote device. */
1703 if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL),
1704 NULL, NULL, 0, 0, NULL, NULL, NULL, &pi))
1705 error ("Unable to start remote stub '%s'. Windows CE error %d.",
1706 stub_file_name, CeGetLastError ());
1708 /* Wait for a connection */
1710 if ((s = accept (s0, NULL, NULL)) < 0)
1711 error ("couldn't set up server for connection.");
1716 /* Start an inferior win32 child process and sets inferior_pid to its pid.
1717 EXEC_FILE is the file to run.
1718 ALLARGS is a string containing the arguments to the program.
1719 ENV is the environment vector to pass. Errors reported with error(). */
1721 child_create_inferior (char *exec_file, char *args, char **env)
1723 PROCESS_INFORMATION pi;
1724 struct target_waitstatus dummy;
1726 DWORD flags, event_code;
1727 char *exec_and_args;
1730 error ("No executable specified, use `target exec'.\n");
1732 flags = DEBUG_PROCESS;
1734 wince_initialize (); /* Make sure we've got a connection. */
1736 remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes);
1738 dcache_flush (remote_dcache);
1740 exec_file = upload_to_device (exec_file, exec_file);
1742 while (*args == ' ')
1745 /* Allocate space for "command<sp>args" */
1748 exec_and_args = alloca (strlen (exec_file) + 1);
1749 strcpy (exec_and_args, exec_file);
1753 exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
1754 sprintf (exec_and_args, "%s %s", exec_file, args);
1757 memset (&pi, 0, sizeof (pi));
1758 /* Execute the process */
1759 if (!create_process (exec_file, exec_and_args, flags, &pi))
1760 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1762 exception_count = 0;
1765 current_process_handle = pi.hProcess;
1766 current_event.dwProcessId = pi.dwProcessId;
1767 memset (¤t_event, 0, sizeof (current_event));
1768 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1769 push_target (&child_ops);
1770 child_init_thread_list ();
1771 child_add_thread (pi.dwThreadId, pi.hThread);
1772 init_wait_for_inferior ();
1773 clear_proceed_status ();
1774 target_terminal_init ();
1775 target_terminal_inferior ();
1777 /* Run until process and threads are loaded */
1778 while (!get_child_debug_event (inferior_pid, &dummy,
1779 CREATE_PROCESS_DEBUG_EVENT, &ret))
1782 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
1785 /* Chile has gone bye-bye. */
1787 child_mourn_inferior ()
1789 (void) child_continue (DBG_CONTINUE, -1);
1790 unpush_target (&child_ops);
1793 connection_initialized = 0;
1794 generic_mourn_inferior ();
1797 /* Move memory from child to/from gdb. */
1799 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1800 int write, struct target_ops *target)
1804 return dcache_xfer_memory (remote_dcache, memaddr, our, len, write);
1807 /* Terminate the process and wait for child to tell us it has completed. */
1809 child_kill_inferior (void)
1811 CHECK (terminate_process (current_process_handle));
1815 if (!child_continue (DBG_CONTINUE, -1))
1817 if (!wait_for_debug_event (¤t_event, INFINITE))
1819 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1823 CHECK (close_handle (current_process_handle));
1824 close_handle (current_thread->h);
1825 target_mourn_inferior (); /* or just child_mourn_inferior? */
1828 /* Resume the child after an exception. */
1830 child_resume (int pid, int step, enum target_signal sig)
1833 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1834 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1836 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1839 /* Get context for currently selected thread */
1840 th = thread_rec (current_event.dwThreadId, FALSE);
1842 if (th->context.ContextFlags)
1844 CHECK (set_thread_context (th->h, &th->context));
1845 th->context.ContextFlags = 0;
1848 dcache_flush (remote_dcache);
1850 /* Allow continuing with the same signal that interrupted us.
1851 Otherwise complain. */
1852 if (sig && sig != last_sig)
1853 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
1856 child_continue (continue_status, pid);
1860 child_prepare_to_store ()
1862 /* Do nothing, since we can store individual regs */
1874 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1877 /* Explicitly upload file to remotedir */
1880 child_load (char *file, int from_tty)
1882 upload_to_device (file, file);
1885 struct target_ops child_ops;
1888 init_child_ops (void)
1890 memset (&child_ops, 0, sizeof (child_ops));
1891 child_ops.to_shortname = (char *) "child";
1892 child_ops.to_longname = (char *) "Windows CE process";
1893 child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command).";
1894 child_ops.to_open = child_open;
1895 child_ops.to_close = child_close;
1896 child_ops.to_resume = child_resume;
1897 child_ops.to_wait = child_wait;
1898 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1899 child_ops.to_store_registers = child_store_inferior_registers;
1900 child_ops.to_prepare_to_store = child_prepare_to_store;
1901 child_ops.to_xfer_memory = child_xfer_memory;
1902 child_ops.to_files_info = child_files_info;
1903 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1904 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1905 child_ops.to_terminal_init = terminal_init_inferior;
1906 child_ops.to_terminal_inferior = terminal_inferior;
1907 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1908 child_ops.to_terminal_ours = terminal_ours;
1909 child_ops.to_terminal_info = child_terminal_info;
1910 child_ops.to_kill = child_kill_inferior;
1911 child_ops.to_load = child_load;
1912 child_ops.to_create_inferior = child_create_inferior;
1913 child_ops.to_mourn_inferior = child_mourn_inferior;
1914 child_ops.to_can_run = child_can_run;
1915 child_ops.to_thread_alive = win32_child_thread_alive;
1916 child_ops.to_stratum = process_stratum;
1917 child_ops.to_has_all_memory = 1;
1918 child_ops.to_has_memory = 1;
1919 child_ops.to_has_stack = 1;
1920 child_ops.to_has_registers = 1;
1921 child_ops.to_has_execution = 1;
1922 child_ops.to_sections = 0;
1923 child_ops.to_sections_end = 0;
1924 child_ops.to_magic = OPS_MAGIC;
1928 /* Handle 'set remoteupload' parameter. */
1930 #define replace_upload(what) \
1931 upload_when = what; \
1932 remote_upload = realloc (remote_upload, strlen (upload_options[upload_when].name) + 1); \
1933 strcpy (remote_upload, upload_options[upload_when].name);
1936 set_upload_type (char *ignore, int from_tty)
1941 if (!remote_upload || !remote_upload[0])
1943 replace_upload (UPLOAD_NEWER);
1945 printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1949 len = strlen (remote_upload);
1950 for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++)
1951 if (len >= upload_options[i].abbrev &&
1952 strncasecmp (remote_upload, upload_options[i].name, len) == 0)
1958 bad_option = remote_upload;
1959 replace_upload (UPLOAD_NEWER);
1960 error ("Unknown upload type: %s.", bad_option);
1964 _initialize_inftarg ()
1966 struct cmd_list_element *set;
1970 (add_set_cmd ((char *) "remotedirectory", no_class,
1971 var_string_noescape, (char *) &remote_directory,
1972 (char *) "Set directory for remote upload.\n",
1975 remote_directory = xstrdup (remote_directory);
1977 set = add_set_cmd ((char *) "remoteupload", no_class,
1978 var_string_noescape, (char *) &remote_upload,
1979 (char *) "Set how to upload executables to remote device.\n",
1981 add_show_from_set (set, &showlist);
1982 set->function.cfunc = set_upload_type;
1983 set_upload_type (NULL, 0);
1984 set_dcache_state (1);
1987 (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
1988 (char *) &debug_exec,
1989 (char *) "Set whether to display execution in child process.",
1994 (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
1995 (char *) &remote_add_host,
1996 (char *) "Set whether to add this host to remote stub arguments for\n
1997 debugging over a network.", &setlist),
2001 (add_set_cmd ((char *) "debugevents", class_support, var_boolean,
2002 (char *) &debug_events,
2003 (char *) "Set whether to display kernel events in child process.",
2008 (add_set_cmd ((char *) "debugmemory", class_support, var_boolean,
2009 (char *) &debug_memory,
2010 (char *) "Set whether to display memory accesses in child process.",
2015 (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean,
2016 (char *) &debug_exceptions,
2017 (char *) "Set whether to display kernel exceptions in child process.",
2021 add_target (&child_ops);
2024 /* Determine if the thread referenced by "pid" is alive
2025 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2026 it means that the pid has died. Otherwise it is assumed to be alive. */
2028 win32_child_thread_alive (int pid)
2030 return thread_alive (thread_rec (pid, FALSE)->h);
2033 /* Convert pid to printable format. */
2035 cygwin_pid_to_str (int pid)
2037 static char buf[80];
2038 if (pid == current_event.dwProcessId)
2039 sprintf (buf, "process %d", pid);
2041 sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);