1 /* Target-vector operations for controlling Windows CE child processes, for GDB.
3 Copyright (C) 1999, 2000, 2001, 2004, 2006 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions, A Red Hat Company.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
24 /* by Christopher Faylor (cgf@cygnus.com) */
26 /* We assume we're being built with and will be used for cygwin. */
30 #define SH4 /* Just to get all of the CONTEXT defines. */
34 #include "frame.h" /* required by inferior.h */
37 #include "exceptions.h"
41 #include <sys/types.h>
48 #include <cygwin/in.h>
49 #include <cygwin/socket.h>
54 #include "gdb_string.h"
55 #include "gdbthread.h"
57 #include <sys/param.h>
58 #include "wince-stub.h"
62 #include "mips-tdep.h"
65 /* If we're not using the old Cygwin header file set, define the
66 following which never should have been in the generic Win32 API
67 headers in the first place since they were our own invention... */
68 #ifndef _GNU_H_WINDOWS_H
69 #define FLAG_TRACE_BIT 0x100
70 #ifdef CONTEXT_FLOATING_POINT
71 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
73 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
78 #define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
80 #define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
82 /* The string sent by cygwin when it processes a signal.
83 FIXME: This should be in a cygwin include file. */
84 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
86 #define CHECK(x) check (x, __FILE__,__LINE__)
87 #define DEBUG_EXEC(x) if (debug_exec) printf x
88 #define DEBUG_EVENTS(x) if (debug_events) printf x
89 #define DEBUG_MEM(x) if (debug_memory) printf x
90 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
92 static int connection_initialized
= 0; /* True if we've initialized a
95 /* The directory where the stub and executable files are uploaded. */
96 static const char *remote_directory
= "\\gdb";
98 /* The types automatic upload available. */
105 upload_when
= UPLOAD_NEWER
;
107 /* Valid options for 'set remoteupload'. Note that options
108 must track upload_when enum. */
129 static char *remote_upload
= NULL
; /* Set by set remoteupload. */
130 static int remote_add_host
= 0;
132 static int win32_child_thread_alive (ptid_t
);
133 void child_kill_inferior (void);
135 static int last_sig
= 0; /* Set if a signal was received from
136 the debugged process. */
138 /* Thread information structure used to track information that is
139 not available in gdb's thread structure. */
140 typedef struct thread_info_struct
142 struct thread_info_struct
*next
;
147 int stepped
; /* True if stepped. */
153 static thread_info thread_head
=
155 static thread_info
* thread_rec (DWORD id
, int get_context
);
157 /* The process and thread handles for the above context. */
159 static DEBUG_EVENT current_event
; /* The current debug event from
160 WaitForDebugEvent. */
161 static HANDLE current_process_handle
; /* Currently executing process. */
162 static thread_info
*current_thread
; /* Info on currently selected
164 static thread_info
*this_thread
; /* Info on thread returned by
165 wait_for_debug_event. */
166 static DWORD main_thread_id
; /* Thread ID of the main thread. */
168 /* Counts of things. */
169 static int exception_count
= 0;
170 static int event_count
= 0;
173 static int debug_exec
= 0; /* show execution */
174 static int debug_events
= 0; /* show events from kernel */
175 static int debug_memory
= 0; /* show target memory accesses */
176 static int debug_exceptions
= 0; /* show target exceptions */
178 /* An array of offset mappings into a Win32 Context structure.
179 This is a one-to-one mapping which is indexed by gdb's register
180 numbers. It retrieves an offset into the context structure where
181 the 4 byte register is located.
182 An offset value of -1 indicates that Win32 does not provide this
183 register in it's CONTEXT structure. regptr will return zero for this
186 This is used by the regptr function. */
187 #define context_offset(x) ((int)&(((PCONTEXT)NULL)->x))
188 static const int mappings
[NUM_REGS
+ 1] =
191 context_offset (Eax
),
192 context_offset (Ecx
),
193 context_offset (Edx
),
194 context_offset (Ebx
),
195 context_offset (Esp
),
196 context_offset (Ebp
),
197 context_offset (Esi
),
198 context_offset (Edi
),
199 context_offset (Eip
),
200 context_offset (EFlags
),
201 context_offset (SegCs
),
202 context_offset (SegSs
),
203 context_offset (SegDs
),
204 context_offset (SegEs
),
205 context_offset (SegFs
),
206 context_offset (SegGs
),
207 context_offset (FloatSave
.RegisterArea
[0 * 10]),
208 context_offset (FloatSave
.RegisterArea
[1 * 10]),
209 context_offset (FloatSave
.RegisterArea
[2 * 10]),
210 context_offset (FloatSave
.RegisterArea
[3 * 10]),
211 context_offset (FloatSave
.RegisterArea
[4 * 10]),
212 context_offset (FloatSave
.RegisterArea
[5 * 10]),
213 context_offset (FloatSave
.RegisterArea
[6 * 10]),
214 context_offset (FloatSave
.RegisterArea
[7 * 10]),
226 context_offset (R10
),
227 context_offset (R11
),
228 context_offset (R12
),
229 context_offset (R13
),
230 context_offset (R14
),
231 context_offset (R15
),
232 context_offset (Fir
),
233 context_offset (PR
), /* Procedure Register */
234 context_offset (GBR
), /* Global Base Register */
235 context_offset (MACH
), /* Accumulate */
236 context_offset (MACL
), /* Multiply */
237 context_offset (Psr
),
238 context_offset (Fpul
),
239 context_offset (Fpscr
),
240 context_offset (FRegs
[0]),
241 context_offset (FRegs
[1]),
242 context_offset (FRegs
[2]),
243 context_offset (FRegs
[3]),
244 context_offset (FRegs
[4]),
245 context_offset (FRegs
[5]),
246 context_offset (FRegs
[6]),
247 context_offset (FRegs
[7]),
248 context_offset (FRegs
[8]),
249 context_offset (FRegs
[9]),
250 context_offset (FRegs
[10]),
251 context_offset (FRegs
[11]),
252 context_offset (FRegs
[12]),
253 context_offset (FRegs
[13]),
254 context_offset (FRegs
[14]),
255 context_offset (FRegs
[15]),
256 context_offset (xFRegs
[0]),
257 context_offset (xFRegs
[1]),
258 context_offset (xFRegs
[2]),
259 context_offset (xFRegs
[3]),
260 context_offset (xFRegs
[4]),
261 context_offset (xFRegs
[5]),
262 context_offset (xFRegs
[6]),
263 context_offset (xFRegs
[7]),
264 context_offset (xFRegs
[8]),
265 context_offset (xFRegs
[9]),
266 context_offset (xFRegs
[10]),
267 context_offset (xFRegs
[11]),
268 context_offset (xFRegs
[12]),
269 context_offset (xFRegs
[13]),
270 context_offset (xFRegs
[14]),
271 context_offset (xFRegs
[15]),
273 context_offset (IntZero
),
274 context_offset (IntAt
),
275 context_offset (IntV0
),
276 context_offset (IntV1
),
277 context_offset (IntA0
),
278 context_offset (IntA1
),
279 context_offset (IntA2
),
280 context_offset (IntA3
),
281 context_offset (IntT0
),
282 context_offset (IntT1
),
283 context_offset (IntT2
),
284 context_offset (IntT3
),
285 context_offset (IntT4
),
286 context_offset (IntT5
),
287 context_offset (IntT6
),
288 context_offset (IntT7
),
289 context_offset (IntS0
),
290 context_offset (IntS1
),
291 context_offset (IntS2
),
292 context_offset (IntS3
),
293 context_offset (IntS4
),
294 context_offset (IntS5
),
295 context_offset (IntS6
),
296 context_offset (IntS7
),
297 context_offset (IntT8
),
298 context_offset (IntT9
),
299 context_offset (IntK0
),
300 context_offset (IntK1
),
301 context_offset (IntGp
),
302 context_offset (IntSp
),
303 context_offset (IntS8
),
304 context_offset (IntRa
),
305 context_offset (Psr
),
306 context_offset (IntLo
),
307 context_offset (IntHi
),
310 context_offset (Fir
),
311 context_offset (FltF0
),
312 context_offset (FltF1
),
313 context_offset (FltF2
),
314 context_offset (FltF3
),
315 context_offset (FltF4
),
316 context_offset (FltF5
),
317 context_offset (FltF6
),
318 context_offset (FltF7
),
319 context_offset (FltF8
),
320 context_offset (FltF9
),
321 context_offset (FltF10
),
322 context_offset (FltF11
),
323 context_offset (FltF12
),
324 context_offset (FltF13
),
325 context_offset (FltF14
),
326 context_offset (FltF15
),
327 context_offset (FltF16
),
328 context_offset (FltF17
),
329 context_offset (FltF18
),
330 context_offset (FltF19
),
331 context_offset (FltF20
),
332 context_offset (FltF21
),
333 context_offset (FltF22
),
334 context_offset (FltF23
),
335 context_offset (FltF24
),
336 context_offset (FltF25
),
337 context_offset (FltF26
),
338 context_offset (FltF27
),
339 context_offset (FltF28
),
340 context_offset (FltF29
),
341 context_offset (FltF30
),
342 context_offset (FltF31
),
343 context_offset (Fsr
),
344 context_offset (Fir
),
357 context_offset (R10
),
358 context_offset (R11
),
359 context_offset (R12
),
372 context_offset (Psr
),
377 /* Return a pointer into a CONTEXT field indexed by gdb register number.
378 Return a pointer to an address pointing to zero if there is no
379 corresponding CONTEXT field for the given register number.
382 regptr (LPCONTEXT c
, int r
)
384 static ULONG zero
= 0;
389 p
= (ULONG
*) (((char *) c
) + mappings
[r
]);
393 /******************** Beginning of stub interface ********************/
395 /* Stub interface description:
397 The Windows CE stub implements a crude RPC. The hand-held device
398 connects to gdb using port 7000. gdb and the stub then communicate
401 byte 0: command id (e.g. Create Process)
408 byte 3-n: arbitrary memory.
410 The interface is deterministic, i.e., if the stub expects a DWORD
411 then the gdb server should send a DWORD.
414 /* Note: In the functions below, the `huh' parameter is a string
415 passed from the function containing a descriptive string concerning
416 the current operation. This is used for error reporting.
418 The 'what' parameter is a command id as found in wince-stub.h.
420 Hopefully, the rest of the parameters are self-explanatory.
423 static int s
; /* communication socket */
425 /* v-style interface for handling varying argyment list error messages.
426 Displays the error message in a dialog box and exits when user clicks
429 vstub_error (LPCSTR fmt
, va_list * args
)
432 vsprintf (buf
, fmt
, args
);
437 /* The standard way to display an error message and exit. */
439 stub_error (LPCSTR fmt
,...)
442 va_start (args
, fmt
);
443 vstub_error (fmt
, args
);
446 /* Standard "oh well" can't communicate error. Someday this might
447 attempt synchronization. */
449 attempt_resync (LPCSTR huh
, int s
)
451 stub_error ("lost synchronization with target attempting %s", huh
);
454 /* Read arbitrary stuff from a socket. */
456 sockread (LPCSTR huh
, int s
, void *str
, size_t n
)
460 if (recv (s
, str
, n
, 0) == n
)
462 attempt_resync (huh
, s
);
466 /* Write arbitrary stuff to a socket. */
468 sockwrite (LPCSTR huh
, const void *str
, size_t n
)
472 if (send (s
, str
, n
, 0) == n
)
474 attempt_resync (huh
, s
);
478 /* Output an id/dword to the host. */
480 putdword (LPCSTR huh
, gdb_wince_id what
, DWORD n
)
482 if (sockwrite (huh
, &what
, sizeof (what
)) != sizeof (what
))
483 stub_error ("error writing record id to host for %s", huh
);
484 if (sockwrite (huh
, &n
, sizeof (n
)) != sizeof (n
))
485 stub_error ("error writing %s to host.", huh
);
488 /* Output an id/word to the host. */
490 putword (LPCSTR huh
, gdb_wince_id what
, WORD n
)
492 if (sockwrite (huh
, &what
, sizeof (what
)) != sizeof (what
))
493 stub_error ("error writing record id to host for %s", huh
);
494 if (sockwrite (huh
, &n
, sizeof (n
)) != sizeof (n
))
495 stub_error ("error writing %s host.", huh
);
498 /* Convenience define for outputting a "gdb_wince_len" type. */
499 #define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
501 /* Put an arbitrary block of memory to the gdb host. This comes in
502 two chunks an id/dword representing the length and the stream of
505 putmemory (LPCSTR huh
, gdb_wince_id what
,
506 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
514 a block of memory starting at mem of len bytes. If res == 0, sends
515 -GetLastError () and 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)
559 then nbytes is actually an error and nothing else follows. Use
560 SetLastError to remember this. if nbytes > 0, retrieve a block of
564 getresult (LPCSTR huh
, gdb_wince_id what
, LPVOID buf
,
565 gdb_wince_len
* nbytes
)
571 *nbytes
= getlen (huh
, what
);
573 if ((short) *nbytes
< 0)
575 SetLastError (-(short) *nbytes
);
579 if ((gdb_wince_len
) sockread (huh
, s
, buf
, *nbytes
) != *nbytes
)
580 stub_error ("couldn't read information from wince stub - %s", huh
);
585 /* Convert "narrow" string to "wide". Manipulates a buffer ring of 8
586 buffers which hold the translated string. This is an arbitrary limit
587 but it is approximately double the current needs of this module.
590 towide (const char *s
, gdb_wince_len
* out_len
)
593 static LPWSTR outs
[8] =
594 {NULL
/*, NULL, etc. */ };
600 /* First determine the length required to hold the converted string. */
601 *out_len
= sizeof (WCHAR
) * MultiByteToWideChar (CP_ACP
, 0, s
,
604 return NULL
; /* The conversion failed. */
606 if (++n
>= (sizeof (outs
) / sizeof (outs
[0])))
609 /* Allocate space for the converted string, reusing any previously
610 allocated space, if applicable. Note that if outs[n] is NULL,
611 xrealloc will act as a malloc (under cygwin, at least).
613 outs
[n
] = (LPWSTR
) xrealloc (outs
[n
], *out_len
);
614 memset (outs
[n
], 0, *out_len
);
615 (void) MultiByteToWideChar (CP_ACP
, 0, s
, -1, outs
[n
], *out_len
);
619 /******************** Emulation routines start here. ********************
621 The functions below are modelled after their Win32 counterparts.
622 They are named similarly to Win32 and take exactly the same
623 arguments except where otherwise noted. They communicate with the
624 stub on the hand-held device by sending their arguments over the
625 socket and waiting for results from the socket.
627 There is one universal change. In cases where a length is expected
628 to be returned in a DWORD, we use a gdb_wince_len type instead.
629 Currently this is an unsigned short which is smaller than the
630 standard Win32 DWORD. This is done to minimize unnecessary traffic
631 since the connection to Windows CE can be slow. To change this,
632 modify the typedef in wince-stub.h and change the putlen/getlen
633 macros in this file and in the stub.
637 create_process (LPSTR exec_file
, LPSTR args
, DWORD flags
,
638 PROCESS_INFORMATION
* pi
)
643 buf
= towide (exec_file
, &len
);
644 putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS
, buf
, len
);
645 buf
= towide (args
, &len
);
646 putmemory ("CreateProcess args", GDB_CREATEPROCESS
, buf
, len
);
647 putdword ("CreateProcess flags", GDB_CREATEPROCESS
, flags
);
648 return getresult ("CreateProcess result", GDB_CREATEPROCESS
, pi
, NULL
);
651 /* Emulate TerminateProcess.
652 Don't bother with the second argument since CE ignores it.
655 terminate_process (HANDLE h
)
657 gdb_wince_result res
;
660 puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS
, h
);
662 return getresult ("TerminateProcess result",
663 GDB_TERMINATEPROCESS
, &res
, NULL
);
667 wait_for_debug_event (DEBUG_EVENT
* ev
, DWORD ms
)
671 putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT
, ms
);
673 return getresult ("WaitForDebugEvent event",
674 GDB_WAITFORDEBUGEVENT
, ev
, NULL
);
678 get_thread_context (HANDLE h
, CONTEXT
* c
)
682 puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT
, h
);
683 putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT
,
686 return getresult ("GetThreadContext context",
687 GDB_GETTHREADCONTEXT
, c
, NULL
);
691 set_thread_context (HANDLE h
, CONTEXT
* c
)
693 gdb_wince_result res
;
696 puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT
, h
);
697 putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT
,
700 return getresult ("SetThreadContext context",
701 GDB_SETTHREADCONTEXT
, &res
, NULL
);
705 read_process_memory (HANDLE h
, LPCVOID where
,
706 LPVOID buf
, gdb_wince_len len
,
707 gdb_wince_len
* nbytes
)
711 puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY
, h
);
712 putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY
, where
);
713 putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY
, len
);
715 return getresult ("ReadProcessMemory buf",
716 GDB_READPROCESSMEMORY
, buf
, nbytes
);
720 write_process_memory (HANDLE h
, LPCVOID where
,
721 LPCVOID buf
, gdb_wince_len len
,
722 gdb_wince_len
* nbytes
)
726 puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY
, h
);
727 putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY
, where
);
728 putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY
, buf
, len
);
730 return getresult ("WriteProcessMemory result",
731 GDB_WRITEPROCESSMEMORY
, nbytes
, NULL
);
735 remote_read_bytes (CORE_ADDR memaddr
, char *myaddr
, int len
)
737 gdb_wince_len nbytes
;
738 if (!read_process_memory (current_process_handle
,
747 remote_write_bytes (CORE_ADDR memaddr
, char *myaddr
, int len
)
749 gdb_wince_len nbytes
;
750 if (!write_process_memory (current_process_handle
,
758 /* This is not a standard Win32 function. It instructs the stub to
759 return TRUE if the thread referenced by HANDLE h is alive.
762 thread_alive (HANDLE h
)
764 gdb_wince_result res
;
767 puthandle ("ThreadAlive handle", GDB_THREADALIVE
, h
);
768 return getresult ("ThreadAlive result", GDB_THREADALIVE
, &res
, NULL
);
772 suspend_thread (HANDLE h
)
776 puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD
, h
);
777 return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD
);
781 resume_thread (HANDLE h
)
785 puthandle ("ResumeThread handle", GDB_RESUMETHREAD
, h
);
786 return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD
);
790 continue_debug_event (DWORD pid
, DWORD tid
, DWORD status
)
792 gdb_wince_result res
;
795 putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT
, pid
);
796 putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT
, tid
);
797 putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT
, status
);
798 return getresult ("ContinueDebugEvent result",
799 GDB_CONTINUEDEBUGEVENT
, &res
, NULL
);
803 close_handle (HANDLE h
)
805 gdb_wince_result res
;
808 puthandle ("CloseHandle handle", GDB_CLOSEHANDLE
, h
);
809 return (int) getresult ("CloseHandle result",
810 GDB_CLOSEHANDLE
, &res
, NULL
);
813 /* This is not a standard Win32 interface. This function tells the
821 (void) putdword ("Stopping gdb stub", GDB_STOPSTUB
, 0);
825 /******************** End of emulation routines. ********************/
826 /******************** End of stub interface ********************/
828 #define check_for_step(a, x) (x)
832 undoSStep (thread_info
* th
)
836 remove_single_step_breakpoints ();
842 wince_software_single_step (enum target_signal ignore
,
843 int insert_breakpoints_p
)
846 /* Info on currently selected thread. */
847 thread_info
*th
= current_thread
;
848 CORE_ADDR
mips_next_pc (CORE_ADDR pc
);
850 if (!insert_breakpoints_p
)
857 pc
= read_register (PC_REGNUM
);
858 th
->step_pc
= mips_next_pc (pc
);
859 insert_single_step_breakpoint (th
->step_pc
);
863 /* Renesas SH architecture instruction encoding masks */
865 #define COND_BR_MASK 0xff00
866 #define UCOND_DBR_MASK 0xe000
867 #define UCOND_RBR_MASK 0xf0df
868 #define TRAPA_MASK 0xff00
870 #define COND_DISP 0x00ff
871 #define UCOND_DISP 0x0fff
872 #define UCOND_REG 0x0f00
874 /* Renesas SH instruction opcodes */
876 #define BF_INSTR 0x8b00
877 #define BT_INSTR 0x8900
878 #define BRA_INSTR 0xa000
879 #define BSR_INSTR 0xb000
880 #define JMP_INSTR 0x402b
881 #define JSR_INSTR 0x400b
882 #define RTS_INSTR 0x000b
883 #define RTE_INSTR 0x002b
884 #define TRAPA_INSTR 0xc300
885 #define SSTEP_INSTR 0xc3ff
888 #define T_BIT_MASK 0x0001
891 sh_get_next_pc (CONTEXT
*c
)
896 unsigned short opcode
;
898 instrMem
= (short *) c
->Fir
;
900 opcode
= read_memory_integer ((CORE_ADDR
) c
->Fir
, sizeof (opcode
));
902 if ((opcode
& COND_BR_MASK
) == BT_INSTR
)
904 if (c
->Psr
& T_BIT_MASK
)
906 displacement
= (opcode
& COND_DISP
) << 1;
907 if (displacement
& 0x80)
908 displacement
|= 0xffffff00;
910 * Remember PC points to second instr.
911 * after PC of branch ... so add 4
913 instrMem
= (short *) (c
->Fir
+ displacement
+ 4);
918 else if ((opcode
& COND_BR_MASK
) == BF_INSTR
)
920 if (c
->Psr
& T_BIT_MASK
)
924 displacement
= (opcode
& COND_DISP
) << 1;
925 if (displacement
& 0x80)
926 displacement
|= 0xffffff00;
928 * Remember PC points to second instr.
929 * after PC of branch ... so add 4
931 instrMem
= (short *) (c
->Fir
+ displacement
+ 4);
934 else if ((opcode
& UCOND_DBR_MASK
) == BRA_INSTR
)
936 displacement
= (opcode
& UCOND_DISP
) << 1;
937 if (displacement
& 0x0800)
938 displacement
|= 0xfffff000;
941 * Remember PC points to second instr.
942 * after PC of branch ... so add 4
944 instrMem
= (short *) (c
->Fir
+ displacement
+ 4);
946 else if ((opcode
& UCOND_RBR_MASK
) == JSR_INSTR
)
948 reg
= (char) ((opcode
& UCOND_REG
) >> 8);
950 instrMem
= (short *) *regptr (c
, reg
);
952 else if (opcode
== RTS_INSTR
)
953 instrMem
= (short *) c
->PR
;
954 else if (opcode
== RTE_INSTR
)
955 instrMem
= (short *) *regptr (c
, 15);
956 else if ((opcode
& TRAPA_MASK
) == TRAPA_INSTR
)
957 instrMem
= (short *) ((opcode
& ~TRAPA_MASK
) << 2);
961 return (CORE_ADDR
) instrMem
;
963 /* Single step (in a painstaking fashion) by inspecting the current
964 instruction and setting a breakpoint on the "next" instruction
965 which would be executed. This code hails from sh-stub.c.
968 undoSStep (thread_info
* th
)
972 remove_single_step_breakpoints ();
978 /* Single step (in a painstaking fashion) by inspecting the current
979 instruction and setting a breakpoint on the "next" instruction
980 which would be executed. This code hails from sh-stub.c.
983 wince_software_single_step (enum target_signal ignore
,
984 int insert_breakpoints_p
)
986 /* Info on currently selected thread. */
987 thread_info
*th
= current_thread
;
989 if (!insert_breakpoints_p
)
996 th
->step_pc
= sh_get_next_pc (&th
->context
);
997 insert_single_step_breakpoint (th
->step_pc
);
1001 #undef check_for_step
1003 static enum target_signal
1004 check_for_step (DEBUG_EVENT
*ev
, enum target_signal x
)
1006 thread_info
*th
= thread_rec (ev
->dwThreadId
, 1);
1009 th
->step_pc
== (CORE_ADDR
) ev
->u
.Exception
.ExceptionRecord
.ExceptionAddress
)
1010 return TARGET_SIGNAL_TRAP
;
1015 /* Single step (in a painstaking fashion) by inspecting the current
1016 instruction and setting a breakpoint on the "next" instruction
1017 which would be executed. This code hails from sh-stub.c.
1020 undoSStep (thread_info
* th
)
1024 remove_single_step_breakpoints ();
1030 wince_software_single_step (enum target_signal ignore
,
1031 int insert_breakpoints_p
)
1034 /* Info on currently selected thread. */
1035 thread_info
*th
= current_thread
;
1036 CORE_ADDR
mips_next_pc (CORE_ADDR pc
);
1038 if (!insert_breakpoints_p
)
1045 pc
= read_register (PC_REGNUM
);
1046 th
->step_pc
= arm_get_next_pc (pc
);
1047 insert_single_step_breakpoint (th
->step_pc
);
1052 /* Find a thread record given a thread id.
1053 If get_context then also retrieve the context for this thread. */
1055 static thread_info
*
1056 thread_rec (DWORD id
, int get_context
)
1060 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1063 if (!th
->suspend_count
&& get_context
)
1065 if (get_context
> 0 && th
!= this_thread
)
1066 th
->suspend_count
= suspend_thread (th
->h
) + 1;
1067 else if (get_context
< 0)
1068 th
->suspend_count
= -1;
1070 th
->context
.ContextFlags
= CONTEXT_DEBUGGER
;
1071 get_thread_context (th
->h
, &th
->context
);
1078 /* Add a thread to the thread list. */
1079 static thread_info
*
1080 child_add_thread (DWORD id
, HANDLE h
)
1084 if ((th
= thread_rec (id
, FALSE
)))
1087 th
= (thread_info
*) xmalloc (sizeof (*th
));
1088 memset (th
, 0, sizeof (*th
));
1091 th
->next
= thread_head
.next
;
1092 thread_head
.next
= th
;
1097 /* Clear out any old thread list and reintialize it to a
1100 child_init_thread_list (void)
1102 thread_info
*th
= &thread_head
;
1104 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
1105 init_thread_list ();
1106 while (th
->next
!= NULL
)
1108 thread_info
*here
= th
->next
;
1109 th
->next
= here
->next
;
1110 (void) close_handle (here
->h
);
1115 /* Delete a thread from the list of threads. */
1117 child_delete_thread (DWORD id
)
1122 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id
));
1125 for (th
= &thread_head
;
1126 th
->next
!= NULL
&& th
->next
->id
!= id
;
1130 if (th
->next
!= NULL
)
1132 thread_info
*here
= th
->next
;
1133 th
->next
= here
->next
;
1134 close_handle (here
->h
);
1140 check (BOOL ok
, const char *file
, int line
)
1143 printf_filtered ("error return %s:%d was %d\n",
1144 file
, line
, GetLastError ());
1148 do_child_fetch_inferior_registers (int r
)
1152 regcache_raw_supply (current_regcache
, r
,
1153 (char *) regptr (¤t_thread
->context
, r
));
1157 for (r
= 0; r
< NUM_REGS
; r
++)
1158 do_child_fetch_inferior_registers (r
);
1163 child_fetch_inferior_registers (int r
)
1165 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
1166 do_child_fetch_inferior_registers (r
);
1170 do_child_store_inferior_registers (int r
)
1173 deprecated_read_register_gen (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
1176 for (r
= 0; r
< NUM_REGS
; r
++)
1177 do_child_store_inferior_registers (r
);
1181 /* Store a new register value into the current thread context. */
1183 child_store_inferior_registers (int r
)
1185 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
1186 do_child_store_inferior_registers (r
);
1189 /* Wait for child to do something. Return pid of child, or -1 in case
1190 of error; store status through argument pointer OURSTATUS. */
1193 handle_load_dll (void *dummy
)
1195 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
1196 char dll_buf
[MAX_PATH
+ 1];
1197 char *p
, *bufp
, *imgp
, *dll_name
, *dll_basename
;
1200 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
1201 if (!event
->lpImageName
)
1205 for (bufp
= dll_buf
, imgp
= event
->lpImageName
;
1206 bufp
< dll_buf
+ sizeof (dll_buf
);
1207 bufp
+= 16, imgp
+= 16)
1209 gdb_wince_len nbytes
= 0;
1210 (void) read_process_memory (current_process_handle
,
1211 imgp
, bufp
, 16, &nbytes
);
1213 if (!nbytes
&& bufp
== dll_buf
)
1214 return 1; /* couldn't read it */
1215 for (p
= bufp
; p
< bufp
+ nbytes
; p
++)
1220 if (event
->fUnicode
)
1231 dll_buf
[len
] = '\0';
1233 dll_name
= alloca (len
);
1238 if (!event
->fUnicode
)
1239 memcpy (dll_name
, dll_buf
, len
);
1241 WideCharToMultiByte (CP_ACP
, 0, (LPCWSTR
) dll_buf
,
1242 len
, dll_name
, len
, 0, 0);
1244 while ((p
= strchr (dll_name
, '\\')))
1247 /* FIXME!! It would be nice to define one symbol which pointed to
1248 the front of the dll if we can't find any symbols. */
1250 if (!(dll_basename
= strrchr (dll_name
, '/')))
1251 dll_basename
= dll_name
;
1255 /* The symbols in a dll are offset by 0x1000, which is the
1256 the offset from 0 of the first byte in an image - because
1257 of the file header and the section alignment.
1259 FIXME: Is this the real reason that we need the 0x1000 ? */
1261 printf_unfiltered ("%x:%s", event
->lpBaseOfDll
, dll_name
);
1262 printf_unfiltered ("\n");
1267 /* Handle DEBUG_STRING output from child process. */
1269 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
1274 gdb_wince_len nbytes_read
;
1275 gdb_wince_len nbytes
= current_event
.u
.DebugString
.nDebugStringLength
;
1280 memset (p
, 0, sizeof (p
));
1281 if (!read_process_memory (current_process_handle
,
1282 current_event
.u
.DebugString
.lpDebugStringData
,
1283 &p
, nbytes
, &nbytes_read
)
1287 memset (s
, 0, sizeof (s
));
1288 WideCharToMultiByte (CP_ACP
, 0, (LPCWSTR
) p
, (int) nbytes_read
,
1289 s
, sizeof (s
) - 1, NULL
, NULL
);
1290 q
= strchr (s
, '\n');
1303 /* Handle target exceptions. */
1305 handle_exception (struct target_waitstatus
*ourstatus
)
1308 if (current_event
.u
.Exception
.dwFirstChance
)
1312 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1314 switch (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
)
1316 case EXCEPTION_ACCESS_VIOLATION
:
1317 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
1318 (unsigned) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
1319 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1321 case STATUS_STACK_OVERFLOW
:
1322 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
1323 (unsigned) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
1324 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1326 case EXCEPTION_BREAKPOINT
:
1327 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
1328 (unsigned) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
1329 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1332 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
1333 (unsigned) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
1334 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1335 /* User typed CTRL-C. Continue with this status. */
1336 last_sig
= SIGINT
; /* FIXME - should check pass state. */
1338 case EXCEPTION_SINGLE_STEP
:
1339 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
1340 (unsigned) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
1341 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1343 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1344 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
1345 /* (unsigned)? */ current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
1346 ourstatus
->value
.sig
= check_for_step (¤t_event
,
1350 /* This may be a structured exception handling exception. In
1351 that case, we want to let the program try to handle it, and
1352 only break if we see the exception a second time. */
1355 ("gdb: unknown target exception 0x%08x at 0x%08x\n",
1356 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1357 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1358 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1365 /* Resume all artificially suspended threads if we are continuing
1368 child_continue (DWORD continue_status
, int id
)
1374 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
1375 (unsigned) current_event
.dwProcessId
,
1376 (unsigned) current_event
.dwThreadId
));
1377 res
= continue_debug_event (current_event
.dwProcessId
,
1378 current_event
.dwThreadId
,
1381 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1382 if (((id
== -1) || (id
== th
->id
)) && th
->suspend_count
)
1384 for (i
= 0; i
< th
->suspend_count
; i
++)
1385 (void) resume_thread (th
->h
);
1386 th
->suspend_count
= 0;
1392 /* Get the next event from the child. Return 1 if the event requires
1393 handling by WFI (or whatever).
1396 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
,
1397 DWORD target_event_code
, int *retval
)
1401 DWORD continue_status
, event_code
;
1402 thread_info
*th
= NULL
;
1403 static thread_info dummy_thread_info
;
1405 if (!(debug_event
= wait_for_debug_event (¤t_event
, 1000)))
1412 continue_status
= DBG_CONTINUE
;
1415 event_code
= current_event
.dwDebugEventCode
;
1416 breakout
= event_code
== target_event_code
;
1420 case CREATE_THREAD_DEBUG_EVENT
:
1421 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1422 (unsigned) current_event
.dwProcessId
,
1423 (unsigned) current_event
.dwThreadId
,
1424 "CREATE_THREAD_DEBUG_EVENT"));
1425 /* Record the existence of this thread */
1426 th
= child_add_thread (current_event
.dwThreadId
,
1427 current_event
.u
.CreateThread
.hThread
);
1429 printf_unfiltered ("[New %s]\n",
1430 target_pid_to_str (current_event
.dwThreadId
));
1433 case EXIT_THREAD_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 "EXIT_THREAD_DEBUG_EVENT"));
1438 child_delete_thread (current_event
.dwThreadId
);
1439 th
= &dummy_thread_info
;
1442 case CREATE_PROCESS_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 "CREATE_PROCESS_DEBUG_EVENT"));
1447 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1449 main_thread_id
= current_event
.dwThreadId
;
1450 inferior_ptid
= pid_to_ptid (main_thread_id
);
1451 /* Add the main thread */
1452 th
= child_add_thread (PIDGET (inferior_ptid
),
1453 current_event
.u
.CreateProcessInfo
.hThread
);
1456 case EXIT_PROCESS_DEBUG_EVENT
:
1457 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1458 (unsigned) current_event
.dwProcessId
,
1459 (unsigned) current_event
.dwThreadId
,
1460 "EXIT_PROCESS_DEBUG_EVENT"));
1461 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1462 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1463 close_handle (current_process_handle
);
1464 *retval
= current_event
.dwProcessId
;
1468 case LOAD_DLL_DEBUG_EVENT
:
1469 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1470 (unsigned) current_event
.dwProcessId
,
1471 (unsigned) current_event
.dwThreadId
,
1472 "LOAD_DLL_DEBUG_EVENT"));
1473 catch_errors (handle_load_dll
, NULL
,
1474 (char *) "", RETURN_MASK_ALL
);
1475 registers_changed (); /* mark all regs invalid */
1478 case UNLOAD_DLL_DEBUG_EVENT
:
1479 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1480 (unsigned) current_event
.dwProcessId
,
1481 (unsigned) current_event
.dwThreadId
,
1482 "UNLOAD_DLL_DEBUG_EVENT"));
1483 break; /* FIXME: don't know what to do here */
1485 case EXCEPTION_DEBUG_EVENT
:
1486 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1487 (unsigned) current_event
.dwProcessId
,
1488 (unsigned) current_event
.dwThreadId
,
1489 "EXCEPTION_DEBUG_EVENT"));
1490 if (handle_exception (ourstatus
))
1491 *retval
= current_event
.dwThreadId
;
1494 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1499 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1500 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1501 (unsigned) current_event
.dwProcessId
,
1502 (unsigned) current_event
.dwThreadId
,
1503 "OUTPUT_DEBUG_STRING_EVENT"));
1504 handle_output_debug_string ( ourstatus
);
1507 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
1508 current_event
.dwProcessId
,
1509 current_event
.dwThreadId
);
1510 printf_unfiltered (" unknown event code %d\n",
1511 current_event
.dwDebugEventCode
);
1516 this_thread
= current_thread
= th
?: thread_rec (current_event
.dwThreadId
,
1519 CHECK (child_continue (continue_status
, -1));
1525 /* Wait for interesting events to occur in the target process. */
1527 child_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1531 int pid
= PIDGET (ptid
);
1533 /* We loop when we get a non-standard exception rather than return
1534 with a SPURIOUS because resume can try and step or modify things,
1535 which needs a current_thread->h. But some of these exceptions mark
1536 the birth or death of threads, which mean that the current thread
1537 isn't necessarily what you think it is. */
1540 if (get_child_debug_event (pid
, ourstatus
,
1541 EXCEPTION_DEBUG_EVENT
, &retval
))
1542 return pid_to_ptid (retval
);
1547 if (deprecated_ui_loop_hook
!= NULL
)
1548 detach
= deprecated_ui_loop_hook (0);
1551 child_kill_inferior ();
1555 /* Print status information about what we're accessing. */
1558 child_files_info (struct target_ops
*ignore
)
1560 printf_unfiltered ("\tUsing the running image of child %s.\n",
1561 target_pid_to_str (inferior_ptid
));
1565 child_open (char *arg
, int from_tty
)
1567 error (_("Use the \"run\" command to start a child process."));
1570 #define FACTOR (0x19db1ded53ea710LL)
1571 #define NSPERSEC 10000000
1573 /* Convert a Win32 time to "UNIX" format. */
1575 to_time_t (FILETIME
* ptr
)
1577 /* A file time is the number of 100ns since jan 1 1601
1578 stuffed into two long words.
1579 A time_t is the number of seconds since jan 1 1970. */
1582 long long x
= ((long long) ptr
->dwHighDateTime
<< 32) + ((unsigned) ptr
->dwLowDateTime
);
1583 x
-= FACTOR
; /* Number of 100ns between 1601 and 1970. */
1584 rem
= x
% ((long long) NSPERSEC
);
1585 rem
+= (NSPERSEC
/ 2);
1586 x
/= (long long) NSPERSEC
; /* Number of 100ns in a second. */
1587 x
+= (long long) (rem
/ NSPERSEC
);
1591 /* Upload a file to the remote device depending on the user's
1592 'set remoteupload' specification. */
1594 upload_to_device (const char *to
, const char *from
)
1597 const char *dir
= remote_directory
?: "\\gdb";
1599 static char *remotefile
= NULL
;
1603 const char *in_to
= to
;
1604 FILETIME crtime
, actime
, wrtime
;
1609 /* Look for a path separator and only use trailing part. */
1610 while ((p
= strpbrk (to
, "/\\")) != NULL
)
1614 error (_("no filename found to upload - %s."), in_to
);
1616 len
= strlen (dir
) + strlen (to
) + 2;
1617 remotefile
= (char *) xrealloc (remotefile
, len
);
1618 strcpy (remotefile
, dir
);
1619 strcat (remotefile
, "\\");
1620 strcat (remotefile
, to
);
1622 if (upload_when
== UPLOAD_NEVER
)
1623 return remotefile
; /* Don't bother uploading. */
1625 /* Open the source. */
1626 if ((fd
= openp (getenv ("PATH"), OPF_TRY_CWD_FIRST
, (char *) from
,
1627 O_RDONLY
, 0, NULL
)) < 0)
1628 error (_("couldn't open %s"), from
);
1630 /* Get the time for later comparison. */
1631 if (fstat (fd
, &st
))
1632 st
.st_mtime
= (time_t) - 1;
1634 /* Always attempt to create the directory on the remote system. */
1635 wstr
= towide (dir
, NULL
);
1636 (void) CeCreateDirectory (wstr
, NULL
);
1638 /* Attempt to open the remote file, creating it if it doesn't exist. */
1639 wstr
= towide (remotefile
, NULL
);
1640 h
= CeCreateFile (wstr
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
1641 OPEN_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1643 /* Some kind of problem? */
1644 err
= CeGetLastError ();
1645 if (h
== NULL
|| h
== INVALID_HANDLE_VALUE
)
1646 error (_("error opening file \"%s\". Windows error %d."),
1649 CeGetFileTime (h
, &crtime
, &actime
, &wrtime
);
1650 utime
= to_time_t (&wrtime
);
1652 if (utime
< st
.st_mtime
)
1655 strcpy (buf
, ctime(&utime
));
1656 printf ("%s < %s\n", buf
, ctime(&st
.st_mtime
));
1659 /* See if we need to upload the file. */
1660 if (upload_when
== UPLOAD_ALWAYS
||
1661 err
!= ERROR_ALREADY_EXISTS
||
1662 !CeGetFileTime (h
, &crtime
, &actime
, &wrtime
) ||
1663 to_time_t (&wrtime
) < st
.st_mtime
)
1669 /* Upload the file. */
1670 while ((n
= read (fd
, buf
, sizeof (buf
))) > 0)
1671 if (!CeWriteFile (h
, buf
, (DWORD
) n
, &nbytes
, NULL
))
1672 error (_("error writing to remote device - %d."),
1677 if (!CeCloseHandle (h
))
1678 error (_("error closing remote file - %d."), CeGetLastError ());
1683 /* Initialize the connection to the remote device. */
1685 wince_initialize (void)
1690 struct sockaddr_in sin
;
1691 char *stub_file_name
;
1693 PROCESS_INFORMATION pi
;
1695 if (!connection_initialized
)
1696 switch (CeRapiInit ())
1699 connection_initialized
= 1;
1703 error (_("Can't initialize connection to remote device."));
1706 /* Upload the stub to the handheld device. */
1707 stub_file_name
= upload_to_device ("wince-stub.exe", WINCE_STUB
);
1708 strcpy (args
, stub_file_name
);
1710 if (remote_add_host
)
1713 hostname
= strchr (args
, '\0');
1714 if (gethostname (hostname
, sizeof (args
) - strlen (args
)))
1715 error (_("couldn't get hostname of this system."));
1719 if ((s0
= socket (AF_INET
, SOCK_STREAM
, 0)) < 0)
1720 stub_error ("Couldn't connect to host system.");
1722 /* Allow rapid reuse of the port. */
1724 (void) setsockopt (s0
, SOL_SOCKET
, SO_REUSEADDR
,
1725 (char *) &tmp
, sizeof (tmp
));
1728 /* Set up the information for connecting to the host gdb process. */
1729 memset (&sin
, 0, sizeof (sin
));
1730 sin
.sin_family
= AF_INET
;
1731 sin
.sin_port
= htons (7000); /* FIXME: This should be configurable. */
1733 if (bind (s0
, (struct sockaddr
*) &sin
, sizeof (sin
)))
1734 error (_("couldn't bind socket"));
1737 error (_("Couldn't open socket for listening."));
1739 /* Start up the stub on the remote device. */
1740 if (!CeCreateProcess (towide (stub_file_name
, NULL
),
1741 towide (args
, NULL
),
1743 NULL
, NULL
, NULL
, &pi
))
1744 error (_("Unable to start remote stub '%s'. Windows CE error %d."),
1745 stub_file_name
, CeGetLastError ());
1747 /* Wait for a connection */
1749 if ((s
= accept (s0
, NULL
, NULL
)) < 0)
1750 error (_("couldn't set up server for connection."));
1755 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1756 EXEC_FILE is the file to run.
1757 ALLARGS is a string containing the arguments to the program.
1758 ENV is the environment vector to pass.
1759 Errors reported with error(). */
1761 child_create_inferior (char *exec_file
, char *args
, char **env
,
1764 PROCESS_INFORMATION pi
;
1765 struct target_waitstatus dummy
;
1767 DWORD flags
, event_code
;
1768 char *exec_and_args
;
1771 error (_("No executable specified, use `target exec'."));
1773 flags
= DEBUG_PROCESS
;
1775 wince_initialize (); /* Make sure we've got a connection. */
1777 exec_file
= upload_to_device (exec_file
, exec_file
);
1779 while (*args
== ' ')
1782 /* Allocate space for "command<sp>args" */
1785 exec_and_args
= alloca (strlen (exec_file
) + 1);
1786 strcpy (exec_and_args
, exec_file
);
1790 exec_and_args
= alloca (strlen (exec_file
+ strlen (args
) + 2));
1791 sprintf (exec_and_args
, "%s %s", exec_file
, args
);
1794 memset (&pi
, 0, sizeof (pi
));
1795 /* Execute the process. */
1796 if (!create_process (exec_file
, exec_and_args
, flags
, &pi
))
1797 error (_("Error creating process %s, (error %d)."),
1798 exec_file
, GetLastError ());
1800 exception_count
= 0;
1803 current_process_handle
= pi
.hProcess
;
1804 current_event
.dwProcessId
= pi
.dwProcessId
;
1805 memset (¤t_event
, 0, sizeof (current_event
));
1806 current_event
.dwThreadId
= pi
.dwThreadId
;
1807 inferior_ptid
= pid_to_ptid (current_event
.dwThreadId
);
1808 push_target (&deprecated_child_ops
);
1809 child_init_thread_list ();
1810 child_add_thread (pi
.dwThreadId
, pi
.hThread
);
1811 init_wait_for_inferior ();
1812 clear_proceed_status ();
1813 target_terminal_init ();
1814 target_terminal_inferior ();
1816 /* Run until process and threads are loaded */
1817 while (!get_child_debug_event (PIDGET (inferior_ptid
), &dummy
,
1818 CREATE_PROCESS_DEBUG_EVENT
, &ret
))
1822 /* Chile has gone bye-bye. */
1824 child_mourn_inferior (void)
1826 (void) child_continue (DBG_CONTINUE
, -1);
1827 unpush_target (&deprecated_child_ops
);
1830 connection_initialized
= 0;
1831 generic_mourn_inferior ();
1834 /* Move memory from child to/from gdb. */
1836 child_xfer_memory (CORE_ADDR memaddr
, gdb_byte
*our
,
1838 struct mem_attrib
*attrib
,
1839 struct target_ops
*target
)
1845 res
= remote_write_bytes (memaddr
, our
, len
);
1847 res
= remote_read_bytes (memaddr
, our
, len
);
1852 /* Terminate the process and wait for child to tell us it has
1855 child_kill_inferior (void)
1857 CHECK (terminate_process (current_process_handle
));
1861 if (!child_continue (DBG_CONTINUE
, -1))
1863 if (!wait_for_debug_event (¤t_event
, INFINITE
))
1865 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1869 CHECK (close_handle (current_process_handle
));
1870 close_handle (current_thread
->h
);
1871 target_mourn_inferior (); /* or just child_mourn_inferior? */
1874 /* Resume the child after an exception. */
1876 child_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1879 DWORD continue_status
= last_sig
> 0 && last_sig
< NSIG
?
1880 DBG_EXCEPTION_NOT_HANDLED
: DBG_CONTINUE
;
1881 int pid
= PIDGET (ptid
);
1883 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1886 /* Get context for currently selected thread */
1887 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1889 if (th
->context
.ContextFlags
)
1891 CHECK (set_thread_context (th
->h
, &th
->context
));
1892 th
->context
.ContextFlags
= 0;
1895 /* Allow continuing with the same signal that interrupted us.
1896 Otherwise complain. */
1897 if (sig
&& sig
!= last_sig
)
1898 fprintf_unfiltered (gdb_stderr
,
1899 "Can't send signals to the child. signal %d\n",
1903 child_continue (continue_status
, pid
);
1907 child_prepare_to_store (void)
1909 /* Do nothing, since we can store individual regs */
1913 child_can_run (void)
1921 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1922 PIDGET (inferior_ptid
)));
1925 /* Explicitly upload file to remotedir */
1928 child_load (char *file
, int from_tty
)
1930 upload_to_device (file
, file
);
1934 init_child_ops (void)
1936 memset (&deprecated_child_ops
, 0, sizeof (deprecated_child_ops
));
1937 deprecated_child_ops
.to_shortname
= (char *) "child";
1938 deprecated_child_ops
.to_longname
= (char *) "Windows CE process";
1939 deprecated_child_ops
.to_doc
= (char *) "Windows CE process (started by the \"run\" command).";
1940 deprecated_child_ops
.to_open
= child_open
;
1941 deprecated_child_ops
.to_close
= child_close
;
1942 deprecated_child_ops
.to_resume
= child_resume
;
1943 deprecated_child_ops
.to_wait
= child_wait
;
1944 deprecated_child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
1945 deprecated_child_ops
.to_store_registers
= child_store_inferior_registers
;
1946 deprecated_child_ops
.to_prepare_to_store
= child_prepare_to_store
;
1947 deprecated_child_ops
.deprecated_xfer_memory
= child_xfer_memory
;
1948 deprecated_child_ops
.to_files_info
= child_files_info
;
1949 deprecated_child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1950 deprecated_child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1951 deprecated_child_ops
.to_terminal_init
= terminal_init_inferior
;
1952 deprecated_child_ops
.to_terminal_inferior
= terminal_inferior
;
1953 deprecated_child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1954 deprecated_child_ops
.to_terminal_ours
= terminal_ours
;
1955 deprecated_child_ops
.to_terminal_save_ours
= terminal_save_ours
;
1956 deprecated_child_ops
.to_terminal_info
= child_terminal_info
;
1957 deprecated_child_ops
.to_kill
= child_kill_inferior
;
1958 deprecated_child_ops
.to_load
= child_load
;
1959 deprecated_child_ops
.to_create_inferior
= child_create_inferior
;
1960 deprecated_child_ops
.to_mourn_inferior
= child_mourn_inferior
;
1961 deprecated_child_ops
.to_can_run
= child_can_run
;
1962 deprecated_child_ops
.to_thread_alive
= win32_child_thread_alive
;
1963 deprecated_child_ops
.to_stratum
= process_stratum
;
1964 deprecated_child_ops
.to_has_all_memory
= 1;
1965 deprecated_child_ops
.to_has_memory
= 1;
1966 deprecated_child_ops
.to_has_stack
= 1;
1967 deprecated_child_ops
.to_has_registers
= 1;
1968 deprecated_child_ops
.to_has_execution
= 1;
1969 deprecated_child_ops
.to_magic
= OPS_MAGIC
;
1973 /* Handle 'set remoteupload' parameter. */
1975 #define replace_upload(what) \
1976 upload_when = what; \
1977 remote_upload = xrealloc (remote_upload, \
1978 strlen (upload_options[upload_when].name) + 1); \
1979 strcpy (remote_upload, upload_options[upload_when].name);
1982 set_upload_type (char *ignore
, int from_tty
)
1987 if (!remote_upload
|| !remote_upload
[0])
1989 replace_upload (UPLOAD_NEWER
);
1991 printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1995 len
= strlen (remote_upload
);
1997 i
< (sizeof (upload_options
) / sizeof (upload_options
[0]));
1999 if (len
>= upload_options
[i
].abbrev
&&
2000 strncasecmp (remote_upload
, upload_options
[i
].name
, len
) == 0)
2006 bad_option
= remote_upload
;
2007 replace_upload (UPLOAD_NEWER
);
2008 error (_("Unknown upload type: %s."), bad_option
);
2012 _initialize_wince (void)
2014 struct cmd_list_element
*set
;
2017 add_setshow_string_noescape_cmd ("remotedirectory", no_class
,
2018 &remote_directory
, _("\
2019 Set directory for remote upload."), _("\
2020 Show directory for remote upload."), NULL
,
2021 NULL
, /* FIXME: i18n: */
2023 &setlist
, &showlist
);
2024 remote_directory
= xstrdup (remote_directory
);
2026 add_setshow_string_noescape_cmd ("remoteupload", no_class
,
2027 &remote_upload
, _("\
2028 Set how to upload executables to remote device."), _("\
2029 Show how to upload executables to remote device."), NULL
,
2030 NULL
, /* FIXME: i18n: */
2031 set_upload_type
, NULL
,
2032 &setlist
, &showlist
);
2033 set_upload_type (NULL
, 0);
2035 add_setshow_boolean_cmd ("debugexec", class_support
, &debug_exec
, _("\
2036 Set whether to display execution in child process."), _("\
2037 Show whether to display execution in child process."), NULL
,
2039 NULL
, /* FIXME: i18n: */
2040 &setlist
, &showlist
);
2042 add_setshow_boolean_cmd ("remoteaddhost", class_support
,
2043 &remote_add_host
, _("\
2044 Set whether to add this host to remote stub arguments for\n\
2045 debugging over a network."), _("\
2046 Show whether to add this host to remote stub arguments for\n\
2047 debugging over a network."), NULL
,
2049 NULL
, /* FIXME: i18n: */
2050 &setlist
, &showlist
);
2052 add_setshow_boolean_cmd ("debugevents", class_support
, &debug_events
, _("\
2053 Set whether to display kernel events in child process."), _("\
2054 Show whether to display kernel events in child process."), NULL
,
2056 NULL
, /* FIXME: i18n: */
2057 &setlist
, &showlist
);
2059 add_setshow_boolean_cmd ("debugmemory", class_support
, &debug_memory
, _("\
2060 Set whether to display memory accesses in child process."), _("\
2061 Show whether to display memory accesses in child process."), NULL
,
2063 NULL
, /* FIXME: i18n: */
2064 &setlist
, &showlist
);
2066 add_setshow_boolean_cmd ("debugexceptions", class_support
,
2067 &debug_exceptions
, _("\
2068 Set whether to display kernel exceptions in child process."), _("\
2069 Show whether to display kernel exceptions in child process."), NULL
,
2071 NULL
, /* FIXME: i18n: */
2072 &setlist
, &showlist
);
2074 add_target (&deprecated_child_ops
);
2077 /* Determine if the thread referenced by "pid" is alive by "polling"
2078 it. If WaitForSingleObject returns WAIT_OBJECT_0 it means that the
2079 pid has died. Otherwise it is assumed to be alive. */
2081 win32_child_thread_alive (ptid_t ptid
)
2083 int pid
= PIDGET (ptid
);
2084 return thread_alive (thread_rec (pid
, FALSE
)->h
);
2087 /* Convert pid to printable format. */
2089 cygwin_pid_to_str (int pid
)
2091 static char buf
[80];
2092 if (pid
== current_event
.dwProcessId
)
2093 sprintf (buf
, "process %d", pid
);
2095 sprintf (buf
, "thread %d.0x%x",
2096 (unsigned) current_event
.dwProcessId
, pid
);