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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [win32-nat.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/* Target-vector operations for controlling win32 child processes, for GDB.
2
   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
3
   Free Software Foundation, Inc.
4
   Contributed by Cygnus Solutions, A Red Hat Company.
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 2 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 eve nthe 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, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
/* by Steve Chamberlain, sac@cygnus.com */
24
 
25
/* We assume we're being built with and will be used for cygwin.  */
26
 
27
#include "defs.h"
28
#include "frame.h"              /* required by inferior.h */
29
#include "inferior.h"
30
#include "target.h"
31
#include "gdbcore.h"
32
#include "command.h"
33
#include "completer.h"
34
#include "regcache.h"
35
#include <signal.h>
36
#include <sys/types.h>
37
#include <fcntl.h>
38
#include <stdlib.h>
39
#include <windows.h>
40
#include <imagehlp.h>
41
#include <sys/cygwin.h>
42
 
43
#include "buildsym.h"
44
#include "symfile.h"
45
#include "objfiles.h"
46
#include "gdb_string.h"
47
#include "gdbthread.h"
48
#include "gdbcmd.h"
49
#include <sys/param.h>
50
#include <unistd.h>
51
 
52
/* The ui's event loop. */
53
extern int (*ui_loop_hook) (int signo);
54
 
55
/* If we're not using the old Cygwin header file set, define the
56
   following which never should have been in the generic Win32 API
57
   headers in the first place since they were our own invention... */
58
#ifndef _GNU_H_WINDOWS_H
59
enum
60
  {
61
    FLAG_TRACE_BIT = 0x100,
62
    CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
63
  };
64
#endif
65
#include <sys/procfs.h>
66
#include <psapi.h>
67
 
68
/* The string sent by cygwin when it processes a signal.
69
   FIXME: This should be in a cygwin include file. */
70
#define CYGWIN_SIGNAL_STRING "cygwin: signal"
71
 
72
#define CHECK(x)        check (x, __FILE__,__LINE__)
73
#define DEBUG_EXEC(x)   if (debug_exec)         printf x
74
#define DEBUG_EVENTS(x) if (debug_events)       printf x
75
#define DEBUG_MEM(x)    if (debug_memory)       printf x
76
#define DEBUG_EXCEPT(x) if (debug_exceptions)   printf x
77
 
78
/* Forward declaration */
79
extern struct target_ops child_ops;
80
 
81
static void child_stop (void);
82
static int win32_child_thread_alive (ptid_t);
83
void child_kill_inferior (void);
84
 
85
static int last_sig = 0; /* Set if a signal was received from the
86
                                   debugged process */
87
/* Thread information structure used to track information that is
88
   not available in gdb's thread structure. */
89
typedef struct thread_info_struct
90
  {
91
    struct thread_info_struct *next;
92
    DWORD id;
93
    HANDLE h;
94
    char *name;
95
    int suspend_count;
96
    CONTEXT context;
97
    STACKFRAME sf;
98
  }
99
thread_info;
100
 
101
static thread_info thread_head;
102
 
103
/* The process and thread handles for the above context. */
104
 
105
static DEBUG_EVENT current_event;       /* The current debug event from
106
                                           WaitForDebugEvent */
107
static HANDLE current_process_handle;   /* Currently executing process */
108
static thread_info *current_thread;     /* Info on currently selected thread */
109
static DWORD main_thread_id;    /* Thread ID of the main thread */
110
 
111
/* Counts of things. */
112
static int exception_count = 0;
113
static int event_count = 0;
114
 
115
/* User options. */
116
static int new_console = 0;
117
static int new_group = 1;
118
static int debug_exec = 0;       /* show execution */
119
static int debug_events = 0;     /* show events from kernel */
120
static int debug_memory = 0;     /* show target memory accesses */
121
static int debug_exceptions = 0; /* show target exceptions */
122
 
123
/* This vector maps GDB's idea of a register's number into an address
124
   in the win32 exception context vector.
125
 
126
   It also contains the bit mask needed to load the register in question.
127
 
128
   One day we could read a reg, we could inspect the context we
129
   already have loaded, if it doesn't have the bit set that we need,
130
   we read that set of registers in using GetThreadContext.  If the
131
   context already contains what we need, we just unpack it. Then to
132
   write a register, first we have to ensure that the context contains
133
   the other regs of the group, and then we copy the info in and set
134
   out bit. */
135
 
136
#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
137
static const int mappings[] =
138
{
139
  context_offset (Eax),
140
  context_offset (Ecx),
141
  context_offset (Edx),
142
  context_offset (Ebx),
143
  context_offset (Esp),
144
  context_offset (Ebp),
145
  context_offset (Esi),
146
  context_offset (Edi),
147
  context_offset (Eip),
148
  context_offset (EFlags),
149
  context_offset (SegCs),
150
  context_offset (SegSs),
151
  context_offset (SegDs),
152
  context_offset (SegEs),
153
  context_offset (SegFs),
154
  context_offset (SegGs),
155
  context_offset (FloatSave.RegisterArea[0 * 10]),
156
  context_offset (FloatSave.RegisterArea[1 * 10]),
157
  context_offset (FloatSave.RegisterArea[2 * 10]),
158
  context_offset (FloatSave.RegisterArea[3 * 10]),
159
  context_offset (FloatSave.RegisterArea[4 * 10]),
160
  context_offset (FloatSave.RegisterArea[5 * 10]),
161
  context_offset (FloatSave.RegisterArea[6 * 10]),
162
  context_offset (FloatSave.RegisterArea[7 * 10]),
163
  context_offset (FloatSave.ControlWord),
164
  context_offset (FloatSave.StatusWord),
165
  context_offset (FloatSave.TagWord),
166
  context_offset (FloatSave.ErrorSelector),
167
  context_offset (FloatSave.ErrorOffset),
168
  context_offset (FloatSave.DataSelector),
169
  context_offset (FloatSave.DataOffset),
170
  context_offset (FloatSave.ErrorSelector)
171
};
172
 
173
#undef context_offset
174
 
175
/* This vector maps the target's idea of an exception (extracted
176
   from the DEBUG_EVENT structure) to GDB's idea. */
177
 
178
struct xlate_exception
179
  {
180
    int them;
181
    enum target_signal us;
182
  };
183
 
184
static const struct xlate_exception
185
  xlate[] =
186
{
187
  {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
188
  {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
189
  {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
190
  {DBG_CONTROL_C, TARGET_SIGNAL_INT},
191
  {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
192
  {-1, -1}};
193
 
194
/* Find a thread record given a thread id.
195
   If get_context then also retrieve the context for this
196
   thread. */
197
static thread_info *
198
thread_rec (DWORD id, int get_context)
199
{
200
  thread_info *th;
201
 
202
  for (th = &thread_head; (th = th->next) != NULL;)
203
    if (th->id == id)
204
      {
205
        if (!th->suspend_count && get_context)
206
          {
207
            if (get_context > 0 && id != current_event.dwThreadId)
208
              th->suspend_count = SuspendThread (th->h) + 1;
209
            else if (get_context < 0)
210
              th->suspend_count = -1;
211
 
212
            th->context.ContextFlags = CONTEXT_DEBUGGER;
213
            GetThreadContext (th->h, &th->context);
214
          }
215
        return th;
216
      }
217
 
218
  return NULL;
219
}
220
 
221
/* Add a thread to the thread list */
222
static thread_info *
223
child_add_thread (DWORD id, HANDLE h)
224
{
225
  thread_info *th;
226
 
227
  if ((th = thread_rec (id, FALSE)))
228
    return th;
229
 
230
  th = (thread_info *) xmalloc (sizeof (*th));
231
  memset (th, 0, sizeof (*th));
232
  th->id = id;
233
  th->h = h;
234
  th->next = thread_head.next;
235
  thread_head.next = th;
236
  add_thread (pid_to_ptid (id));
237
  return th;
238
}
239
 
240
/* Clear out any old thread list and reintialize it to a
241
   pristine state. */
242
static void
243
child_init_thread_list (void)
244
{
245
  thread_info *th = &thread_head;
246
 
247
  DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
248
  init_thread_list ();
249
  while (th->next != NULL)
250
    {
251
      thread_info *here = th->next;
252
      th->next = here->next;
253
      (void) CloseHandle (here->h);
254
      xfree (here);
255
    }
256
}
257
 
258
/* Delete a thread from the list of threads */
259
static void
260
child_delete_thread (DWORD id)
261
{
262
  thread_info *th;
263
 
264
  if (info_verbose)
265
    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
266
  delete_thread (pid_to_ptid (id));
267
 
268
  for (th = &thread_head;
269
       th->next != NULL && th->next->id != id;
270
       th = th->next)
271
    continue;
272
 
273
  if (th->next != NULL)
274
    {
275
      thread_info *here = th->next;
276
      th->next = here->next;
277
      CloseHandle (here->h);
278
      xfree (here);
279
    }
280
}
281
 
282
static void
283
check (BOOL ok, const char *file, int line)
284
{
285
  if (!ok)
286
    printf_filtered ("error return %s:%d was %lu\n", file, line, GetLastError ());
287
}
288
 
289
static void
290
do_child_fetch_inferior_registers (int r)
291
{
292
  char *context_offset = ((char *) &current_thread->context) + mappings[r];
293
  long l;
294
  if (r == FCS_REGNUM)
295
    {
296
      l = *((long *) context_offset) & 0xffff;
297
      supply_register (r, (char *) &l);
298
    }
299
  else if (r == FOP_REGNUM)
300
    {
301
      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
302
      supply_register (r, (char *) &l);
303
    }
304
  else if (r >= 0)
305
    supply_register (r, context_offset);
306
  else
307
    {
308
      for (r = 0; r < NUM_REGS; r++)
309
        do_child_fetch_inferior_registers (r);
310
    }
311
}
312
 
313
static void
314
child_fetch_inferior_registers (int r)
315
{
316
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
317
  do_child_fetch_inferior_registers (r);
318
}
319
 
320
static void
321
do_child_store_inferior_registers (int r)
322
{
323
  if (r >= 0)
324
    read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
325
  else
326
    {
327
      for (r = 0; r < NUM_REGS; r++)
328
        do_child_store_inferior_registers (r);
329
    }
330
}
331
 
332
/* Store a new register value into the current thread context */
333
static void
334
child_store_inferior_registers (int r)
335
{
336
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
337
  do_child_store_inferior_registers (r);
338
}
339
 
340
static int psapi_loaded = 0;
341
static HMODULE psapi_module_handle = NULL;
342
static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
343
static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
344
static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
345
 
346
int
347
psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
348
{
349
  DWORD len;
350
  MODULEINFO mi;
351
  int i;
352
  HMODULE dh_buf[1];
353
  HMODULE *DllHandle = dh_buf;
354
  DWORD cbNeeded;
355
  BOOL ok;
356
 
357
  if (!psapi_loaded ||
358
      psapi_EnumProcessModules == NULL ||
359
      psapi_GetModuleInformation == NULL ||
360
      psapi_GetModuleFileNameExA == NULL)
361
    {
362
      if (psapi_loaded)
363
        goto failed;
364
      psapi_loaded = 1;
365
      psapi_module_handle = LoadLibrary ("psapi.dll");
366
      if (!psapi_module_handle)
367
        {
368
          /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
369
          goto failed;
370
        }
371
      psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
372
      psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
373
      psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
374
                                                    "GetModuleFileNameExA");
375
      if (psapi_EnumProcessModules == NULL ||
376
          psapi_GetModuleInformation == NULL ||
377
          psapi_GetModuleFileNameExA == NULL)
378
        goto failed;
379
    }
380
 
381
  cbNeeded = 0;
382
  ok = (*psapi_EnumProcessModules) (current_process_handle,
383
                                    DllHandle,
384
                                    sizeof (HMODULE),
385
                                    &cbNeeded);
386
 
387
  if (!ok || !cbNeeded)
388
    goto failed;
389
 
390
  DllHandle = (HMODULE *) alloca (cbNeeded);
391
  if (!DllHandle)
392
    goto failed;
393
 
394
  ok = (*psapi_EnumProcessModules) (current_process_handle,
395
                                    DllHandle,
396
                                    cbNeeded,
397
                                    &cbNeeded);
398
  if (!ok)
399
    goto failed;
400
 
401
  for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
402
    {
403
      if (!(*psapi_GetModuleInformation) (current_process_handle,
404
                                          DllHandle[i],
405
                                          &mi,
406
                                          sizeof (mi)))
407
        error ("Can't get module info");
408
 
409
      len = (*psapi_GetModuleFileNameExA) (current_process_handle,
410
                                           DllHandle[i],
411
                                           dll_name_ret,
412
                                           MAX_PATH);
413
      if (len == 0)
414
        error ("Error getting dll name: %u\n", GetLastError ());
415
 
416
      if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
417
        return 1;
418
    }
419
 
420
failed:
421
  dll_name_ret[0] = '\0';
422
  return 0;
423
}
424
 
425
/* Encapsulate the information required in a call to
426
   symbol_file_add_args */
427
struct safe_symbol_file_add_args
428
{
429
  char *name;
430
  int from_tty;
431
  struct section_addr_info *addrs;
432
  int mainline;
433
  int flags;
434
  struct ui_file *err, *out;
435
  struct objfile *ret;
436
};
437
 
438
/* Call symbol_file_add with stderr redirected.  We don't care if there
439
   are errors. */
440
static int
441
safe_symbol_file_add_stub (void *argv)
442
{
443
#define p ((struct safe_symbol_file_add_args *)argv)
444
  p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
445
  return !!p->ret;
446
#undef p
447
}
448
 
449
/* Restore gdb's stderr after calling symbol_file_add */
450
static void
451
safe_symbol_file_add_cleanup (void *p)
452
{
453
#define sp ((struct safe_symbol_file_add_args *)p)
454
  gdb_flush (gdb_stderr);
455
  gdb_flush (gdb_stdout);
456
  ui_file_delete (gdb_stderr);
457
  ui_file_delete (gdb_stdout);
458
  gdb_stderr = sp->err;
459
  gdb_stdout = sp->out;
460
#undef sp
461
}
462
 
463
/* symbol_file_add wrapper that prevents errors from being displayed. */
464
static struct objfile *
465
safe_symbol_file_add (char *name, int from_tty,
466
                      struct section_addr_info *addrs,
467
                      int mainline, int flags)
468
{
469
  struct safe_symbol_file_add_args p;
470
  struct cleanup *cleanup;
471
 
472
  cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
473
 
474
  p.err = gdb_stderr;
475
  p.out = gdb_stdout;
476
  gdb_flush (gdb_stderr);
477
  gdb_flush (gdb_stdout);
478
  gdb_stderr = ui_file_new ();
479
  gdb_stdout = ui_file_new ();
480
  p.name = name;
481
  p.from_tty = from_tty;
482
  p.addrs = addrs;
483
  p.mainline = mainline;
484
  p.flags = flags;
485
  catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
486
 
487
  do_cleanups (cleanup);
488
  return p.ret;
489
}
490
 
491
/* Maintain a linked list of "so" information. */
492
struct so_stuff
493
{
494
  struct so_stuff *next, **last;
495
  DWORD load_addr;
496
  char name[0];
497
}
498
solib_start, *solib_end;
499
 
500
/* Remember the maximum DLL length for printing in info dll command. */
501
int max_dll_name_len;
502
 
503
static void
504
register_loaded_dll (const char *name, DWORD load_addr)
505
{
506
  struct so_stuff *so;
507
  so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (name) + 8 + 2);
508
  so->load_addr = load_addr;
509
  strcpy (so->name, name);
510
 
511
  solib_end->next = so;
512
  solib_end = so;
513
  so->next = NULL;
514
}
515
 
516
/* Wait for child to do something.  Return pid of child, or -1 in case
517
   of error; store status through argument pointer OURSTATUS.  */
518
static int
519
handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
520
{
521
  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
522
  DWORD dll_name_ptr;
523
  DWORD done;
524
  char dll_buf[MAX_PATH + 1];
525
  char *dll_name = NULL;
526
  int len;
527
  char *p;
528
 
529
  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
530
 
531
  if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
532
    dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
533
 
534
  dll_name = dll_buf;
535
 
536
  /* Attempt to read the name of the dll that was detected.
537
     This is documented to work only when actively debugging
538
     a program.  It will not work for attached processes. */
539
  if (dll_name == NULL || *dll_name == '\0')
540
    {
541
      DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
542
      int len = 0;
543
      char b[2];
544
 
545
      ReadProcessMemory (current_process_handle,
546
                         (LPCVOID) event->lpImageName,
547
                         (char *) &dll_name_ptr,
548
                         sizeof (dll_name_ptr), &done);
549
 
550
      /* See if we could read the address of a string, and that the
551
         address isn't null. */
552
 
553
      if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
554
        return 1;
555
 
556
      do
557
        {
558
          ReadProcessMemory (current_process_handle,
559
                             (LPCVOID) (dll_name_ptr + len * size),
560
                             &b,
561
                             size,
562
                             &done);
563
          len++;
564
        }
565
      while ((b[0] != 0 || b[size - 1] != 0) && done == size);
566
 
567
      dll_name = alloca (len);
568
 
569
      if (event->fUnicode)
570
        {
571
          WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
572
          ReadProcessMemory (current_process_handle,
573
                             (LPCVOID) dll_name_ptr,
574
                             unicode_dll_name,
575
                             len * sizeof (WCHAR),
576
                             &done);
577
 
578
          WideCharToMultiByte (CP_ACP, 0,
579
                               unicode_dll_name, len,
580
                               dll_name, len, 0, 0);
581
        }
582
      else
583
        {
584
          ReadProcessMemory (current_process_handle,
585
                             (LPCVOID) dll_name_ptr,
586
                             dll_name,
587
                             len,
588
                             &done);
589
        }
590
    }
591
 
592
  if (!dll_name)
593
    return 1;
594
 
595
  (void) strlwr (dll_name);
596
 
597
  while ((p = strchr (dll_name, '\\')))
598
    *p = '/';
599
 
600
  register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
601
  len = strlen (dll_name);
602
  if (len > max_dll_name_len)
603
    max_dll_name_len = len;
604
 
605
  return 1;
606
}
607
 
608
/* Return name of last loaded DLL. */
609
char *
610
child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED)
611
{
612
  return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
613
}
614
 
615
/* Clear list of loaded DLLs. */
616
void
617
child_clear_solibs (void)
618
{
619
  struct so_stuff *so, *so1 = solib_start.next;
620
 
621
  while ((so = so1) != NULL)
622
    {
623
      so1 = so->next;
624
      xfree (so);
625
    }
626
 
627
  solib_start.next = NULL;
628
  solib_end = &solib_start;
629
  max_dll_name_len = sizeof ("DLL Name") - 1;
630
}
631
 
632
/* Add DLL symbol information. */
633
void
634
solib_symbols_add (char *name, CORE_ADDR load_addr)
635
{
636
  struct section_addr_info section_addrs;
637
 
638
  /* The symbols in a dll are offset by 0x1000, which is the
639
     the offset from 0 of the first byte in an image - because
640
     of the file header and the section alignment. */
641
 
642
  if (!name || !name[0])
643
    return;
644
 
645
  memset (&section_addrs, 0, sizeof (section_addrs));
646
  section_addrs.other[0].name = ".text";
647
  section_addrs.other[0].addr = load_addr;
648
  safe_symbol_file_add (name, 0, &section_addrs, 0, OBJF_SHARED);
649
 
650
  return;
651
}
652
 
653
/* Load DLL symbol info. */
654
void
655
dll_symbol_command (char *args, int from_tty ATTRIBUTE_UNUSED)
656
{
657
  int n;
658
  dont_repeat ();
659
 
660
  if (args == NULL)
661
    error ("dll-symbols requires a file name");
662
 
663
  n = strlen (args);
664
  if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
665
    {
666
      char *newargs = (char *) alloca (n + 4 + 1);
667
      strcpy (newargs, args);
668
      strcat (newargs, ".dll");
669
      args = newargs;
670
    }
671
 
672
  safe_symbol_file_add (args, 0, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
673
}
674
 
675
/* List currently loaded DLLs. */
676
void
677
info_dll_command (char *ignore ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
678
{
679
  struct so_stuff *so = &solib_start;
680
 
681
  if (!so->next)
682
    return;
683
 
684
  printf ("%*s  Load Address\n", -max_dll_name_len, "DLL Name");
685
  while ((so = so->next) != NULL)
686
    printf_filtered ("%*s  %08lx\n", -max_dll_name_len, so->name, so->load_addr);
687
 
688
  return;
689
}
690
 
691
/* Handle DEBUG_STRING output from child process.
692
   Cygwin prepends its messages with a "cygwin:".  Interpret this as
693
   a Cygwin signal.  Otherwise just print the string as a warning. */
694
static int
695
handle_output_debug_string (struct target_waitstatus *ourstatus)
696
{
697
  char *s;
698
  int gotasig = FALSE;
699
 
700
  if (!target_read_string
701
    ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
702
      || !s || !*s)
703
    return gotasig;
704
 
705
  if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
706
    {
707
      if (strncmp (s, "cYg", 3) != 0)
708
        warning ("%s", s);
709
    }
710
  else
711
    {
712
      char *p;
713
      int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
714
      gotasig = target_signal_from_host (sig);
715
      ourstatus->value.sig = gotasig;
716
      if (gotasig)
717
        ourstatus->kind = TARGET_WAITKIND_STOPPED;
718
    }
719
 
720
  xfree (s);
721
  return gotasig;
722
}
723
 
724
static int
725
handle_exception (struct target_waitstatus *ourstatus)
726
{
727
  thread_info *th;
728
  DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
729
 
730
  ourstatus->kind = TARGET_WAITKIND_STOPPED;
731
 
732
  /* Record the context of the current thread */
733
  th = thread_rec (current_event.dwThreadId, -1);
734
 
735
  switch (code)
736
    {
737
    case EXCEPTION_ACCESS_VIOLATION:
738
      DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
739
       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
740
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
741
      last_sig = SIGSEGV;
742
      break;
743
    case STATUS_FLOAT_UNDERFLOW:
744
    case STATUS_FLOAT_DIVIDE_BY_ZERO:
745
    case STATUS_FLOAT_OVERFLOW:
746
    case STATUS_INTEGER_DIVIDE_BY_ZERO:
747
      DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
748
       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
749
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
750
      last_sig = SIGFPE;
751
      break;
752
    case STATUS_STACK_OVERFLOW:
753
      DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
754
       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
755
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
756
      break;
757
    case EXCEPTION_BREAKPOINT:
758
      DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
759
       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
760
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
761
      break;
762
    case DBG_CONTROL_C:
763
      DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
764
       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
765
      ourstatus->value.sig = TARGET_SIGNAL_INT;
766
      last_sig = SIGINT;        /* FIXME - should check pass state */
767
      break;
768
    case EXCEPTION_SINGLE_STEP:
769
      DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
770
       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
771
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
772
      break;
773
    case EXCEPTION_ILLEGAL_INSTRUCTION:
774
      DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
775
       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
776
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
777
      last_sig = SIGILL;
778
      break;
779
    default:
780
      printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
781
                    current_event.u.Exception.ExceptionRecord.ExceptionCode,
782
        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
783
      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
784
      break;
785
    }
786
  exception_count++;
787
  return 1;
788
}
789
 
790
/* Resume all artificially suspended threads if we are continuing
791
   execution */
792
static BOOL
793
child_continue (DWORD continue_status, int id)
794
{
795
  int i;
796
  thread_info *th;
797
  BOOL res;
798
 
799
  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
800
                 current_event.dwProcessId, current_event.dwThreadId));
801
  res = ContinueDebugEvent (current_event.dwProcessId,
802
                            current_event.dwThreadId,
803
                            continue_status);
804
  continue_status = 0;
805
  if (res)
806
    for (th = &thread_head; (th = th->next) != NULL;)
807
      if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
808
        {
809
          for (i = 0; i < th->suspend_count; i++)
810
            (void) ResumeThread (th->h);
811
          th->suspend_count = 0;
812
        }
813
 
814
  return res;
815
}
816
 
817
/* Get the next event from the child.  Return 1 if the event requires
818
   handling by WFI (or whatever).
819
 */
820
static int
821
get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
822
{
823
  BOOL debug_event;
824
  DWORD continue_status, event_code;
825
  thread_info *th = NULL;
826
  static thread_info dummy_thread_info;
827
  int retval = 0;
828
 
829
  last_sig = 0;
830
 
831
  if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
832
    goto out;
833
 
834
  event_count++;
835
  continue_status = DBG_CONTINUE;
836
 
837
  event_code = current_event.dwDebugEventCode;
838
  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
839
 
840
  switch (event_code)
841
    {
842
    case CREATE_THREAD_DEBUG_EVENT:
843
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
844
                     (unsigned) current_event.dwProcessId,
845
                     (unsigned) current_event.dwThreadId,
846
                     "CREATE_THREAD_DEBUG_EVENT"));
847
      /* Record the existence of this thread */
848
      th = child_add_thread (current_event.dwThreadId,
849
                             current_event.u.CreateThread.hThread);
850
      if (info_verbose)
851
        printf_unfiltered ("[New %s]\n",
852
                           target_pid_to_str (
853
                             pid_to_ptid (current_event.dwThreadId)));
854
      retval = current_event.dwThreadId;
855
      break;
856
 
857
    case EXIT_THREAD_DEBUG_EVENT:
858
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
859
                     (unsigned) current_event.dwProcessId,
860
                     (unsigned) current_event.dwThreadId,
861
                     "EXIT_THREAD_DEBUG_EVENT"));
862
      child_delete_thread (current_event.dwThreadId);
863
      th = &dummy_thread_info;
864
      break;
865
 
866
    case CREATE_PROCESS_DEBUG_EVENT:
867
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
868
                     (unsigned) current_event.dwProcessId,
869
                     (unsigned) current_event.dwThreadId,
870
                     "CREATE_PROCESS_DEBUG_EVENT"));
871
      current_process_handle = current_event.u.CreateProcessInfo.hProcess;
872
 
873
      main_thread_id = current_event.dwThreadId;
874
      /* Add the main thread */
875
#if 0
876
      th = child_add_thread (current_event.dwProcessId,
877
                             current_event.u.CreateProcessInfo.hProcess);
878
#endif
879
      th = child_add_thread (main_thread_id,
880
                             current_event.u.CreateProcessInfo.hThread);
881
      retval = ourstatus->value.related_pid = current_event.dwThreadId;
882
      break;
883
 
884
    case EXIT_PROCESS_DEBUG_EVENT:
885
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
886
                     (unsigned) current_event.dwProcessId,
887
                     (unsigned) current_event.dwThreadId,
888
                     "EXIT_PROCESS_DEBUG_EVENT"));
889
      ourstatus->kind = TARGET_WAITKIND_EXITED;
890
      ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
891
      CloseHandle (current_process_handle);
892
      retval = main_thread_id;
893
      break;
894
 
895
    case LOAD_DLL_DEBUG_EVENT:
896
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
897
                     (unsigned) current_event.dwProcessId,
898
                     (unsigned) current_event.dwThreadId,
899
                     "LOAD_DLL_DEBUG_EVENT"));
900
      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
901
      registers_changed ();     /* mark all regs invalid */
902
      ourstatus->kind = TARGET_WAITKIND_LOADED;
903
      ourstatus->value.integer = 0;
904
      retval = main_thread_id;
905
      break;
906
 
907
    case UNLOAD_DLL_DEBUG_EVENT:
908
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
909
                     (unsigned) current_event.dwProcessId,
910
                     (unsigned) current_event.dwThreadId,
911
                     "UNLOAD_DLL_DEBUG_EVENT"));
912
      break;                    /* FIXME: don't know what to do here */
913
 
914
    case EXCEPTION_DEBUG_EVENT:
915
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
916
                     (unsigned) current_event.dwProcessId,
917
                     (unsigned) current_event.dwThreadId,
918
                     "EXCEPTION_DEBUG_EVENT"));
919
      handle_exception (ourstatus);
920
      retval = current_event.dwThreadId;
921
      break;
922
 
923
    case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
924
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
925
                     (unsigned) current_event.dwProcessId,
926
                     (unsigned) current_event.dwThreadId,
927
                     "OUTPUT_DEBUG_STRING_EVENT"));
928
      if (handle_output_debug_string (ourstatus))
929
        retval = main_thread_id;
930
      break;
931
 
932
    default:
933
      printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
934
                         (DWORD) current_event.dwProcessId,
935
                         (DWORD) current_event.dwThreadId);
936
      printf_unfiltered ("                 unknown event code %ld\n",
937
                         current_event.dwDebugEventCode);
938
      break;
939
    }
940
 
941
  if (!retval)
942
    CHECK (child_continue (continue_status, -1));
943
  else
944
    {
945
      current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
946
      inferior_ptid = pid_to_ptid (retval);
947
    }
948
 
949
out:
950
  return retval;
951
}
952
 
953
/* Wait for interesting events to occur in the target process. */
954
static ptid_t
955
child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
956
{
957
  int pid = PIDGET (ptid);
958
 
959
  /* We loop when we get a non-standard exception rather than return
960
     with a SPURIOUS because resume can try and step or modify things,
961
     which needs a current_thread->h.  But some of these exceptions mark
962
     the birth or death of threads, which mean that the current thread
963
     isn't necessarily what you think it is. */
964
 
965
  while (1)
966
    {
967
      int retval = get_child_debug_event (pid, ourstatus);
968
      if (retval)
969
        return pid_to_ptid (retval);
970
      else
971
        {
972
          int detach = 0;
973
 
974
          if (ui_loop_hook != NULL)
975
            detach = ui_loop_hook (0);
976
 
977
          if (detach)
978
            child_kill_inferior ();
979
        }
980
    }
981
}
982
 
983
static void
984
do_initial_child_stuff (DWORD pid)
985
{
986
  extern int stop_after_trap;
987
 
988
  last_sig = 0;
989
  event_count = 0;
990
  exception_count = 0;
991
  current_event.dwProcessId = pid;
992
  memset (&current_event, 0, sizeof (current_event));
993
  push_target (&child_ops);
994
  child_init_thread_list ();
995
  child_clear_solibs ();
996
  clear_proceed_status ();
997
  init_wait_for_inferior ();
998
 
999
  target_terminal_init ();
1000
  target_terminal_inferior ();
1001
 
1002
  while (1)
1003
    {
1004
      stop_after_trap = 1;
1005
      wait_for_inferior ();
1006
      if (stop_signal != TARGET_SIGNAL_TRAP)
1007
        resume (0, stop_signal);
1008
      else
1009
        break;
1010
    }
1011
  stop_after_trap = 0;
1012
  return;
1013
}
1014
 
1015
/* Attach to process PID, then initialize for debugging it.  */
1016
 
1017
static void
1018
child_attach (char *args, int from_tty)
1019
{
1020
  BOOL ok;
1021
  DWORD pid;
1022
 
1023
  if (!args)
1024
    error_no_arg ("process-id to attach");
1025
 
1026
  pid = strtoul (args, 0, 0);
1027
  ok = DebugActiveProcess (pid);
1028
 
1029
  if (!ok)
1030
    error ("Can't attach to process.");
1031
 
1032
  if (from_tty)
1033
    {
1034
      char *exec_file = (char *) get_exec_file (0);
1035
 
1036
      if (exec_file)
1037
        printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1038
                           target_pid_to_str (pid_to_ptid (pid)));
1039
      else
1040
        printf_unfiltered ("Attaching to %s\n",
1041
                           target_pid_to_str (pid_to_ptid (pid)));
1042
 
1043
      gdb_flush (gdb_stdout);
1044
    }
1045
 
1046
  do_initial_child_stuff (pid);
1047
  target_terminal_ours ();
1048
}
1049
 
1050
static void
1051
child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
1052
{
1053
  if (from_tty)
1054
    {
1055
      char *exec_file = get_exec_file (0);
1056
      if (exec_file == 0)
1057
        exec_file = "";
1058
      printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
1059
                         target_pid_to_str (inferior_ptid));
1060
      gdb_flush (gdb_stdout);
1061
    }
1062
  inferior_ptid = null_ptid;
1063
  unpush_target (&child_ops);
1064
}
1065
 
1066
/* Print status information about what we're accessing.  */
1067
 
1068
static void
1069
child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
1070
{
1071
  printf_unfiltered ("\tUsing the running image of %s %s.\n",
1072
      attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
1073
}
1074
 
1075
/* ARGSUSED */
1076
static void
1077
child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
1078
{
1079
  error ("Use the \"run\" command to start a Unix child process.");
1080
}
1081
 
1082
/* Start an inferior win32 child process and sets inferior_ptid to its pid.
1083
   EXEC_FILE is the file to run.
1084
   ALLARGS is a string containing the arguments to the program.
1085
   ENV is the environment vector to pass.  Errors reported with error().  */
1086
 
1087
static void
1088
child_create_inferior (char *exec_file, char *allargs, char **env)
1089
{
1090
  char real_path[MAXPATHLEN];
1091
  char *winenv;
1092
  char *temp;
1093
  int envlen;
1094
  int i;
1095
  STARTUPINFO si;
1096
  PROCESS_INFORMATION pi;
1097
  BOOL ret;
1098
  DWORD flags;
1099
  char *args;
1100
 
1101
  if (!exec_file)
1102
    error ("No executable specified, use `target exec'.\n");
1103
 
1104
  memset (&si, 0, sizeof (si));
1105
  si.cb = sizeof (si);
1106
 
1107
  cygwin_conv_to_win32_path (exec_file, real_path);
1108
 
1109
  flags = DEBUG_ONLY_THIS_PROCESS;
1110
 
1111
  if (new_group)
1112
    flags |= CREATE_NEW_PROCESS_GROUP;
1113
 
1114
  if (new_console)
1115
    flags |= CREATE_NEW_CONSOLE;
1116
 
1117
  args = alloca (strlen (real_path) + strlen (allargs) + 2);
1118
 
1119
  strcpy (args, real_path);
1120
 
1121
  strcat (args, " ");
1122
  strcat (args, allargs);
1123
 
1124
  /* Prepare the environment vars for CreateProcess.  */
1125
  {
1126
    /* This code use to assume all env vars were file names and would
1127
       translate them all to win32 style.  That obviously doesn't work in the
1128
       general case.  The current rule is that we only translate PATH.
1129
       We need to handle PATH because we're about to call CreateProcess and
1130
       it uses PATH to find DLL's.  Fortunately PATH has a well-defined value
1131
       in both posix and win32 environments.  cygwin.dll will change it back
1132
       to posix style if necessary.  */
1133
 
1134
    static const char *conv_path_names[] =
1135
    {
1136
      "PATH=",
1137
 
1138
    };
1139
 
1140
    /* CreateProcess takes the environment list as a null terminated set of
1141
       strings (i.e. two nulls terminate the list).  */
1142
 
1143
    /* Get total size for env strings.  */
1144
    for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1145
      {
1146
        int j, len;
1147
 
1148
        for (j = 0; conv_path_names[j]; j++)
1149
          {
1150
            len = strlen (conv_path_names[j]);
1151
            if (strncmp (conv_path_names[j], env[i], len) == 0)
1152
              {
1153
                if (cygwin_posix_path_list_p (env[i] + len))
1154
                  envlen += len
1155
                    + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1156
                else
1157
                  envlen += strlen (env[i]) + 1;
1158
                break;
1159
              }
1160
          }
1161
        if (conv_path_names[j] == NULL)
1162
          envlen += strlen (env[i]) + 1;
1163
      }
1164
 
1165
    winenv = alloca (envlen + 1);
1166
 
1167
    /* Copy env strings into new buffer.  */
1168
    for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1169
      {
1170
        int j, len;
1171
 
1172
        for (j = 0; conv_path_names[j]; j++)
1173
          {
1174
            len = strlen (conv_path_names[j]);
1175
            if (strncmp (conv_path_names[j], env[i], len) == 0)
1176
              {
1177
                if (cygwin_posix_path_list_p (env[i] + len))
1178
                  {
1179
                    memcpy (temp, env[i], len);
1180
                    cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1181
                  }
1182
                else
1183
                  strcpy (temp, env[i]);
1184
                break;
1185
              }
1186
          }
1187
        if (conv_path_names[j] == NULL)
1188
          strcpy (temp, env[i]);
1189
 
1190
        temp += strlen (temp) + 1;
1191
      }
1192
 
1193
    /* Final nil string to terminate new env.  */
1194
    *temp = 0;
1195
  }
1196
 
1197
  ret = CreateProcess (0,
1198
                       args,    /* command line */
1199
                       NULL,    /* Security */
1200
                       NULL,    /* thread */
1201
                       TRUE,    /* inherit handles */
1202
                       flags,   /* start flags */
1203
                       winenv,
1204
                       NULL,    /* current directory */
1205
                       &si,
1206
                       &pi);
1207
  if (!ret)
1208
    error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1209
 
1210
  do_initial_child_stuff (pi.dwProcessId);
1211
 
1212
  /* child_continue (DBG_CONTINUE, -1); */
1213
  proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1214
}
1215
 
1216
static void
1217
child_mourn_inferior (void)
1218
{
1219
  (void) child_continue (DBG_CONTINUE, -1);
1220
  unpush_target (&child_ops);
1221
  generic_mourn_inferior ();
1222
}
1223
 
1224
/* Send a SIGINT to the process group.  This acts just like the user typed a
1225
   ^C on the controlling terminal. */
1226
 
1227
static void
1228
child_stop (void)
1229
{
1230
  DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1231
  CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1232
  registers_changed ();         /* refresh register state */
1233
}
1234
 
1235
int
1236
child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1237
                   int write, struct mem_attrib *mem ATTRIBUTE_UNUSED,
1238
                   struct target_ops *target ATTRIBUTE_UNUSED)
1239
{
1240
  DWORD done;
1241
  if (write)
1242
    {
1243
      DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1244
                  len, (DWORD) memaddr));
1245
      WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1246
                          len, &done);
1247
      FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1248
    }
1249
  else
1250
    {
1251
      DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1252
                  len, (DWORD) memaddr));
1253
      ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1254
                         &done);
1255
    }
1256
  return done;
1257
}
1258
 
1259
void
1260
child_kill_inferior (void)
1261
{
1262
  CHECK (TerminateProcess (current_process_handle, 0));
1263
 
1264
  for (;;)
1265
    {
1266
      if (!child_continue (DBG_CONTINUE, -1))
1267
        break;
1268
      if (!WaitForDebugEvent (&current_event, INFINITE))
1269
        break;
1270
      if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1271
        break;
1272
    }
1273
 
1274
  CHECK (CloseHandle (current_process_handle));
1275
 
1276
  /* this may fail in an attached process so don't check. */
1277
  (void) CloseHandle (current_thread->h);
1278
  target_mourn_inferior ();     /* or just child_mourn_inferior? */
1279
}
1280
 
1281
void
1282
child_resume (ptid_t ptid, int step, enum target_signal sig)
1283
{
1284
  thread_info *th;
1285
  DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1286
  DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1287
  int pid = PIDGET (ptid);
1288
 
1289
  last_sig = 0;
1290
 
1291
  DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1292
               pid, step, sig));
1293
 
1294
  /* Get context for currently selected thread */
1295
  th = thread_rec (current_event.dwThreadId, FALSE);
1296
  if (th)
1297
    {
1298
      if (step)
1299
        {
1300
          /* Single step by setting t bit */
1301
          child_fetch_inferior_registers (PS_REGNUM);
1302
          th->context.EFlags |= FLAG_TRACE_BIT;
1303
        }
1304
 
1305
      if (th->context.ContextFlags)
1306
        {
1307
          CHECK (SetThreadContext (th->h, &th->context));
1308
          th->context.ContextFlags = 0;
1309
        }
1310
    }
1311
 
1312
  /* Allow continuing with the same signal that interrupted us.
1313
     Otherwise complain. */
1314
 
1315
  child_continue (continue_status, pid);
1316
}
1317
 
1318
static void
1319
child_prepare_to_store (void)
1320
{
1321
  /* Do nothing, since we can store individual regs */
1322
}
1323
 
1324
static int
1325
child_can_run (void)
1326
{
1327
  return 1;
1328
}
1329
 
1330
static void
1331
child_close (int x ATTRIBUTE_UNUSED)
1332
{
1333
  DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1334
                PIDGET (inferior_ptid)));
1335
}
1336
 
1337
struct target_ops child_ops;
1338
 
1339
static void
1340
init_child_ops (void)
1341
{
1342
  child_ops.to_shortname = "child";
1343
  child_ops.to_longname = "Win32 child process";
1344
  child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1345
  child_ops.to_open = child_open;
1346
  child_ops.to_close = child_close;
1347
  child_ops.to_attach = child_attach;
1348
  child_ops.to_detach = child_detach;
1349
  child_ops.to_resume = child_resume;
1350
  child_ops.to_wait = child_wait;
1351
  child_ops.to_fetch_registers = child_fetch_inferior_registers;
1352
  child_ops.to_store_registers = child_store_inferior_registers;
1353
  child_ops.to_prepare_to_store = child_prepare_to_store;
1354
  child_ops.to_xfer_memory = child_xfer_memory;
1355
  child_ops.to_files_info = child_files_info;
1356
  child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1357
  child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1358
  child_ops.to_terminal_init = terminal_init_inferior;
1359
  child_ops.to_terminal_inferior = terminal_inferior;
1360
  child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1361
  child_ops.to_terminal_ours = terminal_ours;
1362
  child_ops.to_terminal_info = child_terminal_info;
1363
  child_ops.to_kill = child_kill_inferior;
1364
  child_ops.to_load = 0;
1365
  child_ops.to_lookup_symbol = 0;
1366
  child_ops.to_create_inferior = child_create_inferior;
1367
  child_ops.to_mourn_inferior = child_mourn_inferior;
1368
  child_ops.to_can_run = child_can_run;
1369
  child_ops.to_notice_signals = 0;
1370
  child_ops.to_thread_alive = win32_child_thread_alive;
1371
  child_ops.to_pid_to_str = cygwin_pid_to_str;
1372
  child_ops.to_stop = child_stop;
1373
  child_ops.to_stratum = process_stratum;
1374
  child_ops.DONT_USE = 0;
1375
  child_ops.to_has_all_memory = 1;
1376
  child_ops.to_has_memory = 1;
1377
  child_ops.to_has_stack = 1;
1378
  child_ops.to_has_registers = 1;
1379
  child_ops.to_has_execution = 1;
1380
  child_ops.to_sections = 0;
1381
  child_ops.to_sections_end = 0;
1382
  child_ops.to_magic = OPS_MAGIC;
1383
}
1384
 
1385
void
1386
_initialize_inftarg (void)
1387
{
1388
  struct cmd_list_element *c;
1389
 
1390
  init_child_ops ();
1391
 
1392
  c = add_com ("dll-symbols", class_files, dll_symbol_command,
1393
               "Load dll library symbols from FILE.");
1394
  c->completer = filename_completer;
1395
 
1396
  auto_solib_add = 1;
1397
  add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1398
 
1399
  add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1400
                                  (char *) &new_console,
1401
                 "Set creation of new console when creating child process.",
1402
                                  &setlist),
1403
                     &showlist);
1404
 
1405
  add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1406
                                  (char *) &new_group,
1407
                   "Set creation of new group when creating child process.",
1408
                                  &setlist),
1409
                     &showlist);
1410
 
1411
  add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1412
                                  (char *) &debug_exec,
1413
                       "Set whether to display execution in child process.",
1414
                                  &setlist),
1415
                     &showlist);
1416
 
1417
  add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1418
                                  (char *) &debug_events,
1419
                   "Set whether to display kernel events in child process.",
1420
                                  &setlist),
1421
                     &showlist);
1422
 
1423
  add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1424
                                  (char *) &debug_memory,
1425
                 "Set whether to display memory accesses in child process.",
1426
                                  &setlist),
1427
                     &showlist);
1428
 
1429
  add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1430
                                  (char *) &debug_exceptions,
1431
               "Set whether to display kernel exceptions in child process.",
1432
                                  &setlist),
1433
                     &showlist);
1434
 
1435
  add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1436
  add_info_alias ("sharedlibrary", "dll", 1);
1437
 
1438
  add_target (&child_ops);
1439
}
1440
 
1441
/* Determine if the thread referenced by "pid" is alive
1442
   by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
1443
   it means that the pid has died.  Otherwise it is assumed to be alive. */
1444
static int
1445
win32_child_thread_alive (ptid_t ptid)
1446
{
1447
  int pid = PIDGET (ptid);
1448
 
1449
  return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1450
    FALSE : TRUE;
1451
}
1452
 
1453
/* Convert pid to printable format. */
1454
char *
1455
cygwin_pid_to_str (ptid_t ptid)
1456
{
1457
  static char buf[80];
1458
  int pid = PIDGET (ptid);
1459
 
1460
  if ((DWORD) pid == current_event.dwProcessId)
1461
    sprintf (buf, "process %d", pid);
1462
  else
1463
    sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1464
  return buf;
1465
}
1466
 
1467
static int
1468
core_dll_symbols_add (char *dll_name, DWORD base_addr)
1469
{
1470
  struct objfile *objfile;
1471
  char *objfile_basename;
1472
  const char *dll_basename;
1473
 
1474
  if (!(dll_basename = strrchr (dll_name, '/')))
1475
    dll_basename = dll_name;
1476
  else
1477
    dll_basename++;
1478
 
1479
  ALL_OBJFILES (objfile)
1480
  {
1481
    objfile_basename = strrchr (objfile->name, '/');
1482
 
1483
    if (objfile_basename &&
1484
        strcmp (dll_basename, objfile_basename + 1) == 0)
1485
      {
1486
        printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1487
                           base_addr, dll_name);
1488
        goto out;
1489
      }
1490
  }
1491
 
1492
  register_loaded_dll (dll_name, base_addr + 0x1000);
1493
  solib_symbols_add (dll_name, (CORE_ADDR) base_addr + 0x1000);
1494
 
1495
out:
1496
  return 1;
1497
}
1498
 
1499
typedef struct
1500
{
1501
  struct target_ops *target;
1502
  bfd_vma addr;
1503
}
1504
map_code_section_args;
1505
 
1506
static void
1507
map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
1508
{
1509
  int old;
1510
  int update_coreops;
1511
  struct section_table *new_target_sect_ptr;
1512
 
1513
  map_code_section_args *args = (map_code_section_args *) obj;
1514
  struct target_ops *target = args->target;
1515
  if (sect->flags & SEC_CODE)
1516
    {
1517
      update_coreops = core_ops.to_sections == target->to_sections;
1518
 
1519
      if (target->to_sections)
1520
        {
1521
          old = target->to_sections_end - target->to_sections;
1522
          target->to_sections = (struct section_table *)
1523
            xrealloc ((char *) target->to_sections,
1524
                      (sizeof (struct section_table)) * (1 + old));
1525
        }
1526
      else
1527
        {
1528
          old = 0;
1529
          target->to_sections = (struct section_table *)
1530
            xmalloc ((sizeof (struct section_table)));
1531
        }
1532
      target->to_sections_end = target->to_sections + (1 + old);
1533
 
1534
      /* Update the to_sections field in the core_ops structure
1535
         if needed.  */
1536
      if (update_coreops)
1537
        {
1538
          core_ops.to_sections = target->to_sections;
1539
          core_ops.to_sections_end = target->to_sections_end;
1540
        }
1541
      new_target_sect_ptr = target->to_sections + old;
1542
      new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1543
      new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1544
        bfd_section_size (abfd, sect);;
1545
      new_target_sect_ptr->the_bfd_section = sect;
1546
      new_target_sect_ptr->bfd = abfd;
1547
    }
1548
}
1549
 
1550
static int
1551
dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1552
{
1553
  bfd *dll_bfd;
1554
  map_code_section_args map_args;
1555
  asection *lowest_sect;
1556
  char *name;
1557
  if (dll_name == NULL || target == NULL)
1558
    return 0;
1559
  name = xstrdup (dll_name);
1560
  dll_bfd = bfd_openr (name, "pei-i386");
1561
  if (dll_bfd == NULL)
1562
    return 0;
1563
 
1564
  if (bfd_check_format (dll_bfd, bfd_object))
1565
    {
1566
      lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1567
      if (lowest_sect == NULL)
1568
        return 0;
1569
      map_args.target = target;
1570
      map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1571
 
1572
      bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
1573
    }
1574
 
1575
  return 1;
1576
}
1577
 
1578
static void
1579
core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
1580
{
1581
  struct target_ops *target = (struct target_ops *) obj;
1582
 
1583
  DWORD base_addr;
1584
 
1585
  int dll_name_size;
1586
  char *dll_name = NULL;
1587
  char *buf = NULL;
1588
  struct win32_pstatus *pstatus;
1589
  char *p;
1590
 
1591
  if (strncmp (sect->name, ".module", 7))
1592
    return;
1593
 
1594
  buf = (char *) xmalloc (sect->_raw_size + 1);
1595
  if (!buf)
1596
    {
1597
      printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1598
      goto out;
1599
    }
1600
  if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1601
    goto out;
1602
 
1603
  pstatus = (struct win32_pstatus *) buf;
1604
 
1605
  memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1606
  dll_name_size = pstatus->data.module_info.module_name_size;
1607
  if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1608
      goto out;
1609
 
1610
  dll_name = (char *) xmalloc (dll_name_size + 1);
1611
  if (!dll_name)
1612
    {
1613
      printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1614
      goto out;
1615
    }
1616
  strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1617
 
1618
  while ((p = strchr (dll_name, '\\')))
1619
    *p = '/';
1620
 
1621
  if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1622
    printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1623
 
1624
  if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1625
    printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1626
 
1627
out:
1628
  if (buf)
1629
    xfree (buf);
1630
  if (dll_name)
1631
    xfree (dll_name);
1632
  return;
1633
}
1634
 
1635
void
1636
child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED, struct target_ops *target)
1637
{
1638
  if (core_bfd)
1639
    {
1640
      child_clear_solibs ();
1641
      bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1642
    }
1643
  else
1644
    {
1645
      if (solib_end && solib_end->name)
1646
        solib_symbols_add (solib_end->name, solib_end->load_addr);
1647
    }
1648
}
1649
 
1650
static void
1651
fetch_elf_core_registers (char *core_reg_sect,
1652
                          unsigned core_reg_size,
1653
                          int which,
1654
                          CORE_ADDR reg_addr)
1655
{
1656
  int r;
1657
  if (core_reg_size < sizeof (CONTEXT))
1658
    {
1659
      error ("Core file register section too small (%u bytes).", core_reg_size);
1660
      return;
1661
    }
1662
  for (r = 0; r < NUM_REGS; r++)
1663
    supply_register (r, core_reg_sect + mappings[r]);
1664
}
1665
 
1666
static struct core_fns win32_elf_core_fns =
1667
{
1668
  bfd_target_elf_flavour,
1669
  default_check_format,
1670
  default_core_sniffer,
1671
  fetch_elf_core_registers,
1672
  NULL
1673
};
1674
 
1675
void
1676
_initialize_core_win32 (void)
1677
{
1678
  add_core_fns (&win32_elf_core_fns);
1679
}

powered by: WebSVN 2.1.0

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