Fix thread-extra-info name. qfThreadExtraInfo ->qThreadExtraInfo.
[deliverable/binutils-gdb.git] / gdb / wince.c
1 /* Target-vector operations for controlling Windows CE child processes, for GDB.
2 Copyright 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions, A Red Hat Company.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21 */
22
23 /* by Christopher Faylor (cgf@cygnus.com) */
24
25 /* We assume we're being built with and will be used for cygwin. */
26
27 #ifdef SHx
28 #undef SH4
29 #define SH4 /* Just to get all of the CONTEXT defines. */
30 #endif
31
32 #include "defs.h"
33 #include "frame.h" /* required by inferior.h */
34 #include "inferior.h"
35 #include "target.h"
36 #include "gdbcore.h"
37 #include "command.h"
38 #include <signal.h>
39 #include <sys/types.h>
40 #include <fcntl.h>
41 #include <stdlib.h>
42
43 #include <windows.h>
44 #include <rapi.h>
45 #include <netdb.h>
46 #include <cygwin/in.h>
47 #include <cygwin/socket.h>
48
49 #include "buildsym.h"
50 #include "symfile.h"
51 #include "objfiles.h"
52 #include "gdb_string.h"
53 #include "gdbthread.h"
54 #include "gdbcmd.h"
55 #include <sys/param.h>
56 #include "wince-stub.h"
57 #include "dcache.h"
58
59 /* The ui's event loop. */
60 extern int (*ui_loop_hook) PARAMS ((int signo));
61
62 /* If we're not using the old Cygwin header file set, define the
63 following which never should have been in the generic Win32 API
64 headers in the first place since they were our own invention... */
65 #ifndef _GNU_H_WINDOWS_H
66 #define FLAG_TRACE_BIT 0x100
67 #ifdef CONTEXT_FLOATING_POINT
68 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
69 #else
70 #define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
71 #endif
72 #endif
73
74 #ifdef SH4
75 #define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
76 #else
77 #define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
78 #endif
79 /* The string sent by cygwin when it processes a signal.
80 FIXME: This should be in a cygwin include file. */
81 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
82
83 #define CHECK(x) check (x, __FILE__,__LINE__)
84 #define DEBUG_EXEC(x) if (debug_exec) printf x
85 #define DEBUG_EVENTS(x) if (debug_events) printf x
86 #define DEBUG_MEM(x) if (debug_memory) printf x
87 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
88
89 static int connection_initialized = 0; /* True if we've initialized a RAPI session. */
90
91 static DCACHE *remote_dcache;
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 /* Forward declaration */
131 extern struct target_ops child_ops;
132
133 static int win32_child_thread_alive PARAMS ((int));
134 void child_kill_inferior PARAMS ((void));
135
136 static int last_sig = 0; /* Set if a signal was received from the
137 debugged process */
138
139 /* Thread information structure used to track information that is
140 not available in gdb's thread structure. */
141 typedef struct thread_info_struct
142 {
143 struct thread_info_struct *next;
144 DWORD id;
145 HANDLE h;
146 char *name;
147 int suspend_count;
148 int stepped; /* True if stepped. */
149 CORE_ADDR step_pc;
150 unsigned long step_instr;
151 unsigned long step_prev;
152 CONTEXT context;
153 }
154 thread_info;
155
156 static thread_info thread_head =
157 {NULL};
158
159 /* The process and thread handles for the above context. */
160
161 static DEBUG_EVENT current_event; /* The current debug event from
162 WaitForDebugEvent */
163 static HANDLE current_process_handle; /* Currently executing process */
164 static thread_info *current_thread; /* Info on currently selected thread */
165 static thread_info *this_thread; /* Info on thread returned by wait_for_debug_event */
166 static DWORD main_thread_id; /* Thread ID of the main thread */
167
168 /* Counts of things. */
169 static int exception_count = 0;
170 static int event_count = 0;
171
172 /* User options. */
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 */
177
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
184 register.
185
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] =
189 {
190 #ifdef __i386__
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]),
215 #elif defined(SHx)
216 context_offset (R0),
217 context_offset (R1),
218 context_offset (R2),
219 context_offset (R3),
220 context_offset (R4),
221 context_offset (R5),
222 context_offset (R6),
223 context_offset (R7),
224 context_offset (R8),
225 context_offset (R9),
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]),
272 #elif defined(MIPS)
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),
308 -1, /* bad */
309 -1, /* cause */
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),
345 -1, /* fp */
346 #elif defined(ARM)
347 context_offset (R0),
348 context_offset (R1),
349 context_offset (R2),
350 context_offset (R3),
351 context_offset (R4),
352 context_offset (R5),
353 context_offset (R6),
354 context_offset (R7),
355 context_offset (R8),
356 context_offset (R9),
357 context_offset (R10),
358 context_offset (R11),
359 context_offset (R12),
360 context_offset (Sp),
361 context_offset (Lr),
362 context_offset (Pc),
363 -1,
364 -1,
365 -1,
366 -1,
367 -1,
368 -1,
369 -1,
370 -1,
371 -1,
372 context_offset (Psr),
373 #endif
374 -1
375 };
376
377 /* This vector maps the target's idea of an exception (extracted
378 from the DEBUG_EVENT structure) to GDB's idea. */
379
380 struct xlate_exception
381 {
382 int them;
383 enum target_signal us;
384 };
385
386 static const struct xlate_exception
387 xlate[] =
388 {
389 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
390 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
391 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
392 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
393 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
394 {-1, -1}};
395
396 /******************** Beginning of stub interface ********************/
397
398 /* Stub interface description:
399
400 The Windows CE stub implements a crude RPC. The hand-held device
401 connects to gdb using port 7000. gdb and the stub then communicate
402 using packets where:
403
404 byte 0: command id (e.g. Create Process)
405
406 byte 1-4: DWORD
407
408 byte 1-2: WORD
409
410 byte 1-2: length
411 byte 3-n: arbitrary memory.
412
413 The interface is deterministic, i.e., if the stub expects a DWORD then
414 the gdb server should send a DWORD.
415 */
416
417 /* Note: In the functions below, the `huh' parameter is a string passed from the
418 function containing a descriptive string concerning the current operation.
419 This is used for error reporting.
420
421 The 'what' parameter is a command id as found in wince-stub.h.
422
423 Hopefully, the rest of the parameters are self-explanatory.
424 */
425
426 static int s; /* communication socket */
427
428 /* v-style interface for handling varying argyment list error messages.
429 Displays the error message in a dialog box and exits when user clicks
430 on OK. */
431 static void
432 vstub_error (LPCSTR fmt, va_list * args)
433 {
434 char buf[4096];
435 vsprintf (buf, fmt, args);
436 s = -1;
437 error ("%s", buf);
438 }
439
440 /* The standard way to display an error message and exit. */
441 static void
442 stub_error (LPCSTR fmt,...)
443 {
444 va_list args;
445 va_start (args, fmt);
446 vstub_error (fmt, args);
447 }
448
449 /* Standard "oh well" can't communicate error. Someday this might attempt
450 synchronization. */
451 static void
452 attempt_resync (LPCSTR huh, int s)
453 {
454 stub_error ("lost synchronization with target attempting %s", huh);
455 }
456
457 /* Read arbitrary stuff from a socket. */
458 static int
459 sockread (LPCSTR huh, int s, void *str, size_t n)
460 {
461 for (;;)
462 {
463 if (recv (s, str, n, 0) == n)
464 return n;
465 attempt_resync (huh, s);
466 }
467 }
468
469 /* Write arbitrary stuff to a socket. */
470 static int
471 sockwrite (LPCSTR huh, const void *str, size_t n)
472 {
473 for (;;)
474 {
475 if (send (s, str, n, 0) == n)
476 return n;
477 attempt_resync (huh, s);
478 }
479 }
480
481 /* Output an id/dword to the host */
482 static void
483 putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
484 {
485 if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
486 stub_error ("error writing record id to host for %s", huh);
487 if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
488 stub_error ("error writing %s to host.", huh);
489 }
490
491 /* Output an id/word to the host */
492 static void
493 putword (LPCSTR huh, gdb_wince_id what, WORD n)
494 {
495 if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
496 stub_error ("error writing record id to host for %s", huh);
497 if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
498 stub_error ("error writing %s host.", huh);
499 }
500
501 /* Convenience define for outputting a "gdb_wince_len" type. */
502 #define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
503
504 /* Put an arbitrary block of memory to the gdb host. This comes in
505 two chunks an id/dword representing the length and the stream of memory
506 itself. */
507 static void
508 putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
509 {
510 putlen (huh, what, len);
511 if (((short) len > 0) && sockwrite (huh, mem, len) != len)
512 stub_error ("error writing %s to host.", huh);
513 }
514
515 /* Output the result of an operation to the host. If res != 0, sends a block of
516 memory starting at mem of len bytes. If res == 0, sends -GetLastError () and
517 avoids sending the mem. */
518 static DWORD
519 getdword (LPCSTR huh, gdb_wince_id what_this)
520 {
521 DWORD n;
522 gdb_wince_id what;
523 do
524 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
525 stub_error ("error getting record type from host - %s.", huh);
526 while (what_this != what);
527
528 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
529 stub_error ("error getting %s from host.", huh);
530
531 return n;
532 }
533
534 /* Get a an ID (possibly) and a WORD from the host gdb.
535 Don't bother with the id if the main loop has already
536 read it. */
537 static WORD
538 getword (LPCSTR huh, gdb_wince_id what_this)
539 {
540 WORD n;
541 gdb_wince_id what;
542 do
543 if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
544 stub_error ("error getting record type from host - %s.", huh);
545 while (what_this != what);
546
547 if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
548 stub_error ("error getting %s from host.", huh);
549
550 return n;
551 }
552
553 /* Handy defines for getting/putting various types of values. */
554 #define gethandle(huh, what) (HANDLE) getdword ((huh), (what))
555 #define getpvoid(huh, what) (LPVOID) getdword ((huh), (what))
556 #define getlen(huh, what) (gdb_wince_len) getword ((huh), (what))
557 #define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h))
558 #define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p))
559
560 /* Retrieve the result of an operation from the stub. If nbytes < 0) then nbytes
561 is actually an error and nothing else follows. Use SetLastError to remember this.
562 if nbytes > 0, retrieve a block of *nbytes into buf.
563 */
564 int
565 getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
566 {
567 gdb_wince_len dummy;
568 if (nbytes == NULL)
569 nbytes = &dummy;
570
571 *nbytes = getlen (huh, what);
572
573 if ((short) *nbytes < 0)
574 {
575 SetLastError (-(short) *nbytes);
576 return 0;
577 }
578
579 if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
580 stub_error ("couldn't read information from wince stub - %s", huh);
581
582 return 1;
583 }
584
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.
588 */
589 LPWSTR
590 towide (const char *s, gdb_wince_len * out_len)
591 {
592 static int n = -1;
593 static LPWSTR outs[8] =
594 {NULL /*, NULL, etc. */ };
595 gdb_wince_len dummy;
596
597 if (!out_len)
598 out_len = &dummy;
599
600 /* First determine the length required to hold the converted string. */
601 *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
602 if (!*out_len)
603 return NULL; /* The conversion failed */
604
605 if (++n >= (sizeof (outs) / sizeof (outs[0])))
606 n = 0; /* wrap */
607
608 /* Allocate space for the converted string, reusing any previously allocated
609 space, if applicable. Note that if outs[n] is NULL, realloc will act as
610 a malloc (under cygwin, at least).
611 */
612 outs[n] = (LPWSTR) realloc (outs[n], *out_len);
613 memset (outs[n], 0, *out_len);
614 (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len);
615 return outs[n];
616 }
617
618 /******************** Emulation routines start here. ********************
619
620 The functions below are modelled after their Win32 counterparts. They are named
621 similarly to Win32 and take exactly the same arguments except where otherwise noted.
622 They communicate with the stub on the hand-held device by sending their arguments
623 over the socket and waiting for results from the socket.
624
625 There is one universal change. In cases where a length is expected to be returned
626 in a DWORD, we use a gdb_wince_len type instead. Currently this is an unsigned short
627 which is smaller than the standard Win32 DWORD. This is done to minimize unnecessary
628 traffic since the connection to Windows CE can be slow. To change this, modify the
629 typedef in wince-stub.h and change the putlen/getlen macros in this file and in
630 the stub.
631 */
632 static int
633 create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
634 {
635 gdb_wince_len len;
636 LPWSTR buf;
637
638 buf = towide (exec_file, &len);
639 putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len);
640 buf = towide (args, &len);
641 putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len);
642 putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags);
643 return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL);
644 }
645
646 /* Emulate TerminateProcess. Don't bother with the second argument since CE
647 ignores it.
648 */
649 static int
650 terminate_process (HANDLE h)
651 {
652 gdb_wince_result res;
653 if (s < 0)
654 return 1;
655 puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
656 return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
657 }
658
659 static int
660 wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
661 {
662 if (s < 0)
663 return 1;
664 putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
665 return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
666 }
667
668 static int
669 get_thread_context (HANDLE h, CONTEXT * c)
670 {
671 if (s < 0)
672 return 1;
673 puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
674 putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
675 return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
676 }
677
678 static int
679 set_thread_context (HANDLE h, CONTEXT * c)
680 {
681 gdb_wince_result res;
682 if (s < 0)
683 return 1;
684 puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
685 putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c));
686 return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL);
687 }
688
689 static int
690 read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
691 {
692 if (s < 0)
693 return 1;
694 puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
695 putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
696 putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
697
698 return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
699 }
700
701 static int
702 write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
703 {
704 if (s < 0)
705 return 1;
706 puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
707 putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
708 putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
709
710 return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
711 }
712
713 static int
714 remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
715 {
716 gdb_wince_len nbytes;
717 if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
718 (LPVOID) myaddr, len, &nbytes))
719 return -1;
720 return nbytes;
721 }
722
723 static int
724 remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
725 {
726 gdb_wince_len nbytes;
727 if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
728 (LPCVOID) myaddr, len, &nbytes))
729 return -1;
730 return nbytes;
731 }
732
733 /* This is not a standard Win32 function. It instructs the stub to return TRUE
734 if the thread referenced by HANDLE h is alive.
735 */
736 static int
737 thread_alive (HANDLE h)
738 {
739 gdb_wince_result res;
740 if (s < 0)
741 return 1;
742 puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
743 return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
744 }
745
746 static int
747 suspend_thread (HANDLE h)
748 {
749 if (s < 0)
750 return 1;
751 puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
752 return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
753 }
754
755 static int
756 resume_thread (HANDLE h)
757 {
758 if (s < 0)
759 return 1;
760 puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
761 return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
762 }
763
764 static int
765 continue_debug_event (DWORD pid, DWORD tid, DWORD status)
766 {
767 gdb_wince_result res;
768 if (s < 0)
769 return 0;
770 putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid);
771 putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid);
772 putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status);
773 return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL);
774 }
775
776 static int
777 close_handle (HANDLE h)
778 {
779 gdb_wince_result res;
780 if (s < 0)
781 return 1;
782 puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
783 return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
784 }
785
786 /* This is not a standard Win32 interface. This function tells the stub
787 to terminate.
788 */
789 static void
790 stop_stub ()
791 {
792 if (s < 0)
793 return;
794 (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
795 s = -1;
796 }
797
798 /******************** End of emulation routines. ********************/
799 /******************** End of stub interface ********************/
800
801 /* Find a thread record given a thread id.
802 If get_context then also retrieve the context for this
803 thread. */
804 static thread_info *
805 thread_rec (DWORD id, int get_context)
806 {
807 thread_info *th;
808
809 for (th = &thread_head; (th = th->next) != NULL;)
810 if (th->id == id)
811 {
812 if (!th->suspend_count && get_context)
813 {
814 if (get_context > 0 && th != this_thread)
815 th->suspend_count = suspend_thread (th->h) + 1;
816 else if (get_context < 0)
817 th->suspend_count = -1;
818
819 th->context.ContextFlags = CONTEXT_DEBUGGER;
820 get_thread_context (th->h, &th->context);
821 }
822 return th;
823 }
824
825 return NULL;
826 }
827
828 /* Add a thread to the thread list */
829 static thread_info *
830 child_add_thread (DWORD id, HANDLE h)
831 {
832 thread_info *th;
833
834 if ((th = thread_rec (id, FALSE)))
835 return th;
836
837 th = (thread_info *) xmalloc (sizeof (*th));
838 memset (th, 0, sizeof (*th));
839 th->id = id;
840 th->h = h;
841 th->next = thread_head.next;
842 thread_head.next = th;
843 add_thread (id);
844 return th;
845 }
846
847 /* Clear out any old thread list and reintialize it to a
848 pristine state. */
849 static void
850 child_init_thread_list ()
851 {
852 thread_info *th = &thread_head;
853
854 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
855 init_thread_list ();
856 while (th->next != NULL)
857 {
858 thread_info *here = th->next;
859 th->next = here->next;
860 (void) close_handle (here->h);
861 free (here);
862 }
863 }
864
865 /* Delete a thread from the list of threads */
866 static void
867 child_delete_thread (DWORD id)
868 {
869 thread_info *th;
870
871 if (info_verbose)
872 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
873 delete_thread (id);
874
875 for (th = &thread_head;
876 th->next != NULL && th->next->id != id;
877 th = th->next)
878 continue;
879
880 if (th->next != NULL)
881 {
882 thread_info *here = th->next;
883 th->next = here->next;
884 close_handle (here->h);
885 free (here);
886 }
887 }
888
889 static void
890 check (BOOL ok, const char *file, int line)
891 {
892 if (!ok)
893 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
894 }
895
896 /* Return a pointer into a CONTEXT field indexed by gdb register number.
897 Return a pointer to an address pointing to zero if there is no
898 corresponding CONTEXT field for the given register number.
899 */
900 static ULONG *
901 regptr (LPCONTEXT c, int r)
902 {
903 static ULONG zero = 0;
904 ULONG *p;
905 if (mappings[r] < 0)
906 p = &zero;
907 else
908 p = (ULONG *) (((char *) c) + mappings[r]);
909 return p;
910 }
911
912 static void
913 do_child_fetch_inferior_registers (int r)
914 {
915 if (r >= 0)
916 {
917 supply_register (r, (char *) regptr (&current_thread->context, r));
918 }
919 else
920 {
921 for (r = 0; r < NUM_REGS; r++)
922 do_child_fetch_inferior_registers (r);
923 }
924 }
925
926 static void
927 child_fetch_inferior_registers (int r)
928 {
929 current_thread = thread_rec (inferior_pid, TRUE);
930 do_child_fetch_inferior_registers (r);
931 }
932
933 static void
934 do_child_store_inferior_registers (int r)
935 {
936 if (r >= 0)
937 read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
938 else
939 {
940 for (r = 0; r < NUM_REGS; r++)
941 do_child_store_inferior_registers (r);
942 }
943 }
944
945 /* Store a new register value into the current thread context */
946 static void
947 child_store_inferior_registers (int r)
948 {
949 current_thread = thread_rec (inferior_pid, TRUE);
950 do_child_store_inferior_registers (r);
951 }
952
953 /* Wait for child to do something. Return pid of child, or -1 in case
954 of error; store status through argument pointer OURSTATUS. */
955
956 static int
957 handle_load_dll (PTR dummy)
958 {
959 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
960 char dll_buf[MAX_PATH + 1];
961 char *p, *bufp, *imgp, *dll_name, *dll_basename;
962 int len;
963
964 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
965 if (!event->lpImageName)
966 return 1;
967
968 len = 0;
969 for (bufp = dll_buf, imgp = event->lpImageName;
970 bufp < dll_buf + sizeof (dll_buf);
971 bufp += 16, imgp += 16)
972 {
973 gdb_wince_len nbytes = 0;
974 (void) read_process_memory (current_process_handle,
975 imgp, bufp, 16, &nbytes);
976
977 if (!nbytes && bufp == dll_buf)
978 return 1; /* couldn't read it */
979 for (p = bufp; p < bufp + nbytes; p++)
980 {
981 len++;
982 if (*p == '\0')
983 goto out;
984 if (event->fUnicode)
985 p++;
986 }
987 if (!nbytes)
988 break;
989 }
990
991 out:
992 if (!len)
993 return 1;
994 dll_buf[len] = '\0';
995 dll_name = alloca (len);
996
997 if (!dll_name)
998 return 1;
999
1000 if (!event->fUnicode)
1001 memcpy (dll_name, dll_buf, len);
1002 else
1003 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len,
1004 dll_name, len, 0, 0);
1005
1006 while ((p = strchr (dll_name, '\\')))
1007 *p = '/';
1008
1009 /* FIXME!! It would be nice to define one symbol which pointed to the
1010 front of the dll if we can't find any symbols. */
1011
1012 if (!(dll_basename = strrchr (dll_name, '/')))
1013 dll_basename = dll_name;
1014 else
1015 dll_basename++;
1016
1017 /* The symbols in a dll are offset by 0x1000, which is the
1018 the offset from 0 of the first byte in an image - because
1019 of the file header and the section alignment.
1020
1021 FIXME: Is this the real reason that we need the 0x1000 ? */
1022
1023 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
1024 #if 0 /* FIXME: Need to use RAPI stuff to read the file someday. */
1025 {
1026 struct section_addr_info section_addrs;
1027 memset (&section_addrs, 0, sizeof (section_addrs));
1028 section_addrs.text_addr = (int) event->lpBaseOfDll + 0x1000;
1029 symbol_file_add (dll_name, 0, &section_addrs, 0, OBJF_SHARED);
1030 }
1031 #endif
1032 printf_unfiltered ("\n");
1033
1034 return 1;
1035 }
1036
1037 /* Handle DEBUG_STRING output from child process.
1038 Cygwin prepends its messages with a "cygwin:". Interpret this as
1039 a Cygwin signal. Otherwise just print the string as a warning. */
1040 static void
1041 handle_output_debug_string (struct target_waitstatus *ourstatus)
1042 {
1043 char p[256];
1044 char s[255];
1045 char *q;
1046 gdb_wince_len nbytes_read;
1047 gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;
1048
1049 if (nbytes > 255)
1050 nbytes = 255;
1051
1052 memset (p, 0, sizeof (p));
1053 if (!read_process_memory (current_process_handle,
1054 current_event.u.DebugString.lpDebugStringData,
1055 &p, nbytes, &nbytes_read)
1056 || !*p)
1057 return;
1058
1059 memset (s, 0, sizeof (s));
1060 WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) p, (int) nbytes_read, s,
1061 sizeof (s) - 1, NULL, NULL);
1062 q = strchr (s, '\n');
1063 if (q != NULL)
1064 {
1065 *q = '\0';
1066 if (*--q = '\r')
1067 *q = '\0';
1068 }
1069
1070 warning (s);
1071 return;
1072 }
1073
1074 /* Handle target exceptions. */
1075 static int
1076 handle_exception (struct target_waitstatus *ourstatus)
1077 {
1078 thread_info *th;
1079
1080 if (current_event.u.Exception.dwFirstChance)
1081 return 0;
1082
1083 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1084
1085 /* Record the context of the current thread */
1086 th = thread_rec (current_event.dwThreadId, -1);
1087
1088 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
1089 {
1090 case EXCEPTION_ACCESS_VIOLATION:
1091 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
1092 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1093 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1094 break;
1095 case STATUS_STACK_OVERFLOW:
1096 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
1097 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1098 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1099 break;
1100 case EXCEPTION_BREAKPOINT:
1101 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
1102 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1103 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1104 break;
1105 case DBG_CONTROL_C:
1106 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
1107 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1108 ourstatus->value.sig = TARGET_SIGNAL_INT;
1109 /* User typed CTRL-C. Continue with this status */
1110 last_sig = SIGINT; /* FIXME - should check pass state */
1111 break;
1112 case EXCEPTION_SINGLE_STEP:
1113 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
1114 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1115 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1116 break;
1117 default:
1118 /* This may be a structured exception handling exception. In
1119 that case, we want to let the program try to handle it, and
1120 only break if we see the exception a second time. */
1121
1122 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
1123 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1124 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1125 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1126 break;
1127 }
1128 exception_count++;
1129 return 1;
1130 }
1131
1132 /* Resume all artificially suspended threads if we are continuing
1133 execution */
1134 static BOOL
1135 child_continue (DWORD continue_status, int id)
1136 {
1137 int i;
1138 thread_info *th;
1139 BOOL res;
1140
1141 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
1142 (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId));
1143 res = continue_debug_event (current_event.dwProcessId,
1144 current_event.dwThreadId,
1145 continue_status);
1146 if (res)
1147 for (th = &thread_head; (th = th->next) != NULL;)
1148 if (((id == -1) || (id == th->id)) && th->suspend_count)
1149 {
1150 for (i = 0; i < th->suspend_count; i++)
1151 (void) resume_thread (th->h);
1152 th->suspend_count = 0;
1153 }
1154
1155 return res;
1156 }
1157
1158 /* Get the next event from the child. Return 1 if the event requires
1159 handling by WFI (or whatever).
1160 */
1161 static int
1162 get_child_debug_event (int pid, struct target_waitstatus *ourstatus, DWORD * event_code, int *retval)
1163 {
1164 BOOL debug_event;
1165 DWORD continue_status;
1166 int breakout = 1;
1167
1168 if (!(debug_event = wait_for_debug_event (&current_event, 1000)))
1169 {
1170 breakout = *retval = *event_code = 0;
1171 goto out;
1172 }
1173
1174 this_thread = thread_rec (current_event.dwThreadId, FALSE);
1175 event_count++;
1176 continue_status = DBG_CONTINUE;
1177 *retval = 0;
1178 switch (*event_code = current_event.dwDebugEventCode)
1179 {
1180 case CREATE_THREAD_DEBUG_EVENT:
1181 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1182 (unsigned) current_event.dwProcessId,
1183 (unsigned) current_event.dwThreadId,
1184 "CREATE_THREAD_DEBUG_EVENT"));
1185 /* Record the existence of this thread */
1186 child_add_thread (current_event.dwThreadId,
1187 current_event.u.CreateThread.hThread);
1188 if (info_verbose)
1189 printf_unfiltered ("[New %s]\n",
1190 target_pid_to_str (current_event.dwThreadId));
1191 break;
1192
1193 case EXIT_THREAD_DEBUG_EVENT:
1194 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1195 (unsigned) current_event.dwProcessId,
1196 (unsigned) current_event.dwThreadId,
1197 "EXIT_THREAD_DEBUG_EVENT"));
1198 child_delete_thread (current_event.dwThreadId);
1199 break;
1200
1201 case CREATE_PROCESS_DEBUG_EVENT:
1202 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1203 (unsigned) current_event.dwProcessId,
1204 (unsigned) current_event.dwThreadId,
1205 "CREATE_PROCESS_DEBUG_EVENT"));
1206 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1207
1208 main_thread_id = inferior_pid = current_event.dwThreadId;
1209 /* Add the main thread */
1210 current_thread = child_add_thread (inferior_pid,
1211 current_event.u.CreateProcessInfo.hThread);
1212 break;
1213
1214 case EXIT_PROCESS_DEBUG_EVENT:
1215 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1216 (unsigned) current_event.dwProcessId,
1217 (unsigned) current_event.dwThreadId,
1218 "EXIT_PROCESS_DEBUG_EVENT"));
1219 ourstatus->kind = TARGET_WAITKIND_EXITED;
1220 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1221 close_handle (current_process_handle);
1222 *retval = current_event.dwProcessId;
1223 goto out;
1224
1225 case LOAD_DLL_DEBUG_EVENT:
1226 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1227 (unsigned) current_event.dwProcessId,
1228 (unsigned) current_event.dwThreadId,
1229 "LOAD_DLL_DEBUG_EVENT"));
1230 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1231 registers_changed (); /* mark all regs invalid */
1232 break;
1233
1234 case UNLOAD_DLL_DEBUG_EVENT:
1235 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1236 (unsigned) current_event.dwProcessId,
1237 (unsigned) current_event.dwThreadId,
1238 "UNLOAD_DLL_DEBUG_EVENT"));
1239 break; /* FIXME: don't know what to do here */
1240
1241 case EXCEPTION_DEBUG_EVENT:
1242 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1243 (unsigned) current_event.dwProcessId,
1244 (unsigned) current_event.dwThreadId,
1245 "EXCEPTION_DEBUG_EVENT"));
1246 if (handle_exception (ourstatus))
1247 {
1248 char buf[32];
1249 *retval = current_event.dwThreadId;
1250 remote_read_bytes (read_pc (), buf, sizeof (buf));
1251 dcache_xfer_memory (remote_dcache, read_pc (), buf, sizeof (buf), 0);
1252 goto out;
1253 }
1254 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1255 break;
1256
1257 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1258 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1259 (unsigned) current_event.dwProcessId,
1260 (unsigned) current_event.dwThreadId,
1261 "OUTPUT_DEBUG_STRING_EVENT"));
1262 handle_output_debug_string (ourstatus);
1263 break;
1264 default:
1265 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
1266 current_event.dwProcessId,
1267 current_event.dwThreadId);
1268 printf_unfiltered (" unknown event code %d\n",
1269 current_event.dwDebugEventCode);
1270 break;
1271 }
1272
1273 breakout = 0;
1274 CHECK (child_continue (continue_status, -1));
1275
1276 out:
1277 return breakout;
1278 }
1279
1280 /* Wait for interesting events to occur in the target process. */
1281 static int
1282 child_wait (int pid, struct target_waitstatus *ourstatus)
1283 {
1284 DWORD event_code;
1285 int retval;
1286
1287 /* We loop when we get a non-standard exception rather than return
1288 with a SPURIOUS because resume can try and step or modify things,
1289 which needs a current_thread->h. But some of these exceptions mark
1290 the birth or death of threads, which mean that the current thread
1291 isn't necessarily what you think it is. */
1292
1293 while (1)
1294 if (get_child_debug_event (pid, ourstatus, &event_code, &retval))
1295 return retval;
1296 else
1297 {
1298 int detach = 0;
1299
1300 if (ui_loop_hook != NULL)
1301 detach = ui_loop_hook (0);
1302
1303 if (detach)
1304 child_kill_inferior ();
1305 }
1306 }
1307
1308 /* Print status information about what we're accessing. */
1309
1310 static void
1311 child_files_info (ignore)
1312 struct target_ops *ignore;
1313 {
1314 printf_unfiltered ("\tUsing the running image of child %s.\n",
1315 target_pid_to_str (inferior_pid));
1316 }
1317
1318 /* ARGSUSED */
1319 static void
1320 child_open (arg, from_tty)
1321 char *arg;
1322 int from_tty;
1323 {
1324 error ("Use the \"run\" command to start a child process.");
1325 }
1326
1327 #define FACTOR (0x19db1ded53ea710LL)
1328 #define NSPERSEC 10000000
1329
1330 /* Convert a Win32 time to "UNIX" format. */
1331 long
1332 to_time_t (FILETIME * ptr)
1333 {
1334 /* A file time is the number of 100ns since jan 1 1601
1335 stuffed into two long words.
1336 A time_t is the number of seconds since jan 1 1970. */
1337
1338 long rem;
1339 long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime);
1340 x -= FACTOR; /* number of 100ns between 1601 and 1970 */
1341 rem = x % ((long long) NSPERSEC);
1342 rem += (NSPERSEC / 2);
1343 x /= (long long) NSPERSEC; /* number of 100ns in a second */
1344 x += (long long) (rem / NSPERSEC);
1345 return x;
1346 }
1347
1348 /* Upload a file to the remote device depending on the user's
1349 'set remoteupload' specification. */
1350 char *
1351 upload_to_device (const char *to, const char *from)
1352 {
1353 HANDLE h;
1354 const char *dir = remote_directory ? : "\\gdb";
1355 int len;
1356 static char *remotefile = NULL;
1357 LPWSTR wstr;
1358 char *p;
1359 DWORD err;
1360 const char *in_to = to;
1361 FILETIME ctime, atime, wtime;
1362 struct stat st;
1363 int fd;
1364
1365 /* Look for a path separator and only use trailing part. */
1366 while ((p = strpbrk (to, "/\\")) != NULL)
1367 to = p + 1;
1368
1369 if (!*to)
1370 error ("no filename found to upload - %s.", in_to);
1371
1372 len = strlen (dir) + strlen (to) + 2;
1373 remotefile = (char *) realloc (remotefile, len);
1374 strcpy (remotefile, dir);
1375 strcat (remotefile, "\\");
1376 strcat (remotefile, to);
1377
1378 if (upload_when == UPLOAD_NEVER)
1379 return remotefile; /* Don't bother uploading. */
1380
1381 /* Open the source. */
1382 if ((fd = openp (getenv ("PATH"), TRUE, (char *) from, O_RDONLY, 0, NULL)) < 0)
1383 error ("couldn't open %s", from);
1384
1385 /* Get the time for later comparison. */
1386 if (fstat (fd, &st))
1387 st.st_mtime = (time_t) - 1;
1388
1389 /* Always attempt to create the directory on the remote system. */
1390 wstr = towide (dir, NULL);
1391 (void) CeCreateDirectory (wstr, NULL);
1392
1393 /* Attempt to open the remote file, creating it if it doesn't exist. */
1394 wstr = towide (remotefile, NULL);
1395 h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1396 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1397
1398 /* Some kind of problem? */
1399 err = CeGetLastError ();
1400 if (h == NULL)
1401 error ("error creating file to \"%s\". Windows error %d.",
1402 remotefile, err);
1403
1404 /* See if we need to upload the file. */
1405 if (upload_when == UPLOAD_ALWAYS ||
1406 err != ERROR_ALREADY_EXISTS ||
1407 !CeGetFileTime (h, &ctime, &atime, &wtime) ||
1408 to_time_t (&wtime) < st.st_mtime)
1409 {
1410 DWORD nbytes;
1411 char buf[4096];
1412 int n;
1413
1414 /* Upload the file. */
1415 while ((n = read (fd, buf, sizeof (buf))) > 0)
1416 if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL))
1417 error ("error writing to remote device - %d.",
1418 CeGetLastError ());
1419 }
1420
1421 close (fd);
1422 CeCloseHandle (h);
1423
1424 return remotefile;
1425 }
1426
1427 /* Initialize the connection to the remote device. */
1428 static void
1429 wince_initialize ()
1430 {
1431 int tmp;
1432 char args[256];
1433 char *hostname;
1434 struct sockaddr_in sin;
1435 char *stub_file_name;
1436 int s0;
1437 PROCESS_INFORMATION pi;
1438
1439 if (!connection_initialized)
1440 switch (CeRapiInit ())
1441 {
1442 case 0:
1443 connection_initialized = 1;
1444 break;
1445 default:
1446 CeRapiUninit ();
1447 error ("Can't initialize connection to remote device.\n");
1448 break;
1449 }
1450
1451 /* Upload the stub to the handheld device. */
1452 stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB);
1453 strcpy (args, stub_file_name);
1454
1455 if (remote_add_host)
1456 {
1457 strcat (args, " ");
1458 hostname = strchr (args, '\0');
1459 if (gethostname (hostname, sizeof (args) - strlen (args)))
1460 error ("couldn't get hostname of this system.");
1461 }
1462
1463 /* Get a socket. */
1464 if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1465 stub_error ("Couldn't connect to host system.");
1466
1467 /* Allow rapid reuse of the port. */
1468 tmp = 1;
1469 (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1470
1471
1472 /* Set up the information for connecting to the host gdb process. */
1473 memset (&sin, 0, sizeof (sin));
1474 sin.sin_family = AF_INET;
1475 sin.sin_port = htons (7000); /* FIXME: This should be configurable */
1476
1477 if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
1478 error ("couldn't bind socket");
1479
1480 if (listen (s0, 1))
1481 error ("Couldn't open socket for listening.\n");
1482
1483 /* Start up the stub on the remote device. */
1484 if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL),
1485 NULL, NULL, 0, 0, NULL, NULL, NULL, &pi))
1486 error ("Unable to start remote stub '%s'. Windows CE error %d.",
1487 stub_file_name, CeGetLastError ());
1488
1489 /* Wait for a connection */
1490
1491 if ((s = accept (s0, NULL, NULL)) < 0)
1492 error ("couldn't set up server for connection.");
1493
1494 close (s0);
1495 }
1496
1497 /* Start an inferior win32 child process and sets inferior_pid to its pid.
1498 EXEC_FILE is the file to run.
1499 ALLARGS is a string containing the arguments to the program.
1500 ENV is the environment vector to pass. Errors reported with error(). */
1501 static void
1502 child_create_inferior (char *exec_file, char *args, char **env)
1503 {
1504 PROCESS_INFORMATION pi;
1505 struct target_waitstatus dummy;
1506 int ret;
1507 DWORD flags, event_code;
1508 char *exec_and_args;
1509
1510 if (!exec_file)
1511 error ("No executable specified, use `target exec'.\n");
1512
1513 flags = DEBUG_PROCESS;
1514
1515 wince_initialize (); /* Make sure we've got a connection. */
1516 if (!remote_dcache)
1517 remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes);
1518 else
1519 dcache_flush (remote_dcache);
1520
1521 exec_file = upload_to_device (exec_file, exec_file);
1522
1523 while (*args == ' ')
1524 args++;
1525
1526 /* Allocate space for "command<sp>args" */
1527 if (*args == '\0')
1528 {
1529 exec_and_args = alloca (strlen (exec_file) + 1);
1530 strcpy (exec_and_args, exec_file);
1531 }
1532 else
1533 {
1534 exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
1535 sprintf (exec_and_args, "%s %s", exec_file, args);
1536 }
1537
1538 memset (&pi, 0, sizeof (pi));
1539 /* Execute the process */
1540 if (!create_process (exec_file, exec_and_args, flags, &pi))
1541 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1542
1543 exception_count = 0;
1544 event_count = 0;
1545
1546 current_process_handle = pi.hProcess;
1547 current_event.dwProcessId = pi.dwProcessId;
1548 memset (&current_event, 0, sizeof (current_event));
1549 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1550 push_target (&child_ops);
1551 child_init_thread_list ();
1552 child_add_thread (pi.dwThreadId, pi.hThread);
1553 init_wait_for_inferior ();
1554 clear_proceed_status ();
1555 target_terminal_init ();
1556 target_terminal_inferior ();
1557
1558
1559 /* Run until process and threads are loaded */
1560 do
1561 get_child_debug_event (inferior_pid, &dummy, &event_code, &ret);
1562 while (event_code != CREATE_PROCESS_DEBUG_EVENT);
1563
1564 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
1565 }
1566
1567 /* Chile has gone bye-bye. */
1568 static void
1569 child_mourn_inferior ()
1570 {
1571 (void) child_continue (DBG_CONTINUE, -1);
1572 unpush_target (&child_ops);
1573 stop_stub ();
1574 CeRapiUninit ();
1575 connection_initialized = 0;
1576 generic_mourn_inferior ();
1577 }
1578
1579 /* Move memory from child to/from gdb. */
1580 int
1581 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1582 int write, struct target_ops *target)
1583 {
1584 if (len <= 0)
1585 return 0;
1586 return dcache_xfer_memory (remote_dcache, memaddr, our, len, write);
1587 }
1588
1589 /* Terminate the process and wait for child to tell us it has completed. */
1590 void
1591 child_kill_inferior (void)
1592 {
1593 CHECK (terminate_process (current_process_handle));
1594
1595 for (;;)
1596 {
1597 if (!child_continue (DBG_CONTINUE, -1))
1598 break;
1599 if (!wait_for_debug_event (&current_event, INFINITE))
1600 break;
1601 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1602 break;
1603 }
1604
1605 CHECK (close_handle (current_process_handle));
1606 close_handle (current_thread->h);
1607 target_mourn_inferior (); /* or just child_mourn_inferior? */
1608 }
1609
1610 #ifdef MIPS
1611 static void
1612 undoSStep (thread_info * th)
1613 {
1614 if (th->stepped)
1615 {
1616 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
1617 th->stepped = 0;
1618 }
1619 }
1620
1621 void
1622 wince_software_single_step (unsigned int ignore, int insert_breakpoints_p)
1623 {
1624 unsigned long pc;
1625 thread_info *th = current_thread; /* Info on currently selected thread */
1626 CORE_ADDR mips_next_pc (CORE_ADDR pc);
1627
1628 if (!insert_breakpoints_p)
1629 {
1630 undoSStep (th);
1631 return;
1632 }
1633
1634 th->stepped = 1;
1635 pc = read_register (PC_REGNUM);
1636 th->step_pc = mips_next_pc (pc);
1637 th->step_prev = 0;
1638 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1639 }
1640 #elif SHx
1641 /* Hitachi SH architecture instruction encoding masks */
1642
1643 #define COND_BR_MASK 0xff00
1644 #define UCOND_DBR_MASK 0xe000
1645 #define UCOND_RBR_MASK 0xf0df
1646 #define TRAPA_MASK 0xff00
1647
1648 #define COND_DISP 0x00ff
1649 #define UCOND_DISP 0x0fff
1650 #define UCOND_REG 0x0f00
1651
1652 /* Hitachi SH instruction opcodes */
1653
1654 #define BF_INSTR 0x8b00
1655 #define BT_INSTR 0x8900
1656 #define BRA_INSTR 0xa000
1657 #define BSR_INSTR 0xb000
1658 #define JMP_INSTR 0x402b
1659 #define JSR_INSTR 0x400b
1660 #define RTS_INSTR 0x000b
1661 #define RTE_INSTR 0x002b
1662 #define TRAPA_INSTR 0xc300
1663 #define SSTEP_INSTR 0xc3ff
1664
1665
1666 #define T_BIT_MASK 0x0001
1667
1668 /* Undo the effect of a previous doSStep. If we single stepped,
1669 restore the old instruction. */
1670
1671 static void
1672 undoSStep (thread_info * th)
1673 {
1674 if (th->stepped)
1675 {
1676 gdb_wince_len done;
1677 write_process_memory (current_process_handle, (LPVOID) th->step_pc,
1678 (LPVOID) & th->step_instr, sizeof (short), &done);
1679 if (done != sizeof (short))
1680 error ("error unsetting single step.");
1681 th->stepped = 0;
1682 }
1683 }
1684
1685 /* Single step (in a painstaking fashion) by inspecting the current
1686 instruction and setting a breakpoint on the "next" instruction
1687 which would be executed. This code hails from sh-stub.c.
1688 */
1689 void
1690 wince_software_single_step (unsigned int ignore, int insert_breakpoints_p)
1691 {
1692 thread_info *th = current_thread; /* Info on currently selected thread */
1693
1694 if (!insert_breakpoints_p)
1695 undoSStep (th);
1696 else
1697 {
1698 short *instrMem;
1699 int displacement;
1700 int reg;
1701 unsigned short opcode;
1702 gdb_wince_len done;
1703 LPCONTEXT c = &th->context;
1704
1705 instrMem = (short *) c->Fir;
1706
1707 read_process_memory (current_process_handle, (LPCVOID) c->Fir, &opcode,
1708 sizeof (opcode), &done);
1709 if (done != sizeof (opcode))
1710 error ("couldn't retrieve opcode");
1711 th->stepped = 1;
1712
1713 if ((opcode & COND_BR_MASK) == BT_INSTR)
1714 {
1715 if (c->Psr & T_BIT_MASK)
1716 {
1717 displacement = (opcode & COND_DISP) << 1;
1718 if (displacement & 0x80)
1719 displacement |= 0xffffff00;
1720 /*
1721 * Remember PC points to second instr.
1722 * after PC of branch ... so add 4
1723 */
1724 instrMem = (short *) (c->Fir + displacement + 4);
1725 }
1726 else
1727 instrMem += 1;
1728 }
1729 else if ((opcode & COND_BR_MASK) == BF_INSTR)
1730 {
1731 if (c->Psr & T_BIT_MASK)
1732 instrMem += 1;
1733 else
1734 {
1735 displacement = (opcode & COND_DISP) << 1;
1736 if (displacement & 0x80)
1737 displacement |= 0xffffff00;
1738 /*
1739 * Remember PC points to second instr.
1740 * after PC of branch ... so add 4
1741 */
1742 instrMem = (short *) (c->Fir + displacement + 4);
1743 }
1744 }
1745 else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
1746 {
1747 displacement = (opcode & UCOND_DISP) << 1;
1748 if (displacement & 0x0800)
1749 displacement |= 0xfffff000;
1750
1751 /*
1752 * Remember PC points to second instr.
1753 * after PC of branch ... so add 4
1754 */
1755 instrMem = (short *) (c->Fir + displacement + 4);
1756 }
1757 else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
1758 {
1759 reg = (char) ((opcode & UCOND_REG) >> 8);
1760
1761 instrMem = (short *) *regptr (c, reg);
1762 }
1763 else if (opcode == RTS_INSTR)
1764 instrMem = (short *) c->PR;
1765 else if (opcode == RTE_INSTR)
1766 instrMem = (short *) *regptr (c, 15);
1767 else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
1768 instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
1769 else
1770 instrMem += 1;
1771
1772 th->step_pc = (CORE_ADDR) instrMem;
1773
1774 read_process_memory (current_process_handle, (LPVOID) instrMem,
1775 (LPVOID) & th->step_instr, sizeof (short), &done);
1776 opcode = SSTEP_INSTR;
1777 write_process_memory (current_process_handle, (LPVOID) instrMem,
1778 (LPVOID) & opcode, sizeof (short), &done);
1779 }
1780 }
1781 #elif defined (ARM)
1782 /* Single step (in a painstaking fashion) by inspecting the current
1783 instruction and setting a breakpoint on the "next" instruction
1784 which would be executed. This code hails from sh-stub.c.
1785 */
1786 static void
1787 undoSStep (thread_info * th)
1788 {
1789 if (th->stepped)
1790 {
1791 memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
1792 th->stepped = 0;
1793 }
1794 }
1795
1796 void
1797 wince_software_single_step (unsigned int ignore, int insert_breakpoints_p)
1798 {
1799 unsigned long pc;
1800 thread_info *th = current_thread; /* Info on currently selected thread */
1801 CORE_ADDR mips_next_pc (CORE_ADDR pc);
1802
1803 if (!insert_breakpoints_p)
1804 {
1805 undoSStep (th);
1806 return;
1807 }
1808
1809 th->stepped = 1;
1810 pc = read_register (PC_REGNUM);
1811 th->step_pc = arm_get_next_pc (pc);
1812 th->step_prev = 0;
1813 memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1814 }
1815 #endif
1816
1817 /* Resume the child after an exception. */
1818 void
1819 child_resume (int pid, int step, enum target_signal sig)
1820 {
1821 thread_info *th;
1822 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1823 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1824
1825 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1826 pid, step, sig));
1827
1828 /* Get context for currently selected thread */
1829 th = thread_rec (current_event.dwThreadId, FALSE);
1830
1831 if (th->context.ContextFlags)
1832 {
1833 CHECK (set_thread_context (th->h, &th->context));
1834 th->context.ContextFlags = 0;
1835 }
1836
1837 dcache_flush (remote_dcache);
1838
1839 /* Allow continuing with the same signal that interrupted us.
1840 Otherwise complain. */
1841 if (sig && sig != last_sig)
1842 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
1843
1844 last_sig = 0;
1845 child_continue (continue_status, pid);
1846 }
1847
1848 static void
1849 child_prepare_to_store ()
1850 {
1851 /* Do nothing, since we can store individual regs */
1852 }
1853
1854 static int
1855 child_can_run ()
1856 {
1857 return 1;
1858 }
1859
1860 static void
1861 child_close ()
1862 {
1863 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1864 }
1865
1866 /* Explicitly upload file to remotedir */
1867
1868 static void
1869 child_load (char *file, int from_tty)
1870 {
1871 upload_to_device (file, file);
1872 }
1873
1874 struct target_ops child_ops;
1875
1876 static void
1877 init_child_ops (void)
1878 {
1879 memset (&child_ops, 0, sizeof (child_ops));
1880 child_ops.to_shortname = (char *) "child";
1881 child_ops.to_longname = (char *) "Windows CE process";
1882 child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command).";
1883 child_ops.to_open = child_open;
1884 child_ops.to_close = child_close;
1885 child_ops.to_resume = child_resume;
1886 child_ops.to_wait = child_wait;
1887 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1888 child_ops.to_store_registers = child_store_inferior_registers;
1889 child_ops.to_prepare_to_store = child_prepare_to_store;
1890 child_ops.to_xfer_memory = child_xfer_memory;
1891 child_ops.to_files_info = child_files_info;
1892 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1893 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1894 child_ops.to_terminal_init = terminal_init_inferior;
1895 child_ops.to_terminal_inferior = terminal_inferior;
1896 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1897 child_ops.to_terminal_ours = terminal_ours;
1898 child_ops.to_terminal_info = child_terminal_info;
1899 child_ops.to_kill = child_kill_inferior;
1900 child_ops.to_load = child_load;
1901 child_ops.to_create_inferior = child_create_inferior;
1902 child_ops.to_mourn_inferior = child_mourn_inferior;
1903 child_ops.to_can_run = child_can_run;
1904 child_ops.to_thread_alive = win32_child_thread_alive;
1905 child_ops.to_stratum = process_stratum;
1906 child_ops.to_has_all_memory = 1;
1907 child_ops.to_has_memory = 1;
1908 child_ops.to_has_stack = 1;
1909 child_ops.to_has_registers = 1;
1910 child_ops.to_has_execution = 1;
1911 child_ops.to_sections = 0;
1912 child_ops.to_sections_end = 0;
1913 child_ops.to_magic = OPS_MAGIC;
1914 }
1915
1916
1917 /* Handle 'set remoteupload' parameter. */
1918
1919 #define replace_upload(what) \
1920 upload_when = UPLOAD_NEWER; \
1921 remote_upload = realloc (remote_upload, strlen (upload_options[upload_when].name)); \
1922 strcpy (remote_upload, upload_options[upload_when].name);
1923
1924 static void
1925 set_upload_type (char *ignore, int from_tty)
1926 {
1927 int i, len;
1928 char *bad_option;
1929
1930 if (!remote_upload || !remote_upload[0])
1931 {
1932 replace_upload (UPLOAD_NEWER);
1933 if (from_tty)
1934 printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1935 return;
1936 }
1937
1938 len = strlen (remote_upload);
1939 for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++)
1940 if (len >= upload_options[i].abbrev &&
1941 strncasecmp (remote_upload, upload_options[i].name, len) == 0)
1942 {
1943 remote_upload = (char *) upload_options[i].name;
1944 upload_when = i;
1945 return;
1946 }
1947
1948 bad_option = remote_upload;
1949 replace_upload (UPLOAD_NEWER);
1950 error ("Unknown upload type: %s.", bad_option);
1951 }
1952
1953 void
1954 _initialize_inftarg ()
1955 {
1956 struct cmd_list_element *set;
1957 init_child_ops ();
1958
1959 add_show_from_set
1960 (add_set_cmd ((char *) "remotedirectory", no_class,
1961 var_string_noescape, (char *) &remote_directory,
1962 (char *) "Set directory for remote upload.\n",
1963 &setlist),
1964 &showlist);
1965 remote_directory = xstrdup (remote_directory);
1966
1967 set = add_set_cmd ((char *) "remoteupload", no_class,
1968 var_string_noescape, (char *) &remote_upload,
1969 (char *) "Set how to upload executables to remote device.\n",
1970 &setlist);
1971 add_show_from_set (set, &showlist);
1972 set->function.cfunc = set_upload_type;
1973 set_upload_type (NULL, 0);
1974 set_dcache_state (1);
1975
1976 add_show_from_set
1977 (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
1978 (char *) &debug_exec,
1979 (char *) "Set whether to display execution in child process.",
1980 &setlist),
1981 &showlist);
1982
1983 add_show_from_set
1984 (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
1985 (char *) &remote_add_host,
1986 (char *) "Set whether to add this host to remote stub arguments for\n
1987 debugging over a network.", &setlist),
1988 &showlist);
1989
1990 add_show_from_set
1991 (add_set_cmd ((char *) "debugevents", class_support, var_boolean,
1992 (char *) &debug_events,
1993 (char *) "Set whether to display kernel events in child process.",
1994 &setlist),
1995 &showlist);
1996
1997 add_show_from_set
1998 (add_set_cmd ((char *) "debugmemory", class_support, var_boolean,
1999 (char *) &debug_memory,
2000 (char *) "Set whether to display memory accesses in child process.",
2001 &setlist),
2002 &showlist);
2003
2004 add_show_from_set
2005 (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean,
2006 (char *) &debug_exceptions,
2007 (char *) "Set whether to display kernel exceptions in child process.",
2008 &setlist),
2009 &showlist);
2010
2011 add_target (&child_ops);
2012 }
2013
2014 /* Determine if the thread referenced by "pid" is alive
2015 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2016 it means that the pid has died. Otherwise it is assumed to be alive. */
2017 static int
2018 win32_child_thread_alive (int pid)
2019 {
2020 return thread_alive (thread_rec (pid, FALSE)->h);
2021 }
2022
2023 /* Convert pid to printable format. */
2024 char *
2025 cygwin_pid_to_str (int pid)
2026 {
2027 static char buf[80];
2028 if (pid == current_event.dwProcessId)
2029 sprintf (buf, "process %d", pid);
2030 else
2031 sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);
2032 return buf;
2033 }
This page took 0.070929 seconds and 4 git commands to generate.