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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [win32-nat.c] - Blame information for rev 1780

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

Line No. Rev Author Line
1 1181 sfurman
/* Target-vector operations for controlling win32 child processes, for GDB.
2
 
3
   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
4
   Software Foundation, Inc.
5
 
6
   Contributed by Cygnus Solutions, A Red Hat Company.
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 2 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 59 Temple Place - Suite 330,
23
   Boston, MA 02111-1307, USA.  */
24
 
25
/* Originally by Steve Chamberlain, sac@cygnus.com */
26
 
27
/* We assume we're being built with and will be used for cygwin.  */
28
 
29
#include "defs.h"
30
#include "tm.h"                 /* required for SSE registers */
31
#include "frame.h"              /* required by inferior.h */
32
#include "inferior.h"
33
#include "target.h"
34
#include "gdbcore.h"
35
#include "command.h"
36
#include "completer.h"
37
#include "regcache.h"
38
#include "top.h"
39
#include "i386-tdep.h"
40
#include <signal.h>
41
#include <sys/types.h>
42
#include <fcntl.h>
43
#include <stdlib.h>
44
#include <windows.h>
45
#include <imagehlp.h>
46
#include <sys/cygwin.h>
47
 
48
#include "buildsym.h"
49
#include "symfile.h"
50
#include "objfiles.h"
51
#include "gdb_string.h"
52
#include "gdbthread.h"
53
#include "gdbcmd.h"
54
#include <sys/param.h>
55
#include <unistd.h>
56
 
57
/* The ui's event loop. */
58
extern int (*ui_loop_hook) (int signo);
59
 
60
/* If we're not using the old Cygwin header file set, define the
61
   following which never should have been in the generic Win32 API
62
   headers in the first place since they were our own invention... */
63
#ifndef _GNU_H_WINDOWS_H
64
enum
65
  {
66
    FLAG_TRACE_BIT = 0x100,
67
    CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
68
  };
69
#endif
70
#include <sys/procfs.h>
71
#include <psapi.h>
72
 
73
#ifdef HAVE_SSE_REGS
74
#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
75
        | CONTEXT_EXTENDED_REGISTERS
76
#else
77
#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS
78
#endif
79
 
80
static unsigned dr[8];
81
static int debug_registers_changed = 0;
82
static int debug_registers_used = 0;
83
 
84
/* The string sent by cygwin when it processes a signal.
85
   FIXME: This should be in a cygwin include file. */
86
#define CYGWIN_SIGNAL_STRING "cygwin: signal"
87
 
88
#define CHECK(x)        check (x, __FILE__,__LINE__)
89
#define DEBUG_EXEC(x)   if (debug_exec)         printf_unfiltered x
90
#define DEBUG_EVENTS(x) if (debug_events)       printf_unfiltered x
91
#define DEBUG_MEM(x)    if (debug_memory)       printf_unfiltered x
92
#define DEBUG_EXCEPT(x) if (debug_exceptions)   printf_unfiltered x
93
 
94
/* Forward declaration */
95
extern struct target_ops child_ops;
96
 
97
static void child_stop (void);
98
static int win32_child_thread_alive (ptid_t);
99
void child_kill_inferior (void);
100
 
101
static enum target_signal last_sig = TARGET_SIGNAL_0;
102
/* Set if a signal was received from the debugged process */
103
 
104
/* Thread information structure used to track information that is
105
   not available in gdb's thread structure. */
106
typedef struct thread_info_struct
107
  {
108
    struct thread_info_struct *next;
109
    DWORD id;
110
    HANDLE h;
111
    char *name;
112
    int suspend_count;
113
    CONTEXT context;
114
    STACKFRAME sf;
115
  }
116
thread_info;
117
 
118
static thread_info thread_head;
119
 
120
/* The process and thread handles for the above context. */
121
 
122
static DEBUG_EVENT current_event;       /* The current debug event from
123
                                           WaitForDebugEvent */
124
static HANDLE current_process_handle;   /* Currently executing process */
125
static thread_info *current_thread;     /* Info on currently selected thread */
126
static DWORD main_thread_id;            /* Thread ID of the main thread */
127
static pid_t cygwin_pid;                /* pid of cygwin process */
128
 
129
/* Counts of things. */
130
static int exception_count = 0;
131
static int event_count = 0;
132
static int saw_create;
133
 
134
/* User options. */
135
static int new_console = 0;
136
static int new_group = 1;
137
static int debug_exec = 0;               /* show execution */
138
static int debug_events = 0;             /* show events from kernel */
139
static int debug_memory = 0;             /* show target memory accesses */
140
static int debug_exceptions = 0; /* show target exceptions */
141
static int useshell = 0;         /* use shell for subprocesses */
142
 
143
/* This vector maps GDB's idea of a register's number into an address
144
   in the win32 exception context vector.
145
 
146
   It also contains the bit mask needed to load the register in question.
147
 
148
   One day we could read a reg, we could inspect the context we
149
   already have loaded, if it doesn't have the bit set that we need,
150
   we read that set of registers in using GetThreadContext.  If the
151
   context already contains what we need, we just unpack it. Then to
152
   write a register, first we have to ensure that the context contains
153
   the other regs of the group, and then we copy the info in and set
154
   out bit. */
155
 
156
#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
157
static const int mappings[] =
158
{
159
  context_offset (Eax),
160
  context_offset (Ecx),
161
  context_offset (Edx),
162
  context_offset (Ebx),
163
  context_offset (Esp),
164
  context_offset (Ebp),
165
  context_offset (Esi),
166
  context_offset (Edi),
167
  context_offset (Eip),
168
  context_offset (EFlags),
169
  context_offset (SegCs),
170
  context_offset (SegSs),
171
  context_offset (SegDs),
172
  context_offset (SegEs),
173
  context_offset (SegFs),
174
  context_offset (SegGs),
175
  context_offset (FloatSave.RegisterArea[0 * 10]),
176
  context_offset (FloatSave.RegisterArea[1 * 10]),
177
  context_offset (FloatSave.RegisterArea[2 * 10]),
178
  context_offset (FloatSave.RegisterArea[3 * 10]),
179
  context_offset (FloatSave.RegisterArea[4 * 10]),
180
  context_offset (FloatSave.RegisterArea[5 * 10]),
181
  context_offset (FloatSave.RegisterArea[6 * 10]),
182
  context_offset (FloatSave.RegisterArea[7 * 10]),
183
  context_offset (FloatSave.ControlWord),
184
  context_offset (FloatSave.StatusWord),
185
  context_offset (FloatSave.TagWord),
186
  context_offset (FloatSave.ErrorSelector),
187
  context_offset (FloatSave.ErrorOffset),
188
  context_offset (FloatSave.DataSelector),
189
  context_offset (FloatSave.DataOffset),
190
  context_offset (FloatSave.ErrorSelector)
191
#ifdef HAVE_SSE_REGS
192
  /* XMM0-7 */ ,
193
  context_offset (ExtendedRegisters[10*16]),
194
  context_offset (ExtendedRegisters[11*16]),
195
  context_offset (ExtendedRegisters[12*16]),
196
  context_offset (ExtendedRegisters[13*16]),
197
  context_offset (ExtendedRegisters[14*16]),
198
  context_offset (ExtendedRegisters[15*16]),
199
  context_offset (ExtendedRegisters[16*16]),
200
  context_offset (ExtendedRegisters[17*16]),
201
  /* MXCSR */
202
  context_offset (ExtendedRegisters[24])
203
#endif
204
};
205
 
206
#undef context_offset
207
 
208
/* This vector maps the target's idea of an exception (extracted
209
   from the DEBUG_EVENT structure) to GDB's idea. */
210
 
211
struct xlate_exception
212
  {
213
    int them;
214
    enum target_signal us;
215
  };
216
 
217
static const struct xlate_exception
218
  xlate[] =
219
{
220
  {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
221
  {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
222
  {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
223
  {DBG_CONTROL_C, TARGET_SIGNAL_INT},
224
  {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
225
  {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
226
  {-1, -1}};
227
 
228
static void
229
check (BOOL ok, const char *file, int line)
230
{
231
  if (!ok)
232
    printf_filtered ("error return %s:%d was %lu\n", file, line,
233
                     GetLastError ());
234
}
235
 
236
 
237
/* Find a thread record given a thread id.
238
   If get_context then also retrieve the context for this
239
   thread. */
240
static thread_info *
241
thread_rec (DWORD id, int get_context)
242
{
243
  thread_info *th;
244
 
245
  for (th = &thread_head; (th = th->next) != NULL;)
246
    if (th->id == id)
247
      {
248
        if (!th->suspend_count && get_context)
249
          {
250
            if (get_context > 0 && id != current_event.dwThreadId)
251
              th->suspend_count = SuspendThread (th->h) + 1;
252
            else if (get_context < 0)
253
              th->suspend_count = -1;
254
 
255
            th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
256
            GetThreadContext (th->h, &th->context);
257
            if (id == current_event.dwThreadId)
258
              {
259
                /* Copy dr values from that thread.  */
260
                dr[0] = th->context.Dr0;
261
                dr[1] = th->context.Dr1;
262
                dr[2] = th->context.Dr2;
263
                dr[3] = th->context.Dr3;
264
                dr[6] = th->context.Dr6;
265
                dr[7] = th->context.Dr7;
266
              }
267
          }
268
        return th;
269
      }
270
 
271
  return NULL;
272
}
273
 
274
/* Add a thread to the thread list */
275
static thread_info *
276
child_add_thread (DWORD id, HANDLE h)
277
{
278
  thread_info *th;
279
 
280
  if ((th = thread_rec (id, FALSE)))
281
    return th;
282
 
283
  th = (thread_info *) xmalloc (sizeof (*th));
284
  memset (th, 0, sizeof (*th));
285
  th->id = id;
286
  th->h = h;
287
  th->next = thread_head.next;
288
  thread_head.next = th;
289
  add_thread (pid_to_ptid (id));
290
  /* Set the debug registers for the new thread in they are used.  */
291
  if (debug_registers_used)
292
    {
293
      /* Only change the value of the debug registers.  */
294
      th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
295
      CHECK (GetThreadContext (th->h, &th->context));
296
      th->context.Dr0 = dr[0];
297
      th->context.Dr1 = dr[1];
298
      th->context.Dr2 = dr[2];
299
      th->context.Dr3 = dr[3];
300
      /* th->context.Dr6 = dr[6];
301
      FIXME: should we set dr6 also ?? */
302
      th->context.Dr7 = dr[7];
303
      CHECK (SetThreadContext (th->h, &th->context));
304
      th->context.ContextFlags = 0;
305
    }
306
  return th;
307
}
308
 
309
/* Clear out any old thread list and reintialize it to a
310
   pristine state. */
311
static void
312
child_init_thread_list (void)
313
{
314
  thread_info *th = &thread_head;
315
 
316
  DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
317
  init_thread_list ();
318
  while (th->next != NULL)
319
    {
320
      thread_info *here = th->next;
321
      th->next = here->next;
322
      (void) CloseHandle (here->h);
323
      xfree (here);
324
    }
325
}
326
 
327
/* Delete a thread from the list of threads */
328
static void
329
child_delete_thread (DWORD id)
330
{
331
  thread_info *th;
332
 
333
  if (info_verbose)
334
    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
335
  delete_thread (pid_to_ptid (id));
336
 
337
  for (th = &thread_head;
338
       th->next != NULL && th->next->id != id;
339
       th = th->next)
340
    continue;
341
 
342
  if (th->next != NULL)
343
    {
344
      thread_info *here = th->next;
345
      th->next = here->next;
346
      CloseHandle (here->h);
347
      xfree (here);
348
    }
349
}
350
 
351
static void
352
do_child_fetch_inferior_registers (int r)
353
{
354
  char *context_offset = ((char *) &current_thread->context) + mappings[r];
355
  long l;
356
  if (r == FCS_REGNUM)
357
    {
358
      l = *((long *) context_offset) & 0xffff;
359
      supply_register (r, (char *) &l);
360
    }
361
  else if (r == FOP_REGNUM)
362
    {
363
      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
364
      supply_register (r, (char *) &l);
365
    }
366
  else if (r >= 0)
367
    supply_register (r, context_offset);
368
  else
369
    {
370
      for (r = 0; r < NUM_REGS; r++)
371
        do_child_fetch_inferior_registers (r);
372
    }
373
}
374
 
375
static void
376
child_fetch_inferior_registers (int r)
377
{
378
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
379
  do_child_fetch_inferior_registers (r);
380
}
381
 
382
static void
383
do_child_store_inferior_registers (int r)
384
{
385
  if (r >= 0)
386
    read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
387
  else
388
    {
389
      for (r = 0; r < NUM_REGS; r++)
390
        do_child_store_inferior_registers (r);
391
    }
392
}
393
 
394
/* Store a new register value into the current thread context */
395
static void
396
child_store_inferior_registers (int r)
397
{
398
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
399
  do_child_store_inferior_registers (r);
400
}
401
 
402
static int psapi_loaded = 0;
403
static HMODULE psapi_module_handle = NULL;
404
static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
405
static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
406
static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
407
 
408
int
409
psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
410
{
411
  DWORD len;
412
  MODULEINFO mi;
413
  int i;
414
  HMODULE dh_buf[1];
415
  HMODULE *DllHandle = dh_buf;
416
  DWORD cbNeeded;
417
  BOOL ok;
418
 
419
  if (!psapi_loaded ||
420
      psapi_EnumProcessModules == NULL ||
421
      psapi_GetModuleInformation == NULL ||
422
      psapi_GetModuleFileNameExA == NULL)
423
    {
424
      if (psapi_loaded)
425
        goto failed;
426
      psapi_loaded = 1;
427
      psapi_module_handle = LoadLibrary ("psapi.dll");
428
      if (!psapi_module_handle)
429
        {
430
          /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
431
          goto failed;
432
        }
433
      psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
434
      psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
435
      psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
436
                                                    "GetModuleFileNameExA");
437
      if (psapi_EnumProcessModules == NULL ||
438
          psapi_GetModuleInformation == NULL ||
439
          psapi_GetModuleFileNameExA == NULL)
440
        goto failed;
441
    }
442
 
443
  cbNeeded = 0;
444
  ok = (*psapi_EnumProcessModules) (current_process_handle,
445
                                    DllHandle,
446
                                    sizeof (HMODULE),
447
                                    &cbNeeded);
448
 
449
  if (!ok || !cbNeeded)
450
    goto failed;
451
 
452
  DllHandle = (HMODULE *) alloca (cbNeeded);
453
  if (!DllHandle)
454
    goto failed;
455
 
456
  ok = (*psapi_EnumProcessModules) (current_process_handle,
457
                                    DllHandle,
458
                                    cbNeeded,
459
                                    &cbNeeded);
460
  if (!ok)
461
    goto failed;
462
 
463
  for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
464
    {
465
      if (!(*psapi_GetModuleInformation) (current_process_handle,
466
                                          DllHandle[i],
467
                                          &mi,
468
                                          sizeof (mi)))
469
        error ("Can't get module info");
470
 
471
      len = (*psapi_GetModuleFileNameExA) (current_process_handle,
472
                                           DllHandle[i],
473
                                           dll_name_ret,
474
                                           MAX_PATH);
475
      if (len == 0)
476
        error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
477
 
478
      if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
479
        return 1;
480
    }
481
 
482
failed:
483
  dll_name_ret[0] = '\0';
484
  return 0;
485
}
486
 
487
/* Encapsulate the information required in a call to
488
   symbol_file_add_args */
489
struct safe_symbol_file_add_args
490
{
491
  char *name;
492
  int from_tty;
493
  struct section_addr_info *addrs;
494
  int mainline;
495
  int flags;
496
  struct ui_file *err, *out;
497
  struct objfile *ret;
498
};
499
 
500
/* Maintain a linked list of "so" information. */
501
struct so_stuff
502
{
503
  struct so_stuff *next;
504
  DWORD load_addr;
505
  DWORD end_addr;
506
  int loaded;
507
  struct objfile *objfile;
508
  char name[1];
509
} solib_start, *solib_end;
510
 
511
/* Call symbol_file_add with stderr redirected.  We don't care if there
512
   are errors. */
513
static int
514
safe_symbol_file_add_stub (void *argv)
515
{
516
#define p ((struct safe_symbol_file_add_args *)argv)
517
  struct so_stuff *so = &solib_start;
518
 
519
  while ((so = so->next))
520
    if (so->loaded && strcasecmp (so->name, p->name) == 0)
521
      return 0;
522
  p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
523
  return !!p->ret;
524
#undef p
525
}
526
 
527
/* Restore gdb's stderr after calling symbol_file_add */
528
static void
529
safe_symbol_file_add_cleanup (void *p)
530
{
531
#define sp ((struct safe_symbol_file_add_args *)p)
532
  gdb_flush (gdb_stderr);
533
  gdb_flush (gdb_stdout);
534
  ui_file_delete (gdb_stderr);
535
  ui_file_delete (gdb_stdout);
536
  gdb_stderr = sp->err;
537
  gdb_stdout = sp->out;
538
#undef sp
539
}
540
 
541
/* symbol_file_add wrapper that prevents errors from being displayed. */
542
static struct objfile *
543
safe_symbol_file_add (char *name, int from_tty,
544
                      struct section_addr_info *addrs,
545
                      int mainline, int flags)
546
{
547
  struct safe_symbol_file_add_args p;
548
  struct cleanup *cleanup;
549
 
550
  cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
551
 
552
  p.err = gdb_stderr;
553
  p.out = gdb_stdout;
554
  gdb_flush (gdb_stderr);
555
  gdb_flush (gdb_stdout);
556
  gdb_stderr = ui_file_new ();
557
  gdb_stdout = ui_file_new ();
558
  p.name = name;
559
  p.from_tty = from_tty;
560
  p.addrs = addrs;
561
  p.mainline = mainline;
562
  p.flags = flags;
563
  catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
564
 
565
  do_cleanups (cleanup);
566
  return p.ret;
567
}
568
 
569
/* Remember the maximum DLL length for printing in info dll command. */
570
int max_dll_name_len;
571
 
572
static void
573
register_loaded_dll (const char *name, DWORD load_addr)
574
{
575
  struct so_stuff *so;
576
  char ppath[MAX_PATH + 1];
577
  char buf[MAX_PATH + 1];
578
  char cwd[MAX_PATH + 1];
579
  char *p;
580
  WIN32_FIND_DATA w32_fd;
581
  HANDLE h = FindFirstFile(name, &w32_fd);
582
  MEMORY_BASIC_INFORMATION m;
583
  size_t len;
584
 
585
  if (h == INVALID_HANDLE_VALUE)
586
    strcpy (buf, name);
587
  else
588
    {
589
      FindClose (h);
590
      strcpy (buf, name);
591
      if (GetCurrentDirectory (MAX_PATH + 1, cwd))
592
        {
593
          p = strrchr (buf, '\\');
594
          if (p)
595
            p[1] = '\0';
596
          SetCurrentDirectory (buf);
597
          GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
598
          SetCurrentDirectory (cwd);
599
        }
600
    }
601
 
602
  cygwin_conv_to_posix_path (buf, ppath);
603
  so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
604
  so->loaded = 0;
605
  so->load_addr = load_addr;
606
  if (!VirtualQueryEx (current_process_handle, (void *) load_addr, &m,
607
                       sizeof (m)))
608
    so->end_addr = (DWORD) m.AllocationBase + m.RegionSize;
609
  else
610
    so->end_addr = load_addr + 0x2000;  /* completely arbitrary */
611
 
612
  so->next = NULL;
613
  so->objfile = NULL;
614
  strcpy (so->name, ppath);
615
 
616
  solib_end->next = so;
617
  solib_end = so;
618
  len = strlen (ppath);
619
  if (len > max_dll_name_len)
620
    max_dll_name_len = len;
621
}
622
 
623
char *
624
get_image_name (HANDLE h, void *address, int unicode)
625
{
626
  static char buf[(2 * MAX_PATH) + 1];
627
  DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
628
  char *address_ptr;
629
  int len = 0;
630
  char b[2];
631
  DWORD done;
632
 
633
  /* Attempt to read the name of the dll that was detected.
634
     This is documented to work only when actively debugging
635
     a program.  It will not work for attached processes. */
636
  if (address == NULL)
637
    return NULL;
638
 
639
  ReadProcessMemory (h, address,  &address_ptr, sizeof (address_ptr), &done);
640
 
641
  /* See if we could read the address of a string, and that the
642
     address isn't null. */
643
 
644
  if (done != sizeof (address_ptr) || !address_ptr)
645
    return NULL;
646
 
647
  /* Find the length of the string */
648
  do
649
    {
650
      ReadProcessMemory (h, address_ptr + len * size, &b, size, &done);
651
      len++;
652
    }
653
  while ((b[0] != 0 || b[size - 1] != 0) && done == size);
654
 
655
  if (!unicode)
656
    ReadProcessMemory (h, address_ptr, buf, len, &done);
657
  else
658
    {
659
      WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
660
      ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
661
                         &done);
662
 
663
      WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
664
    }
665
 
666
  return buf;
667
}
668
 
669
/* Wait for child to do something.  Return pid of child, or -1 in case
670
   of error; store status through argument pointer OURSTATUS.  */
671
static int
672
handle_load_dll (void *dummy)
673
{
674
  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
675
  char dll_buf[MAX_PATH + 1];
676
  char *dll_name = NULL;
677
  char *p;
678
 
679
  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
680
 
681
  if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
682
    dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
683
 
684
  dll_name = dll_buf;
685
 
686
  if (*dll_name == '\0')
687
    dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
688
  if (!dll_name)
689
    return 1;
690
 
691
  register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
692
 
693
  return 1;
694
}
695
 
696
static int
697
handle_unload_dll (void *dummy)
698
{
699
  DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
700
  struct so_stuff *so;
701
 
702
  for (so = &solib_start; so->next != NULL; so = so->next)
703
    if (so->next->load_addr == lpBaseOfDll)
704
      {
705
        struct so_stuff *sodel = so->next;
706
        so->next = sodel->next;
707
        if (!so->next)
708
          solib_end = so;
709
        if (sodel->objfile)
710
          free_objfile (sodel->objfile);
711
        xfree(sodel);
712
        return 1;
713
      }
714
  error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll);
715
 
716
  return 0;
717
}
718
 
719
char *
720
solib_address (CORE_ADDR address)
721
{
722
  struct so_stuff *so;
723
  for (so = &solib_start; so->next != NULL; so = so->next)
724
    if (address >= so->load_addr && address <= so->end_addr)
725
      return so->name;
726
  return NULL;
727
}
728
 
729
/* Return name of last loaded DLL. */
730
char *
731
child_solib_loaded_library_pathname (int pid)
732
{
733
  return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
734
}
735
 
736
/* Clear list of loaded DLLs. */
737
void
738
child_clear_solibs (void)
739
{
740
  struct so_stuff *so, *so1 = solib_start.next;
741
 
742
  while ((so = so1) != NULL)
743
    {
744
      so1 = so->next;
745
      xfree (so);
746
    }
747
 
748
  solib_start.next = NULL;
749
  solib_start.objfile = NULL;
750
  solib_end = &solib_start;
751
  max_dll_name_len = sizeof ("DLL Name") - 1;
752
}
753
 
754
/* Add DLL symbol information. */
755
static struct objfile *
756
solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
757
{
758
  struct section_addr_info section_addrs;
759
 
760
  /* The symbols in a dll are offset by 0x1000, which is the
761
     the offset from 0 of the first byte in an image - because
762
     of the file header and the section alignment. */
763
 
764
  if (!name || !name[0])
765
    return NULL;
766
 
767
  memset (&section_addrs, 0, sizeof (section_addrs));
768
  section_addrs.other[0].name = ".text";
769
  section_addrs.other[0].addr = load_addr;
770
  return safe_symbol_file_add (name, from_tty, &section_addrs, 0, OBJF_SHARED);
771
}
772
 
773
/* Load DLL symbol info. */
774
void
775
dll_symbol_command (char *args, int from_tty)
776
{
777
  int n;
778
  dont_repeat ();
779
 
780
  if (args == NULL)
781
    error ("dll-symbols requires a file name");
782
 
783
  n = strlen (args);
784
  if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
785
    {
786
      char *newargs = (char *) alloca (n + 4 + 1);
787
      strcpy (newargs, args);
788
      strcat (newargs, ".dll");
789
      args = newargs;
790
    }
791
 
792
  safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
793
}
794
 
795
/* List currently loaded DLLs. */
796
void
797
info_dll_command (char *ignore, int from_tty)
798
{
799
  struct so_stuff *so = &solib_start;
800
 
801
  if (!so->next)
802
    return;
803
 
804
  printf_filtered ("%*s  Load Address\n", -max_dll_name_len, "DLL Name");
805
  while ((so = so->next) != NULL)
806
    printf_filtered ("%*s  %08lx\n", -max_dll_name_len, so->name, so->load_addr);
807
 
808
  return;
809
}
810
 
811
/* Handle DEBUG_STRING output from child process.
812
   Cygwin prepends its messages with a "cygwin:".  Interpret this as
813
   a Cygwin signal.  Otherwise just print the string as a warning. */
814
static int
815
handle_output_debug_string (struct target_waitstatus *ourstatus)
816
{
817
  char *s;
818
  int gotasig = FALSE;
819
 
820
  if (!target_read_string
821
    ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
822
      || !s || !*s)
823
    return gotasig;
824
 
825
  if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
826
    {
827
      if (strncmp (s, "cYg", 3) != 0)
828
        warning ("%s", s);
829
    }
830
  else
831
    {
832
      char *p;
833
      int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
834
      gotasig = target_signal_from_host (sig);
835
      ourstatus->value.sig = gotasig;
836
      if (gotasig)
837
        ourstatus->kind = TARGET_WAITKIND_STOPPED;
838
    }
839
 
840
  xfree (s);
841
  return gotasig;
842
}
843
 
844
static int
845
display_selector (HANDLE thread, DWORD sel)
846
{
847
  LDT_ENTRY info;
848
  if (GetThreadSelectorEntry (thread, sel, &info))
849
    {
850
      int base, limit;
851
      printf_filtered ("0x%03lx: ", sel);
852
      if (!info.HighWord.Bits.Pres)
853
        {
854
          puts_filtered ("Segment not present\n");
855
          return 0;
856
        }
857
      base = (info.HighWord.Bits.BaseHi << 24) +
858
             (info.HighWord.Bits.BaseMid << 16)
859
             + info.BaseLow;
860
      limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
861
      if (info.HighWord.Bits.Granularity)
862
       limit = (limit << 12) | 0xfff;
863
      printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
864
      if (info.HighWord.Bits.Default_Big)
865
        puts_filtered(" 32-bit ");
866
      else
867
        puts_filtered(" 16-bit ");
868
      switch ((info.HighWord.Bits.Type & 0xf) >> 1)
869
        {
870
        case 0:
871
          puts_filtered ("Data (Read-Only, Exp-up");
872
          break;
873
        case 1:
874
          puts_filtered ("Data (Read/Write, Exp-up");
875
          break;
876
        case 2:
877
          puts_filtered ("Unused segment (");
878
          break;
879
        case 3:
880
          puts_filtered ("Data (Read/Write, Exp-down");
881
          break;
882
        case 4:
883
          puts_filtered ("Code (Exec-Only, N.Conf");
884
          break;
885
        case 5:
886
          puts_filtered ("Code (Exec/Read, N.Conf");
887
          break;
888
        case 6:
889
          puts_filtered ("Code (Exec-Only, Conf");
890
          break;
891
        case 7:
892
          puts_filtered ("Code (Exec/Read, Conf");
893
          break;
894
        default:
895
          printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
896
        }
897
      if ((info.HighWord.Bits.Type & 0x1) == 0)
898
        puts_filtered(", N.Acc");
899
      puts_filtered (")\n");
900
      if ((info.HighWord.Bits.Type & 0x10) == 0)
901
        puts_filtered("System selector ");
902
      printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
903
      if (info.HighWord.Bits.Granularity)
904
        puts_filtered ("Page granular.\n");
905
      else
906
        puts_filtered ("Byte granular.\n");
907
      return 1;
908
    }
909
  else
910
    {
911
      printf_filtered ("Invalid selector 0x%lx.\n",sel);
912
      return 0;
913
    }
914
}
915
 
916
static void
917
display_selectors (char * args, int from_tty)
918
{
919
  if (!current_thread)
920
    {
921
      puts_filtered ("Impossible to display selectors now.\n");
922
      return;
923
    }
924
  if (!args)
925
    {
926
 
927
      puts_filtered ("Selector $cs\n");
928
      display_selector (current_thread->h,
929
        current_thread->context.SegCs);
930
      puts_filtered ("Selector $ds\n");
931
      display_selector (current_thread->h,
932
        current_thread->context.SegDs);
933
      puts_filtered ("Selector $es\n");
934
      display_selector (current_thread->h,
935
        current_thread->context.SegEs);
936
      puts_filtered ("Selector $ss\n");
937
      display_selector (current_thread->h,
938
        current_thread->context.SegSs);
939
      puts_filtered ("Selector $fs\n");
940
      display_selector (current_thread->h,
941
        current_thread->context.SegFs);
942
      puts_filtered ("Selector $gs\n");
943
      display_selector (current_thread->h,
944
        current_thread->context.SegGs);
945
    }
946
  else
947
    {
948
      int sel;
949
      sel = parse_and_eval_long (args);
950
      printf_filtered ("Selector \"%s\"\n",args);
951
      display_selector (current_thread->h, sel);
952
    }
953
}
954
 
955
static struct cmd_list_element *info_w32_cmdlist = NULL;
956
 
957
static void
958
info_w32_command (char *args, int from_tty)
959
{
960
  help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
961
}
962
 
963
 
964
#define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
965
  printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
966
  (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
967
 
968
static int
969
handle_exception (struct target_waitstatus *ourstatus)
970
{
971
  thread_info *th;
972
  DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
973
 
974
  ourstatus->kind = TARGET_WAITKIND_STOPPED;
975
 
976
  /* Record the context of the current thread */
977
  th = thread_rec (current_event.dwThreadId, -1);
978
 
979
  switch (code)
980
    {
981
    case EXCEPTION_ACCESS_VIOLATION:
982
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
983
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
984
      break;
985
    case STATUS_STACK_OVERFLOW:
986
      DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
987
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
988
      break;
989
    case STATUS_FLOAT_DENORMAL_OPERAND:
990
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
991
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
992
      break;
993
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
994
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
995
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
996
      break;
997
    case STATUS_FLOAT_INEXACT_RESULT:
998
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
999
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1000
      break;
1001
    case STATUS_FLOAT_INVALID_OPERATION:
1002
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1003
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1004
      break;
1005
    case STATUS_FLOAT_OVERFLOW:
1006
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1007
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1008
      break;
1009
    case STATUS_FLOAT_STACK_CHECK:
1010
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1011
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1012
      break;
1013
    case STATUS_FLOAT_UNDERFLOW:
1014
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1015
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1016
      break;
1017
    case STATUS_FLOAT_DIVIDE_BY_ZERO:
1018
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1019
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1020
      break;
1021
    case STATUS_INTEGER_DIVIDE_BY_ZERO:
1022
      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1023
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1024
      break;
1025
    case STATUS_INTEGER_OVERFLOW:
1026
      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1027
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1028
      break;
1029
    case EXCEPTION_BREAKPOINT:
1030
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1031
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1032
      break;
1033
    case DBG_CONTROL_C:
1034
      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1035
      ourstatus->value.sig = TARGET_SIGNAL_INT;
1036
      break;
1037
    case DBG_CONTROL_BREAK:
1038
      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1039
      ourstatus->value.sig = TARGET_SIGNAL_INT;
1040
      break;
1041
    case EXCEPTION_SINGLE_STEP:
1042
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1043
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1044
      break;
1045
    case EXCEPTION_ILLEGAL_INSTRUCTION:
1046
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1047
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1048
      break;
1049
    case EXCEPTION_PRIV_INSTRUCTION:
1050
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1051
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1052
      break;
1053
    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1054
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1055
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1056
      break;
1057
    default:
1058
      if (current_event.u.Exception.dwFirstChance)
1059
        return 0;
1060
      printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1061
                    current_event.u.Exception.ExceptionRecord.ExceptionCode,
1062
        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1063
      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1064
      break;
1065
    }
1066
  exception_count++;
1067
  last_sig = ourstatus->value.sig;
1068
  return 1;
1069
}
1070
 
1071
/* Resume all artificially suspended threads if we are continuing
1072
   execution */
1073
static BOOL
1074
child_continue (DWORD continue_status, int id)
1075
{
1076
  int i;
1077
  thread_info *th;
1078
  BOOL res;
1079
 
1080
  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1081
                  current_event.dwProcessId, current_event.dwThreadId,
1082
                  continue_status == DBG_CONTINUE ?
1083
                  "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1084
  res = ContinueDebugEvent (current_event.dwProcessId,
1085
                            current_event.dwThreadId,
1086
                            continue_status);
1087
  continue_status = 0;
1088
  if (res)
1089
    for (th = &thread_head; (th = th->next) != NULL;)
1090
      if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
1091
        {
1092
 
1093
          for (i = 0; i < th->suspend_count; i++)
1094
            (void) ResumeThread (th->h);
1095
          th->suspend_count = 0;
1096
          if (debug_registers_changed)
1097
            {
1098
              /* Only change the value of the debug reisters */
1099
              th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
1100
              th->context.Dr0 = dr[0];
1101
              th->context.Dr1 = dr[1];
1102
              th->context.Dr2 = dr[2];
1103
              th->context.Dr3 = dr[3];
1104
              /* th->context.Dr6 = dr[6];
1105
                 FIXME: should we set dr6 also ?? */
1106
              th->context.Dr7 = dr[7];
1107
              CHECK (SetThreadContext (th->h, &th->context));
1108
              th->context.ContextFlags = 0;
1109
            }
1110
        }
1111
 
1112
  debug_registers_changed = 0;
1113
  return res;
1114
}
1115
 
1116
/* Get the next event from the child.  Return 1 if the event requires
1117
   handling by WFI (or whatever).
1118
 */
1119
static int
1120
get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
1121
{
1122
  BOOL debug_event;
1123
  DWORD continue_status, event_code;
1124
  thread_info *th = NULL;
1125
  static thread_info dummy_thread_info;
1126
  int retval = 0;
1127
 
1128
  last_sig = TARGET_SIGNAL_0;
1129
 
1130
  if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
1131
    goto out;
1132
 
1133
  event_count++;
1134
  continue_status = DBG_CONTINUE;
1135
 
1136
  event_code = current_event.dwDebugEventCode;
1137
  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1138
 
1139
  switch (event_code)
1140
    {
1141
    case CREATE_THREAD_DEBUG_EVENT:
1142
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1143
                     (unsigned) current_event.dwProcessId,
1144
                     (unsigned) current_event.dwThreadId,
1145
                     "CREATE_THREAD_DEBUG_EVENT"));
1146
      if (saw_create != 1)
1147
        break;
1148
      /* Record the existence of this thread */
1149
      th = child_add_thread (current_event.dwThreadId,
1150
                             current_event.u.CreateThread.hThread);
1151
      if (info_verbose)
1152
        printf_unfiltered ("[New %s]\n",
1153
                           target_pid_to_str (
1154
                             pid_to_ptid (current_event.dwThreadId)));
1155
      retval = current_event.dwThreadId;
1156
      break;
1157
 
1158
    case EXIT_THREAD_DEBUG_EVENT:
1159
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1160
                     (unsigned) current_event.dwProcessId,
1161
                     (unsigned) current_event.dwThreadId,
1162
                     "EXIT_THREAD_DEBUG_EVENT"));
1163
      if (saw_create != 1)
1164
        break;
1165
      child_delete_thread (current_event.dwThreadId);
1166
      th = &dummy_thread_info;
1167
      break;
1168
 
1169
    case CREATE_PROCESS_DEBUG_EVENT:
1170
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1171
                     (unsigned) current_event.dwProcessId,
1172
                     (unsigned) current_event.dwThreadId,
1173
                     "CREATE_PROCESS_DEBUG_EVENT"));
1174
      CloseHandle (current_event.u.CreateProcessInfo.hFile);
1175
      if (++saw_create != 1)
1176
        {
1177
          CloseHandle (current_event.u.CreateProcessInfo.hProcess);
1178
          break;
1179
        }
1180
 
1181
      current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1182
      main_thread_id = current_event.dwThreadId;
1183
      /* Add the main thread */
1184
#if 0
1185
      th = child_add_thread (current_event.dwProcessId,
1186
                             current_event.u.CreateProcessInfo.hProcess);
1187
#endif
1188
      th = child_add_thread (main_thread_id,
1189
                             current_event.u.CreateProcessInfo.hThread);
1190
      retval = ourstatus->value.related_pid = current_event.dwThreadId;
1191
      break;
1192
 
1193
    case EXIT_PROCESS_DEBUG_EVENT:
1194
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1195
                     (unsigned) current_event.dwProcessId,
1196
                     (unsigned) current_event.dwThreadId,
1197
                     "EXIT_PROCESS_DEBUG_EVENT"));
1198
      if (saw_create != 1)
1199
        break;
1200
      ourstatus->kind = TARGET_WAITKIND_EXITED;
1201
      ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1202
      CloseHandle (current_process_handle);
1203
      retval = main_thread_id;
1204
      break;
1205
 
1206
    case LOAD_DLL_DEBUG_EVENT:
1207
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1208
                     (unsigned) current_event.dwProcessId,
1209
                     (unsigned) current_event.dwThreadId,
1210
                     "LOAD_DLL_DEBUG_EVENT"));
1211
      CloseHandle (current_event.u.LoadDll.hFile);
1212
      if (saw_create != 1)
1213
        break;
1214
      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1215
      registers_changed ();     /* mark all regs invalid */
1216
      ourstatus->kind = TARGET_WAITKIND_LOADED;
1217
      ourstatus->value.integer = 0;
1218
      retval = main_thread_id;
1219
      re_enable_breakpoints_in_shlibs ();
1220
      break;
1221
 
1222
    case UNLOAD_DLL_DEBUG_EVENT:
1223
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1224
                     (unsigned) current_event.dwProcessId,
1225
                     (unsigned) current_event.dwThreadId,
1226
                     "UNLOAD_DLL_DEBUG_EVENT"));
1227
      if (saw_create != 1)
1228
        break;
1229
      catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1230
      registers_changed ();     /* mark all regs invalid */
1231
      /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1232
         does not exist yet. */
1233
      break;
1234
 
1235
    case EXCEPTION_DEBUG_EVENT:
1236
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1237
                     (unsigned) current_event.dwProcessId,
1238
                     (unsigned) current_event.dwThreadId,
1239
                     "EXCEPTION_DEBUG_EVENT"));
1240
      if (saw_create != 1)
1241
        break;
1242
      if (handle_exception (ourstatus))
1243
        retval = current_event.dwThreadId;
1244
      break;
1245
 
1246
    case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
1247
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1248
                     (unsigned) current_event.dwProcessId,
1249
                     (unsigned) current_event.dwThreadId,
1250
                     "OUTPUT_DEBUG_STRING_EVENT"));
1251
      if (saw_create != 1)
1252
        break;
1253
      if (handle_output_debug_string (ourstatus))
1254
        retval = main_thread_id;
1255
      break;
1256
 
1257
    default:
1258
      if (saw_create != 1)
1259
        break;
1260
      printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1261
                         (DWORD) current_event.dwProcessId,
1262
                         (DWORD) current_event.dwThreadId);
1263
      printf_unfiltered ("                 unknown event code %ld\n",
1264
                         current_event.dwDebugEventCode);
1265
      break;
1266
    }
1267
 
1268
  if (!retval || saw_create != 1)
1269
    CHECK (child_continue (continue_status, -1));
1270
  else
1271
    {
1272
      current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
1273
      inferior_ptid = pid_to_ptid (retval);
1274
    }
1275
 
1276
out:
1277
  return retval;
1278
}
1279
 
1280
/* Wait for interesting events to occur in the target process. */
1281
static ptid_t
1282
child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1283
{
1284
  int pid = PIDGET (ptid);
1285
 
1286
  /* We loop when we get a non-standard exception rather than return
1287
     with a SPURIOUS because resume can try and step or modify things,
1288
     which needs a current_thread->h.  But some of these exceptions mark
1289
     the birth or death of threads, which mean that the current thread
1290
     isn't necessarily what you think it is. */
1291
 
1292
  while (1)
1293
    {
1294
      int retval = get_child_debug_event (pid, ourstatus);
1295
      if (retval)
1296
        return pid_to_ptid (retval);
1297
      else
1298
        {
1299
          int detach = 0;
1300
 
1301
          if (ui_loop_hook != NULL)
1302
            detach = ui_loop_hook (0);
1303
 
1304
          if (detach)
1305
            child_kill_inferior ();
1306
        }
1307
    }
1308
}
1309
 
1310
static void
1311
do_initial_child_stuff (DWORD pid)
1312
{
1313
  extern int stop_after_trap;
1314
  int i;
1315
 
1316
  last_sig = TARGET_SIGNAL_0;
1317
  event_count = 0;
1318
  exception_count = 0;
1319
  debug_registers_changed = 0;
1320
  debug_registers_used = 0;
1321
  for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1322
    dr[i] = 0;
1323
  current_event.dwProcessId = pid;
1324
  memset (&current_event, 0, sizeof (current_event));
1325
  push_target (&child_ops);
1326
  child_init_thread_list ();
1327
  disable_breakpoints_in_shlibs (1);
1328
  child_clear_solibs ();
1329
  clear_proceed_status ();
1330
  init_wait_for_inferior ();
1331
 
1332
  target_terminal_init ();
1333
  target_terminal_inferior ();
1334
 
1335
  while (1)
1336
    {
1337
      stop_after_trap = 1;
1338
      wait_for_inferior ();
1339
      if (stop_signal != TARGET_SIGNAL_TRAP)
1340
        resume (0, stop_signal);
1341
      else
1342
        break;
1343
    }
1344
  stop_after_trap = 0;
1345
  return;
1346
}
1347
 
1348
/* Since Windows XP, detaching from a process is supported by Windows.
1349
   The following code tries loading the appropriate functions dynamically.
1350
   If loading these functions succeeds use them to actually detach from
1351
   the inferior process, otherwise behave as usual, pretending that
1352
   detach has worked. */
1353
static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1354
static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1355
 
1356
static int
1357
has_detach_ability (void)
1358
{
1359
  static HMODULE kernel32 = NULL;
1360
 
1361
  if (!kernel32)
1362
    kernel32 = LoadLibrary ("kernel32.dll");
1363
  if (kernel32)
1364
    {
1365
      if (!DebugSetProcessKillOnExit)
1366
        DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1367
                                                 "DebugSetProcessKillOnExit");
1368
      if (!DebugActiveProcessStop)
1369
        DebugActiveProcessStop = GetProcAddress (kernel32,
1370
                                                 "DebugActiveProcessStop");
1371
      if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1372
        return 1;
1373
    }
1374
  return 0;
1375
}
1376
 
1377
/* Attach to process PID, then initialize for debugging it.  */
1378
static void
1379
child_attach (char *args, int from_tty)
1380
{
1381
  BOOL ok;
1382
  DWORD pid;
1383
 
1384
  if (!args)
1385
    error_no_arg ("process-id to attach");
1386
 
1387
  pid = strtoul (args, 0, 0);
1388
  ok = DebugActiveProcess (pid);
1389
  saw_create = 0;
1390
 
1391
  if (!ok)
1392
    error ("Can't attach to process.");
1393
 
1394
  if (has_detach_ability ())
1395
    {
1396
      attach_flag = 1;
1397
      DebugSetProcessKillOnExit (FALSE);
1398
    }
1399
 
1400
  if (from_tty)
1401
    {
1402
      char *exec_file = (char *) get_exec_file (0);
1403
 
1404
      if (exec_file)
1405
        printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1406
                           target_pid_to_str (pid_to_ptid (pid)));
1407
      else
1408
        printf_unfiltered ("Attaching to %s\n",
1409
                           target_pid_to_str (pid_to_ptid (pid)));
1410
 
1411
      gdb_flush (gdb_stdout);
1412
    }
1413
 
1414
  do_initial_child_stuff (pid);
1415
  target_terminal_ours ();
1416
}
1417
 
1418
static void
1419
child_detach (char *args, int from_tty)
1420
{
1421
  int detached = 1;
1422
 
1423
  if (has_detach_ability ())
1424
    {
1425
      delete_command (NULL, 0);
1426
      child_continue (DBG_CONTINUE, -1);
1427
      if (!DebugActiveProcessStop (current_event.dwProcessId))
1428
        {
1429
          error ("Can't detach process %lu (error %lu)",
1430
                 current_event.dwProcessId, GetLastError ());
1431
          detached = 0;
1432
        }
1433
      DebugSetProcessKillOnExit (FALSE);
1434
    }
1435
  if (detached && from_tty)
1436
    {
1437
      char *exec_file = get_exec_file (0);
1438
      if (exec_file == 0)
1439
        exec_file = "";
1440
      printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1441
                         current_event.dwProcessId);
1442
      gdb_flush (gdb_stdout);
1443
    }
1444
  inferior_ptid = null_ptid;
1445
  unpush_target (&child_ops);
1446
}
1447
 
1448
/* Print status information about what we're accessing.  */
1449
 
1450
static void
1451
child_files_info (struct target_ops *ignore)
1452
{
1453
  printf_unfiltered ("\tUsing the running image of %s %s.\n",
1454
      attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
1455
}
1456
 
1457
/* ARGSUSED */
1458
static void
1459
child_open (char *arg, int from_tty)
1460
{
1461
  error ("Use the \"run\" command to start a Unix child process.");
1462
}
1463
 
1464
/* Start an inferior win32 child process and sets inferior_ptid to its pid.
1465
   EXEC_FILE is the file to run.
1466
   ALLARGS is a string containing the arguments to the program.
1467
   ENV is the environment vector to pass.  Errors reported with error().  */
1468
 
1469
static void
1470
child_create_inferior (char *exec_file, char *allargs, char **env)
1471
{
1472
  char *winenv;
1473
  char *temp;
1474
  int envlen;
1475
  int i;
1476
  STARTUPINFO si;
1477
  PROCESS_INFORMATION pi;
1478
  BOOL ret;
1479
  DWORD flags;
1480
  char *args;
1481
  char real_path[MAXPATHLEN];
1482
  char *toexec;
1483
  char shell[MAX_PATH + 1]; /* Path to shell */
1484
  const char *sh;
1485
 
1486
  if (!exec_file)
1487
    error ("No executable specified, use `target exec'.\n");
1488
 
1489
  memset (&si, 0, sizeof (si));
1490
  si.cb = sizeof (si);
1491
 
1492
  if (!useshell)
1493
    {
1494
      flags = DEBUG_ONLY_THIS_PROCESS;
1495
      cygwin_conv_to_win32_path (exec_file, real_path);
1496
      toexec = real_path;
1497
    }
1498
  else
1499
    {
1500
      char *newallargs;
1501
      sh = getenv ("SHELL");
1502
      if (!sh)
1503
        sh = "/bin/sh";
1504
      cygwin_conv_to_win32_path (sh, shell);
1505
      newallargs = alloca (sizeof (" -c 'exec  '") + strlen (exec_file)
1506
                           + strlen (allargs) + 2);
1507
      sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1508
      allargs = newallargs;
1509
      toexec = shell;
1510
      flags = DEBUG_PROCESS;
1511
    }
1512
 
1513
  if (new_group)
1514
    flags |= CREATE_NEW_PROCESS_GROUP;
1515
 
1516
  if (new_console)
1517
    flags |= CREATE_NEW_CONSOLE;
1518
 
1519
  args = alloca (strlen (toexec) + strlen (allargs) + 2);
1520
  strcpy (args, toexec);
1521
  strcat (args, " ");
1522
  strcat (args, allargs);
1523
 
1524
  /* Prepare the environment vars for CreateProcess.  */
1525
  {
1526
    /* This code used to assume all env vars were file names and would
1527
       translate them all to win32 style.  That obviously doesn't work in the
1528
       general case.  The current rule is that we only translate PATH.
1529
       We need to handle PATH because we're about to call CreateProcess and
1530
       it uses PATH to find DLL's.  Fortunately PATH has a well-defined value
1531
       in both posix and win32 environments.  cygwin.dll will change it back
1532
       to posix style if necessary.  */
1533
 
1534
    static const char *conv_path_names[] =
1535
    {
1536
      "PATH=",
1537
 
1538
    };
1539
 
1540
    /* CreateProcess takes the environment list as a null terminated set of
1541
       strings (i.e. two nulls terminate the list).  */
1542
 
1543
    /* Get total size for env strings.  */
1544
    for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1545
      {
1546
        int j, len;
1547
 
1548
        for (j = 0; conv_path_names[j]; j++)
1549
          {
1550
            len = strlen (conv_path_names[j]);
1551
            if (strncmp (conv_path_names[j], env[i], len) == 0)
1552
              {
1553
                if (cygwin_posix_path_list_p (env[i] + len))
1554
                  envlen += len
1555
                    + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1556
                else
1557
                  envlen += strlen (env[i]) + 1;
1558
                break;
1559
              }
1560
          }
1561
        if (conv_path_names[j] == NULL)
1562
          envlen += strlen (env[i]) + 1;
1563
      }
1564
 
1565
    winenv = alloca (envlen + 1);
1566
 
1567
    /* Copy env strings into new buffer.  */
1568
    for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1569
      {
1570
        int j, len;
1571
 
1572
        for (j = 0; conv_path_names[j]; j++)
1573
          {
1574
            len = strlen (conv_path_names[j]);
1575
            if (strncmp (conv_path_names[j], env[i], len) == 0)
1576
              {
1577
                if (cygwin_posix_path_list_p (env[i] + len))
1578
                  {
1579
                    memcpy (temp, env[i], len);
1580
                    cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1581
                  }
1582
                else
1583
                  strcpy (temp, env[i]);
1584
                break;
1585
              }
1586
          }
1587
        if (conv_path_names[j] == NULL)
1588
          strcpy (temp, env[i]);
1589
 
1590
        temp += strlen (temp) + 1;
1591
      }
1592
 
1593
    /* Final nil string to terminate new env.  */
1594
    *temp = 0;
1595
  }
1596
 
1597
  ret = CreateProcess (0,
1598
                       args,    /* command line */
1599
                       NULL,    /* Security */
1600
                       NULL,    /* thread */
1601
                       TRUE,    /* inherit handles */
1602
                       flags,   /* start flags */
1603
                       winenv,
1604
                       NULL,    /* current directory */
1605
                       &si,
1606
                       &pi);
1607
  if (!ret)
1608
    error ("Error creating process %s, (error %d)\n", exec_file, (unsigned) GetLastError ());
1609
 
1610
  CloseHandle (pi.hThread);
1611
  CloseHandle (pi.hProcess);
1612
 
1613
  if (useshell && shell[0] != '\0')
1614
    saw_create = -1;
1615
  else
1616
    saw_create = 0;
1617
 
1618
  do_initial_child_stuff (pi.dwProcessId);
1619
 
1620
  /* child_continue (DBG_CONTINUE, -1); */
1621
  proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1622
}
1623
 
1624
static void
1625
child_mourn_inferior (void)
1626
{
1627
  (void) child_continue (DBG_CONTINUE, -1);
1628
  i386_cleanup_dregs();
1629
  unpush_target (&child_ops);
1630
  generic_mourn_inferior ();
1631
}
1632
 
1633
/* Send a SIGINT to the process group.  This acts just like the user typed a
1634
   ^C on the controlling terminal. */
1635
 
1636
static void
1637
child_stop (void)
1638
{
1639
  DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1640
  CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1641
  registers_changed ();         /* refresh register state */
1642
}
1643
 
1644
int
1645
child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1646
                   int write, struct mem_attrib *mem,
1647
                   struct target_ops *target)
1648
{
1649
  DWORD done;
1650
  if (write)
1651
    {
1652
      DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1653
                  len, (DWORD) memaddr));
1654
      WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1655
                          len, &done);
1656
      FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1657
    }
1658
  else
1659
    {
1660
      DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1661
                  len, (DWORD) memaddr));
1662
      ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1663
                         &done);
1664
    }
1665
  return done;
1666
}
1667
 
1668
void
1669
child_kill_inferior (void)
1670
{
1671
  CHECK (TerminateProcess (current_process_handle, 0));
1672
 
1673
  for (;;)
1674
    {
1675
      if (!child_continue (DBG_CONTINUE, -1))
1676
        break;
1677
      if (!WaitForDebugEvent (&current_event, INFINITE))
1678
        break;
1679
      if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1680
        break;
1681
    }
1682
 
1683
  CHECK (CloseHandle (current_process_handle));
1684
 
1685
  /* this may fail in an attached process so don't check. */
1686
  (void) CloseHandle (current_thread->h);
1687
  target_mourn_inferior ();     /* or just child_mourn_inferior? */
1688
}
1689
 
1690
void
1691
child_resume (ptid_t ptid, int step, enum target_signal sig)
1692
{
1693
  thread_info *th;
1694
  DWORD continue_status = DBG_CONTINUE;
1695
 
1696
  int pid = PIDGET (ptid);
1697
 
1698
  if (sig != TARGET_SIGNAL_0)
1699
    {
1700
      if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1701
        {
1702
          DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1703
        }
1704
      else if (sig == last_sig)
1705
        continue_status = DBG_EXCEPTION_NOT_HANDLED;
1706
      else
1707
#if 0
1708
/* This code does not seem to work, because
1709
  the kernel does probably not consider changes in the ExceptionRecord
1710
  structure when passing the exception to the inferior.
1711
  Note that this seems possible in the exception handler itself.  */
1712
        {
1713
          int i;
1714
          for (i = 0; xlate[i].them != -1; i++)
1715
            if (xlate[i].us == sig)
1716
              {
1717
                current_event.u.Exception.ExceptionRecord.ExceptionCode =
1718
                  xlate[i].them;
1719
                continue_status = DBG_EXCEPTION_NOT_HANDLED;
1720
                break;
1721
              }
1722
          if (continue_status == DBG_CONTINUE)
1723
            {
1724
              DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1725
            }
1726
        }
1727
#endif
1728
        DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1729
          last_sig));
1730
    }
1731
 
1732
  last_sig = TARGET_SIGNAL_0;
1733
 
1734
  DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1735
               pid, step, sig));
1736
 
1737
  /* Get context for currently selected thread */
1738
  th = thread_rec (current_event.dwThreadId, FALSE);
1739
  if (th)
1740
    {
1741
      if (step)
1742
        {
1743
          /* Single step by setting t bit */
1744
          child_fetch_inferior_registers (PS_REGNUM);
1745
          th->context.EFlags |= FLAG_TRACE_BIT;
1746
        }
1747
 
1748
      if (th->context.ContextFlags)
1749
        {
1750
     if (debug_registers_changed)
1751
       {
1752
          th->context.Dr0 = dr[0];
1753
          th->context.Dr1 = dr[1];
1754
          th->context.Dr2 = dr[2];
1755
          th->context.Dr3 = dr[3];
1756
          /* th->context.Dr6 = dr[6];
1757
           FIXME: should we set dr6 also ?? */
1758
          th->context.Dr7 = dr[7];
1759
       }
1760
          CHECK (SetThreadContext (th->h, &th->context));
1761
          th->context.ContextFlags = 0;
1762
        }
1763
    }
1764
 
1765
  /* Allow continuing with the same signal that interrupted us.
1766
     Otherwise complain. */
1767
 
1768
  child_continue (continue_status, pid);
1769
}
1770
 
1771
static void
1772
child_prepare_to_store (void)
1773
{
1774
  /* Do nothing, since we can store individual regs */
1775
}
1776
 
1777
static int
1778
child_can_run (void)
1779
{
1780
  return 1;
1781
}
1782
 
1783
static void
1784
child_close (int x)
1785
{
1786
  DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1787
                PIDGET (inferior_ptid)));
1788
}
1789
 
1790
struct target_ops child_ops;
1791
 
1792
static void
1793
init_child_ops (void)
1794
{
1795
  child_ops.to_shortname = "child";
1796
  child_ops.to_longname = "Win32 child process";
1797
  child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1798
  child_ops.to_open = child_open;
1799
  child_ops.to_close = child_close;
1800
  child_ops.to_attach = child_attach;
1801
  child_ops.to_detach = child_detach;
1802
  child_ops.to_resume = child_resume;
1803
  child_ops.to_wait = child_wait;
1804
  child_ops.to_fetch_registers = child_fetch_inferior_registers;
1805
  child_ops.to_store_registers = child_store_inferior_registers;
1806
  child_ops.to_prepare_to_store = child_prepare_to_store;
1807
  child_ops.to_xfer_memory = child_xfer_memory;
1808
  child_ops.to_files_info = child_files_info;
1809
  child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1810
  child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1811
  child_ops.to_terminal_init = terminal_init_inferior;
1812
  child_ops.to_terminal_inferior = terminal_inferior;
1813
  child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1814
  child_ops.to_terminal_ours = terminal_ours;
1815
  child_ops.to_terminal_save_ours = terminal_save_ours;
1816
  child_ops.to_terminal_info = child_terminal_info;
1817
  child_ops.to_kill = child_kill_inferior;
1818
  child_ops.to_load = 0;
1819
  child_ops.to_lookup_symbol = 0;
1820
  child_ops.to_create_inferior = child_create_inferior;
1821
  child_ops.to_mourn_inferior = child_mourn_inferior;
1822
  child_ops.to_can_run = child_can_run;
1823
  child_ops.to_notice_signals = 0;
1824
  child_ops.to_thread_alive = win32_child_thread_alive;
1825
  child_ops.to_pid_to_str = cygwin_pid_to_str;
1826
  child_ops.to_stop = child_stop;
1827
  child_ops.to_stratum = process_stratum;
1828
  child_ops.DONT_USE = 0;
1829
  child_ops.to_has_all_memory = 1;
1830
  child_ops.to_has_memory = 1;
1831
  child_ops.to_has_stack = 1;
1832
  child_ops.to_has_registers = 1;
1833
  child_ops.to_has_execution = 1;
1834
  child_ops.to_sections = 0;
1835
  child_ops.to_sections_end = 0;
1836
  child_ops.to_magic = OPS_MAGIC;
1837
}
1838
 
1839
void
1840
_initialize_win32_nat (void)
1841
{
1842
  struct cmd_list_element *c;
1843
 
1844
  init_child_ops ();
1845
 
1846
  c = add_com ("dll-symbols", class_files, dll_symbol_command,
1847
               "Load dll library symbols from FILE.");
1848
  set_cmd_completer (c, filename_completer);
1849
 
1850
  add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1851
 
1852
  add_show_from_set (add_set_cmd ("shell", class_support, var_boolean,
1853
                                  (char *) &useshell,
1854
                 "Set use of shell to start subprocess.",
1855
                                  &setlist),
1856
                     &showlist);
1857
 
1858
  add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1859
                                  (char *) &new_console,
1860
                 "Set creation of new console when creating child process.",
1861
                                  &setlist),
1862
                     &showlist);
1863
 
1864
  add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1865
                                  (char *) &new_group,
1866
                   "Set creation of new group when creating child process.",
1867
                                  &setlist),
1868
                     &showlist);
1869
 
1870
  add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1871
                                  (char *) &debug_exec,
1872
                       "Set whether to display execution in child process.",
1873
                                  &setlist),
1874
                     &showlist);
1875
 
1876
  add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1877
                                  (char *) &debug_events,
1878
                   "Set whether to display kernel events in child process.",
1879
                                  &setlist),
1880
                     &showlist);
1881
 
1882
  add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1883
                                  (char *) &debug_memory,
1884
                 "Set whether to display memory accesses in child process.",
1885
                                  &setlist),
1886
                     &showlist);
1887
 
1888
  add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1889
                                  (char *) &debug_exceptions,
1890
               "Set whether to display kernel exceptions in child process.",
1891
                                  &setlist),
1892
                     &showlist);
1893
 
1894
  add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1895
  add_info_alias ("sharedlibrary", "dll", 1);
1896
 
1897
  add_prefix_cmd ("w32", class_info, info_w32_command,
1898
                  "Print information specific to Win32 debugging.",
1899
                  &info_w32_cmdlist, "info w32 ", 0, &infolist);
1900
 
1901
  add_cmd ("selector", class_info, display_selectors,
1902
           "Display selectors infos.",
1903
           &info_w32_cmdlist);
1904
 
1905
  add_target (&child_ops);
1906
}
1907
 
1908
/* Hardware watchpoint support, adapted from go32-nat.c code.  */
1909
 
1910
/* Pass the address ADDR to the inferior in the I'th debug register.
1911
   Here we just store the address in dr array, the registers will be
1912
   actually set up when child_continue is called.  */
1913
void
1914
cygwin_set_dr (int i, CORE_ADDR addr)
1915
{
1916
  if (i < 0 || i > 3)
1917
    internal_error (__FILE__, __LINE__,
1918
                    "Invalid register %d in cygwin_set_dr.\n", i);
1919
  dr[i] = (unsigned) addr;
1920
  debug_registers_changed = 1;
1921
  debug_registers_used = 1;
1922
}
1923
 
1924
/* Pass the value VAL to the inferior in the DR7 debug control
1925
   register.  Here we just store the address in D_REGS, the watchpoint
1926
   will be actually set up in child_wait.  */
1927
void
1928
cygwin_set_dr7 (unsigned val)
1929
{
1930
  dr[7] = val;
1931
  debug_registers_changed = 1;
1932
  debug_registers_used = 1;
1933
}
1934
 
1935
/* Get the value of the DR6 debug status register from the inferior.
1936
   Here we just return the value stored in dr[6]
1937
   by the last call to thread_rec for current_event.dwThreadId id.  */
1938
unsigned
1939
cygwin_get_dr6 (void)
1940
{
1941
  return dr[6];
1942
}
1943
 
1944
 
1945
/* Determine if the thread referenced by "pid" is alive
1946
   by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
1947
   it means that the pid has died.  Otherwise it is assumed to be alive. */
1948
static int
1949
win32_child_thread_alive (ptid_t ptid)
1950
{
1951
  int pid = PIDGET (ptid);
1952
 
1953
  return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1954
    FALSE : TRUE;
1955
}
1956
 
1957
/* Convert pid to printable format. */
1958
char *
1959
cygwin_pid_to_str (ptid_t ptid)
1960
{
1961
  static char buf[80];
1962
  int pid = PIDGET (ptid);
1963
 
1964
  if ((DWORD) pid == current_event.dwProcessId)
1965
    sprintf (buf, "process %d", pid);
1966
  else
1967
    sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1968
  return buf;
1969
}
1970
 
1971
static int
1972
core_dll_symbols_add (char *dll_name, DWORD base_addr)
1973
{
1974
  struct objfile *objfile;
1975
  char *objfile_basename;
1976
  const char *dll_basename;
1977
 
1978
  if (!(dll_basename = strrchr (dll_name, '/')))
1979
    dll_basename = dll_name;
1980
  else
1981
    dll_basename++;
1982
 
1983
  ALL_OBJFILES (objfile)
1984
  {
1985
    objfile_basename = strrchr (objfile->name, '/');
1986
 
1987
    if (objfile_basename &&
1988
        strcmp (dll_basename, objfile_basename + 1) == 0)
1989
      {
1990
        printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1991
                           base_addr, dll_name);
1992
        goto out;
1993
      }
1994
  }
1995
 
1996
  register_loaded_dll (dll_name, base_addr + 0x1000);
1997
  solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
1998
 
1999
out:
2000
  return 1;
2001
}
2002
 
2003
typedef struct
2004
{
2005
  struct target_ops *target;
2006
  bfd_vma addr;
2007
}
2008
map_code_section_args;
2009
 
2010
static void
2011
map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
2012
{
2013
  int old;
2014
  int update_coreops;
2015
  struct section_table *new_target_sect_ptr;
2016
 
2017
  map_code_section_args *args = (map_code_section_args *) obj;
2018
  struct target_ops *target = args->target;
2019
  if (sect->flags & SEC_CODE)
2020
    {
2021
      update_coreops = core_ops.to_sections == target->to_sections;
2022
 
2023
      if (target->to_sections)
2024
        {
2025
          old = target->to_sections_end - target->to_sections;
2026
          target->to_sections = (struct section_table *)
2027
            xrealloc ((char *) target->to_sections,
2028
                      (sizeof (struct section_table)) * (1 + old));
2029
        }
2030
      else
2031
        {
2032
          old = 0;
2033
          target->to_sections = (struct section_table *)
2034
            xmalloc ((sizeof (struct section_table)));
2035
        }
2036
      target->to_sections_end = target->to_sections + (1 + old);
2037
 
2038
      /* Update the to_sections field in the core_ops structure
2039
         if needed.  */
2040
      if (update_coreops)
2041
        {
2042
          core_ops.to_sections = target->to_sections;
2043
          core_ops.to_sections_end = target->to_sections_end;
2044
        }
2045
      new_target_sect_ptr = target->to_sections + old;
2046
      new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
2047
      new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
2048
        bfd_section_size (abfd, sect);;
2049
      new_target_sect_ptr->the_bfd_section = sect;
2050
      new_target_sect_ptr->bfd = abfd;
2051
    }
2052
}
2053
 
2054
static int
2055
dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
2056
{
2057
  bfd *dll_bfd;
2058
  map_code_section_args map_args;
2059
  asection *lowest_sect;
2060
  char *name;
2061
  if (dll_name == NULL || target == NULL)
2062
    return 0;
2063
  name = xstrdup (dll_name);
2064
  dll_bfd = bfd_openr (name, "pei-i386");
2065
  if (dll_bfd == NULL)
2066
    return 0;
2067
 
2068
  if (bfd_check_format (dll_bfd, bfd_object))
2069
    {
2070
      lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
2071
      if (lowest_sect == NULL)
2072
        return 0;
2073
      map_args.target = target;
2074
      map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
2075
 
2076
      bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
2077
    }
2078
 
2079
  return 1;
2080
}
2081
 
2082
static void
2083
core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
2084
{
2085
  struct target_ops *target = (struct target_ops *) obj;
2086
 
2087
  DWORD base_addr;
2088
 
2089
  int dll_name_size;
2090
  char *dll_name = NULL;
2091
  char *buf = NULL;
2092
  struct win32_pstatus *pstatus;
2093
  char *p;
2094
 
2095
  if (strncmp (sect->name, ".module", 7))
2096
    return;
2097
 
2098
  buf = (char *) xmalloc (sect->_raw_size + 1);
2099
  if (!buf)
2100
    {
2101
      printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2102
      goto out;
2103
    }
2104
  if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
2105
    goto out;
2106
 
2107
  pstatus = (struct win32_pstatus *) buf;
2108
 
2109
  memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
2110
  dll_name_size = pstatus->data.module_info.module_name_size;
2111
  if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
2112
      goto out;
2113
 
2114
  dll_name = (char *) xmalloc (dll_name_size + 1);
2115
  if (!dll_name)
2116
    {
2117
      printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2118
      goto out;
2119
    }
2120
  strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
2121
 
2122
  while ((p = strchr (dll_name, '\\')))
2123
    *p = '/';
2124
 
2125
  if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
2126
    printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
2127
 
2128
  if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
2129
    printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
2130
 
2131
out:
2132
  if (buf)
2133
    xfree (buf);
2134
  if (dll_name)
2135
    xfree (dll_name);
2136
  return;
2137
}
2138
 
2139
void
2140
child_solib_add (char *filename, int from_tty, struct target_ops *target,
2141
                 int readsyms)
2142
{
2143
  if (!readsyms)
2144
    return;
2145
  if (core_bfd)
2146
    {
2147
      child_clear_solibs ();
2148
      bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
2149
    }
2150
  else
2151
    {
2152
      if (solib_end && solib_end->name)
2153
             solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
2154
                                                solib_end->load_addr);
2155
    }
2156
}
2157
 
2158
static void
2159
fetch_elf_core_registers (char *core_reg_sect,
2160
                          unsigned core_reg_size,
2161
                          int which,
2162
                          CORE_ADDR reg_addr)
2163
{
2164
  int r;
2165
  if (core_reg_size < sizeof (CONTEXT))
2166
    {
2167
      error ("Core file register section too small (%u bytes).", core_reg_size);
2168
      return;
2169
    }
2170
  for (r = 0; r < NUM_REGS; r++)
2171
    supply_register (r, core_reg_sect + mappings[r]);
2172
}
2173
 
2174
static struct core_fns win32_elf_core_fns =
2175
{
2176
  bfd_target_elf_flavour,
2177
  default_check_format,
2178
  default_core_sniffer,
2179
  fetch_elf_core_registers,
2180
  NULL
2181
};
2182
 
2183
void
2184
_initialize_core_win32 (void)
2185
{
2186
  add_core_fns (&win32_elf_core_fns);
2187
}
2188
 
2189
void
2190
_initialize_check_for_gdb_ini (void)
2191
{
2192
  char *homedir;
2193
  if (inhibit_gdbinit)
2194
    return;
2195
 
2196
  homedir = getenv ("HOME");
2197
  if (homedir)
2198
    {
2199
      char *p;
2200
      char *oldini = (char *) alloca (strlen (homedir) +
2201
                                      sizeof ("/gdb.ini"));
2202
      strcpy (oldini, homedir);
2203
      p = strchr (oldini, '\0');
2204
      if (p > oldini && p[-1] != '/')
2205
        *p++ = '/';
2206
      strcpy (p, "gdb.ini");
2207
      if (access (oldini, 0) == 0)
2208
        {
2209
          int len = strlen (oldini);
2210
          char *newini = alloca (len + 1);
2211
          sprintf (newini, "%.*s.gdbinit",
2212
            (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2213
          warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
2214
        }
2215
    }
2216
}

powered by: WebSVN 2.1.0

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