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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [gdbserver/] [win32-low.c] - Blame information for rev 826

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Low level interface to Windows debugging, for gdbserver.
2
   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3
 
4
   Contributed by Leo Zayas.  Based on "win32-nat.c" from GDB.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "server.h"
22
#include "regcache.h"
23
#include "gdb/signals.h"
24
#include "gdb/fileio.h"
25
#include "mem-break.h"
26
#include "win32-low.h"
27
 
28
#include <windows.h>
29
#include <winnt.h>
30
#include <imagehlp.h>
31
#include <tlhelp32.h>
32
#include <psapi.h>
33
#include <sys/param.h>
34
#include <malloc.h>
35
#include <process.h>
36
 
37
#ifndef USE_WIN32API
38
#include <sys/cygwin.h>
39
#endif
40
 
41
#define OUTMSG(X) do { printf X; fflush (stderr); } while (0)
42
 
43
#define OUTMSG2(X) \
44
  do                                            \
45
    {                                           \
46
      if (debug_threads)                        \
47
        {                                       \
48
          printf X;                             \
49
          fflush (stderr);                      \
50
        }                                       \
51
    } while (0)
52
 
53
#ifndef _T
54
#define _T(x) TEXT (x)
55
#endif
56
 
57
#ifndef COUNTOF
58
#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
59
#endif
60
 
61
#ifdef _WIN32_WCE
62
# define GETPROCADDRESS(DLL, PROC) \
63
  ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC)))
64
#else
65
# define GETPROCADDRESS(DLL, PROC) \
66
  ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
67
#endif
68
 
69
int using_threads = 1;
70
 
71
/* Globals.  */
72
static int attaching = 0;
73
static HANDLE current_process_handle = NULL;
74
static DWORD current_process_id = 0;
75
static DWORD main_thread_id = 0;
76
static enum target_signal last_sig = TARGET_SIGNAL_0;
77
 
78
/* The current debug event from WaitForDebugEvent.  */
79
static DEBUG_EVENT current_event;
80
 
81
/* Non zero if an interrupt request is to be satisfied by suspending
82
   all threads.  */
83
static int soft_interrupt_requested = 0;
84
 
85
/* Non zero if the inferior is stopped in a simulated breakpoint done
86
   by suspending all the threads.  */
87
static int faked_breakpoint = 0;
88
 
89
#define NUM_REGS (the_low_target.num_regs)
90
 
91
typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
92
typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
93
typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
94
typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
95
 
96
static void win32_resume (struct thread_resume *resume_info, size_t n);
97
 
98
/* Get the thread ID from the current selected inferior (the current
99
   thread).  */
100
static ptid_t
101
current_inferior_ptid (void)
102
{
103
  return ((struct inferior_list_entry*) current_inferior)->id;
104
}
105
 
106
/* The current debug event from WaitForDebugEvent.  */
107
static ptid_t
108
debug_event_ptid (DEBUG_EVENT *event)
109
{
110
  return ptid_build (event->dwProcessId, event->dwThreadId, 0);
111
}
112
 
113
/* Get the thread context of the thread associated with TH.  */
114
 
115
static void
116
win32_get_thread_context (win32_thread_info *th)
117
{
118
  memset (&th->context, 0, sizeof (CONTEXT));
119
  (*the_low_target.get_thread_context) (th, &current_event);
120
#ifdef _WIN32_WCE
121
  memcpy (&th->base_context, &th->context, sizeof (CONTEXT));
122
#endif
123
}
124
 
125
/* Set the thread context of the thread associated with TH.  */
126
 
127
static void
128
win32_set_thread_context (win32_thread_info *th)
129
{
130
#ifdef _WIN32_WCE
131
  /* Calling SuspendThread on a thread that is running kernel code
132
     will report that the suspending was successful, but in fact, that
133
     will often not be true.  In those cases, the context returned by
134
     GetThreadContext will not be correct by the time the thread
135
     stops, hence we can't set that context back into the thread when
136
     resuming - it will most likelly crash the inferior.
137
     Unfortunately, there is no way to know when the thread will
138
     really stop.  To work around it, we'll only write the context
139
     back to the thread when either the user or GDB explicitly change
140
     it between stopping and resuming.  */
141
  if (memcmp (&th->context, &th->base_context, sizeof (CONTEXT)) != 0)
142
#endif
143
    (*the_low_target.set_thread_context) (th, &current_event);
144
}
145
 
146
/* Find a thread record given a thread id.  If GET_CONTEXT is set then
147
   also retrieve the context for this thread.  */
148
static win32_thread_info *
149
thread_rec (ptid_t ptid, int get_context)
150
{
151
  struct thread_info *thread;
152
  win32_thread_info *th;
153
 
154
  thread = (struct thread_info *) find_inferior_id (&all_threads, ptid);
155
  if (thread == NULL)
156
    return NULL;
157
 
158
  th = inferior_target_data (thread);
159
  if (get_context && th->context.ContextFlags == 0)
160
    {
161
      if (!th->suspended)
162
        {
163
          if (SuspendThread (th->h) == (DWORD) -1)
164
            {
165
              DWORD err = GetLastError ();
166
              OUTMSG (("warning: SuspendThread failed in thread_rec, "
167
                       "(error %d): %s\n", (int) err, strwinerror (err)));
168
            }
169
          else
170
            th->suspended = 1;
171
        }
172
 
173
      win32_get_thread_context (th);
174
    }
175
 
176
  return th;
177
}
178
 
179
/* Add a thread to the thread list.  */
180
static win32_thread_info *
181
child_add_thread (DWORD pid, DWORD tid, HANDLE h)
182
{
183
  win32_thread_info *th;
184
  ptid_t ptid = ptid_build (pid, tid, 0);
185
 
186
  if ((th = thread_rec (ptid, FALSE)))
187
    return th;
188
 
189
  th = xcalloc (1, sizeof (*th));
190
  th->tid = tid;
191
  th->h = h;
192
 
193
  add_thread (ptid, th);
194
  set_inferior_regcache_data ((struct thread_info *)
195
                              find_inferior_id (&all_threads, ptid),
196
                              new_register_cache ());
197
 
198
  if (the_low_target.thread_added != NULL)
199
    (*the_low_target.thread_added) (th);
200
 
201
  return th;
202
}
203
 
204
/* Delete a thread from the list of threads.  */
205
static void
206
delete_thread_info (struct inferior_list_entry *thread)
207
{
208
  win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
209
 
210
  remove_thread ((struct thread_info *) thread);
211
  CloseHandle (th->h);
212
  free (th);
213
}
214
 
215
/* Delete a thread from the list of threads.  */
216
static void
217
child_delete_thread (DWORD pid, DWORD tid)
218
{
219
  struct inferior_list_entry *thread;
220
  ptid_t ptid;
221
 
222
  /* If the last thread is exiting, just return.  */
223
  if (all_threads.head == all_threads.tail)
224
    return;
225
 
226
  ptid = ptid_build (pid, tid, 0);
227
  thread = find_inferior_id (&all_threads, ptid);
228
  if (thread == NULL)
229
    return;
230
 
231
  delete_thread_info (thread);
232
}
233
 
234
/* These watchpoint related wrapper functions simply pass on the function call
235
   if the low target has registered a corresponding function.  */
236
 
237
static int
238
win32_insert_point (char type, CORE_ADDR addr, int len)
239
{
240
  if (the_low_target.insert_point != NULL)
241
    return the_low_target.insert_point (type, addr, len);
242
  else
243
    /* Unsupported (see target.h).  */
244
    return 1;
245
}
246
 
247
static int
248
win32_remove_point (char type, CORE_ADDR addr, int len)
249
{
250
  if (the_low_target.remove_point != NULL)
251
    return the_low_target.remove_point (type, addr, len);
252
  else
253
    /* Unsupported (see target.h).  */
254
    return 1;
255
}
256
 
257
static int
258
win32_stopped_by_watchpoint (void)
259
{
260
  if (the_low_target.stopped_by_watchpoint != NULL)
261
    return the_low_target.stopped_by_watchpoint ();
262
  else
263
    return 0;
264
}
265
 
266
static CORE_ADDR
267
win32_stopped_data_address (void)
268
{
269
  if (the_low_target.stopped_data_address != NULL)
270
    return the_low_target.stopped_data_address ();
271
  else
272
    return 0;
273
}
274
 
275
 
276
/* Transfer memory from/to the debugged process.  */
277
static int
278
child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
279
                   int write, struct target_ops *target)
280
{
281
  SIZE_T done;
282
  long addr = (long) memaddr;
283
 
284
  if (write)
285
    {
286
      WriteProcessMemory (current_process_handle, (LPVOID) addr,
287
                          (LPCVOID) our, len, &done);
288
      FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
289
    }
290
  else
291
    {
292
      ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
293
                         len, &done);
294
    }
295
  return done;
296
}
297
 
298
/* Clear out any old thread list and reinitialize it to a pristine
299
   state. */
300
static void
301
child_init_thread_list (void)
302
{
303
  for_each_inferior (&all_threads, delete_thread_info);
304
}
305
 
306
static void
307
do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
308
{
309
  last_sig = TARGET_SIGNAL_0;
310
 
311
  current_process_handle = proch;
312
  current_process_id = pid;
313
  main_thread_id = 0;
314
 
315
  soft_interrupt_requested = 0;
316
  faked_breakpoint = 0;
317
 
318
  memset (&current_event, 0, sizeof (current_event));
319
 
320
  add_process (pid, attached);
321
  child_init_thread_list ();
322
 
323
  if (the_low_target.initial_stuff != NULL)
324
    (*the_low_target.initial_stuff) ();
325
}
326
 
327
/* Resume all artificially suspended threads if we are continuing
328
   execution.  */
329
static int
330
continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
331
{
332
  struct thread_info *thread = (struct thread_info *) this_thread;
333
  int thread_id = * (int *) id_ptr;
334
  win32_thread_info *th = inferior_target_data (thread);
335
 
336
  if ((thread_id == -1 || thread_id == th->tid)
337
      && th->suspended)
338
    {
339
      if (th->context.ContextFlags)
340
        {
341
          win32_set_thread_context (th);
342
          th->context.ContextFlags = 0;
343
        }
344
 
345
      if (ResumeThread (th->h) == (DWORD) -1)
346
        {
347
          DWORD err = GetLastError ();
348
          OUTMSG (("warning: ResumeThread failed in continue_one_thread, "
349
                   "(error %d): %s\n", (int) err, strwinerror (err)));
350
        }
351
      th->suspended = 0;
352
    }
353
 
354
  return 0;
355
}
356
 
357
static BOOL
358
child_continue (DWORD continue_status, int thread_id)
359
{
360
  /* The inferior will only continue after the ContinueDebugEvent
361
     call.  */
362
  find_inferior (&all_threads, continue_one_thread, &thread_id);
363
  faked_breakpoint = 0;
364
 
365
  if (!ContinueDebugEvent (current_event.dwProcessId,
366
                           current_event.dwThreadId,
367
                           continue_status))
368
    return FALSE;
369
 
370
  return TRUE;
371
}
372
 
373
/* Fetch register(s) from the current thread context.  */
374
static void
375
child_fetch_inferior_registers (struct regcache *regcache, int r)
376
{
377
  int regno;
378
  win32_thread_info *th = thread_rec (current_inferior_ptid (), TRUE);
379
  if (r == -1 || r > NUM_REGS)
380
    child_fetch_inferior_registers (regcache, NUM_REGS);
381
  else
382
    for (regno = 0; regno < r; regno++)
383
      (*the_low_target.fetch_inferior_register) (regcache, th, regno);
384
}
385
 
386
/* Store a new register value into the current thread context.  We don't
387
   change the program's context until later, when we resume it.  */
388
static void
389
child_store_inferior_registers (struct regcache *regcache, int r)
390
{
391
  int regno;
392
  win32_thread_info *th = thread_rec (current_inferior_ptid (), TRUE);
393
  if (r == -1 || r == 0 || r > NUM_REGS)
394
    child_store_inferior_registers (regcache, NUM_REGS);
395
  else
396
    for (regno = 0; regno < r; regno++)
397
      (*the_low_target.store_inferior_register) (regcache, th, regno);
398
}
399
 
400
/* Map the Windows error number in ERROR to a locale-dependent error
401
   message string and return a pointer to it.  Typically, the values
402
   for ERROR come from GetLastError.
403
 
404
   The string pointed to shall not be modified by the application,
405
   but may be overwritten by a subsequent call to strwinerror
406
 
407
   The strwinerror function does not change the current setting
408
   of GetLastError.  */
409
 
410
char *
411
strwinerror (DWORD error)
412
{
413
  static char buf[1024];
414
  TCHAR *msgbuf;
415
  DWORD lasterr = GetLastError ();
416
  DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
417
                               | FORMAT_MESSAGE_ALLOCATE_BUFFER,
418
                               NULL,
419
                               error,
420
                               0, /* Default language */
421
                               (LPVOID)&msgbuf,
422
                               0,
423
                               NULL);
424
  if (chars != 0)
425
    {
426
      /* If there is an \r\n appended, zap it.  */
427
      if (chars >= 2
428
          && msgbuf[chars - 2] == '\r'
429
          && msgbuf[chars - 1] == '\n')
430
        {
431
          chars -= 2;
432
          msgbuf[chars] = 0;
433
        }
434
 
435
      if (chars > ((COUNTOF (buf)) - 1))
436
        {
437
          chars = COUNTOF (buf) - 1;
438
          msgbuf [chars] = 0;
439
        }
440
 
441
#ifdef UNICODE
442
      wcstombs (buf, msgbuf, chars + 1);
443
#else
444
      strncpy (buf, msgbuf, chars + 1);
445
#endif
446
      LocalFree (msgbuf);
447
    }
448
  else
449
    sprintf (buf, "unknown win32 error (%ld)", error);
450
 
451
  SetLastError (lasterr);
452
  return buf;
453
}
454
 
455
static BOOL
456
create_process (const char *program, char *args,
457
                DWORD flags, PROCESS_INFORMATION *pi)
458
{
459
  BOOL ret;
460
 
461
#ifdef _WIN32_WCE
462
  wchar_t *p, *wprogram, *wargs;
463
  size_t argslen;
464
 
465
  wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
466
  mbstowcs (wprogram, program, strlen (program) + 1);
467
 
468
  for (p = wprogram; *p; ++p)
469
    if (L'/' == *p)
470
      *p = L'\\';
471
 
472
  argslen = strlen (args);
473
  wargs = alloca ((argslen + 1) * sizeof (wchar_t));
474
  mbstowcs (wargs, args, argslen + 1);
475
 
476
  ret = CreateProcessW (wprogram, /* image name */
477
                        wargs,    /* command line */
478
                        NULL,     /* security, not supported */
479
                        NULL,     /* thread, not supported */
480
                        FALSE,    /* inherit handles, not supported */
481
                        flags,    /* start flags */
482
                        NULL,     /* environment, not supported */
483
                        NULL,     /* current directory, not supported */
484
                        NULL,     /* start info, not supported */
485
                        pi);      /* proc info */
486
#else
487
  STARTUPINFOA si = { sizeof (STARTUPINFOA) };
488
 
489
  ret = CreateProcessA (program,  /* image name */
490
                        args,     /* command line */
491
                        NULL,     /* security */
492
                        NULL,     /* thread */
493
                        TRUE,     /* inherit handles */
494
                        flags,    /* start flags */
495
                        NULL,     /* environment */
496
                        NULL,     /* current directory */
497
                        &si,      /* start info */
498
                        pi);      /* proc info */
499
#endif
500
 
501
  return ret;
502
}
503
 
504
/* Start a new process.
505
   PROGRAM is a path to the program to execute.
506
   ARGS is a standard NULL-terminated array of arguments,
507
   to be passed to the inferior as ``argv''.
508
   Returns the new PID on success, -1 on failure.  Registers the new
509
   process with the process list.  */
510
static int
511
win32_create_inferior (char *program, char **program_args)
512
{
513
#ifndef USE_WIN32API
514
  char real_path[MAXPATHLEN];
515
  char *orig_path, *new_path, *path_ptr;
516
#endif
517
  BOOL ret;
518
  DWORD flags;
519
  char *args;
520
  int argslen;
521
  int argc;
522
  PROCESS_INFORMATION pi;
523
  DWORD err;
524
 
525
  /* win32_wait needs to know we're not attaching.  */
526
  attaching = 0;
527
 
528
  if (!program)
529
    error ("No executable specified, specify executable to debug.\n");
530
 
531
  flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
532
 
533
#ifndef USE_WIN32API
534
  orig_path = NULL;
535
  path_ptr = getenv ("PATH");
536
  if (path_ptr)
537
    {
538
      orig_path = alloca (strlen (path_ptr) + 1);
539
      new_path = alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr));
540
      strcpy (orig_path, path_ptr);
541
      cygwin_posix_to_win32_path_list (path_ptr, new_path);
542
      setenv ("PATH", new_path, 1);
543
    }
544
  cygwin_conv_to_win32_path (program, real_path);
545
  program = real_path;
546
#endif
547
 
548
  argslen = 1;
549
  for (argc = 1; program_args[argc]; argc++)
550
    argslen += strlen (program_args[argc]) + 1;
551
  args = alloca (argslen);
552
  args[0] = '\0';
553
  for (argc = 1; program_args[argc]; argc++)
554
    {
555
      /* FIXME: Can we do better about quoting?  How does Cygwin
556
         handle this?  */
557
      strcat (args, " ");
558
      strcat (args, program_args[argc]);
559
    }
560
  OUTMSG2 (("Command line is \"%s\"\n", args));
561
 
562
#ifdef CREATE_NEW_PROCESS_GROUP
563
  flags |= CREATE_NEW_PROCESS_GROUP;
564
#endif
565
 
566
  ret = create_process (program, args, flags, &pi);
567
  err = GetLastError ();
568
  if (!ret && err == ERROR_FILE_NOT_FOUND)
569
    {
570
      char *exename = alloca (strlen (program) + 5);
571
      strcat (strcpy (exename, program), ".exe");
572
      ret = create_process (exename, args, flags, &pi);
573
      err = GetLastError ();
574
    }
575
 
576
#ifndef USE_WIN32API
577
  if (orig_path)
578
    setenv ("PATH", orig_path, 1);
579
#endif
580
 
581
  if (!ret)
582
    {
583
      error ("Error creating process \"%s%s\", (error %d): %s\n",
584
             program, args, (int) err, strwinerror (err));
585
    }
586
  else
587
    {
588
      OUTMSG2 (("Process created: %s\n", (char *) args));
589
    }
590
 
591
#ifndef _WIN32_WCE
592
  /* On Windows CE this handle can't be closed.  The OS reuses
593
     it in the debug events, while the 9x/NT versions of Windows
594
     probably use a DuplicateHandle'd one.  */
595
  CloseHandle (pi.hThread);
596
#endif
597
 
598
  do_initial_child_stuff (pi.hProcess, pi.dwProcessId, 0);
599
 
600
  return current_process_id;
601
}
602
 
603
/* Attach to a running process.
604
   PID is the process ID to attach to, specified by the user
605
   or a higher layer.  */
606
static int
607
win32_attach (unsigned long pid)
608
{
609
  HANDLE h;
610
  winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
611
  DWORD err;
612
#ifdef _WIN32_WCE
613
  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
614
#else
615
  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
616
#endif
617
  DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
618
 
619
  h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
620
  if (h != NULL)
621
    {
622
      if (DebugActiveProcess (pid))
623
        {
624
          if (DebugSetProcessKillOnExit != NULL)
625
            DebugSetProcessKillOnExit (FALSE);
626
 
627
          /* win32_wait needs to know we're attaching.  */
628
          attaching = 1;
629
          do_initial_child_stuff (h, pid, 1);
630
          return 0;
631
        }
632
 
633
      CloseHandle (h);
634
    }
635
 
636
  err = GetLastError ();
637
  error ("Attach to process failed (error %d): %s\n",
638
         (int) err, strwinerror (err));
639
}
640
 
641
/* Handle OUTPUT_DEBUG_STRING_EVENT from child process.  */
642
static void
643
handle_output_debug_string (struct target_waitstatus *ourstatus)
644
{
645
#define READ_BUFFER_LEN 1024
646
  CORE_ADDR addr;
647
  char s[READ_BUFFER_LEN + 1] = { 0 };
648
  DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
649
 
650
  if (nbytes == 0)
651
    return;
652
 
653
  if (nbytes > READ_BUFFER_LEN)
654
    nbytes = READ_BUFFER_LEN;
655
 
656
  addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
657
 
658
  if (current_event.u.DebugString.fUnicode)
659
    {
660
      /* The event tells us how many bytes, not chars, even
661
         in Unicode.  */
662
      WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
663
      if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
664
        return;
665
      wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
666
    }
667
  else
668
    {
669
      if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
670
        return;
671
    }
672
 
673
  if (strncmp (s, "cYg", 3) != 0)
674
    {
675
      if (!server_waiting)
676
        {
677
          OUTMSG2(("%s", s));
678
          return;
679
        }
680
 
681
      monitor_output (s);
682
    }
683
#undef READ_BUFFER_LEN
684
}
685
 
686
static void
687
win32_clear_inferiors (void)
688
{
689
  if (current_process_handle != NULL)
690
    CloseHandle (current_process_handle);
691
 
692
  for_each_inferior (&all_threads, delete_thread_info);
693
  clear_inferiors ();
694
}
695
 
696
/* Kill all inferiors.  */
697
static int
698
win32_kill (int pid)
699
{
700
  struct process_info *process;
701
 
702
  if (current_process_handle == NULL)
703
    return -1;
704
 
705
  TerminateProcess (current_process_handle, 0);
706
  for (;;)
707
    {
708
      if (!child_continue (DBG_CONTINUE, -1))
709
        break;
710
      if (!WaitForDebugEvent (&current_event, INFINITE))
711
        break;
712
      if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
713
        break;
714
      else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
715
        {
716
          struct target_waitstatus our_status = { 0 };
717
          handle_output_debug_string (&our_status);
718
        }
719
    }
720
 
721
  win32_clear_inferiors ();
722
 
723
  process = find_process_pid (pid);
724
  remove_process (process);
725
  return 0;
726
}
727
 
728
/* Detach from inferior PID.  */
729
static int
730
win32_detach (int pid)
731
{
732
  struct process_info *process;
733
  winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
734
  winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
735
#ifdef _WIN32_WCE
736
  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
737
#else
738
  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
739
#endif
740
  DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
741
  DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
742
 
743
  if (DebugSetProcessKillOnExit == NULL
744
      || DebugActiveProcessStop == NULL)
745
    return -1;
746
 
747
  {
748
    struct thread_resume resume;
749
    resume.thread = minus_one_ptid;
750
    resume.kind = resume_continue;
751
    resume.sig = 0;
752
    win32_resume (&resume, 1);
753
  }
754
 
755
  if (!DebugActiveProcessStop (current_process_id))
756
    return -1;
757
 
758
  DebugSetProcessKillOnExit (FALSE);
759
  process = find_process_pid (pid);
760
  remove_process (process);
761
 
762
  win32_clear_inferiors ();
763
  return 0;
764
}
765
 
766
/* Wait for inferiors to end.  */
767
static void
768
win32_join (int pid)
769
{
770
  HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
771
  if (h != NULL)
772
    {
773
      WaitForSingleObject (h, INFINITE);
774
      CloseHandle (h);
775
    }
776
}
777
 
778
/* Return 1 iff the thread with thread ID TID is alive.  */
779
static int
780
win32_thread_alive (ptid_t ptid)
781
{
782
  int res;
783
 
784
  /* Our thread list is reliable; don't bother to poll target
785
     threads.  */
786
  if (find_inferior_id (&all_threads, ptid) != NULL)
787
    res = 1;
788
  else
789
    res = 0;
790
  return res;
791
}
792
 
793
/* Resume the inferior process.  RESUME_INFO describes how we want
794
   to resume.  */
795
static void
796
win32_resume (struct thread_resume *resume_info, size_t n)
797
{
798
  DWORD tid;
799
  enum target_signal sig;
800
  int step;
801
  win32_thread_info *th;
802
  DWORD continue_status = DBG_CONTINUE;
803
  ptid_t ptid;
804
 
805
  /* This handles the very limited set of resume packets that GDB can
806
     currently produce.  */
807
 
808
  if (n == 1 && ptid_equal (resume_info[0].thread, minus_one_ptid))
809
    tid = -1;
810
  else if (n > 1)
811
    tid = -1;
812
  else
813
    /* Yes, we're ignoring resume_info[0].thread.  It'd be tricky to make
814
       the Windows resume code do the right thing for thread switching.  */
815
    tid = current_event.dwThreadId;
816
 
817
  if (!ptid_equal (resume_info[0].thread, minus_one_ptid))
818
    {
819
      sig = resume_info[0].sig;
820
      step = resume_info[0].kind == resume_step;
821
    }
822
  else
823
    {
824
      sig = 0;
825
      step = 0;
826
    }
827
 
828
  if (sig != TARGET_SIGNAL_0)
829
    {
830
      if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
831
        {
832
          OUTMSG (("Cannot continue with signal %d here.\n", sig));
833
        }
834
      else if (sig == last_sig)
835
        continue_status = DBG_EXCEPTION_NOT_HANDLED;
836
      else
837
        OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
838
    }
839
 
840
  last_sig = TARGET_SIGNAL_0;
841
 
842
  /* Get context for the currently selected thread.  */
843
  ptid = debug_event_ptid (&current_event);
844
  th = thread_rec (ptid, FALSE);
845
  if (th)
846
    {
847
      if (th->context.ContextFlags)
848
        {
849
          /* Move register values from the inferior into the thread
850
             context structure.  */
851
          regcache_invalidate ();
852
 
853
          if (step)
854
            {
855
              if (the_low_target.single_step != NULL)
856
                (*the_low_target.single_step) (th);
857
              else
858
                error ("Single stepping is not supported "
859
                       "in this configuration.\n");
860
            }
861
 
862
          win32_set_thread_context (th);
863
          th->context.ContextFlags = 0;
864
        }
865
    }
866
 
867
  /* Allow continuing with the same signal that interrupted us.
868
     Otherwise complain.  */
869
 
870
  child_continue (continue_status, tid);
871
}
872
 
873
static void
874
win32_add_one_solib (const char *name, CORE_ADDR load_addr)
875
{
876
  char buf[MAX_PATH + 1];
877
  char buf2[MAX_PATH + 1];
878
 
879
#ifdef _WIN32_WCE
880
  WIN32_FIND_DATA w32_fd;
881
  WCHAR wname[MAX_PATH + 1];
882
  mbstowcs (wname, name, MAX_PATH);
883
  HANDLE h = FindFirstFile (wname, &w32_fd);
884
#else
885
  WIN32_FIND_DATAA w32_fd;
886
  HANDLE h = FindFirstFileA (name, &w32_fd);
887
#endif
888
 
889
  if (h == INVALID_HANDLE_VALUE)
890
    strcpy (buf, name);
891
  else
892
    {
893
      FindClose (h);
894
      strcpy (buf, name);
895
#ifndef _WIN32_WCE
896
      {
897
        char cwd[MAX_PATH + 1];
898
        char *p;
899
        if (GetCurrentDirectoryA (MAX_PATH + 1, cwd))
900
          {
901
            p = strrchr (buf, '\\');
902
            if (p)
903
              p[1] = '\0';
904
            SetCurrentDirectoryA (buf);
905
            GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p);
906
            SetCurrentDirectoryA (cwd);
907
          }
908
      }
909
#endif
910
    }
911
 
912
#ifndef _WIN32_WCE
913
  if (strcasecmp (buf, "ntdll.dll") == 0)
914
    {
915
      GetSystemDirectoryA (buf, sizeof (buf));
916
      strcat (buf, "\\ntdll.dll");
917
    }
918
#endif
919
 
920
#ifdef __CYGWIN__
921
  cygwin_conv_to_posix_path (buf, buf2);
922
#else
923
  strcpy (buf2, buf);
924
#endif
925
 
926
  loaded_dll (buf2, load_addr);
927
}
928
 
929
static char *
930
get_image_name (HANDLE h, void *address, int unicode)
931
{
932
  static char buf[(2 * MAX_PATH) + 1];
933
  DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
934
  char *address_ptr;
935
  int len = 0;
936
  char b[2];
937
  DWORD done;
938
 
939
  /* Attempt to read the name of the dll that was detected.
940
     This is documented to work only when actively debugging
941
     a program.  It will not work for attached processes. */
942
  if (address == NULL)
943
    return NULL;
944
 
945
#ifdef _WIN32_WCE
946
  /* Windows CE reports the address of the image name,
947
     instead of an address of a pointer into the image name.  */
948
  address_ptr = address;
949
#else
950
  /* See if we could read the address of a string, and that the
951
     address isn't null. */
952
  if (!ReadProcessMemory (h, address,  &address_ptr,
953
                          sizeof (address_ptr), &done)
954
      || done != sizeof (address_ptr)
955
      || !address_ptr)
956
    return NULL;
957
#endif
958
 
959
  /* Find the length of the string */
960
  while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
961
         && (b[0] != 0 || b[size - 1] != 0) && done == size)
962
    continue;
963
 
964
  if (!unicode)
965
    ReadProcessMemory (h, address_ptr, buf, len, &done);
966
  else
967
    {
968
      WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
969
      ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
970
                         &done);
971
 
972
      WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
973
    }
974
 
975
  return buf;
976
}
977
 
978
typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *,
979
                                                  DWORD, LPDWORD);
980
typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE,
981
                                                    LPMODULEINFO, DWORD);
982
typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE,
983
                                                     LPSTR, DWORD);
984
 
985
static winapi_EnumProcessModules win32_EnumProcessModules;
986
static winapi_GetModuleInformation win32_GetModuleInformation;
987
static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA;
988
 
989
static BOOL
990
load_psapi (void)
991
{
992
  static int psapi_loaded = 0;
993
  static HMODULE dll = NULL;
994
 
995
  if (!psapi_loaded)
996
    {
997
      psapi_loaded = 1;
998
      dll = LoadLibrary (TEXT("psapi.dll"));
999
      if (!dll)
1000
        return FALSE;
1001
      win32_EnumProcessModules =
1002
              GETPROCADDRESS (dll, EnumProcessModules);
1003
      win32_GetModuleInformation =
1004
              GETPROCADDRESS (dll, GetModuleInformation);
1005
      win32_GetModuleFileNameExA =
1006
              GETPROCADDRESS (dll, GetModuleFileNameExA);
1007
    }
1008
 
1009
  return (win32_EnumProcessModules != NULL
1010
          && win32_GetModuleInformation != NULL
1011
          && win32_GetModuleFileNameExA != NULL);
1012
}
1013
 
1014
static int
1015
psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1016
{
1017
  DWORD len;
1018
  MODULEINFO mi;
1019
  size_t i;
1020
  HMODULE dh_buf[1];
1021
  HMODULE *DllHandle = dh_buf;
1022
  DWORD cbNeeded;
1023
  BOOL ok;
1024
 
1025
  if (!load_psapi ())
1026
    goto failed;
1027
 
1028
  cbNeeded = 0;
1029
  ok = (*win32_EnumProcessModules) (current_process_handle,
1030
                                    DllHandle,
1031
                                    sizeof (HMODULE),
1032
                                    &cbNeeded);
1033
 
1034
  if (!ok || !cbNeeded)
1035
    goto failed;
1036
 
1037
  DllHandle = (HMODULE *) alloca (cbNeeded);
1038
  if (!DllHandle)
1039
    goto failed;
1040
 
1041
  ok = (*win32_EnumProcessModules) (current_process_handle,
1042
                                    DllHandle,
1043
                                    cbNeeded,
1044
                                    &cbNeeded);
1045
  if (!ok)
1046
    goto failed;
1047
 
1048
  for (i = 0; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++)
1049
    {
1050
      if (!(*win32_GetModuleInformation) (current_process_handle,
1051
                                          DllHandle[i],
1052
                                          &mi,
1053
                                          sizeof (mi)))
1054
        {
1055
          DWORD err = GetLastError ();
1056
          error ("Can't get module info: (error %d): %s\n",
1057
                 (int) err, strwinerror (err));
1058
        }
1059
 
1060
      if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
1061
        {
1062
          len = (*win32_GetModuleFileNameExA) (current_process_handle,
1063
                                               DllHandle[i],
1064
                                               dll_name_ret,
1065
                                               MAX_PATH);
1066
          if (len == 0)
1067
            {
1068
              DWORD err = GetLastError ();
1069
              error ("Error getting dll name: (error %d): %s\n",
1070
                     (int) err, strwinerror (err));
1071
            }
1072
          return 1;
1073
        }
1074
    }
1075
 
1076
failed:
1077
  dll_name_ret[0] = '\0';
1078
  return 0;
1079
}
1080
 
1081
typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD);
1082
typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32);
1083
typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32);
1084
 
1085
static winapi_CreateToolhelp32Snapshot win32_CreateToolhelp32Snapshot;
1086
static winapi_Module32First win32_Module32First;
1087
static winapi_Module32Next win32_Module32Next;
1088
#ifdef _WIN32_WCE
1089
typedef BOOL (WINAPI *winapi_CloseToolhelp32Snapshot) (HANDLE);
1090
static winapi_CloseToolhelp32Snapshot win32_CloseToolhelp32Snapshot;
1091
#endif
1092
 
1093
static BOOL
1094
load_toolhelp (void)
1095
{
1096
  static int toolhelp_loaded = 0;
1097
  static HMODULE dll = NULL;
1098
 
1099
  if (!toolhelp_loaded)
1100
    {
1101
      toolhelp_loaded = 1;
1102
#ifndef _WIN32_WCE
1103
      dll = GetModuleHandle (_T("KERNEL32.DLL"));
1104
#else
1105
      dll = LoadLibrary (L"TOOLHELP.DLL");
1106
#endif
1107
      if (!dll)
1108
        return FALSE;
1109
 
1110
      win32_CreateToolhelp32Snapshot =
1111
        GETPROCADDRESS (dll, CreateToolhelp32Snapshot);
1112
      win32_Module32First = GETPROCADDRESS (dll, Module32First);
1113
      win32_Module32Next = GETPROCADDRESS (dll, Module32Next);
1114
#ifdef _WIN32_WCE
1115
      win32_CloseToolhelp32Snapshot =
1116
        GETPROCADDRESS (dll, CloseToolhelp32Snapshot);
1117
#endif
1118
    }
1119
 
1120
  return (win32_CreateToolhelp32Snapshot != NULL
1121
          && win32_Module32First != NULL
1122
          && win32_Module32Next != NULL
1123
#ifdef _WIN32_WCE
1124
          && win32_CloseToolhelp32Snapshot != NULL
1125
#endif
1126
          );
1127
}
1128
 
1129
static int
1130
toolhelp_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1131
{
1132
  HANDLE snapshot_module;
1133
  MODULEENTRY32 modEntry = { sizeof (MODULEENTRY32) };
1134
  int found = 0;
1135
 
1136
  if (!load_toolhelp ())
1137
    return 0;
1138
 
1139
  snapshot_module = win32_CreateToolhelp32Snapshot (TH32CS_SNAPMODULE,
1140
                                                    current_event.dwProcessId);
1141
  if (snapshot_module == INVALID_HANDLE_VALUE)
1142
    return 0;
1143
 
1144
  /* Ignore the first module, which is the exe.  */
1145
  if (win32_Module32First (snapshot_module, &modEntry))
1146
    while (win32_Module32Next (snapshot_module, &modEntry))
1147
      if ((DWORD) modEntry.modBaseAddr == BaseAddress)
1148
        {
1149
#ifdef UNICODE
1150
          wcstombs (dll_name_ret, modEntry.szExePath, MAX_PATH + 1);
1151
#else
1152
          strcpy (dll_name_ret, modEntry.szExePath);
1153
#endif
1154
          found = 1;
1155
          break;
1156
        }
1157
 
1158
#ifdef _WIN32_WCE
1159
  win32_CloseToolhelp32Snapshot (snapshot_module);
1160
#else
1161
  CloseHandle (snapshot_module);
1162
#endif
1163
  return found;
1164
}
1165
 
1166
static void
1167
handle_load_dll (void)
1168
{
1169
  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1170
  char dll_buf[MAX_PATH + 1];
1171
  char *dll_name = NULL;
1172
  DWORD load_addr;
1173
 
1174
  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
1175
 
1176
  /* Windows does not report the image name of the dlls in the debug
1177
     event on attaches.  We resort to iterating over the list of
1178
     loaded dlls looking for a match by image base.  */
1179
  if (!psapi_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf))
1180
    {
1181
      if (!server_waiting)
1182
        /* On some versions of Windows and Windows CE, we can't create
1183
           toolhelp snapshots while the inferior is stopped in a
1184
           LOAD_DLL_DEBUG_EVENT due to a dll load, but we can while
1185
           Windows is reporting the already loaded dlls.  */
1186
        toolhelp_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf);
1187
    }
1188
 
1189
  dll_name = dll_buf;
1190
 
1191
  if (*dll_name == '\0')
1192
    dll_name = get_image_name (current_process_handle,
1193
                               event->lpImageName, event->fUnicode);
1194
  if (!dll_name)
1195
    return;
1196
 
1197
  /* The symbols in a dll are offset by 0x1000, which is the
1198
     the offset from 0 of the first byte in an image - because
1199
     of the file header and the section alignment. */
1200
 
1201
  load_addr = (DWORD) event->lpBaseOfDll + 0x1000;
1202
  win32_add_one_solib (dll_name, load_addr);
1203
}
1204
 
1205
static void
1206
handle_unload_dll (void)
1207
{
1208
  CORE_ADDR load_addr =
1209
          (CORE_ADDR) (DWORD) current_event.u.UnloadDll.lpBaseOfDll;
1210
  load_addr += 0x1000;
1211
  unloaded_dll (NULL, load_addr);
1212
}
1213
 
1214
static void
1215
handle_exception (struct target_waitstatus *ourstatus)
1216
{
1217
  DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
1218
 
1219
  ourstatus->kind = TARGET_WAITKIND_STOPPED;
1220
 
1221
  switch (code)
1222
    {
1223
    case EXCEPTION_ACCESS_VIOLATION:
1224
      OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
1225
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1226
      break;
1227
    case STATUS_STACK_OVERFLOW:
1228
      OUTMSG2 (("STATUS_STACK_OVERFLOW"));
1229
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1230
      break;
1231
    case STATUS_FLOAT_DENORMAL_OPERAND:
1232
      OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
1233
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1234
      break;
1235
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1236
      OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
1237
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1238
      break;
1239
    case STATUS_FLOAT_INEXACT_RESULT:
1240
      OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
1241
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1242
      break;
1243
    case STATUS_FLOAT_INVALID_OPERATION:
1244
      OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
1245
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1246
      break;
1247
    case STATUS_FLOAT_OVERFLOW:
1248
      OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
1249
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1250
      break;
1251
    case STATUS_FLOAT_STACK_CHECK:
1252
      OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
1253
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1254
      break;
1255
    case STATUS_FLOAT_UNDERFLOW:
1256
      OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
1257
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1258
      break;
1259
    case STATUS_FLOAT_DIVIDE_BY_ZERO:
1260
      OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
1261
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1262
      break;
1263
    case STATUS_INTEGER_DIVIDE_BY_ZERO:
1264
      OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
1265
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1266
      break;
1267
    case STATUS_INTEGER_OVERFLOW:
1268
      OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
1269
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1270
      break;
1271
    case EXCEPTION_BREAKPOINT:
1272
      OUTMSG2 (("EXCEPTION_BREAKPOINT"));
1273
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1274
#ifdef _WIN32_WCE
1275
      /* Remove the initial breakpoint.  */
1276
      check_breakpoints ((CORE_ADDR) (long) current_event
1277
                         .u.Exception.ExceptionRecord.ExceptionAddress);
1278
#endif
1279
      break;
1280
    case DBG_CONTROL_C:
1281
      OUTMSG2 (("DBG_CONTROL_C"));
1282
      ourstatus->value.sig = TARGET_SIGNAL_INT;
1283
      break;
1284
    case DBG_CONTROL_BREAK:
1285
      OUTMSG2 (("DBG_CONTROL_BREAK"));
1286
      ourstatus->value.sig = TARGET_SIGNAL_INT;
1287
      break;
1288
    case EXCEPTION_SINGLE_STEP:
1289
      OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
1290
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1291
      break;
1292
    case EXCEPTION_ILLEGAL_INSTRUCTION:
1293
      OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
1294
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1295
      break;
1296
    case EXCEPTION_PRIV_INSTRUCTION:
1297
      OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
1298
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1299
      break;
1300
    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1301
      OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
1302
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1303
      break;
1304
    default:
1305
      if (current_event.u.Exception.dwFirstChance)
1306
        {
1307
          ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1308
          return;
1309
        }
1310
      OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
1311
                current_event.u.Exception.ExceptionRecord.ExceptionCode,
1312
                (DWORD) current_event.u.Exception.ExceptionRecord.
1313
                ExceptionAddress));
1314
      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1315
      break;
1316
    }
1317
  OUTMSG2 (("\n"));
1318
  last_sig = ourstatus->value.sig;
1319
}
1320
 
1321
 
1322
static void
1323
suspend_one_thread (struct inferior_list_entry *entry)
1324
{
1325
  struct thread_info *thread = (struct thread_info *) entry;
1326
  win32_thread_info *th = inferior_target_data (thread);
1327
 
1328
  if (!th->suspended)
1329
    {
1330
      if (SuspendThread (th->h) == (DWORD) -1)
1331
        {
1332
          DWORD err = GetLastError ();
1333
          OUTMSG (("warning: SuspendThread failed in suspend_one_thread, "
1334
                   "(error %d): %s\n", (int) err, strwinerror (err)));
1335
        }
1336
      else
1337
        th->suspended = 1;
1338
    }
1339
}
1340
 
1341
static void
1342
fake_breakpoint_event (void)
1343
{
1344
  OUTMSG2(("fake_breakpoint_event\n"));
1345
 
1346
  faked_breakpoint = 1;
1347
 
1348
  memset (&current_event, 0, sizeof (current_event));
1349
  current_event.dwThreadId = main_thread_id;
1350
  current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
1351
  current_event.u.Exception.ExceptionRecord.ExceptionCode
1352
    = EXCEPTION_BREAKPOINT;
1353
 
1354
  for_each_inferior (&all_threads, suspend_one_thread);
1355
}
1356
 
1357
#ifdef _WIN32_WCE
1358
static int
1359
auto_delete_breakpoint (CORE_ADDR stop_pc)
1360
{
1361
  return 1;
1362
}
1363
#endif
1364
 
1365
/* Get the next event from the child.  */
1366
 
1367
static int
1368
get_child_debug_event (struct target_waitstatus *ourstatus)
1369
{
1370
  ptid_t ptid;
1371
 
1372
  last_sig = TARGET_SIGNAL_0;
1373
  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1374
 
1375
  /* Check if GDB sent us an interrupt request.  */
1376
  check_remote_input_interrupt_request ();
1377
 
1378
  if (soft_interrupt_requested)
1379
    {
1380
      soft_interrupt_requested = 0;
1381
      fake_breakpoint_event ();
1382
      goto gotevent;
1383
    }
1384
 
1385
#ifndef _WIN32_WCE
1386
  attaching = 0;
1387
#else
1388
  if (attaching)
1389
    {
1390
      /* WinCE doesn't set an initial breakpoint automatically.  To
1391
         stop the inferior, we flush all currently pending debug
1392
         events -- the thread list and the dll list are always
1393
         reported immediatelly without delay, then, we suspend all
1394
         threads and pretend we saw a trap at the current PC of the
1395
         main thread.
1396
 
1397
         Contrary to desktop Windows, Windows CE *does* report the dll
1398
         names on LOAD_DLL_DEBUG_EVENTs resulting from a
1399
         DebugActiveProcess call.  This limits the way we can detect
1400
         if all the dlls have already been reported.  If we get a real
1401
         debug event before leaving attaching, the worst that will
1402
         happen is the user will see a spurious breakpoint.  */
1403
 
1404
      current_event.dwDebugEventCode = 0;
1405
      if (!WaitForDebugEvent (&current_event, 0))
1406
        {
1407
          OUTMSG2(("no attach events left\n"));
1408
          fake_breakpoint_event ();
1409
          attaching = 0;
1410
        }
1411
      else
1412
        OUTMSG2(("got attach event\n"));
1413
    }
1414
  else
1415
#endif
1416
    {
1417
      /* Keep the wait time low enough for confortable remote
1418
         interruption, but high enough so gdbserver doesn't become a
1419
         bottleneck.  */
1420
      if (!WaitForDebugEvent (&current_event, 250))
1421
        {
1422
          DWORD e  = GetLastError();
1423
 
1424
          if (e == ERROR_PIPE_NOT_CONNECTED)
1425
            {
1426
              /* This will happen if the loader fails to succesfully
1427
                 load the application, e.g., if the main executable
1428
                 tries to pull in a non-existing export from a
1429
                 DLL.  */
1430
              ourstatus->kind = TARGET_WAITKIND_EXITED;
1431
              ourstatus->value.integer = 1;
1432
              return 1;
1433
            }
1434
 
1435
          return 0;
1436
        }
1437
    }
1438
 
1439
 gotevent:
1440
 
1441
  switch (current_event.dwDebugEventCode)
1442
    {
1443
    case CREATE_THREAD_DEBUG_EVENT:
1444
      OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
1445
                "for pid=%d tid=%x)\n",
1446
                (unsigned) current_event.dwProcessId,
1447
                (unsigned) current_event.dwThreadId));
1448
 
1449
      /* Record the existence of this thread.  */
1450
      child_add_thread (current_event.dwProcessId,
1451
                        current_event.dwThreadId,
1452
                        current_event.u.CreateThread.hThread);
1453
      break;
1454
 
1455
    case EXIT_THREAD_DEBUG_EVENT:
1456
      OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
1457
                "for pid=%d tid=%x\n",
1458
                (unsigned) current_event.dwProcessId,
1459
                (unsigned) current_event.dwThreadId));
1460
      child_delete_thread (current_event.dwProcessId,
1461
                           current_event.dwThreadId);
1462
 
1463
      current_inferior = (struct thread_info *) all_threads.head;
1464
      return 1;
1465
 
1466
    case CREATE_PROCESS_DEBUG_EVENT:
1467
      OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1468
                "for pid=%d tid=%x\n",
1469
                (unsigned) current_event.dwProcessId,
1470
                (unsigned) current_event.dwThreadId));
1471
      CloseHandle (current_event.u.CreateProcessInfo.hFile);
1472
 
1473
      current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1474
      main_thread_id = current_event.dwThreadId;
1475
 
1476
      ourstatus->kind = TARGET_WAITKIND_EXECD;
1477
      ourstatus->value.execd_pathname = "Main executable";
1478
 
1479
      /* Add the main thread.  */
1480
      child_add_thread (current_event.dwProcessId,
1481
                        main_thread_id,
1482
                        current_event.u.CreateProcessInfo.hThread);
1483
 
1484
      ourstatus->value.related_pid = debug_event_ptid (&current_event);
1485
#ifdef _WIN32_WCE
1486
      if (!attaching)
1487
        {
1488
          /* Windows CE doesn't set the initial breakpoint
1489
             automatically like the desktop versions of Windows do.
1490
             We add it explicitly here.  It will be removed as soon as
1491
             it is hit.  */
1492
          set_breakpoint_at ((CORE_ADDR) (long) current_event.u
1493
                             .CreateProcessInfo.lpStartAddress,
1494
                             auto_delete_breakpoint);
1495
        }
1496
#endif
1497
      break;
1498
 
1499
    case EXIT_PROCESS_DEBUG_EVENT:
1500
      OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1501
                "for pid=%d tid=%x\n",
1502
                (unsigned) current_event.dwProcessId,
1503
                (unsigned) current_event.dwThreadId));
1504
      ourstatus->kind = TARGET_WAITKIND_EXITED;
1505
      ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1506
      child_continue (DBG_CONTINUE, -1);
1507
      CloseHandle (current_process_handle);
1508
      current_process_handle = NULL;
1509
      break;
1510
 
1511
    case LOAD_DLL_DEBUG_EVENT:
1512
      OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1513
                "for pid=%d tid=%x\n",
1514
                (unsigned) current_event.dwProcessId,
1515
                (unsigned) current_event.dwThreadId));
1516
      CloseHandle (current_event.u.LoadDll.hFile);
1517
      handle_load_dll ();
1518
 
1519
      ourstatus->kind = TARGET_WAITKIND_LOADED;
1520
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1521
      break;
1522
 
1523
    case UNLOAD_DLL_DEBUG_EVENT:
1524
      OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1525
                "for pid=%d tid=%x\n",
1526
                (unsigned) current_event.dwProcessId,
1527
                (unsigned) current_event.dwThreadId));
1528
      handle_unload_dll ();
1529
      ourstatus->kind = TARGET_WAITKIND_LOADED;
1530
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1531
      break;
1532
 
1533
    case EXCEPTION_DEBUG_EVENT:
1534
      OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1535
                "for pid=%d tid=%x\n",
1536
                (unsigned) current_event.dwProcessId,
1537
                (unsigned) current_event.dwThreadId));
1538
      handle_exception (ourstatus);
1539
      break;
1540
 
1541
    case OUTPUT_DEBUG_STRING_EVENT:
1542
      /* A message from the kernel (or Cygwin).  */
1543
      OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1544
                "for pid=%d tid=%x\n",
1545
                (unsigned) current_event.dwProcessId,
1546
                (unsigned) current_event.dwThreadId));
1547
      handle_output_debug_string (ourstatus);
1548
      break;
1549
 
1550
    default:
1551
      OUTMSG2 (("gdbserver: kernel event unknown "
1552
                "for pid=%d tid=%x code=%ld\n",
1553
                (unsigned) current_event.dwProcessId,
1554
                (unsigned) current_event.dwThreadId,
1555
                current_event.dwDebugEventCode));
1556
      break;
1557
    }
1558
 
1559
  ptid = debug_event_ptid (&current_event);
1560
  current_inferior =
1561
    (struct thread_info *) find_inferior_id (&all_threads, ptid);
1562
  return 1;
1563
}
1564
 
1565
/* Wait for the inferior process to change state.
1566
   STATUS will be filled in with a response code to send to GDB.
1567
   Returns the signal which caused the process to stop. */
1568
static ptid_t
1569
win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
1570
{
1571
  struct process_info *process;
1572
  struct regcache *regcache;
1573
 
1574
  while (1)
1575
    {
1576
      if (!get_child_debug_event (ourstatus))
1577
        continue;
1578
 
1579
      switch (ourstatus->kind)
1580
        {
1581
        case TARGET_WAITKIND_EXITED:
1582
          OUTMSG2 (("Child exited with retcode = %x\n",
1583
                    ourstatus->value.integer));
1584
 
1585
          process = find_process_pid (current_process_id);
1586
          remove_process (process);
1587
          win32_clear_inferiors ();
1588
          return pid_to_ptid (current_event.dwProcessId);
1589
        case TARGET_WAITKIND_STOPPED:
1590
        case TARGET_WAITKIND_LOADED:
1591
          OUTMSG2 (("Child Stopped with signal = %d \n",
1592
                    ourstatus->value.sig));
1593
 
1594
          regcache = get_thread_regcache (current_inferior, 1);
1595
          child_fetch_inferior_registers (regcache, -1);
1596
 
1597
          if (ourstatus->kind == TARGET_WAITKIND_LOADED
1598
              && !server_waiting)
1599
            {
1600
              /* When gdb connects, we want to be stopped at the
1601
                 initial breakpoint, not in some dll load event.  */
1602
              child_continue (DBG_CONTINUE, -1);
1603
              break;
1604
            }
1605
 
1606
          /* We don't expose _LOADED events to gdbserver core.  See
1607
             the `dlls_changed' global.  */
1608
          if (ourstatus->kind == TARGET_WAITKIND_LOADED)
1609
            ourstatus->kind = TARGET_WAITKIND_STOPPED;
1610
 
1611
          return debug_event_ptid (&current_event);
1612
        default:
1613
          OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind));
1614
          /* fall-through */
1615
        case TARGET_WAITKIND_SPURIOUS:
1616
        case TARGET_WAITKIND_EXECD:
1617
          /* do nothing, just continue */
1618
          child_continue (DBG_CONTINUE, -1);
1619
          break;
1620
        }
1621
    }
1622
}
1623
 
1624
/* Fetch registers from the inferior process.
1625
   If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO.  */
1626
static void
1627
win32_fetch_inferior_registers (struct regcache *regcache, int regno)
1628
{
1629
  child_fetch_inferior_registers (regcache, regno);
1630
}
1631
 
1632
/* Store registers to the inferior process.
1633
   If REGNO is -1, store all registers; otherwise, store at least REGNO.  */
1634
static void
1635
win32_store_inferior_registers (struct regcache *regcache, int regno)
1636
{
1637
  child_store_inferior_registers (regcache, regno);
1638
}
1639
 
1640
/* Read memory from the inferior process.  This should generally be
1641
   called through read_inferior_memory, which handles breakpoint shadowing.
1642
   Read LEN bytes at MEMADDR into a buffer at MYADDR.  */
1643
static int
1644
win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1645
{
1646
  return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
1647
}
1648
 
1649
/* Write memory to the inferior process.  This should generally be
1650
   called through write_inferior_memory, which handles breakpoint shadowing.
1651
   Write LEN bytes from the buffer at MYADDR to MEMADDR.
1652
   Returns 0 on success and errno on failure.  */
1653
static int
1654
win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1655
                             int len)
1656
{
1657
  return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1658
}
1659
 
1660
/* Send an interrupt request to the inferior process. */
1661
static void
1662
win32_request_interrupt (void)
1663
{
1664
  winapi_DebugBreakProcess DebugBreakProcess;
1665
  winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent;
1666
 
1667
#ifdef _WIN32_WCE
1668
  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
1669
#else
1670
  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1671
#endif
1672
 
1673
  GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent);
1674
 
1675
  if (GenerateConsoleCtrlEvent != NULL
1676
      && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
1677
    return;
1678
 
1679
  /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1680
     not a process group id.
1681
     Fallback to XP/Vista 'DebugBreakProcess', which generates a
1682
     breakpoint exception in the interior process.  */
1683
 
1684
  DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess);
1685
 
1686
  if (DebugBreakProcess != NULL
1687
      && DebugBreakProcess (current_process_handle))
1688
    return;
1689
 
1690
  /* Last resort, suspend all threads manually.  */
1691
  soft_interrupt_requested = 1;
1692
}
1693
 
1694
#ifdef _WIN32_WCE
1695
int
1696
win32_error_to_fileio_error (DWORD err)
1697
{
1698
  switch (err)
1699
    {
1700
    case ERROR_BAD_PATHNAME:
1701
    case ERROR_FILE_NOT_FOUND:
1702
    case ERROR_INVALID_NAME:
1703
    case ERROR_PATH_NOT_FOUND:
1704
      return FILEIO_ENOENT;
1705
    case ERROR_CRC:
1706
    case ERROR_IO_DEVICE:
1707
    case ERROR_OPEN_FAILED:
1708
      return FILEIO_EIO;
1709
    case ERROR_INVALID_HANDLE:
1710
      return FILEIO_EBADF;
1711
    case ERROR_ACCESS_DENIED:
1712
    case ERROR_SHARING_VIOLATION:
1713
      return FILEIO_EACCES;
1714
    case ERROR_NOACCESS:
1715
      return FILEIO_EFAULT;
1716
    case ERROR_BUSY:
1717
      return FILEIO_EBUSY;
1718
    case ERROR_ALREADY_EXISTS:
1719
    case ERROR_FILE_EXISTS:
1720
      return FILEIO_EEXIST;
1721
    case ERROR_BAD_DEVICE:
1722
      return FILEIO_ENODEV;
1723
    case ERROR_DIRECTORY:
1724
      return FILEIO_ENOTDIR;
1725
    case ERROR_FILENAME_EXCED_RANGE:
1726
    case ERROR_INVALID_DATA:
1727
    case ERROR_INVALID_PARAMETER:
1728
    case ERROR_NEGATIVE_SEEK:
1729
      return FILEIO_EINVAL;
1730
    case ERROR_TOO_MANY_OPEN_FILES:
1731
      return FILEIO_EMFILE;
1732
    case ERROR_HANDLE_DISK_FULL:
1733
    case ERROR_DISK_FULL:
1734
      return FILEIO_ENOSPC;
1735
    case ERROR_WRITE_PROTECT:
1736
      return FILEIO_EROFS;
1737
    case ERROR_NOT_SUPPORTED:
1738
      return FILEIO_ENOSYS;
1739
    }
1740
 
1741
  return FILEIO_EUNKNOWN;
1742
}
1743
 
1744
static void
1745
wince_hostio_last_error (char *buf)
1746
{
1747
  DWORD winerr = GetLastError ();
1748
  int fileio_err = win32_error_to_fileio_error (winerr);
1749
  sprintf (buf, "F-1,%x", fileio_err);
1750
}
1751
#endif
1752
 
1753
static struct target_ops win32_target_ops = {
1754
  win32_create_inferior,
1755
  win32_attach,
1756
  win32_kill,
1757
  win32_detach,
1758
  win32_join,
1759
  win32_thread_alive,
1760
  win32_resume,
1761
  win32_wait,
1762
  win32_fetch_inferior_registers,
1763
  win32_store_inferior_registers,
1764
  win32_read_inferior_memory,
1765
  win32_write_inferior_memory,
1766
  NULL,
1767
  win32_request_interrupt,
1768
  NULL,
1769
  win32_insert_point,
1770
  win32_remove_point,
1771
  win32_stopped_by_watchpoint,
1772
  win32_stopped_data_address,
1773
  NULL,
1774
  NULL,
1775
  NULL,
1776
#ifdef _WIN32_WCE
1777
  wince_hostio_last_error,
1778
#else
1779
  hostio_last_error_from_errno,
1780
#endif
1781
};
1782
 
1783
/* Initialize the Win32 backend.  */
1784
void
1785
initialize_low (void)
1786
{
1787
  set_target_ops (&win32_target_ops);
1788
  if (the_low_target.breakpoint != NULL)
1789
    set_breakpoint_data (the_low_target.breakpoint,
1790
                         the_low_target.breakpoint_len);
1791
  the_low_target.arch_setup ();
1792
}

powered by: WebSVN 2.1.0

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