1 /* Target-vector operations for controlling Windows CE child processes, for GDB.
3 Copyright 1999, 2000, 2001, 2004 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., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, 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 */
40 #include <sys/types.h>
47 #include <cygwin/in.h>
48 #include <cygwin/socket.h>
53 #include "gdb_string.h"
54 #include "gdbthread.h"
56 #include <sys/param.h>
57 #include "wince-stub.h"
61 #include "mips-tdep.h"
64 /* If we're not using the old Cygwin header file set, define the
65 following which never should have been in the generic Win32 API
66 headers in the first place since they were our own invention... */
67 #ifndef _GNU_H_WINDOWS_H
68 #define FLAG_TRACE_BIT 0x100
69 #ifdef CONTEXT_FLOATING_POINT
70 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
72 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
77 #define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
79 #define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
81 /* The string sent by cygwin when it processes a signal.
82 FIXME: This should be in a cygwin include file. */
83 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
85 #define CHECK(x) check (x, __FILE__,__LINE__)
86 #define DEBUG_EXEC(x) if (debug_exec) printf x
87 #define DEBUG_EVENTS(x) if (debug_events) printf x
88 #define DEBUG_MEM(x) if (debug_memory) printf x
89 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
91 static int connection_initialized = 0; /* True if we've initialized a RAPI session. */
93 /* The directory where the stub and executable files are uploaded. */
94 static const char *remote_directory = "\\gdb";
96 /* The types automatic upload available. */
103 upload_when = UPLOAD_NEWER;
105 /* Valid options for 'set remoteupload'. Note that options
106 must track upload_when enum. */
127 static char *remote_upload = NULL; /* Set by set remoteupload */
128 static int remote_add_host = 0;
130 static int win32_child_thread_alive (ptid_t);
131 void child_kill_inferior (void);
133 static int last_sig = 0; /* Set if a signal was received from the
136 /* Thread information structure used to track information that is
137 not available in gdb's thread structure. */
138 typedef struct thread_info_struct
140 struct thread_info_struct *next;
145 int stepped; /* True if stepped. */
147 unsigned long step_prev;
152 static thread_info thread_head =
154 static thread_info * thread_rec (DWORD id, int get_context);
156 /* The process and thread handles for the above context. */
158 static DEBUG_EVENT current_event; /* The current debug event from
160 static HANDLE current_process_handle; /* Currently executing process */
161 static thread_info *current_thread; /* Info on currently selected thread */
162 static thread_info *this_thread; /* Info on thread returned by wait_for_debug_event */
163 static DWORD main_thread_id; /* Thread ID of the main thread */
165 /* Counts of things. */
166 static int exception_count = 0;
167 static int event_count = 0;
170 static int debug_exec = 0; /* show execution */
171 static int debug_events = 0; /* show events from kernel */
172 static int debug_memory = 0; /* show target memory accesses */
173 static int debug_exceptions = 0; /* show target exceptions */
175 /* An array of offset mappings into a Win32 Context structure.
176 This is a one-to-one mapping which is indexed by gdb's register
177 numbers. It retrieves an offset into the context structure where
178 the 4 byte register is located.
179 An offset value of -1 indicates that Win32 does not provide this
180 register in it's CONTEXT structure. regptr will return zero for this
183 This is used by the regptr function. */
184 #define context_offset(x) ((int)&(((PCONTEXT)NULL)->x))
185 static const int mappings[NUM_REGS + 1] =
188 context_offset (Eax),
189 context_offset (Ecx),
190 context_offset (Edx),
191 context_offset (Ebx),
192 context_offset (Esp),
193 context_offset (Ebp),
194 context_offset (Esi),
195 context_offset (Edi),
196 context_offset (Eip),
197 context_offset (EFlags),
198 context_offset (SegCs),
199 context_offset (SegSs),
200 context_offset (SegDs),
201 context_offset (SegEs),
202 context_offset (SegFs),
203 context_offset (SegGs),
204 context_offset (FloatSave.RegisterArea[0 * 10]),
205 context_offset (FloatSave.RegisterArea[1 * 10]),
206 context_offset (FloatSave.RegisterArea[2 * 10]),
207 context_offset (FloatSave.RegisterArea[3 * 10]),
208 context_offset (FloatSave.RegisterArea[4 * 10]),
209 context_offset (FloatSave.RegisterArea[5 * 10]),
210 context_offset (FloatSave.RegisterArea[6 * 10]),
211 context_offset (FloatSave.RegisterArea[7 * 10]),
223 context_offset (R10),
224 context_offset (R11),
225 context_offset (R12),
226 context_offset (R13),
227 context_offset (R14),
228 context_offset (R15),
229 context_offset (Fir),
230 context_offset (PR), /* Procedure Register */
231 context_offset (GBR), /* Global Base Register */
232 context_offset (MACH), /* Accumulate */
233 context_offset (MACL), /* Multiply */
234 context_offset (Psr),
235 context_offset (Fpul),
236 context_offset (Fpscr),
237 context_offset (FRegs[0]),
238 context_offset (FRegs[1]),
239 context_offset (FRegs[2]),
240 context_offset (FRegs[3]),
241 context_offset (FRegs[4]),
242 context_offset (FRegs[5]),
243 context_offset (FRegs[6]),
244 context_offset (FRegs[7]),
245 context_offset (FRegs[8]),
246 context_offset (FRegs[9]),
247 context_offset (FRegs[10]),
248 context_offset (FRegs[11]),
249 context_offset (FRegs[12]),
250 context_offset (FRegs[13]),
251 context_offset (FRegs[14]),
252 context_offset (FRegs[15]),
253 context_offset (xFRegs[0]),
254 context_offset (xFRegs[1]),
255 context_offset (xFRegs[2]),
256 context_offset (xFRegs[3]),
257 context_offset (xFRegs[4]),
258 context_offset (xFRegs[5]),
259 context_offset (xFRegs[6]),
260 context_offset (xFRegs[7]),
261 context_offset (xFRegs[8]),
262 context_offset (xFRegs[9]),
263 context_offset (xFRegs[10]),
264 context_offset (xFRegs[11]),
265 context_offset (xFRegs[12]),
266 context_offset (xFRegs[13]),
267 context_offset (xFRegs[14]),
268 context_offset (xFRegs[15]),
270 context_offset (IntZero),
271 context_offset (IntAt),
272 context_offset (IntV0),
273 context_offset (IntV1),
274 context_offset (IntA0),
275 context_offset (IntA1),
276 context_offset (IntA2),
277 context_offset (IntA3),
278 context_offset (IntT0),
279 context_offset (IntT1),
280 context_offset (IntT2),
281 context_offset (IntT3),
282 context_offset (IntT4),
283 context_offset (IntT5),
284 context_offset (IntT6),
285 context_offset (IntT7),
286 context_offset (IntS0),
287 context_offset (IntS1),
288 context_offset (IntS2),
289 context_offset (IntS3),
290 context_offset (IntS4),
291 context_offset (IntS5),
292 context_offset (IntS6),
293 context_offset (IntS7),
294 context_offset (IntT8),
295 context_offset (IntT9),
296 context_offset (IntK0),
297 context_offset (IntK1),
298 context_offset (IntGp),
299 context_offset (IntSp),
300 context_offset (IntS8),
301 context_offset (IntRa),
302 context_offset (Psr),
303 context_offset (IntLo),
304 context_offset (IntHi),
307 context_offset (Fir),
308 context_offset (FltF0),
309 context_offset (FltF1),
310 context_offset (FltF2),
311 context_offset (FltF3),
312 context_offset (FltF4),
313 context_offset (FltF5),
314 context_offset (FltF6),
315 context_offset (FltF7),
316 context_offset (FltF8),
317 context_offset (FltF9),
318 context_offset (FltF10),
319 context_offset (FltF11),
320 context_offset (FltF12),
321 context_offset (FltF13),
322 context_offset (FltF14),
323 context_offset (FltF15),
324 context_offset (FltF16),
325 context_offset (FltF17),
326 context_offset (FltF18),
327 context_offset (FltF19),
328 context_offset (FltF20),
329 context_offset (FltF21),
330 context_offset (FltF22),
331 context_offset (FltF23),
332 context_offset (FltF24),
333 context_offset (FltF25),
334 context_offset (FltF26),
335 context_offset (FltF27),
336 context_offset (FltF28),
337 context_offset (FltF29),
338 context_offset (FltF30),
339 context_offset (FltF31),
340 context_offset (Fsr),
341 context_offset (Fir),
354 context_offset (R10),
355 context_offset (R11),
356 context_offset (R12),
369 context_offset (Psr),
374 /* Return a pointer into a CONTEXT field indexed by gdb register number.
375 Return a pointer to an address pointing to zero if there is no
376 corresponding CONTEXT field for the given register number.
379 regptr (LPCONTEXT c, int r)
381 static ULONG zero = 0;
386 p = (ULONG *) (((char *) c) + mappings[r]);
390 /******************** Beginning of stub interface ********************/
392 /* Stub interface description:
394 The Windows CE stub implements a crude RPC. The hand-held device
395 connects to gdb using port 7000. gdb and the stub then communicate
398 byte 0: command id (e.g. Create Process)
405 byte 3-n: arbitrary memory.
407 The interface is deterministic, i.e., if the stub expects a DWORD then
408 the gdb server should send a DWORD.
411 /* Note: In the functions below, the `huh' parameter is a string passed from the
412 function containing a descriptive string concerning the current operation.
413 This is used for error reporting.
415 The 'what' parameter is a command id as found in wince-stub.h.
417 Hopefully, the rest of the parameters are self-explanatory.
420 static int s; /* communication socket */
422 /* v-style interface for handling varying argyment list error messages.
423 Displays the error message in a dialog box and exits when user clicks
426 vstub_error (LPCSTR fmt, va_list * args)
429 vsprintf (buf, fmt, args);
434 /* The standard way to display an error message and exit. */
436 stub_error (LPCSTR fmt,...)
439 va_start (args, fmt);
440 vstub_error (fmt, args);
443 /* Standard "oh well" can't communicate error. Someday this might attempt
446 attempt_resync (LPCSTR huh, int s)
448 stub_error ("lost synchronization with target attempting %s", huh);
451 /* Read arbitrary stuff from a socket. */
453 sockread (LPCSTR huh, int s, void *str, size_t n)
457 if (recv (s, str, n, 0) == n)
459 attempt_resync (huh, s);
463 /* Write arbitrary stuff to a socket. */
465 sockwrite (LPCSTR huh, const void *str, size_t n)
469 if (send (s, str, n, 0) == n)
471 attempt_resync (huh, s);
475 /* Output an id/dword to the host */
477 putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
479 if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
480 stub_error ("error writing record id to host for %s", huh);
481 if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
482 stub_error ("error writing %s to host.", huh);
485 /* Output an id/word to the host */
487 putword (LPCSTR huh, gdb_wince_id what, WORD n)
489 if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
490 stub_error ("error writing record id to host for %s", huh);
491 if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
492 stub_error ("error writing %s host.", huh);
495 /* Convenience define for outputting a "gdb_wince_len" type. */
496 #define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
498 /* Put an arbitrary block of memory to the gdb host. This comes in
499 two chunks an id/dword representing the length and the stream of memory
502 putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
504 putlen (huh, what, len);
505 if (((short) len > 0) && sockwrite (huh, mem, len) != len)
506 stub_error ("error writing %s to host.", huh);
509 /* Output the result of an operation to the host. If res != 0, sends a block of
510 memory starting at mem of len bytes. If res == 0, sends -GetLastError () and
511 avoids sending the mem. */
513 getdword (LPCSTR huh, gdb_wince_id what_this)
518 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
519 stub_error ("error getting record type from host - %s.", huh);
520 while (what_this != what);
522 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
523 stub_error ("error getting %s from host.", huh);
528 /* Get a an ID (possibly) and a WORD from the host gdb.
529 Don't bother with the id if the main loop has already
532 getword (LPCSTR huh, gdb_wince_id what_this)
537 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
538 stub_error ("error getting record type from host - %s.", huh);
539 while (what_this != what);
541 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
542 stub_error ("error getting %s from host.", huh);
547 /* Handy defines for getting/putting various types of values. */
548 #define gethandle(huh, what) (HANDLE) getdword ((huh), (what))
549 #define getpvoid(huh, what) (LPVOID) getdword ((huh), (what))
550 #define getlen(huh, what) (gdb_wince_len) getword ((huh), (what))
551 #define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h))
552 #define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p))
554 /* Retrieve the result of an operation from the stub. If nbytes < 0) then nbytes
555 is actually an error and nothing else follows. Use SetLastError to remember this.
556 if nbytes > 0, retrieve a block of *nbytes into buf.
559 getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
565 *nbytes = getlen (huh, what);
567 if ((short) *nbytes < 0)
569 SetLastError (-(short) *nbytes);
573 if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
574 stub_error ("couldn't read information from wince stub - %s", huh);
579 /* Convert "narrow" string to "wide". Manipulates a buffer ring of 8
580 buffers which hold the translated string. This is an arbitrary limit
581 but it is approximately double the current needs of this module.
584 towide (const char *s, gdb_wince_len * out_len)
587 static LPWSTR outs[8] =
588 {NULL /*, NULL, etc. */ };
594 /* First determine the length required to hold the converted string. */
595 *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
597 return NULL; /* The conversion failed */
599 if (++n >= (sizeof (outs) / sizeof (outs[0])))
602 /* Allocate space for the converted string, reusing any previously allocated
603 space, if applicable. Note that if outs[n] is NULL, xrealloc will act as
604 a malloc (under cygwin, at least).
606 outs[n] = (LPWSTR) xrealloc (outs[n], *out_len);
607 memset (outs[n], 0, *out_len);
608 (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len);
612 /******************** Emulation routines start here. ********************
614 The functions below are modelled after their Win32 counterparts. They are named
615 similarly to Win32 and take exactly the same arguments except where otherwise noted.
616 They communicate with the stub on the hand-held device by sending their arguments
617 over the socket and waiting for results from the socket.
619 There is one universal change. In cases where a length is expected to be returned
620 in a DWORD, we use a gdb_wince_len type instead. Currently this is an unsigned short
621 which is smaller than the standard Win32 DWORD. This is done to minimize unnecessary
622 traffic since the connection to Windows CE can be slow. To change this, modify the
623 typedef in wince-stub.h and change the putlen/getlen macros in this file and in
628 create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
633 buf = towide (exec_file, &len);
634 putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len);
635 buf = towide (args, &len);
636 putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len);
637 putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags);
638 return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL);
641 /* Emulate TerminateProcess. Don't bother with the second argument since CE
645 terminate_process (HANDLE h)
647 gdb_wince_result res;
650 puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
651 return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
655 wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
659 putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
660 return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
664 get_thread_context (HANDLE h, CONTEXT * c)
668 puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
669 putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
670 return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
674 set_thread_context (HANDLE h, CONTEXT * c)
676 gdb_wince_result res;
679 puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
680 putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c));
681 return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL);
685 read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
689 puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
690 putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
691 putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
693 return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
697 write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
701 puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
702 putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
703 putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
705 return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
709 remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
711 gdb_wince_len nbytes;
712 if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
713 (LPVOID) myaddr, len, &nbytes))
719 remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
721 gdb_wince_len nbytes;
722 if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
723 (LPCVOID) myaddr, len, &nbytes))
728 /* This is not a standard Win32 function. It instructs the stub to return TRUE
729 if the thread referenced by HANDLE h is alive.
732 thread_alive (HANDLE h)
734 gdb_wince_result res;
737 puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
738 return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
742 suspend_thread (HANDLE h)
746 puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
747 return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
751 resume_thread (HANDLE h)
755 puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
756 return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
760 continue_debug_event (DWORD pid, DWORD tid, DWORD status)
762 gdb_wince_result res;
765 putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid);
766 putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid);
767 putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status);
768 return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL);
772 close_handle (HANDLE h)
774 gdb_wince_result res;
777 puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
778 return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
781 /* This is not a standard Win32 interface. This function tells the stub
789 (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
793 /******************** End of emulation routines. ********************/
794 /******************** End of stub interface ********************/
796 #define check_for_step(a, x) (x)
800 undoSStep (thread_info * th)
804 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
810 wince_software_single_step (enum target_signal ignore,
811 int insert_breakpoints_p)
814 thread_info *th = current_thread; /* Info on currently selected thread */
815 CORE_ADDR mips_next_pc (CORE_ADDR pc);
817 if (!insert_breakpoints_p)
824 pc = read_register (PC_REGNUM);
825 th->step_pc = mips_next_pc (pc);
827 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
831 /* Renesas SH architecture instruction encoding masks */
833 #define COND_BR_MASK 0xff00
834 #define UCOND_DBR_MASK 0xe000
835 #define UCOND_RBR_MASK 0xf0df
836 #define TRAPA_MASK 0xff00
838 #define COND_DISP 0x00ff
839 #define UCOND_DISP 0x0fff
840 #define UCOND_REG 0x0f00
842 /* Renesas SH instruction opcodes */
844 #define BF_INSTR 0x8b00
845 #define BT_INSTR 0x8900
846 #define BRA_INSTR 0xa000
847 #define BSR_INSTR 0xb000
848 #define JMP_INSTR 0x402b
849 #define JSR_INSTR 0x400b
850 #define RTS_INSTR 0x000b
851 #define RTE_INSTR 0x002b
852 #define TRAPA_INSTR 0xc300
853 #define SSTEP_INSTR 0xc3ff
856 #define T_BIT_MASK 0x0001
859 sh_get_next_pc (CONTEXT *c)
864 unsigned short opcode;
866 instrMem = (short *) c->Fir;
868 opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));
870 if ((opcode & COND_BR_MASK) == BT_INSTR)
872 if (c->Psr & T_BIT_MASK)
874 displacement = (opcode & COND_DISP) << 1;
875 if (displacement & 0x80)
876 displacement |= 0xffffff00;
878 * Remember PC points to second instr.
879 * after PC of branch ... so add 4
881 instrMem = (short *) (c->Fir + displacement + 4);
886 else if ((opcode & COND_BR_MASK) == BF_INSTR)
888 if (c->Psr & T_BIT_MASK)
892 displacement = (opcode & COND_DISP) << 1;
893 if (displacement & 0x80)
894 displacement |= 0xffffff00;
896 * Remember PC points to second instr.
897 * after PC of branch ... so add 4
899 instrMem = (short *) (c->Fir + displacement + 4);
902 else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
904 displacement = (opcode & UCOND_DISP) << 1;
905 if (displacement & 0x0800)
906 displacement |= 0xfffff000;
909 * Remember PC points to second instr.
910 * after PC of branch ... so add 4
912 instrMem = (short *) (c->Fir + displacement + 4);
914 else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
916 reg = (char) ((opcode & UCOND_REG) >> 8);
918 instrMem = (short *) *regptr (c, reg);
920 else if (opcode == RTS_INSTR)
921 instrMem = (short *) c->PR;
922 else if (opcode == RTE_INSTR)
923 instrMem = (short *) *regptr (c, 15);
924 else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
925 instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
929 return (CORE_ADDR) instrMem;
931 /* Single step (in a painstaking fashion) by inspecting the current
932 instruction and setting a breakpoint on the "next" instruction
933 which would be executed. This code hails from sh-stub.c.
936 undoSStep (thread_info * th)
940 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
946 /* Single step (in a painstaking fashion) by inspecting the current
947 instruction and setting a breakpoint on the "next" instruction
948 which would be executed. This code hails from sh-stub.c.
951 wince_software_single_step (enum target_signal ignore,
952 int insert_breakpoints_p)
954 thread_info *th = current_thread; /* Info on currently selected thread */
956 if (!insert_breakpoints_p)
963 th->step_pc = sh_get_next_pc (&th->context);
965 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
969 #undef check_for_step
971 static enum target_signal
972 check_for_step (DEBUG_EVENT *ev, enum target_signal x)
974 thread_info *th = thread_rec (ev->dwThreadId, 1);
977 th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
978 return TARGET_SIGNAL_TRAP;
983 /* Single step (in a painstaking fashion) by inspecting the current
984 instruction and setting a breakpoint on the "next" instruction
985 which would be executed. This code hails from sh-stub.c.
988 undoSStep (thread_info * th)
992 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
998 wince_software_single_step (enum target_signal ignore,
999 int insert_breakpoints_p)
1002 thread_info *th = current_thread; /* Info on currently selected thread */
1003 CORE_ADDR mips_next_pc (CORE_ADDR pc);
1005 if (!insert_breakpoints_p)
1012 pc = read_register (PC_REGNUM);
1013 th->step_pc = arm_get_next_pc (pc);
1015 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1020 /* Find a thread record given a thread id.
1021 If get_context then also retrieve the context for this
1023 static thread_info *
1024 thread_rec (DWORD id, int get_context)
1028 for (th = &thread_head; (th = th->next) != NULL;)
1031 if (!th->suspend_count && get_context)
1033 if (get_context > 0 && th != this_thread)
1034 th->suspend_count = suspend_thread (th->h) + 1;
1035 else if (get_context < 0)
1036 th->suspend_count = -1;
1038 th->context.ContextFlags = CONTEXT_DEBUGGER;
1039 get_thread_context (th->h, &th->context);
1047 /* Add a thread to the thread list */
1048 static thread_info *
1049 child_add_thread (DWORD id, HANDLE h)
1053 if ((th = thread_rec (id, FALSE)))
1056 th = (thread_info *) xmalloc (sizeof (*th));
1057 memset (th, 0, sizeof (*th));
1060 th->next = thread_head.next;
1061 thread_head.next = th;
1066 /* Clear out any old thread list and reintialize it to a
1069 child_init_thread_list (void)
1071 thread_info *th = &thread_head;
1073 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
1074 init_thread_list ();
1075 while (th->next != NULL)
1077 thread_info *here = th->next;
1078 th->next = here->next;
1079 (void) close_handle (here->h);
1084 /* Delete a thread from the list of threads */
1086 child_delete_thread (DWORD id)
1091 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
1094 for (th = &thread_head;
1095 th->next != NULL && th->next->id != id;
1099 if (th->next != NULL)
1101 thread_info *here = th->next;
1102 th->next = here->next;
1103 close_handle (here->h);
1109 check (BOOL ok, const char *file, int line)
1112 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
1116 do_child_fetch_inferior_registers (int r)
1120 regcache_raw_supply (current_regcache, r,
1121 (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 (PIDGET (inferior_ptid), TRUE);
1134 do_child_fetch_inferior_registers (r);
1138 do_child_store_inferior_registers (int r)
1141 deprecated_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 (PIDGET (inferior_ptid), 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 (void *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 = current_event.dwThreadId;
1415 inferior_ptid = pid_to_ptid (main_thread_id);
1416 /* Add the main thread */
1417 th = child_add_thread (PIDGET (inferior_ptid),
1418 current_event.u.CreateProcessInfo.hThread);
1421 case EXIT_PROCESS_DEBUG_EVENT:
1422 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1423 (unsigned) current_event.dwProcessId,
1424 (unsigned) current_event.dwThreadId,
1425 "EXIT_PROCESS_DEBUG_EVENT"));
1426 ourstatus->kind = TARGET_WAITKIND_EXITED;
1427 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1428 close_handle (current_process_handle);
1429 *retval = current_event.dwProcessId;
1433 case LOAD_DLL_DEBUG_EVENT:
1434 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1435 (unsigned) current_event.dwProcessId,
1436 (unsigned) current_event.dwThreadId,
1437 "LOAD_DLL_DEBUG_EVENT"));
1438 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1439 registers_changed (); /* mark all regs invalid */
1442 case UNLOAD_DLL_DEBUG_EVENT:
1443 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1444 (unsigned) current_event.dwProcessId,
1445 (unsigned) current_event.dwThreadId,
1446 "UNLOAD_DLL_DEBUG_EVENT"));
1447 break; /* FIXME: don't know what to do here */
1449 case EXCEPTION_DEBUG_EVENT:
1450 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1451 (unsigned) current_event.dwProcessId,
1452 (unsigned) current_event.dwThreadId,
1453 "EXCEPTION_DEBUG_EVENT"));
1454 if (handle_exception (ourstatus))
1455 *retval = current_event.dwThreadId;
1458 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1463 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1464 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1465 (unsigned) current_event.dwProcessId,
1466 (unsigned) current_event.dwThreadId,
1467 "OUTPUT_DEBUG_STRING_EVENT"));
1468 handle_output_debug_string ( ourstatus);
1471 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
1472 current_event.dwProcessId,
1473 current_event.dwThreadId);
1474 printf_unfiltered (" unknown event code %d\n",
1475 current_event.dwDebugEventCode);
1480 this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1482 CHECK (child_continue (continue_status, -1));
1488 /* Wait for interesting events to occur in the target process. */
1490 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1494 int pid = PIDGET (ptid);
1496 /* We loop when we get a non-standard exception rather than return
1497 with a SPURIOUS because resume can try and step or modify things,
1498 which needs a current_thread->h. But some of these exceptions mark
1499 the birth or death of threads, which mean that the current thread
1500 isn't necessarily what you think it is. */
1503 if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
1504 return pid_to_ptid (retval);
1509 if (deprecated_ui_loop_hook != NULL)
1510 detach = deprecated_ui_loop_hook (0);
1513 child_kill_inferior ();
1517 /* Print status information about what we're accessing. */
1520 child_files_info (struct target_ops *ignore)
1522 printf_unfiltered ("\tUsing the running image of child %s.\n",
1523 target_pid_to_str (inferior_ptid));
1527 child_open (char *arg, int from_tty)
1529 error ("Use the \"run\" command to start a child process.");
1532 #define FACTOR (0x19db1ded53ea710LL)
1533 #define NSPERSEC 10000000
1535 /* Convert a Win32 time to "UNIX" format. */
1537 to_time_t (FILETIME * ptr)
1539 /* A file time is the number of 100ns since jan 1 1601
1540 stuffed into two long words.
1541 A time_t is the number of seconds since jan 1 1970. */
1544 long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime);
1545 x -= FACTOR; /* number of 100ns between 1601 and 1970 */
1546 rem = x % ((long long) NSPERSEC);
1547 rem += (NSPERSEC / 2);
1548 x /= (long long) NSPERSEC; /* number of 100ns in a second */
1549 x += (long long) (rem / NSPERSEC);
1553 /* Upload a file to the remote device depending on the user's
1554 'set remoteupload' specification. */
1556 upload_to_device (const char *to, const char *from)
1559 const char *dir = remote_directory ?: "\\gdb";
1561 static char *remotefile = NULL;
1565 const char *in_to = to;
1566 FILETIME crtime, actime, wrtime;
1571 /* Look for a path separator and only use trailing part. */
1572 while ((p = strpbrk (to, "/\\")) != NULL)
1576 error ("no filename found to upload - %s.", in_to);
1578 len = strlen (dir) + strlen (to) + 2;
1579 remotefile = (char *) xrealloc (remotefile, len);
1580 strcpy (remotefile, dir);
1581 strcat (remotefile, "\\");
1582 strcat (remotefile, to);
1584 if (upload_when == UPLOAD_NEVER)
1585 return remotefile; /* Don't bother uploading. */
1587 /* Open the source. */
1588 if ((fd = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, (char *) from, O_RDONLY,
1590 error ("couldn't open %s", from);
1592 /* Get the time for later comparison. */
1593 if (fstat (fd, &st))
1594 st.st_mtime = (time_t) - 1;
1596 /* Always attempt to create the directory on the remote system. */
1597 wstr = towide (dir, NULL);
1598 (void) CeCreateDirectory (wstr, NULL);
1600 /* Attempt to open the remote file, creating it if it doesn't exist. */
1601 wstr = towide (remotefile, NULL);
1602 h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1603 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1605 /* Some kind of problem? */
1606 err = CeGetLastError ();
1607 if (h == NULL || h == INVALID_HANDLE_VALUE)
1608 error ("error opening file \"%s\". Windows error %d.",
1611 CeGetFileTime (h, &crtime, &actime, &wrtime);
1612 utime = to_time_t (&wrtime);
1614 if (utime < st.st_mtime)
1617 strcpy (buf, ctime(&utime));
1618 printf ("%s < %s\n", buf, ctime(&st.st_mtime));
1621 /* See if we need to upload the file. */
1622 if (upload_when == UPLOAD_ALWAYS ||
1623 err != ERROR_ALREADY_EXISTS ||
1624 !CeGetFileTime (h, &crtime, &actime, &wrtime) ||
1625 to_time_t (&wrtime) < st.st_mtime)
1631 /* Upload the file. */
1632 while ((n = read (fd, buf, sizeof (buf))) > 0)
1633 if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL))
1634 error ("error writing to remote device - %d.",
1639 if (!CeCloseHandle (h))
1640 error ("error closing remote file - %d.", CeGetLastError ());
1645 /* Initialize the connection to the remote device. */
1647 wince_initialize (void)
1652 struct sockaddr_in sin;
1653 char *stub_file_name;
1655 PROCESS_INFORMATION pi;
1657 if (!connection_initialized)
1658 switch (CeRapiInit ())
1661 connection_initialized = 1;
1665 error ("Can't initialize connection to remote device.\n");
1669 /* Upload the stub to the handheld device. */
1670 stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB);
1671 strcpy (args, stub_file_name);
1673 if (remote_add_host)
1676 hostname = strchr (args, '\0');
1677 if (gethostname (hostname, sizeof (args) - strlen (args)))
1678 error ("couldn't get hostname of this system.");
1682 if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1683 stub_error ("Couldn't connect to host system.");
1685 /* Allow rapid reuse of the port. */
1687 (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1690 /* Set up the information for connecting to the host gdb process. */
1691 memset (&sin, 0, sizeof (sin));
1692 sin.sin_family = AF_INET;
1693 sin.sin_port = htons (7000); /* FIXME: This should be configurable */
1695 if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
1696 error ("couldn't bind socket");
1699 error ("Couldn't open socket for listening.\n");
1701 /* Start up the stub on the remote device. */
1702 if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL),
1703 NULL, NULL, 0, 0, NULL, NULL, NULL, &pi))
1704 error ("Unable to start remote stub '%s'. Windows CE error %d.",
1705 stub_file_name, CeGetLastError ());
1707 /* Wait for a connection */
1709 if ((s = accept (s0, NULL, NULL)) < 0)
1710 error ("couldn't set up server for connection.");
1715 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1716 EXEC_FILE is the file to run.
1717 ALLARGS is a string containing the arguments to the program.
1718 ENV is the environment vector to pass. Errors reported with error(). */
1720 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 exec_file = upload_to_device (exec_file, exec_file);
1738 while (*args == ' ')
1741 /* Allocate space for "command<sp>args" */
1744 exec_and_args = alloca (strlen (exec_file) + 1);
1745 strcpy (exec_and_args, exec_file);
1749 exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
1750 sprintf (exec_and_args, "%s %s", exec_file, args);
1753 memset (&pi, 0, sizeof (pi));
1754 /* Execute the process */
1755 if (!create_process (exec_file, exec_and_args, flags, &pi))
1756 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1758 exception_count = 0;
1761 current_process_handle = pi.hProcess;
1762 current_event.dwProcessId = pi.dwProcessId;
1763 memset (¤t_event, 0, sizeof (current_event));
1764 current_event.dwThreadId = pi.dwThreadId;
1765 inferior_ptid = pid_to_ptid (current_event.dwThreadId);
1766 push_target (&deprecated_child_ops);
1767 child_init_thread_list ();
1768 child_add_thread (pi.dwThreadId, pi.hThread);
1769 init_wait_for_inferior ();
1770 clear_proceed_status ();
1771 target_terminal_init ();
1772 target_terminal_inferior ();
1774 /* Run until process and threads are loaded */
1775 while (!get_child_debug_event (PIDGET (inferior_ptid), &dummy,
1776 CREATE_PROCESS_DEBUG_EVENT, &ret))
1779 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
1782 /* Chile has gone bye-bye. */
1784 child_mourn_inferior (void)
1786 (void) child_continue (DBG_CONTINUE, -1);
1787 unpush_target (&deprecated_child_ops);
1790 connection_initialized = 0;
1791 generic_mourn_inferior ();
1794 /* Move memory from child to/from gdb. */
1796 child_xfer_memory (CORE_ADDR memaddr, char *our, int len, int write,
1797 struct mem_attrib *attrib,
1798 struct target_ops *target)
1804 res = remote_write_bytes (memaddr, our, len);
1806 res = remote_read_bytes (memaddr, our, len);
1811 /* Terminate the process and wait for child to tell us it has completed. */
1813 child_kill_inferior (void)
1815 CHECK (terminate_process (current_process_handle));
1819 if (!child_continue (DBG_CONTINUE, -1))
1821 if (!wait_for_debug_event (¤t_event, INFINITE))
1823 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1827 CHECK (close_handle (current_process_handle));
1828 close_handle (current_thread->h);
1829 target_mourn_inferior (); /* or just child_mourn_inferior? */
1832 /* Resume the child after an exception. */
1834 child_resume (ptid_t ptid, int step, enum target_signal sig)
1837 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1838 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1839 int pid = PIDGET (ptid);
1841 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1844 /* Get context for currently selected thread */
1845 th = thread_rec (current_event.dwThreadId, FALSE);
1847 if (th->context.ContextFlags)
1849 CHECK (set_thread_context (th->h, &th->context));
1850 th->context.ContextFlags = 0;
1853 /* Allow continuing with the same signal that interrupted us.
1854 Otherwise complain. */
1855 if (sig && sig != last_sig)
1856 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
1859 child_continue (continue_status, pid);
1863 child_prepare_to_store (void)
1865 /* Do nothing, since we can store individual regs */
1869 child_can_run (void)
1877 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1878 PIDGET (inferior_ptid)));
1881 /* Explicitly upload file to remotedir */
1884 child_load (char *file, int from_tty)
1886 upload_to_device (file, file);
1890 init_child_ops (void)
1892 memset (&deprecated_child_ops, 0, sizeof (deprecated_child_ops));
1893 deprecated_child_ops.to_shortname = (char *) "child";
1894 deprecated_child_ops.to_longname = (char *) "Windows CE process";
1895 deprecated_child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command).";
1896 deprecated_child_ops.to_open = child_open;
1897 deprecated_child_ops.to_close = child_close;
1898 deprecated_child_ops.to_resume = child_resume;
1899 deprecated_child_ops.to_wait = child_wait;
1900 deprecated_child_ops.to_fetch_registers = child_fetch_inferior_registers;
1901 deprecated_child_ops.to_store_registers = child_store_inferior_registers;
1902 deprecated_child_ops.to_prepare_to_store = child_prepare_to_store;
1903 deprecated_child_ops.deprecated_xfer_memory = child_xfer_memory;
1904 deprecated_child_ops.to_files_info = child_files_info;
1905 deprecated_child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1906 deprecated_child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1907 deprecated_child_ops.to_terminal_init = terminal_init_inferior;
1908 deprecated_child_ops.to_terminal_inferior = terminal_inferior;
1909 deprecated_child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1910 deprecated_child_ops.to_terminal_ours = terminal_ours;
1911 deprecated_child_ops.to_terminal_save_ours = terminal_save_ours;
1912 deprecated_child_ops.to_terminal_info = child_terminal_info;
1913 deprecated_child_ops.to_kill = child_kill_inferior;
1914 deprecated_child_ops.to_load = child_load;
1915 deprecated_child_ops.to_create_inferior = child_create_inferior;
1916 deprecated_child_ops.to_mourn_inferior = child_mourn_inferior;
1917 deprecated_child_ops.to_can_run = child_can_run;
1918 deprecated_child_ops.to_thread_alive = win32_child_thread_alive;
1919 deprecated_child_ops.to_stratum = process_stratum;
1920 deprecated_child_ops.to_has_all_memory = 1;
1921 deprecated_child_ops.to_has_memory = 1;
1922 deprecated_child_ops.to_has_stack = 1;
1923 deprecated_child_ops.to_has_registers = 1;
1924 deprecated_child_ops.to_has_execution = 1;
1925 deprecated_child_ops.to_magic = OPS_MAGIC;
1929 /* Handle 'set remoteupload' parameter. */
1931 #define replace_upload(what) \
1932 upload_when = what; \
1933 remote_upload = xrealloc (remote_upload, strlen (upload_options[upload_when].name) + 1); \
1934 strcpy (remote_upload, upload_options[upload_when].name);
1937 set_upload_type (char *ignore, int from_tty)
1942 if (!remote_upload || !remote_upload[0])
1944 replace_upload (UPLOAD_NEWER);
1946 printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1950 len = strlen (remote_upload);
1951 for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++)
1952 if (len >= upload_options[i].abbrev &&
1953 strncasecmp (remote_upload, upload_options[i].name, len) == 0)
1959 bad_option = remote_upload;
1960 replace_upload (UPLOAD_NEWER);
1961 error ("Unknown upload type: %s.", bad_option);
1965 _initialize_wince (void)
1967 struct cmd_list_element *set;
1970 deprecated_add_show_from_set
1971 (add_set_cmd ((char *) "remotedirectory", no_class,
1972 var_string_noescape, (char *) &remote_directory,
1973 (char *) "Set directory for remote upload.\n",
1976 remote_directory = xstrdup (remote_directory);
1978 set = add_set_cmd ((char *) "remoteupload", no_class,
1979 var_string_noescape, (char *) &remote_upload,
1980 (char *) "Set how to upload executables to remote device.\n",
1982 deprecated_add_show_from_set (set, &showlist);
1983 set_cmd_cfunc (set, set_upload_type);
1984 set_upload_type (NULL, 0);
1986 deprecated_add_show_from_set
1987 (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
1988 (char *) &debug_exec,
1989 (char *) "Set whether to display execution in child process.",
1993 deprecated_add_show_from_set
1994 (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
1995 (char *) &remote_add_host,
1997 Set whether to add this host to remote stub arguments for\n\
1998 debugging over a network.", &setlist),
2001 deprecated_add_show_from_set
2002 (add_set_cmd ((char *) "debugevents", class_support, var_boolean,
2003 (char *) &debug_events,
2004 (char *) "Set whether to display kernel events in child process.",
2008 deprecated_add_show_from_set
2009 (add_set_cmd ((char *) "debugmemory", class_support, var_boolean,
2010 (char *) &debug_memory,
2011 (char *) "Set whether to display memory accesses in child process.",
2015 deprecated_add_show_from_set
2016 (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean,
2017 (char *) &debug_exceptions,
2018 (char *) "Set whether to display kernel exceptions in child process.",
2022 add_target (&deprecated_child_ops);
2025 /* Determine if the thread referenced by "pid" is alive
2026 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2027 it means that the pid has died. Otherwise it is assumed to be alive. */
2029 win32_child_thread_alive (ptid_t ptid)
2031 int pid = PIDGET (ptid);
2032 return thread_alive (thread_rec (pid, FALSE)->h);
2035 /* Convert pid to printable format. */
2037 cygwin_pid_to_str (int pid)
2039 static char buf[80];
2040 if (pid == current_event.dwProcessId)
2041 sprintf (buf, "process %d", pid);
2043 sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);