OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [gdb-5.3/] [gdb/] [wince.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Target-vector operations for controlling Windows CE child processes, for GDB.
2
   Copyright 1999, 2000, 2001 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 even the 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 <time.h>
58
#include "regcache.h"
59
 
60
/* The ui's event loop. */
61
extern int (*ui_loop_hook) (int signo);
62
 
63
/* If we're not using the old Cygwin header file set, define the
64
   following which never should have been in the generic Win32 API
65
   headers in the first place since they were our own invention... */
66
#ifndef _GNU_H_WINDOWS_H
67
#define FLAG_TRACE_BIT 0x100
68
#ifdef CONTEXT_FLOATING_POINT
69
#define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
70
#else
71
#define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
72
#endif
73
#endif
74
 
75
#ifdef SH4
76
#define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
77
#else
78
#define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
79
#endif
80
/* The string sent by cygwin when it processes a signal.
81
   FIXME: This should be in a cygwin include file. */
82
#define CYGWIN_SIGNAL_STRING "cygwin: signal"
83
 
84
#define CHECK(x)        check (x, __FILE__,__LINE__)
85
#define DEBUG_EXEC(x)   if (debug_exec)         printf x
86
#define DEBUG_EVENTS(x) if (debug_events)       printf x
87
#define DEBUG_MEM(x)    if (debug_memory)       printf x
88
#define DEBUG_EXCEPT(x) if (debug_exceptions)   printf x
89
 
90
static int connection_initialized = 0;   /* True if we've initialized a RAPI session. */
91
 
92
/* The directory where the stub and executable files are uploaded. */
93
static const char *remote_directory = "\\gdb";
94
 
95
/* The types automatic upload available. */
96
static enum
97
  {
98
    UPLOAD_ALWAYS = 0,
99
    UPLOAD_NEWER = 1,
100
    UPLOAD_NEVER = 2
101
  }
102
upload_when = UPLOAD_NEWER;
103
 
104
/* Valid options for 'set remoteupload'.  Note that options
105
   must track upload_when enum. */
106
static struct opts
107
  {
108
    const char *name;
109
    int abbrev;
110
  }
111
upload_options[3] =
112
{
113
  {
114
    "always", 1
115
  }
116
  ,
117
  {
118
    "newer", 3
119
  }
120
  ,
121
  {
122
    "never", 3
123
  }
124
};
125
 
126
static char *remote_upload = NULL;      /* Set by set remoteupload */
127
static int remote_add_host = 0;
128
 
129
/* Forward declaration */
130
extern struct target_ops child_ops;
131
 
132
static int win32_child_thread_alive (ptid_t);
133
void child_kill_inferior (void);
134
 
135
static int last_sig = 0; /* Set if a signal was received from the
136
                                   debugged process */
137
 
138
/* Thread information structure used to track information that is
139
   not available in gdb's thread structure. */
140
typedef struct thread_info_struct
141
  {
142
    struct thread_info_struct *next;
143
    DWORD id;
144
    HANDLE h;
145
    char *name;
146
    int suspend_count;
147
    int stepped;                /* True if stepped. */
148
    CORE_ADDR step_pc;
149
    unsigned long step_prev;
150
    CONTEXT context;
151
  }
152
thread_info;
153
 
154
static thread_info thread_head =
155
{NULL};
156
static thread_info * thread_rec (DWORD id, int get_context);
157
 
158
/* The process and thread handles for the above context. */
159
 
160
static DEBUG_EVENT current_event;       /* The current debug event from
161
                                           WaitForDebugEvent */
162
static HANDLE current_process_handle;   /* Currently executing process */
163
static thread_info *current_thread;     /* Info on currently selected thread */
164
static thread_info *this_thread;        /* Info on thread returned by wait_for_debug_event */
165
static DWORD main_thread_id;    /* Thread ID of the main thread */
166
 
167
/* Counts of things. */
168
static int exception_count = 0;
169
static int event_count = 0;
170
 
171
/* User options. */
172
static int debug_exec = 0;       /* show execution */
173
static int debug_events = 0;     /* show events from kernel */
174
static int debug_memory = 0;     /* show target memory accesses */
175
static int debug_exceptions = 0; /* show target exceptions */
176
 
177
/* An array of offset mappings into a Win32 Context structure.
178
   This is a one-to-one mapping which is indexed by gdb's register
179
   numbers.  It retrieves an offset into the context structure where
180
   the 4 byte register is located.
181
   An offset value of -1 indicates that Win32 does not provide this
182
   register in it's CONTEXT structure.  regptr will return zero for this
183
   register.
184
 
185
   This is used by the regptr function. */
186
#define context_offset(x) ((int)&(((PCONTEXT)NULL)->x))
187
static const int mappings[NUM_REGS + 1] =
188
{
189
#ifdef __i386__
190
  context_offset (Eax),
191
  context_offset (Ecx),
192
  context_offset (Edx),
193
  context_offset (Ebx),
194
  context_offset (Esp),
195
  context_offset (Ebp),
196
  context_offset (Esi),
197
  context_offset (Edi),
198
  context_offset (Eip),
199
  context_offset (EFlags),
200
  context_offset (SegCs),
201
  context_offset (SegSs),
202
  context_offset (SegDs),
203
  context_offset (SegEs),
204
  context_offset (SegFs),
205
  context_offset (SegGs),
206
  context_offset (FloatSave.RegisterArea[0 * 10]),
207
  context_offset (FloatSave.RegisterArea[1 * 10]),
208
  context_offset (FloatSave.RegisterArea[2 * 10]),
209
  context_offset (FloatSave.RegisterArea[3 * 10]),
210
  context_offset (FloatSave.RegisterArea[4 * 10]),
211
  context_offset (FloatSave.RegisterArea[5 * 10]),
212
  context_offset (FloatSave.RegisterArea[6 * 10]),
213
  context_offset (FloatSave.RegisterArea[7 * 10]),
214
#elif defined(SHx)
215
  context_offset (R0),
216
  context_offset (R1),
217
  context_offset (R2),
218
  context_offset (R3),
219
  context_offset (R4),
220
  context_offset (R5),
221
  context_offset (R6),
222
  context_offset (R7),
223
  context_offset (R8),
224
  context_offset (R9),
225
  context_offset (R10),
226
  context_offset (R11),
227
  context_offset (R12),
228
  context_offset (R13),
229
  context_offset (R14),
230
  context_offset (R15),
231
  context_offset (Fir),
232
  context_offset (PR),          /* Procedure Register */
233
  context_offset (GBR),         /* Global Base Register */
234
  context_offset (MACH),        /* Accumulate */
235
  context_offset (MACL),        /* Multiply */
236
  context_offset (Psr),
237
  context_offset (Fpul),
238
  context_offset (Fpscr),
239
  context_offset (FRegs[0]),
240
  context_offset (FRegs[1]),
241
  context_offset (FRegs[2]),
242
  context_offset (FRegs[3]),
243
  context_offset (FRegs[4]),
244
  context_offset (FRegs[5]),
245
  context_offset (FRegs[6]),
246
  context_offset (FRegs[7]),
247
  context_offset (FRegs[8]),
248
  context_offset (FRegs[9]),
249
  context_offset (FRegs[10]),
250
  context_offset (FRegs[11]),
251
  context_offset (FRegs[12]),
252
  context_offset (FRegs[13]),
253
  context_offset (FRegs[14]),
254
  context_offset (FRegs[15]),
255
  context_offset (xFRegs[0]),
256
  context_offset (xFRegs[1]),
257
  context_offset (xFRegs[2]),
258
  context_offset (xFRegs[3]),
259
  context_offset (xFRegs[4]),
260
  context_offset (xFRegs[5]),
261
  context_offset (xFRegs[6]),
262
  context_offset (xFRegs[7]),
263
  context_offset (xFRegs[8]),
264
  context_offset (xFRegs[9]),
265
  context_offset (xFRegs[10]),
266
  context_offset (xFRegs[11]),
267
  context_offset (xFRegs[12]),
268
  context_offset (xFRegs[13]),
269
  context_offset (xFRegs[14]),
270
  context_offset (xFRegs[15]),
271
#elif defined(MIPS)
272
  context_offset (IntZero),
273
  context_offset (IntAt),
274
  context_offset (IntV0),
275
  context_offset (IntV1),
276
  context_offset (IntA0),
277
  context_offset (IntA1),
278
  context_offset (IntA2),
279
  context_offset (IntA3),
280
  context_offset (IntT0),
281
  context_offset (IntT1),
282
  context_offset (IntT2),
283
  context_offset (IntT3),
284
  context_offset (IntT4),
285
  context_offset (IntT5),
286
  context_offset (IntT6),
287
  context_offset (IntT7),
288
  context_offset (IntS0),
289
  context_offset (IntS1),
290
  context_offset (IntS2),
291
  context_offset (IntS3),
292
  context_offset (IntS4),
293
  context_offset (IntS5),
294
  context_offset (IntS6),
295
  context_offset (IntS7),
296
  context_offset (IntT8),
297
  context_offset (IntT9),
298
  context_offset (IntK0),
299
  context_offset (IntK1),
300
  context_offset (IntGp),
301
  context_offset (IntSp),
302
  context_offset (IntS8),
303
  context_offset (IntRa),
304
  context_offset (Psr),
305
  context_offset (IntLo),
306
  context_offset (IntHi),
307
  -1,                           /* bad */
308
  -1,                           /* cause */
309
  context_offset (Fir),
310
  context_offset (FltF0),
311
  context_offset (FltF1),
312
  context_offset (FltF2),
313
  context_offset (FltF3),
314
  context_offset (FltF4),
315
  context_offset (FltF5),
316
  context_offset (FltF6),
317
  context_offset (FltF7),
318
  context_offset (FltF8),
319
  context_offset (FltF9),
320
  context_offset (FltF10),
321
  context_offset (FltF11),
322
  context_offset (FltF12),
323
  context_offset (FltF13),
324
  context_offset (FltF14),
325
  context_offset (FltF15),
326
  context_offset (FltF16),
327
  context_offset (FltF17),
328
  context_offset (FltF18),
329
  context_offset (FltF19),
330
  context_offset (FltF20),
331
  context_offset (FltF21),
332
  context_offset (FltF22),
333
  context_offset (FltF23),
334
  context_offset (FltF24),
335
  context_offset (FltF25),
336
  context_offset (FltF26),
337
  context_offset (FltF27),
338
  context_offset (FltF28),
339
  context_offset (FltF29),
340
  context_offset (FltF30),
341
  context_offset (FltF31),
342
  context_offset (Fsr),
343
  context_offset (Fir),
344
  -1,                           /* fp */
345
#elif defined(ARM)
346
  context_offset (R0),
347
  context_offset (R1),
348
  context_offset (R2),
349
  context_offset (R3),
350
  context_offset (R4),
351
  context_offset (R5),
352
  context_offset (R6),
353
  context_offset (R7),
354
  context_offset (R8),
355
  context_offset (R9),
356
  context_offset (R10),
357
  context_offset (R11),
358
  context_offset (R12),
359
  context_offset (Sp),
360
  context_offset (Lr),
361
  context_offset (Pc),
362
  -1,
363
  -1,
364
  -1,
365
  -1,
366
  -1,
367
  -1,
368
  -1,
369
  -1,
370
  -1,
371
  context_offset (Psr),
372
#endif
373
  -1
374
};
375
 
376
/* Return a pointer into a CONTEXT field indexed by gdb register number.
377
   Return a pointer to an address pointing to zero if there is no
378
   corresponding CONTEXT field for the given register number.
379
 */
380
static ULONG *
381
regptr (LPCONTEXT c, int r)
382
{
383
  static ULONG zero = 0;
384
  ULONG *p;
385
  if (mappings[r] < 0)
386
    p = &zero;
387
  else
388
    p = (ULONG *) (((char *) c) + mappings[r]);
389
  return p;
390
}
391
 
392
/******************** Beginning of stub interface ********************/
393
 
394
/* Stub interface description:
395
 
396
   The Windows CE stub implements a crude RPC.  The hand-held device
397
   connects to gdb using port 7000.  gdb and the stub then communicate
398
   using packets where:
399
 
400
   byte 0:              command id (e.g. Create Process)
401
 
402
   byte 1-4:    DWORD
403
 
404
   byte 1-2:    WORD
405
 
406
   byte 1-2:    length
407
   byte 3-n:    arbitrary memory.
408
 
409
   The interface is deterministic, i.e., if the stub expects a DWORD then
410
   the gdb server should send a DWORD.
411
 */
412
 
413
/* Note:  In the functions below, the `huh' parameter is a string passed from the
414
   function containing a descriptive string concerning the current operation.
415
   This is used for error reporting.
416
 
417
   The 'what' parameter is a command id as found in wince-stub.h.
418
 
419
   Hopefully, the rest of the parameters are self-explanatory.
420
 */
421
 
422
static int s;                   /* communication socket */
423
 
424
/* v-style interface for handling varying argyment list error messages.
425
   Displays the error message in a dialog box and exits when user clicks
426
   on OK. */
427
static void
428
vstub_error (LPCSTR fmt, va_list * args)
429
{
430
  char buf[4096];
431
  vsprintf (buf, fmt, args);
432
  s = -1;
433
  error ("%s", buf);
434
}
435
 
436
/* The standard way to display an error message and exit. */
437
static void
438
stub_error (LPCSTR fmt,...)
439
{
440
  va_list args;
441
  va_start (args, fmt);
442
  vstub_error (fmt, args);
443
}
444
 
445
/* Standard "oh well" can't communicate error.  Someday this might attempt
446
   synchronization. */
447
static void
448
attempt_resync (LPCSTR huh, int s)
449
{
450
  stub_error ("lost synchronization with target attempting %s", huh);
451
}
452
 
453
/* Read arbitrary stuff from a socket. */
454
static int
455
sockread (LPCSTR huh, int s, void *str, size_t n)
456
{
457
  for (;;)
458
    {
459
      if (recv (s, str, n, 0) == n)
460
        return n;
461
      attempt_resync (huh, s);
462
    }
463
}
464
 
465
/* Write arbitrary stuff to a socket. */
466
static int
467
sockwrite (LPCSTR huh, const void *str, size_t n)
468
{
469
  for (;;)
470
    {
471
      if (send (s, str, n, 0) == n)
472
        return n;
473
      attempt_resync (huh, s);
474
    }
475
}
476
 
477
/* Output an id/dword to the host */
478
static void
479
putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
480
{
481
  if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
482
    stub_error ("error writing record id to host for %s", huh);
483
  if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
484
    stub_error ("error writing %s to host.", huh);
485
}
486
 
487
/* Output an id/word to the host */
488
static void
489
putword (LPCSTR huh, gdb_wince_id what, WORD n)
490
{
491
  if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
492
    stub_error ("error writing record id to host for %s", huh);
493
  if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
494
    stub_error ("error writing %s host.", huh);
495
}
496
 
497
/* Convenience define for outputting a "gdb_wince_len" type. */
498
#define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
499
 
500
/* Put an arbitrary block of memory to the gdb host.  This comes in
501
   two chunks an id/dword representing the length and the stream of memory
502
   itself. */
503
static void
504
putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
505
{
506
  putlen (huh, what, len);
507
  if (((short) len > 0) && sockwrite (huh, mem, len) != len)
508
    stub_error ("error writing %s to host.", huh);
509
}
510
 
511
/* Output the result of an operation to the host.  If res != 0, sends a block of
512
   memory starting at mem of len bytes.  If res == 0, sends -GetLastError () and
513
   avoids sending the mem. */
514
static DWORD
515
getdword (LPCSTR huh, gdb_wince_id what_this)
516
{
517
  DWORD n;
518
  gdb_wince_id what;
519
  do
520
    if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
521
      stub_error ("error getting record type from host - %s.", huh);
522
  while (what_this != what);
523
 
524
  if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
525
    stub_error ("error getting %s from host.", huh);
526
 
527
  return n;
528
}
529
 
530
/* Get a an ID (possibly) and a WORD from the host gdb.
531
   Don't bother with the id if the main loop has already
532
   read it. */
533
static WORD
534
getword (LPCSTR huh, gdb_wince_id what_this)
535
{
536
  WORD n;
537
  gdb_wince_id what;
538
  do
539
    if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
540
      stub_error ("error getting record type from host - %s.", huh);
541
  while (what_this != what);
542
 
543
  if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
544
    stub_error ("error getting %s from host.", huh);
545
 
546
  return n;
547
}
548
 
549
/* Handy defines for getting/putting various types of values. */
550
#define gethandle(huh, what) (HANDLE) getdword ((huh), (what))
551
#define getpvoid(huh, what) (LPVOID) getdword ((huh), (what))
552
#define getlen(huh, what) (gdb_wince_len) getword ((huh), (what))
553
#define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h))
554
#define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p))
555
 
556
/* Retrieve the result of an operation from the stub.  If nbytes < 0) then nbytes
557
   is actually an error and nothing else follows.  Use SetLastError to remember this.
558
   if nbytes > 0, retrieve a block of *nbytes into buf.
559
 */
560
int
561
getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
562
{
563
  gdb_wince_len dummy;
564
  if (nbytes == NULL)
565
    nbytes = &dummy;
566
 
567
  *nbytes = getlen (huh, what);
568
 
569
  if ((short) *nbytes < 0)
570
    {
571
      SetLastError (-(short) *nbytes);
572
      return 0;
573
    }
574
 
575
  if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
576
    stub_error ("couldn't read information from wince stub - %s", huh);
577
 
578
  return 1;
579
}
580
 
581
/* Convert "narrow" string to "wide".  Manipulates a buffer ring of 8
582
   buffers which hold the translated string.  This is an arbitrary limit
583
   but it is approximately double the current needs of this module.
584
 */
585
LPWSTR
586
towide (const char *s, gdb_wince_len * out_len)
587
{
588
  static int n = -1;
589
  static LPWSTR outs[8] =
590
  {NULL /*, NULL, etc. */ };
591
  gdb_wince_len dummy;
592
 
593
  if (!out_len)
594
    out_len = &dummy;
595
 
596
  /* First determine the length required to hold the converted string. */
597
  *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
598
  if (!*out_len)
599
    return NULL;                /* The conversion failed */
600
 
601
  if (++n >= (sizeof (outs) / sizeof (outs[0])))
602
    n = 0;                       /* wrap */
603
 
604
  /* Allocate space for the converted string, reusing any previously allocated
605
     space, if applicable. Note that if outs[n] is NULL, xrealloc will act as
606
     a malloc (under cygwin, at least).
607
   */
608
  outs[n] = (LPWSTR) xrealloc (outs[n], *out_len);
609
  memset (outs[n], 0, *out_len);
610
  (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len);
611
  return outs[n];
612
}
613
 
614
/******************** Emulation routines start here. ********************
615
 
616
  The functions below are modelled after their Win32 counterparts.  They are named
617
  similarly to Win32 and take exactly the same arguments except where otherwise noted.
618
  They communicate with the stub on the hand-held device by sending their arguments
619
  over the socket and waiting for results from the socket.
620
 
621
  There is one universal change.  In cases where a length is expected to be returned
622
  in a DWORD, we use a gdb_wince_len type instead.  Currently this is an unsigned short
623
  which is smaller than the standard Win32 DWORD.  This is done to minimize unnecessary
624
  traffic since the connection to Windows CE can be slow.  To change this, modify the
625
  typedef in wince-stub.h and change the putlen/getlen macros in this file and in
626
  the stub.
627
*/
628
 
629
static int
630
create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
631
{
632
  gdb_wince_len len;
633
  LPWSTR buf;
634
 
635
  buf = towide (exec_file, &len);
636
  putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len);
637
  buf = towide (args, &len);
638
  putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len);
639
  putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags);
640
  return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL);
641
}
642
 
643
/* Emulate TerminateProcess.  Don't bother with the second argument since CE
644
   ignores it.
645
 */
646
static int
647
terminate_process (HANDLE h)
648
{
649
  gdb_wince_result res;
650
  if (s < 0)
651
    return 1;
652
  puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
653
  return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
654
}
655
 
656
static int
657
wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
658
{
659
  if (s < 0)
660
    return 1;
661
  putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
662
  return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
663
}
664
 
665
static int
666
get_thread_context (HANDLE h, CONTEXT * c)
667
{
668
  if (s < 0)
669
    return 1;
670
  puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
671
  putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
672
  return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
673
}
674
 
675
static int
676
set_thread_context (HANDLE h, CONTEXT * c)
677
{
678
  gdb_wince_result res;
679
  if (s < 0)
680
    return 1;
681
  puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
682
  putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c));
683
  return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL);
684
}
685
 
686
static int
687
read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
688
{
689
  if (s < 0)
690
    return 1;
691
  puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
692
  putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
693
  putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
694
 
695
  return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
696
}
697
 
698
static int
699
write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
700
{
701
  if (s < 0)
702
    return 1;
703
  puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
704
  putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
705
  putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
706
 
707
  return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
708
}
709
 
710
static int
711
remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
712
{
713
  gdb_wince_len nbytes;
714
  if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
715
                            (LPVOID) myaddr, len, &nbytes))
716
    return -1;
717
  return nbytes;
718
}
719
 
720
static int
721
remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
722
{
723
  gdb_wince_len nbytes;
724
  if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
725
                             (LPCVOID) myaddr, len, &nbytes))
726
    return -1;
727
  return nbytes;
728
}
729
 
730
/* This is not a standard Win32 function.  It instructs the stub to return TRUE
731
   if the thread referenced by HANDLE h is alive.
732
 */
733
static int
734
thread_alive (HANDLE h)
735
{
736
  gdb_wince_result res;
737
  if (s < 0)
738
    return 1;
739
  puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
740
  return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
741
}
742
 
743
static int
744
suspend_thread (HANDLE h)
745
{
746
  if (s < 0)
747
    return 1;
748
  puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
749
  return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
750
}
751
 
752
static int
753
resume_thread (HANDLE h)
754
{
755
  if (s < 0)
756
    return 1;
757
  puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
758
  return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
759
}
760
 
761
static int
762
continue_debug_event (DWORD pid, DWORD tid, DWORD status)
763
{
764
  gdb_wince_result res;
765
  if (s < 0)
766
    return 0;
767
  putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid);
768
  putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid);
769
  putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status);
770
  return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL);
771
}
772
 
773
static int
774
close_handle (HANDLE h)
775
{
776
  gdb_wince_result res;
777
  if (s < 0)
778
    return 1;
779
  puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
780
  return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
781
}
782
 
783
/* This is not a standard Win32 interface.  This function tells the stub
784
   to terminate.
785
 */
786
static void
787
stop_stub (void)
788
{
789
  if (s < 0)
790
    return;
791
  (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
792
  s = -1;
793
}
794
 
795
/******************** End of emulation routines. ********************/
796
/******************** End of stub interface ********************/
797
 
798
#define check_for_step(a, x) (x)
799
 
800
#ifdef MIPS
801
static void
802
undoSStep (thread_info * th)
803
{
804
  if (th->stepped)
805
    {
806
      memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
807
      th->stepped = 0;
808
    }
809
}
810
 
811
void
812
wince_software_single_step (enum target_signal ignore,
813
                            int insert_breakpoints_p)
814
{
815
  unsigned long pc;
816
  thread_info *th = current_thread;     /* Info on currently selected thread */
817
  CORE_ADDR mips_next_pc (CORE_ADDR pc);
818
 
819
  if (!insert_breakpoints_p)
820
    {
821
      undoSStep (th);
822
      return;
823
    }
824
 
825
  th->stepped = 1;
826
  pc = read_register (PC_REGNUM);
827
  th->step_pc = mips_next_pc (pc);
828
  th->step_prev = 0;
829
  memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
830
  return;
831
}
832
#elif SHx
833
/* Hitachi SH architecture instruction encoding masks */
834
 
835
#define COND_BR_MASK   0xff00
836
#define UCOND_DBR_MASK 0xe000
837
#define UCOND_RBR_MASK 0xf0df
838
#define TRAPA_MASK     0xff00
839
 
840
#define COND_DISP      0x00ff
841
#define UCOND_DISP     0x0fff
842
#define UCOND_REG      0x0f00
843
 
844
/* Hitachi SH instruction opcodes */
845
 
846
#define BF_INSTR       0x8b00
847
#define BT_INSTR       0x8900
848
#define BRA_INSTR      0xa000
849
#define BSR_INSTR      0xb000
850
#define JMP_INSTR      0x402b
851
#define JSR_INSTR      0x400b
852
#define RTS_INSTR      0x000b
853
#define RTE_INSTR      0x002b
854
#define TRAPA_INSTR    0xc300
855
#define SSTEP_INSTR    0xc3ff
856
 
857
 
858
#define T_BIT_MASK     0x0001
859
 
860
static CORE_ADDR
861
sh_get_next_pc (CONTEXT *c)
862
{
863
  short *instrMem;
864
  int displacement;
865
  int reg;
866
  unsigned short opcode;
867
 
868
  instrMem = (short *) c->Fir;
869
 
870
  opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));
871
 
872
  if ((opcode & COND_BR_MASK) == BT_INSTR)
873
    {
874
      if (c->Psr & T_BIT_MASK)
875
        {
876
          displacement = (opcode & COND_DISP) << 1;
877
          if (displacement & 0x80)
878
            displacement |= 0xffffff00;
879
          /*
880
             * Remember PC points to second instr.
881
             * after PC of branch ... so add 4
882
           */
883
          instrMem = (short *) (c->Fir + displacement + 4);
884
        }
885
      else
886
        instrMem += 1;
887
    }
888
  else if ((opcode & COND_BR_MASK) == BF_INSTR)
889
    {
890
      if (c->Psr & T_BIT_MASK)
891
        instrMem += 1;
892
      else
893
        {
894
          displacement = (opcode & COND_DISP) << 1;
895
          if (displacement & 0x80)
896
            displacement |= 0xffffff00;
897
          /*
898
             * Remember PC points to second instr.
899
             * after PC of branch ... so add 4
900
           */
901
          instrMem = (short *) (c->Fir + displacement + 4);
902
        }
903
    }
904
  else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
905
    {
906
      displacement = (opcode & UCOND_DISP) << 1;
907
      if (displacement & 0x0800)
908
        displacement |= 0xfffff000;
909
 
910
      /*
911
         * Remember PC points to second instr.
912
         * after PC of branch ... so add 4
913
       */
914
      instrMem = (short *) (c->Fir + displacement + 4);
915
    }
916
  else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
917
    {
918
      reg = (char) ((opcode & UCOND_REG) >> 8);
919
 
920
      instrMem = (short *) *regptr (c, reg);
921
    }
922
  else if (opcode == RTS_INSTR)
923
    instrMem = (short *) c->PR;
924
  else if (opcode == RTE_INSTR)
925
    instrMem = (short *) *regptr (c, 15);
926
  else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
927
    instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
928
  else
929
    instrMem += 1;
930
 
931
  return (CORE_ADDR) instrMem;
932
}
933
/* Single step (in a painstaking fashion) by inspecting the current
934
   instruction and setting a breakpoint on the "next" instruction
935
   which would be executed.  This code hails from sh-stub.c.
936
 */
937
static void
938
undoSStep (thread_info * th)
939
{
940
  if (th->stepped)
941
    {
942
      memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
943
      th->stepped = 0;
944
    }
945
  return;
946
}
947
 
948
/* Single step (in a painstaking fashion) by inspecting the current
949
   instruction and setting a breakpoint on the "next" instruction
950
   which would be executed.  This code hails from sh-stub.c.
951
 */
952
void
953
wince_software_single_step (enum target_signal ignore,
954
                            int insert_breakpoints_p)
955
{
956
  thread_info *th = current_thread;     /* Info on currently selected thread */
957
 
958
  if (!insert_breakpoints_p)
959
    {
960
      undoSStep (th);
961
      return;
962
    }
963
 
964
  th->stepped = 1;
965
  th->step_pc = sh_get_next_pc (&th->context);
966
  th->step_prev = 0;
967
  memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
968
  return;
969
}
970
#elif defined (ARM)
971
#undef check_for_step
972
 
973
static enum target_signal
974
check_for_step (DEBUG_EVENT *ev, enum target_signal x)
975
{
976
  thread_info *th = thread_rec (ev->dwThreadId, 1);
977
 
978
  if (th->stepped &&
979
      th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
980
    return TARGET_SIGNAL_TRAP;
981
  else
982
    return x;
983
}
984
 
985
/* Single step (in a painstaking fashion) by inspecting the current
986
   instruction and setting a breakpoint on the "next" instruction
987
   which would be executed.  This code hails from sh-stub.c.
988
 */
989
static void
990
undoSStep (thread_info * th)
991
{
992
  if (th->stepped)
993
    {
994
      memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
995
      th->stepped = 0;
996
    }
997
}
998
 
999
void
1000
wince_software_single_step (enum target_signal ignore,
1001
                            int insert_breakpoints_p)
1002
{
1003
  unsigned long pc;
1004
  thread_info *th = current_thread;     /* Info on currently selected thread */
1005
  CORE_ADDR mips_next_pc (CORE_ADDR pc);
1006
 
1007
  if (!insert_breakpoints_p)
1008
    {
1009
      undoSStep (th);
1010
      return;
1011
    }
1012
 
1013
  th->stepped = 1;
1014
  pc = read_register (PC_REGNUM);
1015
  th->step_pc = arm_get_next_pc (pc);
1016
  th->step_prev = 0;
1017
  memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
1018
  return;
1019
}
1020
#endif
1021
 
1022
/* Find a thread record given a thread id.
1023
   If get_context then also retrieve the context for this
1024
   thread. */
1025
static thread_info *
1026
thread_rec (DWORD id, int get_context)
1027
{
1028
  thread_info *th;
1029
 
1030
  for (th = &thread_head; (th = th->next) != NULL;)
1031
    if (th->id == id)
1032
      {
1033
        if (!th->suspend_count && get_context)
1034
          {
1035
            if (get_context > 0 && th != this_thread)
1036
              th->suspend_count = suspend_thread (th->h) + 1;
1037
            else if (get_context < 0)
1038
              th->suspend_count = -1;
1039
 
1040
            th->context.ContextFlags = CONTEXT_DEBUGGER;
1041
            get_thread_context (th->h, &th->context);
1042
          }
1043
        return th;
1044
      }
1045
 
1046
  return NULL;
1047
}
1048
 
1049
/* Add a thread to the thread list */
1050
static thread_info *
1051
child_add_thread (DWORD id, HANDLE h)
1052
{
1053
  thread_info *th;
1054
 
1055
  if ((th = thread_rec (id, FALSE)))
1056
    return th;
1057
 
1058
  th = (thread_info *) xmalloc (sizeof (*th));
1059
  memset (th, 0, sizeof (*th));
1060
  th->id = id;
1061
  th->h = h;
1062
  th->next = thread_head.next;
1063
  thread_head.next = th;
1064
  add_thread (id);
1065
  return th;
1066
}
1067
 
1068
/* Clear out any old thread list and reintialize it to a
1069
   pristine state. */
1070
static void
1071
child_init_thread_list (void)
1072
{
1073
  thread_info *th = &thread_head;
1074
 
1075
  DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
1076
  init_thread_list ();
1077
  while (th->next != NULL)
1078
    {
1079
      thread_info *here = th->next;
1080
      th->next = here->next;
1081
      (void) close_handle (here->h);
1082
      xfree (here);
1083
    }
1084
}
1085
 
1086
/* Delete a thread from the list of threads */
1087
static void
1088
child_delete_thread (DWORD id)
1089
{
1090
  thread_info *th;
1091
 
1092
  if (info_verbose)
1093
    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
1094
  delete_thread (id);
1095
 
1096
  for (th = &thread_head;
1097
       th->next != NULL && th->next->id != id;
1098
       th = th->next)
1099
    continue;
1100
 
1101
  if (th->next != NULL)
1102
    {
1103
      thread_info *here = th->next;
1104
      th->next = here->next;
1105
      close_handle (here->h);
1106
      xfree (here);
1107
    }
1108
}
1109
 
1110
static void
1111
check (BOOL ok, const char *file, int line)
1112
{
1113
  if (!ok)
1114
    printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
1115
}
1116
 
1117
static void
1118
do_child_fetch_inferior_registers (int r)
1119
{
1120
  if (r >= 0)
1121
    {
1122
      supply_register (r, (char *) regptr (&current_thread->context, r));
1123
    }
1124
  else
1125
    {
1126
      for (r = 0; r < NUM_REGS; r++)
1127
        do_child_fetch_inferior_registers (r);
1128
    }
1129
}
1130
 
1131
static void
1132
child_fetch_inferior_registers (int r)
1133
{
1134
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
1135
  do_child_fetch_inferior_registers (r);
1136
}
1137
 
1138
static void
1139
do_child_store_inferior_registers (int r)
1140
{
1141
  if (r >= 0)
1142
    read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
1143
  else
1144
    {
1145
      for (r = 0; r < NUM_REGS; r++)
1146
        do_child_store_inferior_registers (r);
1147
    }
1148
}
1149
 
1150
/* Store a new register value into the current thread context */
1151
static void
1152
child_store_inferior_registers (int r)
1153
{
1154
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
1155
  do_child_store_inferior_registers (r);
1156
}
1157
 
1158
/* Wait for child to do something.  Return pid of child, or -1 in case
1159
   of error; store status through argument pointer OURSTATUS.  */
1160
 
1161
static int
1162
handle_load_dll (void *dummy)
1163
{
1164
  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1165
  char dll_buf[MAX_PATH + 1];
1166
  char *p, *bufp, *imgp, *dll_name, *dll_basename;
1167
  int len;
1168
 
1169
  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1170
  if (!event->lpImageName)
1171
    return 1;
1172
 
1173
  len = 0;
1174
  for (bufp = dll_buf, imgp = event->lpImageName;
1175
       bufp < dll_buf + sizeof (dll_buf);
1176
       bufp += 16, imgp += 16)
1177
    {
1178
      gdb_wince_len nbytes = 0;
1179
      (void) read_process_memory (current_process_handle,
1180
                                  imgp, bufp, 16, &nbytes);
1181
 
1182
      if (!nbytes && bufp == dll_buf)
1183
        return 1;               /* couldn't read it */
1184
      for (p = bufp; p < bufp + nbytes; p++)
1185
        {
1186
          len++;
1187
          if (*p == '\0')
1188
            goto out;
1189
          if (event->fUnicode)
1190
            p++;
1191
        }
1192
      if (!nbytes)
1193
        break;
1194
    }
1195
 
1196
out:
1197
  if (!len)
1198
    return 1;
1199
#if 0
1200
  dll_buf[len] = '\0';
1201
#endif
1202
  dll_name = alloca (len);
1203
 
1204
  if (!dll_name)
1205
    return 1;
1206
 
1207
  if (!event->fUnicode)
1208
    memcpy (dll_name, dll_buf, len);
1209
  else
1210
    WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len,
1211
                         dll_name, len, 0, 0);
1212
 
1213
  while ((p = strchr (dll_name, '\\')))
1214
    *p = '/';
1215
 
1216
  /* FIXME!! It would be nice to define one symbol which pointed to the
1217
     front of the dll if we can't find any symbols. */
1218
 
1219
  if (!(dll_basename = strrchr (dll_name, '/')))
1220
    dll_basename = dll_name;
1221
  else
1222
    dll_basename++;
1223
 
1224
  /* The symbols in a dll are offset by 0x1000, which is the
1225
     the offset from 0 of the first byte in an image - because
1226
     of the file header and the section alignment.
1227
 
1228
     FIXME: Is this the real reason that we need the 0x1000 ? */
1229
 
1230
  printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
1231
  printf_unfiltered ("\n");
1232
 
1233
  return 1;
1234
}
1235
 
1236
/* Handle DEBUG_STRING output from child process. */
1237
static void
1238
handle_output_debug_string (struct target_waitstatus *ourstatus)
1239
{
1240
  char p[256];
1241
  char s[255];
1242
  char *q;
1243
  gdb_wince_len nbytes_read;
1244
  gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;
1245
 
1246
  if (nbytes > 255)
1247
    nbytes = 255;
1248
 
1249
  memset (p, 0, sizeof (p));
1250
  if (!read_process_memory (current_process_handle,
1251
                            current_event.u.DebugString.lpDebugStringData,
1252
                            &p, nbytes, &nbytes_read)
1253
      || !*p)
1254
    return;
1255
 
1256
  memset (s, 0, sizeof (s));
1257
  WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) p, (int) nbytes_read, s,
1258
                       sizeof (s) - 1, NULL, NULL);
1259
  q = strchr (s, '\n');
1260
  if (q != NULL)
1261
    {
1262
      *q = '\0';
1263
      if (*--q = '\r')
1264
        *q = '\0';
1265
    }
1266
 
1267
  warning (s);
1268
 
1269
  return;
1270
}
1271
 
1272
/* Handle target exceptions. */
1273
static int
1274
handle_exception (struct target_waitstatus *ourstatus)
1275
{
1276
#if 0
1277
  if (current_event.u.Exception.dwFirstChance)
1278
    return 0;
1279
#endif
1280
 
1281
  ourstatus->kind = TARGET_WAITKIND_STOPPED;
1282
 
1283
  switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
1284
    {
1285
    case EXCEPTION_ACCESS_VIOLATION:
1286
      DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
1287
                     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1288
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1289
      break;
1290
    case STATUS_STACK_OVERFLOW:
1291
      DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
1292
                     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1293
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1294
      break;
1295
    case EXCEPTION_BREAKPOINT:
1296
      DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
1297
                     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1298
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1299
      break;
1300
    case DBG_CONTROL_C:
1301
      DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
1302
                     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1303
      ourstatus->value.sig = TARGET_SIGNAL_INT;
1304
      /* User typed CTRL-C.  Continue with this status */
1305
      last_sig = SIGINT;        /* FIXME - should check pass state */
1306
      break;
1307
    case EXCEPTION_SINGLE_STEP:
1308
      DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
1309
                     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1310
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1311
      break;
1312
    case EXCEPTION_ILLEGAL_INSTRUCTION:
1313
      DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
1314
               current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1315
      ourstatus->value.sig = check_for_step (&current_event, TARGET_SIGNAL_ILL);
1316
      break;
1317
    default:
1318
      /* This may be a structured exception handling exception.  In
1319
         that case, we want to let the program try to handle it, and
1320
         only break if we see the exception a second time.  */
1321
 
1322
      printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
1323
                    current_event.u.Exception.ExceptionRecord.ExceptionCode,
1324
                current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1325
      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1326
      break;
1327
    }
1328
  exception_count++;
1329
  return 1;
1330
}
1331
 
1332
/* Resume all artificially suspended threads if we are continuing
1333
   execution */
1334
static BOOL
1335
child_continue (DWORD continue_status, int id)
1336
{
1337
  int i;
1338
  thread_info *th;
1339
  BOOL res;
1340
 
1341
  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
1342
                 (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId));
1343
  res = continue_debug_event (current_event.dwProcessId,
1344
                              current_event.dwThreadId,
1345
                              continue_status);
1346
  if (res)
1347
    for (th = &thread_head; (th = th->next) != NULL;)
1348
      if (((id == -1) || (id == th->id)) && th->suspend_count)
1349
        {
1350
          for (i = 0; i < th->suspend_count; i++)
1351
            (void) resume_thread (th->h);
1352
          th->suspend_count = 0;
1353
        }
1354
 
1355
  return res;
1356
}
1357
 
1358
/* Get the next event from the child.  Return 1 if the event requires
1359
   handling by WFI (or whatever).
1360
 */
1361
static int
1362
get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
1363
                       DWORD target_event_code, int *retval)
1364
{
1365
  int breakout = 0;
1366
  BOOL debug_event;
1367
  DWORD continue_status, event_code;
1368
  thread_info *th = NULL;
1369
  static thread_info dummy_thread_info;
1370
 
1371
  if (!(debug_event = wait_for_debug_event (&current_event, 1000)))
1372
    {
1373
      *retval = 0;
1374
      goto out;
1375
    }
1376
 
1377
  event_count++;
1378
  continue_status = DBG_CONTINUE;
1379
  *retval = 0;
1380
 
1381
  event_code = current_event.dwDebugEventCode;
1382
  breakout = event_code == target_event_code;
1383
 
1384
  switch (event_code)
1385
    {
1386
    case CREATE_THREAD_DEBUG_EVENT:
1387
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1388
                     (unsigned) current_event.dwProcessId,
1389
                     (unsigned) current_event.dwThreadId,
1390
                     "CREATE_THREAD_DEBUG_EVENT"));
1391
      /* Record the existence of this thread */
1392
      th = child_add_thread (current_event.dwThreadId,
1393
                             current_event.u.CreateThread.hThread);
1394
      if (info_verbose)
1395
        printf_unfiltered ("[New %s]\n",
1396
                           target_pid_to_str (current_event.dwThreadId));
1397
      break;
1398
 
1399
    case EXIT_THREAD_DEBUG_EVENT:
1400
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1401
                     (unsigned) current_event.dwProcessId,
1402
                     (unsigned) current_event.dwThreadId,
1403
                     "EXIT_THREAD_DEBUG_EVENT"));
1404
      child_delete_thread (current_event.dwThreadId);
1405
      th = &dummy_thread_info;
1406
      break;
1407
 
1408
    case CREATE_PROCESS_DEBUG_EVENT:
1409
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1410
                     (unsigned) current_event.dwProcessId,
1411
                     (unsigned) current_event.dwThreadId,
1412
                     "CREATE_PROCESS_DEBUG_EVENT"));
1413
      current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1414
 
1415
      main_thread_id = current_event.dwThreadId;
1416
      inferior_ptid = pid_to_ptid (main_thread_id);
1417
      /* Add the main thread */
1418
      th = child_add_thread (PIDGET (inferior_ptid),
1419
                             current_event.u.CreateProcessInfo.hThread);
1420
      break;
1421
 
1422
    case EXIT_PROCESS_DEBUG_EVENT:
1423
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1424
                     (unsigned) current_event.dwProcessId,
1425
                     (unsigned) current_event.dwThreadId,
1426
                     "EXIT_PROCESS_DEBUG_EVENT"));
1427
      ourstatus->kind = TARGET_WAITKIND_EXITED;
1428
      ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1429
      close_handle (current_process_handle);
1430
      *retval = current_event.dwProcessId;
1431
      breakout = 1;
1432
      break;
1433
 
1434
    case LOAD_DLL_DEBUG_EVENT:
1435
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1436
                     (unsigned) current_event.dwProcessId,
1437
                     (unsigned) current_event.dwThreadId,
1438
                     "LOAD_DLL_DEBUG_EVENT"));
1439
      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1440
      registers_changed ();     /* mark all regs invalid */
1441
      break;
1442
 
1443
    case UNLOAD_DLL_DEBUG_EVENT:
1444
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1445
                     (unsigned) current_event.dwProcessId,
1446
                     (unsigned) current_event.dwThreadId,
1447
                     "UNLOAD_DLL_DEBUG_EVENT"));
1448
      break;                    /* FIXME: don't know what to do here */
1449
 
1450
    case EXCEPTION_DEBUG_EVENT:
1451
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1452
                     (unsigned) current_event.dwProcessId,
1453
                     (unsigned) current_event.dwThreadId,
1454
                     "EXCEPTION_DEBUG_EVENT"));
1455
      if (handle_exception (ourstatus))
1456
        *retval = current_event.dwThreadId;
1457
      else
1458
        {
1459
          continue_status = DBG_EXCEPTION_NOT_HANDLED;
1460
          breakout = 0;
1461
        }
1462
      break;
1463
 
1464
    case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
1465
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1466
                     (unsigned) current_event.dwProcessId,
1467
                     (unsigned) current_event.dwThreadId,
1468
                     "OUTPUT_DEBUG_STRING_EVENT"));
1469
      handle_output_debug_string ( ourstatus);
1470
      break;
1471
    default:
1472
      printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
1473
                         current_event.dwProcessId,
1474
                         current_event.dwThreadId);
1475
      printf_unfiltered ("                 unknown event code %d\n",
1476
                         current_event.dwDebugEventCode);
1477
      break;
1478
    }
1479
 
1480
  if (breakout)
1481
    this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1482
  else
1483
    CHECK (child_continue (continue_status, -1));
1484
 
1485
out:
1486
  return breakout;
1487
}
1488
 
1489
/* Wait for interesting events to occur in the target process. */
1490
static ptid_t
1491
child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1492
{
1493
  DWORD event_code;
1494
  int retval;
1495
  int pid = PIDGET (ptid);
1496
 
1497
  /* We loop when we get a non-standard exception rather than return
1498
     with a SPURIOUS because resume can try and step or modify things,
1499
     which needs a current_thread->h.  But some of these exceptions mark
1500
     the birth or death of threads, which mean that the current thread
1501
     isn't necessarily what you think it is. */
1502
 
1503
  while (1)
1504
    if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
1505
      return pid_to_ptid (retval);
1506
    else
1507
      {
1508
        int detach = 0;
1509
 
1510
        if (ui_loop_hook != NULL)
1511
          detach = ui_loop_hook (0);
1512
 
1513
        if (detach)
1514
          child_kill_inferior ();
1515
      }
1516
}
1517
 
1518
/* Print status information about what we're accessing.  */
1519
 
1520
static void
1521
child_files_info (struct target_ops *ignore)
1522
{
1523
  printf_unfiltered ("\tUsing the running image of child %s.\n",
1524
                     target_pid_to_str (inferior_ptid));
1525
}
1526
 
1527
/* ARGSUSED */
1528
static void
1529
child_open (char *arg, int from_tty)
1530
{
1531
  error ("Use the \"run\" command to start a child process.");
1532
}
1533
 
1534
#define FACTOR (0x19db1ded53ea710LL)
1535
#define NSPERSEC 10000000
1536
 
1537
/* Convert a Win32 time to "UNIX" format. */
1538
long
1539
to_time_t (FILETIME * ptr)
1540
{
1541
  /* A file time is the number of 100ns since jan 1 1601
1542
     stuffed into two long words.
1543
     A time_t is the number of seconds since jan 1 1970.  */
1544
 
1545
  long rem;
1546
  long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime);
1547
  x -= FACTOR;                  /* number of 100ns between 1601 and 1970 */
1548
  rem = x % ((long long) NSPERSEC);
1549
  rem += (NSPERSEC / 2);
1550
  x /= (long long) NSPERSEC;    /* number of 100ns in a second */
1551
  x += (long long) (rem / NSPERSEC);
1552
  return x;
1553
}
1554
 
1555
/* Upload a file to the remote device depending on the user's
1556
   'set remoteupload' specification. */
1557
char *
1558
upload_to_device (const char *to, const char *from)
1559
{
1560
  HANDLE h;
1561
  const char *dir = remote_directory ?: "\\gdb";
1562
  int len;
1563
  static char *remotefile = NULL;
1564
  LPWSTR wstr;
1565
  char *p;
1566
  DWORD err;
1567
  const char *in_to = to;
1568
  FILETIME crtime, actime, wrtime;
1569
  time_t utime;
1570
  struct stat st;
1571
  int fd;
1572
 
1573
  /* Look for a path separator and only use trailing part. */
1574
  while ((p = strpbrk (to, "/\\")) != NULL)
1575
    to = p + 1;
1576
 
1577
  if (!*to)
1578
    error ("no filename found to upload - %s.", in_to);
1579
 
1580
  len = strlen (dir) + strlen (to) + 2;
1581
  remotefile = (char *) xrealloc (remotefile, len);
1582
  strcpy (remotefile, dir);
1583
  strcat (remotefile, "\\");
1584
  strcat (remotefile, to);
1585
 
1586
  if (upload_when == UPLOAD_NEVER)
1587
    return remotefile;          /* Don't bother uploading. */
1588
 
1589
  /* Open the source. */
1590
  if ((fd = openp (getenv ("PATH"), TRUE, (char *) from, O_RDONLY, 0, NULL)) < 0)
1591
    error ("couldn't open %s", from);
1592
 
1593
  /* Get the time for later comparison. */
1594
  if (fstat (fd, &st))
1595
    st.st_mtime = (time_t) - 1;
1596
 
1597
  /* Always attempt to create the directory on the remote system. */
1598
  wstr = towide (dir, NULL);
1599
  (void) CeCreateDirectory (wstr, NULL);
1600
 
1601
  /* Attempt to open the remote file, creating it if it doesn't exist. */
1602
  wstr = towide (remotefile, NULL);
1603
  h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1604
                    OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1605
 
1606
  /* Some kind of problem? */
1607
  err = CeGetLastError ();
1608
  if (h == NULL || h == INVALID_HANDLE_VALUE)
1609
    error ("error opening file \"%s\".  Windows error %d.",
1610
           remotefile, err);
1611
 
1612
  CeGetFileTime (h, &crtime, &actime, &wrtime);
1613
  utime = to_time_t (&wrtime);
1614
#if 0
1615
  if (utime < st.st_mtime)
1616
    {
1617
      char buf[80];
1618
      strcpy (buf, ctime(&utime));
1619
      printf ("%s < %s\n", buf, ctime(&st.st_mtime));
1620
    }
1621
#endif
1622
  /* See if we need to upload the file. */
1623
  if (upload_when == UPLOAD_ALWAYS ||
1624
      err != ERROR_ALREADY_EXISTS ||
1625
      !CeGetFileTime (h, &crtime, &actime, &wrtime) ||
1626
      to_time_t (&wrtime) < st.st_mtime)
1627
    {
1628
      DWORD nbytes;
1629
      char buf[4096];
1630
      int n;
1631
 
1632
      /* Upload the file. */
1633
      while ((n = read (fd, buf, sizeof (buf))) > 0)
1634
        if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL))
1635
          error ("error writing to remote device - %d.",
1636
                 CeGetLastError ());
1637
    }
1638
 
1639
  close (fd);
1640
  if (!CeCloseHandle (h))
1641
    error ("error closing remote file - %d.", CeGetLastError ());
1642
 
1643
  return remotefile;
1644
}
1645
 
1646
/* Initialize the connection to the remote device. */
1647
static void
1648
wince_initialize (void)
1649
{
1650
  int tmp;
1651
  char args[256];
1652
  char *hostname;
1653
  struct sockaddr_in sin;
1654
  char *stub_file_name;
1655
  int s0;
1656
  PROCESS_INFORMATION pi;
1657
 
1658
  if (!connection_initialized)
1659
    switch (CeRapiInit ())
1660
      {
1661
      case 0:
1662
        connection_initialized = 1;
1663
        break;
1664
      default:
1665
        CeRapiUninit ();
1666
        error ("Can't initialize connection to remote device.\n");
1667
        break;
1668
      }
1669
 
1670
  /* Upload the stub to the handheld device. */
1671
  stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB);
1672
  strcpy (args, stub_file_name);
1673
 
1674
  if (remote_add_host)
1675
    {
1676
      strcat (args, " ");
1677
      hostname = strchr (args, '\0');
1678
      if (gethostname (hostname, sizeof (args) - strlen (args)))
1679
        error ("couldn't get hostname of this system.");
1680
    }
1681
 
1682
  /* Get a socket. */
1683
  if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1684
    stub_error ("Couldn't connect to host system.");
1685
 
1686
  /* Allow rapid reuse of the port. */
1687
  tmp = 1;
1688
  (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1689
 
1690
 
1691
  /* Set up the information for connecting to the host gdb process. */
1692
  memset (&sin, 0, sizeof (sin));
1693
  sin.sin_family = AF_INET;
1694
  sin.sin_port = htons (7000);  /* FIXME: This should be configurable */
1695
 
1696
  if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
1697
    error ("couldn't bind socket");
1698
 
1699
  if (listen (s0, 1))
1700
    error ("Couldn't open socket for listening.\n");
1701
 
1702
  /* Start up the stub on the remote device. */
1703
  if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL),
1704
                        NULL, NULL, 0, 0, NULL, NULL, NULL, &pi))
1705
    error ("Unable to start remote stub '%s'.  Windows CE error %d.",
1706
           stub_file_name, CeGetLastError ());
1707
 
1708
  /* Wait for a connection */
1709
 
1710
  if ((s = accept (s0, NULL, NULL)) < 0)
1711
    error ("couldn't set up server for connection.");
1712
 
1713
  close (s0);
1714
}
1715
 
1716
/* Start an inferior win32 child process and sets inferior_ptid to its pid.
1717
   EXEC_FILE is the file to run.
1718
   ALLARGS is a string containing the arguments to the program.
1719
   ENV is the environment vector to pass.  Errors reported with error().  */
1720
static void
1721
child_create_inferior (char *exec_file, char *args, char **env)
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 (&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 (&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
struct target_ops child_ops;
1890
 
1891
static void
1892
init_child_ops (void)
1893
{
1894
  memset (&child_ops, 0, sizeof (child_ops));
1895
  child_ops.to_shortname = (char *) "child";
1896
  child_ops.to_longname = (char *) "Windows CE process";
1897
  child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command).";
1898
  child_ops.to_open = child_open;
1899
  child_ops.to_close = child_close;
1900
  child_ops.to_resume = child_resume;
1901
  child_ops.to_wait = child_wait;
1902
  child_ops.to_fetch_registers = child_fetch_inferior_registers;
1903
  child_ops.to_store_registers = child_store_inferior_registers;
1904
  child_ops.to_prepare_to_store = child_prepare_to_store;
1905
  child_ops.to_xfer_memory = child_xfer_memory;
1906
  child_ops.to_files_info = child_files_info;
1907
  child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1908
  child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1909
  child_ops.to_terminal_init = terminal_init_inferior;
1910
  child_ops.to_terminal_inferior = terminal_inferior;
1911
  child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1912
  child_ops.to_terminal_ours = terminal_ours;
1913
  child_ops.to_terminal_save_ours = terminal_save_ours;
1914
  child_ops.to_terminal_info = child_terminal_info;
1915
  child_ops.to_kill = child_kill_inferior;
1916
  child_ops.to_load = child_load;
1917
  child_ops.to_create_inferior = child_create_inferior;
1918
  child_ops.to_mourn_inferior = child_mourn_inferior;
1919
  child_ops.to_can_run = child_can_run;
1920
  child_ops.to_thread_alive = win32_child_thread_alive;
1921
  child_ops.to_stratum = process_stratum;
1922
  child_ops.to_has_all_memory = 1;
1923
  child_ops.to_has_memory = 1;
1924
  child_ops.to_has_stack = 1;
1925
  child_ops.to_has_registers = 1;
1926
  child_ops.to_has_execution = 1;
1927
  child_ops.to_sections = 0;
1928
  child_ops.to_sections_end = 0;
1929
  child_ops.to_magic = OPS_MAGIC;
1930
}
1931
 
1932
 
1933
/* Handle 'set remoteupload' parameter. */
1934
 
1935
#define replace_upload(what) \
1936
      upload_when = what; \
1937
      remote_upload = xrealloc (remote_upload, strlen (upload_options[upload_when].name) + 1); \
1938
      strcpy (remote_upload, upload_options[upload_when].name);
1939
 
1940
static void
1941
set_upload_type (char *ignore, int from_tty)
1942
{
1943
  int i, len;
1944
  char *bad_option;
1945
 
1946
  if (!remote_upload || !remote_upload[0])
1947
    {
1948
      replace_upload (UPLOAD_NEWER);
1949
      if (from_tty)
1950
        printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
1951
      return;
1952
    }
1953
 
1954
  len = strlen (remote_upload);
1955
  for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++)
1956
    if (len >= upload_options[i].abbrev &&
1957
        strncasecmp (remote_upload, upload_options[i].name, len) == 0)
1958
      {
1959
        replace_upload (i);
1960
        return;
1961
      }
1962
 
1963
  bad_option = remote_upload;
1964
  replace_upload (UPLOAD_NEWER);
1965
  error ("Unknown upload type: %s.", bad_option);
1966
}
1967
 
1968
void
1969
_initialize_wince (void)
1970
{
1971
  struct cmd_list_element *set;
1972
  init_child_ops ();
1973
 
1974
  add_show_from_set
1975
    (add_set_cmd ((char *) "remotedirectory", no_class,
1976
                  var_string_noescape, (char *) &remote_directory,
1977
                  (char *) "Set directory for remote upload.\n",
1978
                  &setlist),
1979
     &showlist);
1980
  remote_directory = xstrdup (remote_directory);
1981
 
1982
  set = add_set_cmd ((char *) "remoteupload", no_class,
1983
                     var_string_noescape, (char *) &remote_upload,
1984
               (char *) "Set how to upload executables to remote device.\n",
1985
                     &setlist);
1986
  add_show_from_set (set, &showlist);
1987
  set_cmd_cfunc (set, set_upload_type);
1988
  set_upload_type (NULL, 0);
1989
 
1990
  add_show_from_set
1991
    (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
1992
                  (char *) &debug_exec,
1993
              (char *) "Set whether to display execution in child process.",
1994
                  &setlist),
1995
     &showlist);
1996
 
1997
  add_show_from_set
1998
    (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
1999
                  (char *) &remote_add_host,
2000
                  (char *) "Set whether to add this host to remote stub arguments for\n
2001
debugging over a network.", &setlist),
2002
     &showlist);
2003
 
2004
  add_show_from_set
2005
    (add_set_cmd ((char *) "debugevents", class_support, var_boolean,
2006
                  (char *) &debug_events,
2007
          (char *) "Set whether to display kernel events in child process.",
2008
                  &setlist),
2009
     &showlist);
2010
 
2011
  add_show_from_set
2012
    (add_set_cmd ((char *) "debugmemory", class_support, var_boolean,
2013
                  (char *) &debug_memory,
2014
        (char *) "Set whether to display memory accesses in child process.",
2015
                  &setlist),
2016
     &showlist);
2017
 
2018
  add_show_from_set
2019
    (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean,
2020
                  (char *) &debug_exceptions,
2021
      (char *) "Set whether to display kernel exceptions in child process.",
2022
                  &setlist),
2023
     &showlist);
2024
 
2025
  add_target (&child_ops);
2026
}
2027
 
2028
/* Determine if the thread referenced by "pid" is alive
2029
   by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
2030
   it means that the pid has died.  Otherwise it is assumed to be alive. */
2031
static int
2032
win32_child_thread_alive (ptid_t ptid)
2033
{
2034
  int pid = PIDGET (ptid);
2035
  return thread_alive (thread_rec (pid, FALSE)->h);
2036
}
2037
 
2038
/* Convert pid to printable format. */
2039
char *
2040
cygwin_pid_to_str (int pid)
2041
{
2042
  static char buf[80];
2043
  if (pid == current_event.dwProcessId)
2044
    sprintf (buf, "process %d", pid);
2045
  else
2046
    sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);
2047
  return buf;
2048
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.