OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [gdbserver/] [win32-low.c] - Blame information for rev 631

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

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

powered by: WebSVN 2.1.0

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