2004-10-05 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / wince.c
1 /* Target-vector operations for controlling Windows CE child processes, for GDB.
2
3 Copyright 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions, A Red Hat Company.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22 */
23
24 /* by Christopher Faylor (cgf@cygnus.com) */
25
26 /* We assume we're being built with and will be used for cygwin. */
27
28 #ifdef SHx
29 #undef SH4
30 #define SH4 /* Just to get all of the CONTEXT defines. */
31 #endif
32
33 #include "defs.h"
34 #include "frame.h" /* required by inferior.h */
35 #include "inferior.h"
36 #include "target.h"
37 #include "gdbcore.h"
38 #include "command.h"
39 #include <signal.h>
40 #include <sys/types.h>
41 #include <fcntl.h>
42 #include <stdlib.h>
43
44 #include <windows.h>
45 #include <rapi.h>
46 #include <netdb.h>
47 #include <cygwin/in.h>
48 #include <cygwin/socket.h>
49
50 #include "buildsym.h"
51 #include "symfile.h"
52 #include "objfiles.h"
53 #include "gdb_string.h"
54 #include "gdbthread.h"
55 #include "gdbcmd.h"
56 #include <sys/param.h>
57 #include "wince-stub.h"
58 #include <time.h>
59 #include "regcache.h"
60 #ifdef MIPS
61 #include "mips-tdep.h"
62 #endif
63
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)
71 #else
72 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
73 #endif
74 #endif
75
76 #ifdef SH4
77 #define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
78 #else
79 #define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
80 #endif
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"
84
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
90
91 static int connection_initialized = 0; /* True if we've initialized a RAPI session. */
92
93 /* The directory where the stub and executable files are uploaded. */
94 static const char *remote_directory = "\\gdb";
95
96 /* The types automatic upload available. */
97 static enum
98 {
99 UPLOAD_ALWAYS = 0,
100 UPLOAD_NEWER = 1,
101 UPLOAD_NEVER = 2
102 }
103 upload_when = UPLOAD_NEWER;
104
105 /* Valid options for 'set remoteupload'. Note that options
106 must track upload_when enum. */
107 static struct opts
108 {
109 const char *name;
110 int abbrev;
111 }
112 upload_options[3] =
113 {
114 {
115 "always", 1
116 }
117 ,
118 {
119 "newer", 3
120 }
121 ,
122 {
123 "never", 3
124 }
125 };
126
127 static char *remote_upload = NULL; /* Set by set remoteupload */
128 static int remote_add_host = 0;
129
130 static int win32_child_thread_alive (ptid_t);
131 void child_kill_inferior (void);
132
133 static int last_sig = 0; /* Set if a signal was received from the
134 debugged process */
135
136 /* Thread information structure used to track information that is
137 not available in gdb's thread structure. */
138 typedef struct thread_info_struct
139 {
140 struct thread_info_struct *next;
141 DWORD id;
142 HANDLE h;
143 char *name;
144 int suspend_count;
145 int stepped; /* True if stepped. */
146 CORE_ADDR step_pc;
147 unsigned long step_prev;
148 CONTEXT context;
149 }
150 thread_info;
151
152 static thread_info thread_head =
153 {NULL};
154 static thread_info * thread_rec (DWORD id, int get_context);
155
156 /* The process and thread handles for the above context. */
157
158 static DEBUG_EVENT current_event; /* The current debug event from
159 WaitForDebugEvent */
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 */
164
165 /* Counts of things. */
166 static int exception_count = 0;
167 static int event_count = 0;
168
169 /* User options. */
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 */
174
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
181 register.
182
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] =
186 {
187 #ifdef __i386__
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]),
212 #elif defined(SHx)
213 context_offset (R0),
214 context_offset (R1),
215 context_offset (R2),
216 context_offset (R3),
217 context_offset (R4),
218 context_offset (R5),
219 context_offset (R6),
220 context_offset (R7),
221 context_offset (R8),
222 context_offset (R9),
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]),
269 #elif defined(MIPS)
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),
305 -1, /* bad */
306 -1, /* cause */
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),
342 -1, /* fp */
343 #elif defined(ARM)
344 context_offset (R0),
345 context_offset (R1),
346 context_offset (R2),
347 context_offset (R3),
348 context_offset (R4),
349 context_offset (R5),
350 context_offset (R6),
351 context_offset (R7),
352 context_offset (R8),
353 context_offset (R9),
354 context_offset (R10),
355 context_offset (R11),
356 context_offset (R12),
357 context_offset (Sp),
358 context_offset (Lr),
359 context_offset (Pc),
360 -1,
361 -1,
362 -1,
363 -1,
364 -1,
365 -1,
366 -1,
367 -1,
368 -1,
369 context_offset (Psr),
370 #endif
371 -1
372 };
373
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.
377 */
378 static ULONG *
379 regptr (LPCONTEXT c, int r)
380 {
381 static ULONG zero = 0;
382 ULONG *p;
383 if (mappings[r] < 0)
384 p = &zero;
385 else
386 p = (ULONG *) (((char *) c) + mappings[r]);
387 return p;
388 }
389
390 /******************** Beginning of stub interface ********************/
391
392 /* Stub interface description:
393
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
396 using packets where:
397
398 byte 0: command id (e.g. Create Process)
399
400 byte 1-4: DWORD
401
402 byte 1-2: WORD
403
404 byte 1-2: length
405 byte 3-n: arbitrary memory.
406
407 The interface is deterministic, i.e., if the stub expects a DWORD then
408 the gdb server should send a DWORD.
409 */
410
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.
414
415 The 'what' parameter is a command id as found in wince-stub.h.
416
417 Hopefully, the rest of the parameters are self-explanatory.
418 */
419
420 static int s; /* communication socket */
421
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
424 on OK. */
425 static void
426 vstub_error (LPCSTR fmt, va_list * args)
427 {
428 char buf[4096];
429 vsprintf (buf, fmt, args);
430 s = -1;
431 error ("%s", buf);
432 }
433
434 /* The standard way to display an error message and exit. */
435 static void
436 stub_error (LPCSTR fmt,...)
437 {
438 va_list args;
439 va_start (args, fmt);
440 vstub_error (fmt, args);
441 }
442
443 /* Standard "oh well" can't communicate error. Someday this might attempt
444 synchronization. */
445 static void
446 attempt_resync (LPCSTR huh, int s)
447 {
448 stub_error ("lost synchronization with target attempting %s", huh);
449 }
450
451 /* Read arbitrary stuff from a socket. */
452 static int
453 sockread (LPCSTR huh, int s, void *str, size_t n)
454 {
455 for (;;)
456 {
457 if (recv (s, str, n, 0) == n)
458 return n;
459 attempt_resync (huh, s);
460 }
461 }
462
463 /* Write arbitrary stuff to a socket. */
464 static int
465 sockwrite (LPCSTR huh, const void *str, size_t n)
466 {
467 for (;;)
468 {
469 if (send (s, str, n, 0) == n)
470 return n;
471 attempt_resync (huh, s);
472 }
473 }
474
475 /* Output an id/dword to the host */
476 static void
477 putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
478 {
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);
483 }
484
485 /* Output an id/word to the host */
486 static void
487 putword (LPCSTR huh, gdb_wince_id what, WORD n)
488 {
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);
493 }
494
495 /* Convenience define for outputting a "gdb_wince_len" type. */
496 #define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
497
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
500 itself. */
501 static void
502 putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
503 {
504 putlen (huh, what, len);
505 if (((short) len > 0) && sockwrite (huh, mem, len) != len)
506 stub_error ("error writing %s to host.", huh);
507 }
508
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. */
512 static DWORD
513 getdword (LPCSTR huh, gdb_wince_id what_this)
514 {
515 DWORD n;
516 gdb_wince_id what;
517 do
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);
521
522 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
523 stub_error ("error getting %s from host.", huh);
524
525 return n;
526 }
527
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
530 read it. */
531 static WORD
532 getword (LPCSTR huh, gdb_wince_id what_this)
533 {
534 WORD n;
535 gdb_wince_id what;
536 do
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);
540
541 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
542 stub_error ("error getting %s from host.", huh);
543
544 return n;
545 }
546
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))
553
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.
557 */
558 int
559 getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
560 {
561 gdb_wince_len dummy;
562 if (nbytes == NULL)
563 nbytes = &dummy;
564
565 *nbytes = getlen (huh, what);
566
567 if ((short) *nbytes < 0)
568 {
569 SetLastError (-(short) *nbytes);
570 return 0;
571 }
572
573 if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
574 stub_error ("couldn't read information from wince stub - %s", huh);
575
576 return 1;
577 }
578
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.
582 */
583 LPWSTR
584 towide (const char *s, gdb_wince_len * out_len)
585 {
586 static int n = -1;
587 static LPWSTR outs[8] =
588 {NULL /*, NULL, etc. */ };
589 gdb_wince_len dummy;
590
591 if (!out_len)
592 out_len = &dummy;
593
594 /* First determine the length required to hold the converted string. */
595 *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
596 if (!*out_len)
597 return NULL; /* The conversion failed */
598
599 if (++n >= (sizeof (outs) / sizeof (outs[0])))
600 n = 0; /* wrap */
601
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).
605 */
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);
609 return outs[n];
610 }
611
612 /******************** Emulation routines start here. ********************
613
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.
618
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
624 the stub.
625 */
626
627 static int
628 create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
629 {
630 gdb_wince_len len;
631 LPWSTR buf;
632
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);
639 }
640
641 /* Emulate TerminateProcess. Don't bother with the second argument since CE
642 ignores it.
643 */
644 static int
645 terminate_process (HANDLE h)
646 {
647 gdb_wince_result res;
648 if (s < 0)
649 return 1;
650 puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
651 return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
652 }
653
654 static int
655 wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
656 {
657 if (s < 0)
658 return 1;
659 putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
660 return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
661 }
662
663 static int
664 get_thread_context (HANDLE h, CONTEXT * c)
665 {
666 if (s < 0)
667 return 1;
668 puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
669 putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
670 return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
671 }
672
673 static int
674 set_thread_context (HANDLE h, CONTEXT * c)
675 {
676 gdb_wince_result res;
677 if (s < 0)
678 return 1;
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);
682 }
683
684 static int
685 read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
686 {
687 if (s < 0)
688 return 1;
689 puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
690 putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
691 putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
692
693 return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
694 }
695
696 static int
697 write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
698 {
699 if (s < 0)
700 return 1;
701 puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
702 putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
703 putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
704
705 return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
706 }
707
708 static int
709 remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
710 {
711 gdb_wince_len nbytes;
712 if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
713 (LPVOID) myaddr, len, &nbytes))
714 return -1;
715 return nbytes;
716 }
717
718 static int
719 remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
720 {
721 gdb_wince_len nbytes;
722 if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
723 (LPCVOID) myaddr, len, &nbytes))
724 return -1;
725 return nbytes;
726 }
727
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.
730 */
731 static int
732 thread_alive (HANDLE h)
733 {
734 gdb_wince_result res;
735 if (s < 0)
736 return 1;
737 puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
738 return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
739 }
740
741 static int
742 suspend_thread (HANDLE h)
743 {
744 if (s < 0)
745 return 1;
746 puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
747 return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
748 }
749
750 static int
751 resume_thread (HANDLE h)
752 {
753 if (s < 0)
754 return 1;
755 puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
756 return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
757 }
758
759 static int
760 continue_debug_event (DWORD pid, DWORD tid, DWORD status)
761 {
762 gdb_wince_result res;
763 if (s < 0)
764 return 0;
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);
769 }
770
771 static int
772 close_handle (HANDLE h)
773 {
774 gdb_wince_result res;
775 if (s < 0)
776 return 1;
777 puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
778 return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
779 }
780
781 /* This is not a standard Win32 interface. This function tells the stub
782 to terminate.
783 */
784 static void
785 stop_stub (void)
786 {
787 if (s < 0)
788 return;
789 (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
790 s = -1;
791 }
792
793 /******************** End of emulation routines. ********************/
794 /******************** End of stub interface ********************/
795
796 #define check_for_step(a, x) (x)
797
798 #ifdef MIPS
799 static void
800 undoSStep (thread_info * th)
801 {
802 if (th->stepped)
803 {
804 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
805 th->stepped = 0;
806 }
807 }
808
809 void
810 wince_software_single_step (enum target_signal ignore,
811 int insert_breakpoints_p)
812 {
813 unsigned long pc;
814 thread_info *th = current_thread; /* Info on currently selected thread */
815 CORE_ADDR mips_next_pc (CORE_ADDR pc);
816
817 if (!insert_breakpoints_p)
818 {
819 undoSStep (th);
820 return;
821 }
822
823 th->stepped = 1;
824 pc = read_register (PC_REGNUM);
825 th->step_pc = mips_next_pc (pc);
826 th->step_prev = 0;
827 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
828 return;
829 }
830 #elif SHx
831 /* Renesas SH architecture instruction encoding masks */
832
833 #define COND_BR_MASK 0xff00
834 #define UCOND_DBR_MASK 0xe000
835 #define UCOND_RBR_MASK 0xf0df
836 #define TRAPA_MASK 0xff00
837
838 #define COND_DISP 0x00ff
839 #define UCOND_DISP 0x0fff
840 #define UCOND_REG 0x0f00
841
842 /* Renesas SH instruction opcodes */
843
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
854
855
856 #define T_BIT_MASK 0x0001
857
858 static CORE_ADDR
859 sh_get_next_pc (CONTEXT *c)
860 {
861 short *instrMem;
862 int displacement;
863 int reg;
864 unsigned short opcode;
865
866 instrMem = (short *) c->Fir;
867
868 opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));
869
870 if ((opcode & COND_BR_MASK) == BT_INSTR)
871 {
872 if (c->Psr & T_BIT_MASK)
873 {
874 displacement = (opcode & COND_DISP) << 1;
875 if (displacement & 0x80)
876 displacement |= 0xffffff00;
877 /*
878 * Remember PC points to second instr.
879 * after PC of branch ... so add 4
880 */
881 instrMem = (short *) (c->Fir + displacement + 4);
882 }
883 else
884 instrMem += 1;
885 }
886 else if ((opcode & COND_BR_MASK) == BF_INSTR)
887 {
888 if (c->Psr & T_BIT_MASK)
889 instrMem += 1;
890 else
891 {
892 displacement = (opcode & COND_DISP) << 1;
893 if (displacement & 0x80)
894 displacement |= 0xffffff00;
895 /*
896 * Remember PC points to second instr.
897 * after PC of branch ... so add 4
898 */
899 instrMem = (short *) (c->Fir + displacement + 4);
900 }
901 }
902 else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
903 {
904 displacement = (opcode & UCOND_DISP) << 1;
905 if (displacement & 0x0800)
906 displacement |= 0xfffff000;
907
908 /*
909 * Remember PC points to second instr.
910 * after PC of branch ... so add 4
911 */
912 instrMem = (short *) (c->Fir + displacement + 4);
913 }
914 else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
915 {
916 reg = (char) ((opcode & UCOND_REG) >> 8);
917
918 instrMem = (short *) *regptr (c, reg);
919 }
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);
926 else
927 instrMem += 1;
928
929 return (CORE_ADDR) instrMem;
930 }
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.
934 */
935 static void
936 undoSStep (thread_info * th)
937 {
938 if (th->stepped)
939 {
940 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
941 th->stepped = 0;
942 }
943 return;
944 }
945
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.
949 */
950 void
951 wince_software_single_step (enum target_signal ignore,
952 int insert_breakpoints_p)
953 {
954 thread_info *th = current_thread; /* Info on currently selected thread */
955
956 if (!insert_breakpoints_p)
957 {
958 undoSStep (th);
959 return;
960 }
961
962 th->stepped = 1;
963 th->step_pc = sh_get_next_pc (&th->context);
964 th->step_prev = 0;
965 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
966 return;
967 }
968 #elif defined (ARM)
969 #undef check_for_step
970
971 static enum target_signal
972 check_for_step (DEBUG_EVENT *ev, enum target_signal x)
973 {
974 thread_info *th = thread_rec (ev->dwThreadId, 1);
975
976 if (th->stepped &&
977 th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
978 return TARGET_SIGNAL_TRAP;
979 else
980 return x;
981 }
982
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.
986 */
987 static void
988 undoSStep (thread_info * th)
989 {
990 if (th->stepped)
991 {
992 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
993 th->stepped = 0;
994 }
995 }
996
997 void
998 wince_software_single_step (enum target_signal ignore,
999 int insert_breakpoints_p)
1000 {
1001 unsigned long pc;
1002 thread_info *th = current_thread; /* Info on currently selected thread */
1003 CORE_ADDR mips_next_pc (CORE_ADDR pc);
1004
1005 if (!insert_breakpoints_p)
1006 {
1007 undoSStep (th);
1008 return;
1009 }
1010
1011 th->stepped = 1;
1012 pc = read_register (PC_REGNUM);
1013 th->step_pc = arm_get_next_pc (pc);
1014 th->step_prev = 0;
1015 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1016 return;
1017 }
1018 #endif
1019
1020 /* Find a thread record given a thread id.
1021 If get_context then also retrieve the context for this
1022 thread. */
1023 static thread_info *
1024 thread_rec (DWORD id, int get_context)
1025 {
1026 thread_info *th;
1027
1028 for (th = &thread_head; (th = th->next) != NULL;)
1029 if (th->id == id)
1030 {
1031 if (!th->suspend_count && get_context)
1032 {
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;
1037
1038 th->context.ContextFlags = CONTEXT_DEBUGGER;
1039 get_thread_context (th->h, &th->context);
1040 }
1041 return th;
1042 }
1043
1044 return NULL;
1045 }
1046
1047 /* Add a thread to the thread list */
1048 static thread_info *
1049 child_add_thread (DWORD id, HANDLE h)
1050 {
1051 thread_info *th;
1052
1053 if ((th = thread_rec (id, FALSE)))
1054 return th;
1055
1056 th = (thread_info *) xmalloc (sizeof (*th));
1057 memset (th, 0, sizeof (*th));
1058 th->id = id;
1059 th->h = h;
1060 th->next = thread_head.next;
1061 thread_head.next = th;
1062 add_thread (id);
1063 return th;
1064 }
1065
1066 /* Clear out any old thread list and reintialize it to a
1067 pristine state. */
1068 static void
1069 child_init_thread_list (void)
1070 {
1071 thread_info *th = &thread_head;
1072
1073 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
1074 init_thread_list ();
1075 while (th->next != NULL)
1076 {
1077 thread_info *here = th->next;
1078 th->next = here->next;
1079 (void) close_handle (here->h);
1080 xfree (here);
1081 }
1082 }
1083
1084 /* Delete a thread from the list of threads */
1085 static void
1086 child_delete_thread (DWORD id)
1087 {
1088 thread_info *th;
1089
1090 if (info_verbose)
1091 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
1092 delete_thread (id);
1093
1094 for (th = &thread_head;
1095 th->next != NULL && th->next->id != id;
1096 th = th->next)
1097 continue;
1098
1099 if (th->next != NULL)
1100 {
1101 thread_info *here = th->next;
1102 th->next = here->next;
1103 close_handle (here->h);
1104 xfree (here);
1105 }
1106 }
1107
1108 static void
1109 check (BOOL ok, const char *file, int line)
1110 {
1111 if (!ok)
1112 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
1113 }
1114
1115 static void
1116 do_child_fetch_inferior_registers (int r)
1117 {
1118 if (r >= 0)
1119 {
1120 regcache_raw_supply (current_regcache, r,
1121 (char *) regptr (&current_thread->context, r));
1122 }
1123 else
1124 {
1125 for (r = 0; r < NUM_REGS; r++)
1126 do_child_fetch_inferior_registers (r);
1127 }
1128 }
1129
1130 static void
1131 child_fetch_inferior_registers (int r)
1132 {
1133 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
1134 do_child_fetch_inferior_registers (r);
1135 }
1136
1137 static void
1138 do_child_store_inferior_registers (int r)
1139 {
1140 if (r >= 0)
1141 deprecated_read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
1142 else
1143 {
1144 for (r = 0; r < NUM_REGS; r++)
1145 do_child_store_inferior_registers (r);
1146 }
1147 }
1148
1149 /* Store a new register value into the current thread context */
1150 static void
1151 child_store_inferior_registers (int r)
1152 {
1153 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
1154 do_child_store_inferior_registers (r);
1155 }
1156
1157 /* Wait for child to do something. Return pid of child, or -1 in case
1158 of error; store status through argument pointer OURSTATUS. */
1159
1160 static int
1161 handle_load_dll (void *dummy)
1162 {
1163 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1164 char dll_buf[MAX_PATH + 1];
1165 char *p, *bufp, *imgp, *dll_name, *dll_basename;
1166 int len;
1167
1168 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1169 if (!event->lpImageName)
1170 return 1;
1171
1172 len = 0;
1173 for (bufp = dll_buf, imgp = event->lpImageName;
1174 bufp < dll_buf + sizeof (dll_buf);
1175 bufp += 16, imgp += 16)
1176 {
1177 gdb_wince_len nbytes = 0;
1178 (void) read_process_memory (current_process_handle,
1179 imgp, bufp, 16, &nbytes);
1180
1181 if (!nbytes && bufp == dll_buf)
1182 return 1; /* couldn't read it */
1183 for (p = bufp; p < bufp + nbytes; p++)
1184 {
1185 len++;
1186 if (*p == '\0')
1187 goto out;
1188 if (event->fUnicode)
1189 p++;
1190 }
1191 if (!nbytes)
1192 break;
1193 }
1194
1195 out:
1196 if (!len)
1197 return 1;
1198 #if 0
1199 dll_buf[len] = '\0';
1200 #endif
1201 dll_name = alloca (len);
1202
1203 if (!dll_name)
1204 return 1;
1205
1206 if (!event->fUnicode)
1207 memcpy (dll_name, dll_buf, len);
1208 else
1209 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len,
1210 dll_name, len, 0, 0);
1211
1212 while ((p = strchr (dll_name, '\\')))
1213 *p = '/';
1214
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. */
1217
1218 if (!(dll_basename = strrchr (dll_name, '/')))
1219 dll_basename = dll_name;
1220 else
1221 dll_basename++;
1222
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.
1226
1227 FIXME: Is this the real reason that we need the 0x1000 ? */
1228
1229 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
1230 printf_unfiltered ("\n");
1231
1232 return 1;
1233 }
1234
1235 /* Handle DEBUG_STRING output from child process. */
1236 static void
1237 handle_output_debug_string (struct target_waitstatus *ourstatus)
1238 {
1239 char p[256];
1240 char s[255];
1241 char *q;
1242 gdb_wince_len nbytes_read;
1243 gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;
1244
1245 if (nbytes > 255)
1246 nbytes = 255;
1247
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)
1252 || !*p)
1253 return;
1254
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');
1259 if (q != NULL)
1260 {
1261 *q = '\0';
1262 if (*--q = '\r')
1263 *q = '\0';
1264 }
1265
1266 warning (s);
1267
1268 return;
1269 }
1270
1271 /* Handle target exceptions. */
1272 static int
1273 handle_exception (struct target_waitstatus *ourstatus)
1274 {
1275 #if 0
1276 if (current_event.u.Exception.dwFirstChance)
1277 return 0;
1278 #endif
1279
1280 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1281
1282 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
1283 {
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;
1288 break;
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;
1293 break;
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;
1298 break;
1299 case DBG_CONTROL_C:
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 */
1305 break;
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;
1310 break;
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 (&current_event, TARGET_SIGNAL_ILL);
1315 break;
1316 default:
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. */
1320
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;
1325 break;
1326 }
1327 exception_count++;
1328 return 1;
1329 }
1330
1331 /* Resume all artificially suspended threads if we are continuing
1332 execution */
1333 static BOOL
1334 child_continue (DWORD continue_status, int id)
1335 {
1336 int i;
1337 thread_info *th;
1338 BOOL res;
1339
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,
1344 continue_status);
1345 if (res)
1346 for (th = &thread_head; (th = th->next) != NULL;)
1347 if (((id == -1) || (id == th->id)) && th->suspend_count)
1348 {
1349 for (i = 0; i < th->suspend_count; i++)
1350 (void) resume_thread (th->h);
1351 th->suspend_count = 0;
1352 }
1353
1354 return res;
1355 }
1356
1357 /* Get the next event from the child. Return 1 if the event requires
1358 handling by WFI (or whatever).
1359 */
1360 static int
1361 get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
1362 DWORD target_event_code, int *retval)
1363 {
1364 int breakout = 0;
1365 BOOL debug_event;
1366 DWORD continue_status, event_code;
1367 thread_info *th = NULL;
1368 static thread_info dummy_thread_info;
1369
1370 if (!(debug_event = wait_for_debug_event (&current_event, 1000)))
1371 {
1372 *retval = 0;
1373 goto out;
1374 }
1375
1376 event_count++;
1377 continue_status = DBG_CONTINUE;
1378 *retval = 0;
1379
1380 event_code = current_event.dwDebugEventCode;
1381 breakout = event_code == target_event_code;
1382
1383 switch (event_code)
1384 {
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);
1393 if (info_verbose)
1394 printf_unfiltered ("[New %s]\n",
1395 target_pid_to_str (current_event.dwThreadId));
1396 break;
1397
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;
1405 break;
1406
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;
1413
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);
1419 break;
1420
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;
1430 breakout = 1;
1431 break;
1432
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 */
1440 break;
1441
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 */
1448
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;
1456 else
1457 {
1458 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1459 breakout = 0;
1460 }
1461 break;
1462
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);
1469 break;
1470 default:
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);
1476 break;
1477 }
1478
1479 if (breakout)
1480 this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1481 else
1482 CHECK (child_continue (continue_status, -1));
1483
1484 out:
1485 return breakout;
1486 }
1487
1488 /* Wait for interesting events to occur in the target process. */
1489 static ptid_t
1490 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1491 {
1492 DWORD event_code;
1493 int retval;
1494 int pid = PIDGET (ptid);
1495
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. */
1501
1502 while (1)
1503 if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
1504 return pid_to_ptid (retval);
1505 else
1506 {
1507 int detach = 0;
1508
1509 if (deprecated_ui_loop_hook != NULL)
1510 detach = deprecated_ui_loop_hook (0);
1511
1512 if (detach)
1513 child_kill_inferior ();
1514 }
1515 }
1516
1517 /* Print status information about what we're accessing. */
1518
1519 static void
1520 child_files_info (struct target_ops *ignore)
1521 {
1522 printf_unfiltered ("\tUsing the running image of child %s.\n",
1523 target_pid_to_str (inferior_ptid));
1524 }
1525
1526 static void
1527 child_open (char *arg, int from_tty)
1528 {
1529 error ("Use the \"run\" command to start a child process.");
1530 }
1531
1532 #define FACTOR (0x19db1ded53ea710LL)
1533 #define NSPERSEC 10000000
1534
1535 /* Convert a Win32 time to "UNIX" format. */
1536 long
1537 to_time_t (FILETIME * ptr)
1538 {
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. */
1542
1543 long rem;
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);
1550 return x;
1551 }
1552
1553 /* Upload a file to the remote device depending on the user's
1554 'set remoteupload' specification. */
1555 char *
1556 upload_to_device (const char *to, const char *from)
1557 {
1558 HANDLE h;
1559 const char *dir = remote_directory ?: "\\gdb";
1560 int len;
1561 static char *remotefile = NULL;
1562 LPWSTR wstr;
1563 char *p;
1564 DWORD err;
1565 const char *in_to = to;
1566 FILETIME crtime, actime, wrtime;
1567 time_t utime;
1568 struct stat st;
1569 int fd;
1570
1571 /* Look for a path separator and only use trailing part. */
1572 while ((p = strpbrk (to, "/\\")) != NULL)
1573 to = p + 1;
1574
1575 if (!*to)
1576 error ("no filename found to upload - %s.", in_to);
1577
1578 len = strlen (dir) + strlen (to) + 2;
1579 remotefile = (char *) xrealloc (remotefile, len);
1580 strcpy (remotefile, dir);
1581 strcat (remotefile, "\\");
1582 strcat (remotefile, to);
1583
1584 if (upload_when == UPLOAD_NEVER)
1585 return remotefile; /* Don't bother uploading. */
1586
1587 /* Open the source. */
1588 if ((fd = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, (char *) from, O_RDONLY,
1589 0, NULL)) < 0)
1590 error ("couldn't open %s", from);
1591
1592 /* Get the time for later comparison. */
1593 if (fstat (fd, &st))
1594 st.st_mtime = (time_t) - 1;
1595
1596 /* Always attempt to create the directory on the remote system. */
1597 wstr = towide (dir, NULL);
1598 (void) CeCreateDirectory (wstr, NULL);
1599
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);
1604
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.",
1609 remotefile, err);
1610
1611 CeGetFileTime (h, &crtime, &actime, &wrtime);
1612 utime = to_time_t (&wrtime);
1613 #if 0
1614 if (utime < st.st_mtime)
1615 {
1616 char buf[80];
1617 strcpy (buf, ctime(&utime));
1618 printf ("%s < %s\n", buf, ctime(&st.st_mtime));
1619 }
1620 #endif
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)
1626 {
1627 DWORD nbytes;
1628 char buf[4096];
1629 int n;
1630
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.",
1635 CeGetLastError ());
1636 }
1637
1638 close (fd);
1639 if (!CeCloseHandle (h))
1640 error ("error closing remote file - %d.", CeGetLastError ());
1641
1642 return remotefile;
1643 }
1644
1645 /* Initialize the connection to the remote device. */
1646 static void
1647 wince_initialize (void)
1648 {
1649 int tmp;
1650 char args[256];
1651 char *hostname;
1652 struct sockaddr_in sin;
1653 char *stub_file_name;
1654 int s0;
1655 PROCESS_INFORMATION pi;
1656
1657 if (!connection_initialized)
1658 switch (CeRapiInit ())
1659 {
1660 case 0:
1661 connection_initialized = 1;
1662 break;
1663 default:
1664 CeRapiUninit ();
1665 error ("Can't initialize connection to remote device.\n");
1666 break;
1667 }
1668
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);
1672
1673 if (remote_add_host)
1674 {
1675 strcat (args, " ");
1676 hostname = strchr (args, '\0');
1677 if (gethostname (hostname, sizeof (args) - strlen (args)))
1678 error ("couldn't get hostname of this system.");
1679 }
1680
1681 /* Get a socket. */
1682 if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1683 stub_error ("Couldn't connect to host system.");
1684
1685 /* Allow rapid reuse of the port. */
1686 tmp = 1;
1687 (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1688
1689
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 */
1694
1695 if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
1696 error ("couldn't bind socket");
1697
1698 if (listen (s0, 1))
1699 error ("Couldn't open socket for listening.\n");
1700
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 ());
1706
1707 /* Wait for a connection */
1708
1709 if ((s = accept (s0, NULL, NULL)) < 0)
1710 error ("couldn't set up server for connection.");
1711
1712 close (s0);
1713 }
1714
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(). */
1719 static void
1720 child_create_inferior (char *exec_file, char *args, char **env,
1721 int from_tty)
1722 {
1723 PROCESS_INFORMATION pi;
1724 struct target_waitstatus dummy;
1725 int ret;
1726 DWORD flags, event_code;
1727 char *exec_and_args;
1728
1729 if (!exec_file)
1730 error ("No executable specified, use `target exec'.\n");
1731
1732 flags = DEBUG_PROCESS;
1733
1734 wince_initialize (); /* Make sure we've got a connection. */
1735
1736 exec_file = upload_to_device (exec_file, exec_file);
1737
1738 while (*args == ' ')
1739 args++;
1740
1741 /* Allocate space for "command<sp>args" */
1742 if (*args == '\0')
1743 {
1744 exec_and_args = alloca (strlen (exec_file) + 1);
1745 strcpy (exec_and_args, exec_file);
1746 }
1747 else
1748 {
1749 exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
1750 sprintf (exec_and_args, "%s %s", exec_file, args);
1751 }
1752
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 ());
1757
1758 exception_count = 0;
1759 event_count = 0;
1760
1761 current_process_handle = pi.hProcess;
1762 current_event.dwProcessId = pi.dwProcessId;
1763 memset (&current_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 ();
1773
1774 /* Run until process and threads are loaded */
1775 while (!get_child_debug_event (PIDGET (inferior_ptid), &dummy,
1776 CREATE_PROCESS_DEBUG_EVENT, &ret))
1777 continue;
1778
1779 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
1780 }
1781
1782 /* Chile has gone bye-bye. */
1783 static void
1784 child_mourn_inferior (void)
1785 {
1786 (void) child_continue (DBG_CONTINUE, -1);
1787 unpush_target (&deprecated_child_ops);
1788 stop_stub ();
1789 CeRapiUninit ();
1790 connection_initialized = 0;
1791 generic_mourn_inferior ();
1792 }
1793
1794 /* Move memory from child to/from gdb. */
1795 int
1796 child_xfer_memory (CORE_ADDR memaddr, char *our, int len, int write,
1797 struct mem_attrib *attrib,
1798 struct target_ops *target)
1799 {
1800 if (len <= 0)
1801 return 0;
1802
1803 if (write)
1804 res = remote_write_bytes (memaddr, our, len);
1805 else
1806 res = remote_read_bytes (memaddr, our, len);
1807
1808 return res;
1809 }
1810
1811 /* Terminate the process and wait for child to tell us it has completed. */
1812 void
1813 child_kill_inferior (void)
1814 {
1815 CHECK (terminate_process (current_process_handle));
1816
1817 for (;;)
1818 {
1819 if (!child_continue (DBG_CONTINUE, -1))
1820 break;
1821 if (!wait_for_debug_event (&current_event, INFINITE))
1822 break;
1823 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1824 break;
1825 }
1826
1827 CHECK (close_handle (current_process_handle));
1828 close_handle (current_thread->h);
1829 target_mourn_inferior (); /* or just child_mourn_inferior? */
1830 }
1831
1832 /* Resume the child after an exception. */
1833 void
1834 child_resume (ptid_t ptid, int step, enum target_signal sig)
1835 {
1836 thread_info *th;
1837 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1838 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1839 int pid = PIDGET (ptid);
1840
1841 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1842 pid, step, sig));
1843
1844 /* Get context for currently selected thread */
1845 th = thread_rec (current_event.dwThreadId, FALSE);
1846
1847 if (th->context.ContextFlags)
1848 {
1849 CHECK (set_thread_context (th->h, &th->context));
1850 th->context.ContextFlags = 0;
1851 }
1852
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);
1857
1858 last_sig = 0;
1859 child_continue (continue_status, pid);
1860 }
1861
1862 static void
1863 child_prepare_to_store (void)
1864 {
1865 /* Do nothing, since we can store individual regs */
1866 }
1867
1868 static int
1869 child_can_run (void)
1870 {
1871 return 1;
1872 }
1873
1874 static void
1875 child_close (void)
1876 {
1877 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1878 PIDGET (inferior_ptid)));
1879 }
1880
1881 /* Explicitly upload file to remotedir */
1882
1883 static void
1884 child_load (char *file, int from_tty)
1885 {
1886 upload_to_device (file, file);
1887 }
1888
1889 static void
1890 init_child_ops (void)
1891 {
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.to_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;
1926 }
1927
1928
1929 /* Handle 'set remoteupload' parameter. */
1930
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);
1935
1936 static void
1937 set_upload_type (char *ignore, int from_tty)
1938 {
1939 int i, len;
1940 char *bad_option;
1941
1942 if (!remote_upload || !remote_upload[0])
1943 {
1944 replace_upload (UPLOAD_NEWER);
1945 if (from_tty)
1946 printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1947 return;
1948 }
1949
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)
1954 {
1955 replace_upload (i);
1956 return;
1957 }
1958
1959 bad_option = remote_upload;
1960 replace_upload (UPLOAD_NEWER);
1961 error ("Unknown upload type: %s.", bad_option);
1962 }
1963
1964 void
1965 _initialize_wince (void)
1966 {
1967 struct cmd_list_element *set;
1968 init_child_ops ();
1969
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",
1974 &setlist),
1975 &showlist);
1976 remote_directory = xstrdup (remote_directory);
1977
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",
1981 &setlist);
1982 deprecated_add_show_from_set (set, &showlist);
1983 set_cmd_cfunc (set, set_upload_type);
1984 set_upload_type (NULL, 0);
1985
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.",
1990 &setlist),
1991 &showlist);
1992
1993 deprecated_add_show_from_set
1994 (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
1995 (char *) &remote_add_host,
1996 (char *) "\
1997 Set whether to add this host to remote stub arguments for\n\
1998 debugging over a network.", &setlist),
1999 &showlist);
2000
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.",
2005 &setlist),
2006 &showlist);
2007
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.",
2012 &setlist),
2013 &showlist);
2014
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.",
2019 &setlist),
2020 &showlist);
2021
2022 add_target (&deprecated_child_ops);
2023 }
2024
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. */
2028 static int
2029 win32_child_thread_alive (ptid_t ptid)
2030 {
2031 int pid = PIDGET (ptid);
2032 return thread_alive (thread_rec (pid, FALSE)->h);
2033 }
2034
2035 /* Convert pid to printable format. */
2036 char *
2037 cygwin_pid_to_str (int pid)
2038 {
2039 static char buf[80];
2040 if (pid == current_event.dwProcessId)
2041 sprintf (buf, "process %d", pid);
2042 else
2043 sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);
2044 return buf;
2045 }
This page took 0.102997 seconds and 5 git commands to generate.