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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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