* win32-nat.c (get_child_debug_event): Close file handles created after process
[platform/upstream/binutils.git] / gdb / win32-nat.c
1 /* 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       CloseHandle (current_event.u.CreateProcessInfo.hFile);
872       current_process_handle = current_event.u.CreateProcessInfo.hProcess;
873
874       main_thread_id = current_event.dwThreadId;
875       /* Add the main thread */
876 #if 0
877       th = child_add_thread (current_event.dwProcessId,
878                              current_event.u.CreateProcessInfo.hProcess);
879 #endif
880       th = child_add_thread (main_thread_id,
881                              current_event.u.CreateProcessInfo.hThread);
882       retval = ourstatus->value.related_pid = current_event.dwThreadId;
883       break;
884
885     case EXIT_PROCESS_DEBUG_EVENT:
886       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
887                      (unsigned) current_event.dwProcessId,
888                      (unsigned) current_event.dwThreadId,
889                      "EXIT_PROCESS_DEBUG_EVENT"));
890       ourstatus->kind = TARGET_WAITKIND_EXITED;
891       ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
892       CloseHandle (current_process_handle);
893       retval = main_thread_id;
894       break;
895
896     case LOAD_DLL_DEBUG_EVENT:
897       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
898                      (unsigned) current_event.dwProcessId,
899                      (unsigned) current_event.dwThreadId,
900                      "LOAD_DLL_DEBUG_EVENT"));
901       CloseHandle (current_event.u.LoadDll.hFile);
902       catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
903       registers_changed ();     /* mark all regs invalid */
904       ourstatus->kind = TARGET_WAITKIND_LOADED;
905       ourstatus->value.integer = 0;
906       retval = main_thread_id;
907       break;
908
909     case UNLOAD_DLL_DEBUG_EVENT:
910       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
911                      (unsigned) current_event.dwProcessId,
912                      (unsigned) current_event.dwThreadId,
913                      "UNLOAD_DLL_DEBUG_EVENT"));
914       break;                    /* FIXME: don't know what to do here */
915
916     case EXCEPTION_DEBUG_EVENT:
917       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
918                      (unsigned) current_event.dwProcessId,
919                      (unsigned) current_event.dwThreadId,
920                      "EXCEPTION_DEBUG_EVENT"));
921       handle_exception (ourstatus);
922       retval = current_event.dwThreadId;
923       break;
924
925     case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
926       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
927                      (unsigned) current_event.dwProcessId,
928                      (unsigned) current_event.dwThreadId,
929                      "OUTPUT_DEBUG_STRING_EVENT"));
930       if (handle_output_debug_string (ourstatus))
931         retval = main_thread_id;
932       break;
933
934     default:
935       printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
936                          (DWORD) current_event.dwProcessId,
937                          (DWORD) current_event.dwThreadId);
938       printf_unfiltered ("                 unknown event code %ld\n",
939                          current_event.dwDebugEventCode);
940       break;
941     }
942
943   if (!retval)
944     CHECK (child_continue (continue_status, -1));
945   else
946     {
947       current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
948       inferior_ptid = pid_to_ptid (retval);
949     }
950
951 out:
952   return retval;
953 }
954
955 /* Wait for interesting events to occur in the target process. */
956 static ptid_t
957 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
958 {
959   int pid = PIDGET (ptid);
960
961   /* We loop when we get a non-standard exception rather than return
962      with a SPURIOUS because resume can try and step or modify things,
963      which needs a current_thread->h.  But some of these exceptions mark
964      the birth or death of threads, which mean that the current thread
965      isn't necessarily what you think it is. */
966
967   while (1)
968     {
969       int retval = get_child_debug_event (pid, ourstatus);
970       if (retval)
971         return pid_to_ptid (retval);
972       else
973         {
974           int detach = 0;
975
976           if (ui_loop_hook != NULL)
977             detach = ui_loop_hook (0);
978
979           if (detach)
980             child_kill_inferior ();
981         }
982     }
983 }
984
985 static void
986 do_initial_child_stuff (DWORD pid)
987 {
988   extern int stop_after_trap;
989
990   last_sig = 0;
991   event_count = 0;
992   exception_count = 0;
993   current_event.dwProcessId = pid;
994   memset (&current_event, 0, sizeof (current_event));
995   push_target (&child_ops);
996   child_init_thread_list ();
997   child_clear_solibs ();
998   clear_proceed_status ();
999   init_wait_for_inferior ();
1000
1001   target_terminal_init ();
1002   target_terminal_inferior ();
1003
1004   while (1)
1005     {
1006       stop_after_trap = 1;
1007       wait_for_inferior ();
1008       if (stop_signal != TARGET_SIGNAL_TRAP)
1009         resume (0, stop_signal);
1010       else
1011         break;
1012     }
1013   stop_after_trap = 0;
1014   return;
1015 }
1016
1017 /* Attach to process PID, then initialize for debugging it.  */
1018
1019 static void
1020 child_attach (char *args, int from_tty)
1021 {
1022   BOOL ok;
1023   DWORD pid;
1024
1025   if (!args)
1026     error_no_arg ("process-id to attach");
1027
1028   pid = strtoul (args, 0, 0);
1029   ok = DebugActiveProcess (pid);
1030
1031   if (!ok)
1032     error ("Can't attach to process.");
1033
1034   if (from_tty)
1035     {
1036       char *exec_file = (char *) get_exec_file (0);
1037
1038       if (exec_file)
1039         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1040                            target_pid_to_str (pid_to_ptid (pid)));
1041       else
1042         printf_unfiltered ("Attaching to %s\n",
1043                            target_pid_to_str (pid_to_ptid (pid)));
1044
1045       gdb_flush (gdb_stdout);
1046     }
1047
1048   do_initial_child_stuff (pid);
1049   target_terminal_ours ();
1050 }
1051
1052 static void
1053 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
1054 {
1055   if (from_tty)
1056     {
1057       char *exec_file = get_exec_file (0);
1058       if (exec_file == 0)
1059         exec_file = "";
1060       printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
1061                          target_pid_to_str (inferior_ptid));
1062       gdb_flush (gdb_stdout);
1063     }
1064   inferior_ptid = null_ptid;
1065   unpush_target (&child_ops);
1066 }
1067
1068 /* Print status information about what we're accessing.  */
1069
1070 static void
1071 child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
1072 {
1073   printf_unfiltered ("\tUsing the running image of %s %s.\n",
1074       attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
1075 }
1076
1077 /* ARGSUSED */
1078 static void
1079 child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
1080 {
1081   error ("Use the \"run\" command to start a Unix child process.");
1082 }
1083
1084 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1085    EXEC_FILE is the file to run.
1086    ALLARGS is a string containing the arguments to the program.
1087    ENV is the environment vector to pass.  Errors reported with error().  */
1088
1089 static void
1090 child_create_inferior (char *exec_file, char *allargs, char **env)
1091 {
1092   char real_path[MAXPATHLEN];
1093   char *winenv;
1094   char *temp;
1095   int envlen;
1096   int i;
1097   STARTUPINFO si;
1098   PROCESS_INFORMATION pi;
1099   BOOL ret;
1100   DWORD flags;
1101   char *args;
1102
1103   if (!exec_file)
1104     error ("No executable specified, use `target exec'.\n");
1105
1106   memset (&si, 0, sizeof (si));
1107   si.cb = sizeof (si);
1108
1109   cygwin_conv_to_win32_path (exec_file, real_path);
1110
1111   flags = DEBUG_ONLY_THIS_PROCESS;
1112
1113   if (new_group)
1114     flags |= CREATE_NEW_PROCESS_GROUP;
1115
1116   if (new_console)
1117     flags |= CREATE_NEW_CONSOLE;
1118
1119   args = alloca (strlen (real_path) + strlen (allargs) + 2);
1120
1121   strcpy (args, real_path);
1122
1123   strcat (args, " ");
1124   strcat (args, allargs);
1125
1126   /* Prepare the environment vars for CreateProcess.  */
1127   {
1128     /* This code use to assume all env vars were file names and would
1129        translate them all to win32 style.  That obviously doesn't work in the
1130        general case.  The current rule is that we only translate PATH.
1131        We need to handle PATH because we're about to call CreateProcess and
1132        it uses PATH to find DLL's.  Fortunately PATH has a well-defined value
1133        in both posix and win32 environments.  cygwin.dll will change it back
1134        to posix style if necessary.  */
1135
1136     static const char *conv_path_names[] =
1137     {
1138       "PATH=",
1139       0
1140     };
1141
1142     /* CreateProcess takes the environment list as a null terminated set of
1143        strings (i.e. two nulls terminate the list).  */
1144
1145     /* Get total size for env strings.  */
1146     for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1147       {
1148         int j, len;
1149
1150         for (j = 0; conv_path_names[j]; j++)
1151           {
1152             len = strlen (conv_path_names[j]);
1153             if (strncmp (conv_path_names[j], env[i], len) == 0)
1154               {
1155                 if (cygwin_posix_path_list_p (env[i] + len))
1156                   envlen += len
1157                     + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1158                 else
1159                   envlen += strlen (env[i]) + 1;
1160                 break;
1161               }
1162           }
1163         if (conv_path_names[j] == NULL)
1164           envlen += strlen (env[i]) + 1;
1165       }
1166
1167     winenv = alloca (envlen + 1);
1168
1169     /* Copy env strings into new buffer.  */
1170     for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1171       {
1172         int j, len;
1173
1174         for (j = 0; conv_path_names[j]; j++)
1175           {
1176             len = strlen (conv_path_names[j]);
1177             if (strncmp (conv_path_names[j], env[i], len) == 0)
1178               {
1179                 if (cygwin_posix_path_list_p (env[i] + len))
1180                   {
1181                     memcpy (temp, env[i], len);
1182                     cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1183                   }
1184                 else
1185                   strcpy (temp, env[i]);
1186                 break;
1187               }
1188           }
1189         if (conv_path_names[j] == NULL)
1190           strcpy (temp, env[i]);
1191
1192         temp += strlen (temp) + 1;
1193       }
1194
1195     /* Final nil string to terminate new env.  */
1196     *temp = 0;
1197   }
1198
1199   ret = CreateProcess (0,
1200                        args,    /* command line */
1201                        NULL,    /* Security */
1202                        NULL,    /* thread */
1203                        TRUE,    /* inherit handles */
1204                        flags,   /* start flags */
1205                        winenv,
1206                        NULL,    /* current directory */
1207                        &si,
1208                        &pi);
1209   if (!ret)
1210     error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1211
1212   CloseHandle (pi.hThread);
1213   CloseHandle (pi.hProcess);
1214   do_initial_child_stuff (pi.dwProcessId);
1215
1216   /* child_continue (DBG_CONTINUE, -1); */
1217   proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1218 }
1219
1220 static void
1221 child_mourn_inferior (void)
1222 {
1223   (void) child_continue (DBG_CONTINUE, -1);
1224   unpush_target (&child_ops);
1225   generic_mourn_inferior ();
1226 }
1227
1228 /* Send a SIGINT to the process group.  This acts just like the user typed a
1229    ^C on the controlling terminal. */
1230
1231 static void
1232 child_stop (void)
1233 {
1234   DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1235   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1236   registers_changed ();         /* refresh register state */
1237 }
1238
1239 int
1240 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1241                    int write, struct mem_attrib *mem ATTRIBUTE_UNUSED,
1242                    struct target_ops *target ATTRIBUTE_UNUSED)
1243 {
1244   DWORD done;
1245   if (write)
1246     {
1247       DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1248                   len, (DWORD) memaddr));
1249       WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1250                           len, &done);
1251       FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1252     }
1253   else
1254     {
1255       DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1256                   len, (DWORD) memaddr));
1257       ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1258                          &done);
1259     }
1260   return done;
1261 }
1262
1263 void
1264 child_kill_inferior (void)
1265 {
1266   CHECK (TerminateProcess (current_process_handle, 0));
1267
1268   for (;;)
1269     {
1270       if (!child_continue (DBG_CONTINUE, -1))
1271         break;
1272       if (!WaitForDebugEvent (&current_event, INFINITE))
1273         break;
1274       if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1275         break;
1276     }
1277
1278   CHECK (CloseHandle (current_process_handle));
1279
1280   /* this may fail in an attached process so don't check. */
1281   (void) CloseHandle (current_thread->h);
1282   target_mourn_inferior ();     /* or just child_mourn_inferior? */
1283 }
1284
1285 void
1286 child_resume (ptid_t ptid, int step, enum target_signal sig)
1287 {
1288   thread_info *th;
1289   DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1290   DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1291   int pid = PIDGET (ptid);
1292
1293   last_sig = 0;
1294
1295   DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1296                pid, step, sig));
1297
1298   /* Get context for currently selected thread */
1299   th = thread_rec (current_event.dwThreadId, FALSE);
1300   if (th)
1301     {
1302       if (step)
1303         {
1304           /* Single step by setting t bit */
1305           child_fetch_inferior_registers (PS_REGNUM);
1306           th->context.EFlags |= FLAG_TRACE_BIT;
1307         }
1308
1309       if (th->context.ContextFlags)
1310         {
1311           CHECK (SetThreadContext (th->h, &th->context));
1312           th->context.ContextFlags = 0;
1313         }
1314     }
1315
1316   /* Allow continuing with the same signal that interrupted us.
1317      Otherwise complain. */
1318
1319   child_continue (continue_status, pid);
1320 }
1321
1322 static void
1323 child_prepare_to_store (void)
1324 {
1325   /* Do nothing, since we can store individual regs */
1326 }
1327
1328 static int
1329 child_can_run (void)
1330 {
1331   return 1;
1332 }
1333
1334 static void
1335 child_close (int x ATTRIBUTE_UNUSED)
1336 {
1337   DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1338                 PIDGET (inferior_ptid)));
1339 }
1340
1341 struct target_ops child_ops;
1342
1343 static void
1344 init_child_ops (void)
1345 {
1346   child_ops.to_shortname = "child";
1347   child_ops.to_longname = "Win32 child process";
1348   child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1349   child_ops.to_open = child_open;
1350   child_ops.to_close = child_close;
1351   child_ops.to_attach = child_attach;
1352   child_ops.to_detach = child_detach;
1353   child_ops.to_resume = child_resume;
1354   child_ops.to_wait = child_wait;
1355   child_ops.to_fetch_registers = child_fetch_inferior_registers;
1356   child_ops.to_store_registers = child_store_inferior_registers;
1357   child_ops.to_prepare_to_store = child_prepare_to_store;
1358   child_ops.to_xfer_memory = child_xfer_memory;
1359   child_ops.to_files_info = child_files_info;
1360   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1361   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1362   child_ops.to_terminal_init = terminal_init_inferior;
1363   child_ops.to_terminal_inferior = terminal_inferior;
1364   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1365   child_ops.to_terminal_ours = terminal_ours;
1366   child_ops.to_terminal_info = child_terminal_info;
1367   child_ops.to_kill = child_kill_inferior;
1368   child_ops.to_load = 0;
1369   child_ops.to_lookup_symbol = 0;
1370   child_ops.to_create_inferior = child_create_inferior;
1371   child_ops.to_mourn_inferior = child_mourn_inferior;
1372   child_ops.to_can_run = child_can_run;
1373   child_ops.to_notice_signals = 0;
1374   child_ops.to_thread_alive = win32_child_thread_alive;
1375   child_ops.to_pid_to_str = cygwin_pid_to_str;
1376   child_ops.to_stop = child_stop;
1377   child_ops.to_stratum = process_stratum;
1378   child_ops.DONT_USE = 0;
1379   child_ops.to_has_all_memory = 1;
1380   child_ops.to_has_memory = 1;
1381   child_ops.to_has_stack = 1;
1382   child_ops.to_has_registers = 1;
1383   child_ops.to_has_execution = 1;
1384   child_ops.to_sections = 0;
1385   child_ops.to_sections_end = 0;
1386   child_ops.to_magic = OPS_MAGIC;
1387 }
1388
1389 void
1390 _initialize_inftarg (void)
1391 {
1392   struct cmd_list_element *c;
1393
1394   init_child_ops ();
1395
1396   c = add_com ("dll-symbols", class_files, dll_symbol_command,
1397                "Load dll library symbols from FILE.");
1398   c->completer = filename_completer;
1399
1400   auto_solib_add = 1;
1401   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1402
1403   add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1404                                   (char *) &new_console,
1405                  "Set creation of new console when creating child process.",
1406                                   &setlist),
1407                      &showlist);
1408
1409   add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1410                                   (char *) &new_group,
1411                    "Set creation of new group when creating child process.",
1412                                   &setlist),
1413                      &showlist);
1414
1415   add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1416                                   (char *) &debug_exec,
1417                        "Set whether to display execution in child process.",
1418                                   &setlist),
1419                      &showlist);
1420
1421   add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1422                                   (char *) &debug_events,
1423                    "Set whether to display kernel events in child process.",
1424                                   &setlist),
1425                      &showlist);
1426
1427   add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1428                                   (char *) &debug_memory,
1429                  "Set whether to display memory accesses in child process.",
1430                                   &setlist),
1431                      &showlist);
1432
1433   add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1434                                   (char *) &debug_exceptions,
1435                "Set whether to display kernel exceptions in child process.",
1436                                   &setlist),
1437                      &showlist);
1438
1439   add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1440   add_info_alias ("sharedlibrary", "dll", 1);
1441
1442   add_target (&child_ops);
1443 }
1444
1445 /* Determine if the thread referenced by "pid" is alive
1446    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
1447    it means that the pid has died.  Otherwise it is assumed to be alive. */
1448 static int
1449 win32_child_thread_alive (ptid_t ptid)
1450 {
1451   int pid = PIDGET (ptid);
1452
1453   return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1454     FALSE : TRUE;
1455 }
1456
1457 /* Convert pid to printable format. */
1458 char *
1459 cygwin_pid_to_str (ptid_t ptid)
1460 {
1461   static char buf[80];
1462   int pid = PIDGET (ptid);
1463
1464   if ((DWORD) pid == current_event.dwProcessId)
1465     sprintf (buf, "process %d", pid);
1466   else
1467     sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1468   return buf;
1469 }
1470
1471 static int
1472 core_dll_symbols_add (char *dll_name, DWORD base_addr)
1473 {
1474   struct objfile *objfile;
1475   char *objfile_basename;
1476   const char *dll_basename;
1477
1478   if (!(dll_basename = strrchr (dll_name, '/')))
1479     dll_basename = dll_name;
1480   else
1481     dll_basename++;
1482
1483   ALL_OBJFILES (objfile)
1484   {
1485     objfile_basename = strrchr (objfile->name, '/');
1486
1487     if (objfile_basename &&
1488         strcmp (dll_basename, objfile_basename + 1) == 0)
1489       {
1490         printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1491                            base_addr, dll_name);
1492         goto out;
1493       }
1494   }
1495
1496   register_loaded_dll (dll_name, base_addr + 0x1000);
1497   solib_symbols_add (dll_name, (CORE_ADDR) base_addr + 0x1000);
1498
1499 out:
1500   return 1;
1501 }
1502
1503 typedef struct
1504 {
1505   struct target_ops *target;
1506   bfd_vma addr;
1507 }
1508 map_code_section_args;
1509
1510 static void
1511 map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
1512 {
1513   int old;
1514   int update_coreops;
1515   struct section_table *new_target_sect_ptr;
1516
1517   map_code_section_args *args = (map_code_section_args *) obj;
1518   struct target_ops *target = args->target;
1519   if (sect->flags & SEC_CODE)
1520     {
1521       update_coreops = core_ops.to_sections == target->to_sections;
1522
1523       if (target->to_sections)
1524         {
1525           old = target->to_sections_end - target->to_sections;
1526           target->to_sections = (struct section_table *)
1527             xrealloc ((char *) target->to_sections,
1528                       (sizeof (struct section_table)) * (1 + old));
1529         }
1530       else
1531         {
1532           old = 0;
1533           target->to_sections = (struct section_table *)
1534             xmalloc ((sizeof (struct section_table)));
1535         }
1536       target->to_sections_end = target->to_sections + (1 + old);
1537
1538       /* Update the to_sections field in the core_ops structure
1539          if needed.  */
1540       if (update_coreops)
1541         {
1542           core_ops.to_sections = target->to_sections;
1543           core_ops.to_sections_end = target->to_sections_end;
1544         }
1545       new_target_sect_ptr = target->to_sections + old;
1546       new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1547       new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1548         bfd_section_size (abfd, sect);;
1549       new_target_sect_ptr->the_bfd_section = sect;
1550       new_target_sect_ptr->bfd = abfd;
1551     }
1552 }
1553
1554 static int
1555 dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1556 {
1557   bfd *dll_bfd;
1558   map_code_section_args map_args;
1559   asection *lowest_sect;
1560   char *name;
1561   if (dll_name == NULL || target == NULL)
1562     return 0;
1563   name = xstrdup (dll_name);
1564   dll_bfd = bfd_openr (name, "pei-i386");
1565   if (dll_bfd == NULL)
1566     return 0;
1567
1568   if (bfd_check_format (dll_bfd, bfd_object))
1569     {
1570       lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1571       if (lowest_sect == NULL)
1572         return 0;
1573       map_args.target = target;
1574       map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1575
1576       bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
1577     }
1578
1579   return 1;
1580 }
1581
1582 static void
1583 core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
1584 {
1585   struct target_ops *target = (struct target_ops *) obj;
1586
1587   DWORD base_addr;
1588
1589   int dll_name_size;
1590   char *dll_name = NULL;
1591   char *buf = NULL;
1592   struct win32_pstatus *pstatus;
1593   char *p;
1594
1595   if (strncmp (sect->name, ".module", 7))
1596     return;
1597
1598   buf = (char *) xmalloc (sect->_raw_size + 1);
1599   if (!buf)
1600     {
1601       printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1602       goto out;
1603     }
1604   if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1605     goto out;
1606
1607   pstatus = (struct win32_pstatus *) buf;
1608
1609   memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1610   dll_name_size = pstatus->data.module_info.module_name_size;
1611   if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1612       goto out;
1613
1614   dll_name = (char *) xmalloc (dll_name_size + 1);
1615   if (!dll_name)
1616     {
1617       printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1618       goto out;
1619     }
1620   strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1621
1622   while ((p = strchr (dll_name, '\\')))
1623     *p = '/';
1624
1625   if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1626     printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1627
1628   if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1629     printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1630
1631 out:
1632   if (buf)
1633     xfree (buf);
1634   if (dll_name)
1635     xfree (dll_name);
1636   return;
1637 }
1638
1639 void
1640 child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED, struct target_ops *target)
1641 {
1642   if (core_bfd)
1643     {
1644       child_clear_solibs ();
1645       bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1646     }
1647   else
1648     {
1649       if (solib_end && solib_end->name)
1650         solib_symbols_add (solib_end->name, solib_end->load_addr);
1651     }
1652 }
1653
1654 static void
1655 fetch_elf_core_registers (char *core_reg_sect,
1656                           unsigned core_reg_size,
1657                           int which,
1658                           CORE_ADDR reg_addr)
1659 {
1660   int r;
1661   if (core_reg_size < sizeof (CONTEXT))
1662     {
1663       error ("Core file register section too small (%u bytes).", core_reg_size);
1664       return;
1665     }
1666   for (r = 0; r < NUM_REGS; r++)
1667     supply_register (r, core_reg_sect + mappings[r]);
1668 }
1669
1670 static struct core_fns win32_elf_core_fns =
1671 {
1672   bfd_target_elf_flavour,
1673   default_check_format,
1674   default_core_sniffer,
1675   fetch_elf_core_registers,
1676   NULL
1677 };
1678
1679 void
1680 _initialize_core_win32 (void)
1681 {
1682   add_core_fns (&win32_elf_core_fns);
1683 }