* win32-nat.c (safe_symbol_file_add_stub): Properly initialize linked list
[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 /* Maintain a linked list of "so" information. */
439 struct so_stuff
440 {
441   struct so_stuff *next, **last;
442   DWORD load_addr;
443   char name[0];
444 }
445 solib_start, *solib_end;
446
447 /* Call symbol_file_add with stderr redirected.  We don't care if there
448    are errors. */
449 static int
450 safe_symbol_file_add_stub (void *argv)
451 {
452 #define p ((struct safe_symbol_file_add_args *)argv)
453   struct so_stuff *so = &solib_start;
454
455   while ((so = so->next))
456     if (strcasecmp (so->name, p->name) == 0)
457       return 0;
458   p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
459   return !!p->ret;
460 #undef p
461 }
462
463 /* Restore gdb's stderr after calling symbol_file_add */
464 static void
465 safe_symbol_file_add_cleanup (void *p)
466 {
467 #define sp ((struct safe_symbol_file_add_args *)p)
468   gdb_flush (gdb_stderr);
469   gdb_flush (gdb_stdout);
470   /* ui_file_delete (gdb_stderr); */
471   ui_file_delete (gdb_stdout);
472   /* gdb_stderr = sp->err; */
473   gdb_stdout = sp->out;
474 #undef sp
475 }
476
477 /* symbol_file_add wrapper that prevents errors from being displayed. */
478 static struct objfile *
479 safe_symbol_file_add (char *name, int from_tty,
480                       struct section_addr_info *addrs,
481                       int mainline, int flags)
482 {
483   struct safe_symbol_file_add_args p;
484   struct cleanup *cleanup;
485
486   cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
487
488   p.err = gdb_stderr;
489   p.out = gdb_stdout;
490   gdb_flush (gdb_stderr);
491   gdb_flush (gdb_stdout);
492   /* gdb_stderr = ui_file_new (); */
493   gdb_stdout = ui_file_new ();
494   p.name = name;
495   p.from_tty = from_tty;
496   p.addrs = addrs;
497   p.mainline = mainline;
498   p.flags = flags;
499   catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
500
501   do_cleanups (cleanup);
502   return p.ret;
503 }
504
505 /* Remember the maximum DLL length for printing in info dll command. */
506 int max_dll_name_len;
507
508 static void
509 register_loaded_dll (const char *name, DWORD load_addr)
510 {
511   struct so_stuff *so;
512   so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (name) + 8 + 2);
513   so->load_addr = load_addr;
514   strcpy (so->name, name);
515
516   solib_end->next = so;
517   solib_end = so;
518   so->next = NULL;
519 }
520
521 /* Wait for child to do something.  Return pid of child, or -1 in case
522    of error; store status through argument pointer OURSTATUS.  */
523 static int
524 handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
525 {
526   LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
527   DWORD dll_name_ptr;
528   DWORD done;
529   char dll_buf[MAX_PATH + 1];
530   char *dll_name = NULL;
531   int len;
532   char *p;
533
534   dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
535
536   if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
537     dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
538
539   dll_name = dll_buf;
540
541   /* Attempt to read the name of the dll that was detected.
542      This is documented to work only when actively debugging
543      a program.  It will not work for attached processes. */
544   if (dll_name == NULL || *dll_name == '\0')
545     {
546       DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
547       int len = 0;
548       char b[2];
549
550       ReadProcessMemory (current_process_handle,
551                          (LPCVOID) event->lpImageName,
552                          (char *) &dll_name_ptr,
553                          sizeof (dll_name_ptr), &done);
554
555       /* See if we could read the address of a string, and that the
556          address isn't null. */
557
558       if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
559         return 1;
560
561       do
562         {
563           ReadProcessMemory (current_process_handle,
564                              (LPCVOID) (dll_name_ptr + len * size),
565                              &b,
566                              size,
567                              &done);
568           len++;
569         }
570       while ((b[0] != 0 || b[size - 1] != 0) && done == size);
571
572       dll_name = alloca (len);
573
574       if (event->fUnicode)
575         {
576           WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
577           ReadProcessMemory (current_process_handle,
578                              (LPCVOID) dll_name_ptr,
579                              unicode_dll_name,
580                              len * sizeof (WCHAR),
581                              &done);
582
583           WideCharToMultiByte (CP_ACP, 0,
584                                unicode_dll_name, len,
585                                dll_name, len, 0, 0);
586         }
587       else
588         {
589           ReadProcessMemory (current_process_handle,
590                              (LPCVOID) dll_name_ptr,
591                              dll_name,
592                              len,
593                              &done);
594         }
595     }
596
597   if (!dll_name)
598     return 1;
599
600   (void) strlwr (dll_name);
601
602   while ((p = strchr (dll_name, '\\')))
603     *p = '/';
604
605   register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
606   len = strlen (dll_name);
607   if (len > max_dll_name_len)
608     max_dll_name_len = len;
609
610   return 1;
611 }
612
613 /* Return name of last loaded DLL. */
614 char *
615 child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED)
616 {
617   return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
618 }
619
620 /* Clear list of loaded DLLs. */
621 void
622 child_clear_solibs (void)
623 {
624   struct so_stuff *so, *so1 = solib_start.next;
625
626   while ((so = so1) != NULL)
627     {
628       so1 = so->next;
629       xfree (so);
630     }
631
632   solib_start.next = NULL;
633   solib_end = &solib_start;
634   max_dll_name_len = sizeof ("DLL Name") - 1;
635 }
636
637 /* Add DLL symbol information. */
638 static void
639 solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
640 {
641   struct section_addr_info section_addrs;
642
643   /* The symbols in a dll are offset by 0x1000, which is the
644      the offset from 0 of the first byte in an image - because
645      of the file header and the section alignment. */
646
647   if (!name || !name[0])
648     return;
649
650   memset (&section_addrs, 0, sizeof (section_addrs));
651   section_addrs.other[0].name = ".text";
652   section_addrs.other[0].addr = load_addr;
653   safe_symbol_file_add (name, from_tty, 0, 0, OBJF_SHARED);
654
655   return;
656 }
657
658 /* Load DLL symbol info. */
659 void
660 dll_symbol_command (char *args, int from_tty ATTRIBUTE_UNUSED)
661 {
662   int n;
663   dont_repeat ();
664
665   if (args == NULL)
666     error ("dll-symbols requires a file name");
667
668   n = strlen (args);
669   if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
670     {
671       char *newargs = (char *) alloca (n + 4 + 1);
672       strcpy (newargs, args);
673       strcat (newargs, ".dll");
674       args = newargs;
675     }
676
677   safe_symbol_file_add (args, 0, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
678 }
679
680 /* List currently loaded DLLs. */
681 void
682 info_dll_command (char *ignore ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
683 {
684   struct so_stuff *so = &solib_start;
685
686   if (!so->next)
687     return;
688
689   printf ("%*s  Load Address\n", -max_dll_name_len, "DLL Name");
690   while ((so = so->next) != NULL)
691     printf_filtered ("%*s  %08lx\n", -max_dll_name_len, so->name, so->load_addr);
692
693   return;
694 }
695
696 /* Handle DEBUG_STRING output from child process.
697    Cygwin prepends its messages with a "cygwin:".  Interpret this as
698    a Cygwin signal.  Otherwise just print the string as a warning. */
699 static int
700 handle_output_debug_string (struct target_waitstatus *ourstatus)
701 {
702   char *s;
703   int gotasig = FALSE;
704
705   if (!target_read_string
706     ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
707       || !s || !*s)
708     return gotasig;
709
710   if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
711     {
712       if (strncmp (s, "cYg", 3) != 0)
713         warning ("%s", s);
714     }
715   else
716     {
717       char *p;
718       int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
719       gotasig = target_signal_from_host (sig);
720       ourstatus->value.sig = gotasig;
721       if (gotasig)
722         ourstatus->kind = TARGET_WAITKIND_STOPPED;
723     }
724
725   xfree (s);
726   return gotasig;
727 }
728
729 static int
730 handle_exception (struct target_waitstatus *ourstatus)
731 {
732   thread_info *th;
733   DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
734
735   ourstatus->kind = TARGET_WAITKIND_STOPPED;
736
737   /* Record the context of the current thread */
738   th = thread_rec (current_event.dwThreadId, -1);
739
740   switch (code)
741     {
742     case EXCEPTION_ACCESS_VIOLATION:
743       DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
744        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
745       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
746       last_sig = SIGSEGV;
747       break;
748     case STATUS_FLOAT_UNDERFLOW:
749     case STATUS_FLOAT_DIVIDE_BY_ZERO:
750     case STATUS_FLOAT_OVERFLOW:
751     case STATUS_INTEGER_DIVIDE_BY_ZERO:
752       DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
753        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
754       ourstatus->value.sig = TARGET_SIGNAL_FPE;
755       last_sig = SIGFPE;
756       break;
757     case STATUS_STACK_OVERFLOW:
758       DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
759        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
760       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
761       break;
762     case EXCEPTION_BREAKPOINT:
763       DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
764        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
765       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
766       break;
767     case DBG_CONTROL_C:
768       DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
769        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
770       ourstatus->value.sig = TARGET_SIGNAL_INT;
771       last_sig = SIGINT;        /* FIXME - should check pass state */
772       break;
773     case EXCEPTION_SINGLE_STEP:
774       DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
775        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
776       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
777       break;
778     case EXCEPTION_ILLEGAL_INSTRUCTION:
779       DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
780        (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
781       ourstatus->value.sig = TARGET_SIGNAL_ILL;
782       last_sig = SIGILL;
783       break;
784     default:
785       if (current_event.u.Exception.dwFirstChance)
786         return 0;
787       printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
788                     current_event.u.Exception.ExceptionRecord.ExceptionCode,
789         (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
790       ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
791       break;
792     }
793   exception_count++;
794   return 1;
795 }
796
797 /* Resume all artificially suspended threads if we are continuing
798    execution */
799 static BOOL
800 child_continue (DWORD continue_status, int id)
801 {
802   int i;
803   thread_info *th;
804   BOOL res;
805
806   DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
807                  current_event.dwProcessId, current_event.dwThreadId));
808   res = ContinueDebugEvent (current_event.dwProcessId,
809                             current_event.dwThreadId,
810                             continue_status);
811   continue_status = 0;
812   if (res)
813     for (th = &thread_head; (th = th->next) != NULL;)
814       if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
815         {
816           for (i = 0; i < th->suspend_count; i++)
817             (void) ResumeThread (th->h);
818           th->suspend_count = 0;
819         }
820
821   return res;
822 }
823
824 /* Get the next event from the child.  Return 1 if the event requires
825    handling by WFI (or whatever).
826  */
827 static int
828 get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
829 {
830   BOOL debug_event;
831   DWORD continue_status, event_code;
832   thread_info *th = NULL;
833   static thread_info dummy_thread_info;
834   int retval = 0;
835
836   last_sig = 0;
837
838   if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
839     goto out;
840
841   event_count++;
842   continue_status = DBG_CONTINUE;
843
844   event_code = current_event.dwDebugEventCode;
845   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
846
847   switch (event_code)
848     {
849     case CREATE_THREAD_DEBUG_EVENT:
850       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
851                      (unsigned) current_event.dwProcessId,
852                      (unsigned) current_event.dwThreadId,
853                      "CREATE_THREAD_DEBUG_EVENT"));
854       /* Record the existence of this thread */
855       th = child_add_thread (current_event.dwThreadId,
856                              current_event.u.CreateThread.hThread);
857       if (info_verbose)
858         printf_unfiltered ("[New %s]\n",
859                            target_pid_to_str (
860                              pid_to_ptid (current_event.dwThreadId)));
861       retval = current_event.dwThreadId;
862       break;
863
864     case EXIT_THREAD_DEBUG_EVENT:
865       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
866                      (unsigned) current_event.dwProcessId,
867                      (unsigned) current_event.dwThreadId,
868                      "EXIT_THREAD_DEBUG_EVENT"));
869       child_delete_thread (current_event.dwThreadId);
870       th = &dummy_thread_info;
871       break;
872
873     case CREATE_PROCESS_DEBUG_EVENT:
874       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
875                      (unsigned) current_event.dwProcessId,
876                      (unsigned) current_event.dwThreadId,
877                      "CREATE_PROCESS_DEBUG_EVENT"));
878       CloseHandle (current_event.u.CreateProcessInfo.hFile);
879       current_process_handle = current_event.u.CreateProcessInfo.hProcess;
880
881       main_thread_id = current_event.dwThreadId;
882       /* Add the main thread */
883 #if 0
884       th = child_add_thread (current_event.dwProcessId,
885                              current_event.u.CreateProcessInfo.hProcess);
886 #endif
887       th = child_add_thread (main_thread_id,
888                              current_event.u.CreateProcessInfo.hThread);
889       retval = ourstatus->value.related_pid = current_event.dwThreadId;
890       break;
891
892     case EXIT_PROCESS_DEBUG_EVENT:
893       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
894                      (unsigned) current_event.dwProcessId,
895                      (unsigned) current_event.dwThreadId,
896                      "EXIT_PROCESS_DEBUG_EVENT"));
897       ourstatus->kind = TARGET_WAITKIND_EXITED;
898       ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
899       CloseHandle (current_process_handle);
900       retval = main_thread_id;
901       break;
902
903     case LOAD_DLL_DEBUG_EVENT:
904       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
905                      (unsigned) current_event.dwProcessId,
906                      (unsigned) current_event.dwThreadId,
907                      "LOAD_DLL_DEBUG_EVENT"));
908       CloseHandle (current_event.u.LoadDll.hFile);
909       catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
910       registers_changed ();     /* mark all regs invalid */
911       ourstatus->kind = TARGET_WAITKIND_LOADED;
912       ourstatus->value.integer = 0;
913       retval = main_thread_id;
914       break;
915
916     case UNLOAD_DLL_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                      "UNLOAD_DLL_DEBUG_EVENT"));
921       break;                    /* FIXME: don't know what to do here */
922
923     case EXCEPTION_DEBUG_EVENT:
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                      "EXCEPTION_DEBUG_EVENT"));
928       if (handle_exception (ourstatus))
929         retval = current_event.dwThreadId;
930       break;
931
932     case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
933       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
934                      (unsigned) current_event.dwProcessId,
935                      (unsigned) current_event.dwThreadId,
936                      "OUTPUT_DEBUG_STRING_EVENT"));
937       if (handle_output_debug_string (ourstatus))
938         retval = main_thread_id;
939       break;
940
941     default:
942       printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
943                          (DWORD) current_event.dwProcessId,
944                          (DWORD) current_event.dwThreadId);
945       printf_unfiltered ("                 unknown event code %ld\n",
946                          current_event.dwDebugEventCode);
947       break;
948     }
949
950   if (!retval)
951     CHECK (child_continue (continue_status, -1));
952   else
953     {
954       current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
955       inferior_ptid = pid_to_ptid (retval);
956     }
957
958 out:
959   return retval;
960 }
961
962 /* Wait for interesting events to occur in the target process. */
963 static ptid_t
964 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
965 {
966   int pid = PIDGET (ptid);
967
968   /* We loop when we get a non-standard exception rather than return
969      with a SPURIOUS because resume can try and step or modify things,
970      which needs a current_thread->h.  But some of these exceptions mark
971      the birth or death of threads, which mean that the current thread
972      isn't necessarily what you think it is. */
973
974   while (1)
975     {
976       int retval = get_child_debug_event (pid, ourstatus);
977       if (retval)
978         return pid_to_ptid (retval);
979       else
980         {
981           int detach = 0;
982
983           if (ui_loop_hook != NULL)
984             detach = ui_loop_hook (0);
985
986           if (detach)
987             child_kill_inferior ();
988         }
989     }
990 }
991
992 static void
993 do_initial_child_stuff (DWORD pid)
994 {
995   extern int stop_after_trap;
996
997   last_sig = 0;
998   event_count = 0;
999   exception_count = 0;
1000   current_event.dwProcessId = pid;
1001   memset (&current_event, 0, sizeof (current_event));
1002   push_target (&child_ops);
1003   child_init_thread_list ();
1004   child_clear_solibs ();
1005   clear_proceed_status ();
1006   init_wait_for_inferior ();
1007
1008   target_terminal_init ();
1009   target_terminal_inferior ();
1010
1011   while (1)
1012     {
1013       stop_after_trap = 1;
1014       wait_for_inferior ();
1015       if (stop_signal != TARGET_SIGNAL_TRAP)
1016         resume (0, stop_signal);
1017       else
1018         break;
1019     }
1020   stop_after_trap = 0;
1021   return;
1022 }
1023
1024 /* Attach to process PID, then initialize for debugging it.  */
1025
1026 static void
1027 child_attach (char *args, int from_tty)
1028 {
1029   BOOL ok;
1030   DWORD pid;
1031
1032   if (!args)
1033     error_no_arg ("process-id to attach");
1034
1035   pid = strtoul (args, 0, 0);
1036   ok = DebugActiveProcess (pid);
1037
1038   if (!ok)
1039     error ("Can't attach to process.");
1040
1041   if (from_tty)
1042     {
1043       char *exec_file = (char *) get_exec_file (0);
1044
1045       if (exec_file)
1046         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1047                            target_pid_to_str (pid_to_ptid (pid)));
1048       else
1049         printf_unfiltered ("Attaching to %s\n",
1050                            target_pid_to_str (pid_to_ptid (pid)));
1051
1052       gdb_flush (gdb_stdout);
1053     }
1054
1055   do_initial_child_stuff (pid);
1056   target_terminal_ours ();
1057 }
1058
1059 static void
1060 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
1061 {
1062   if (from_tty)
1063     {
1064       char *exec_file = get_exec_file (0);
1065       if (exec_file == 0)
1066         exec_file = "";
1067       printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
1068                          target_pid_to_str (inferior_ptid));
1069       gdb_flush (gdb_stdout);
1070     }
1071   inferior_ptid = null_ptid;
1072   unpush_target (&child_ops);
1073 }
1074
1075 /* Print status information about what we're accessing.  */
1076
1077 static void
1078 child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
1079 {
1080   printf_unfiltered ("\tUsing the running image of %s %s.\n",
1081       attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
1082 }
1083
1084 /* ARGSUSED */
1085 static void
1086 child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
1087 {
1088   error ("Use the \"run\" command to start a Unix child process.");
1089 }
1090
1091 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1092    EXEC_FILE is the file to run.
1093    ALLARGS is a string containing the arguments to the program.
1094    ENV is the environment vector to pass.  Errors reported with error().  */
1095
1096 static void
1097 child_create_inferior (char *exec_file, char *allargs, char **env)
1098 {
1099   char real_path[MAXPATHLEN];
1100   char *winenv;
1101   char *temp;
1102   int envlen;
1103   int i;
1104   STARTUPINFO si;
1105   PROCESS_INFORMATION pi;
1106   BOOL ret;
1107   DWORD flags;
1108   char *args;
1109
1110   if (!exec_file)
1111     error ("No executable specified, use `target exec'.\n");
1112
1113   memset (&si, 0, sizeof (si));
1114   si.cb = sizeof (si);
1115
1116   cygwin_conv_to_win32_path (exec_file, real_path);
1117
1118   flags = DEBUG_ONLY_THIS_PROCESS;
1119
1120   if (new_group)
1121     flags |= CREATE_NEW_PROCESS_GROUP;
1122
1123   if (new_console)
1124     flags |= CREATE_NEW_CONSOLE;
1125
1126   args = alloca (strlen (real_path) + strlen (allargs) + 2);
1127
1128   strcpy (args, real_path);
1129
1130   strcat (args, " ");
1131   strcat (args, allargs);
1132
1133   /* Prepare the environment vars for CreateProcess.  */
1134   {
1135     /* This code use to assume all env vars were file names and would
1136        translate them all to win32 style.  That obviously doesn't work in the
1137        general case.  The current rule is that we only translate PATH.
1138        We need to handle PATH because we're about to call CreateProcess and
1139        it uses PATH to find DLL's.  Fortunately PATH has a well-defined value
1140        in both posix and win32 environments.  cygwin.dll will change it back
1141        to posix style if necessary.  */
1142
1143     static const char *conv_path_names[] =
1144     {
1145       "PATH=",
1146       0
1147     };
1148
1149     /* CreateProcess takes the environment list as a null terminated set of
1150        strings (i.e. two nulls terminate the list).  */
1151
1152     /* Get total size for env strings.  */
1153     for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1154       {
1155         int j, len;
1156
1157         for (j = 0; conv_path_names[j]; j++)
1158           {
1159             len = strlen (conv_path_names[j]);
1160             if (strncmp (conv_path_names[j], env[i], len) == 0)
1161               {
1162                 if (cygwin_posix_path_list_p (env[i] + len))
1163                   envlen += len
1164                     + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1165                 else
1166                   envlen += strlen (env[i]) + 1;
1167                 break;
1168               }
1169           }
1170         if (conv_path_names[j] == NULL)
1171           envlen += strlen (env[i]) + 1;
1172       }
1173
1174     winenv = alloca (envlen + 1);
1175
1176     /* Copy env strings into new buffer.  */
1177     for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1178       {
1179         int j, len;
1180
1181         for (j = 0; conv_path_names[j]; j++)
1182           {
1183             len = strlen (conv_path_names[j]);
1184             if (strncmp (conv_path_names[j], env[i], len) == 0)
1185               {
1186                 if (cygwin_posix_path_list_p (env[i] + len))
1187                   {
1188                     memcpy (temp, env[i], len);
1189                     cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1190                   }
1191                 else
1192                   strcpy (temp, env[i]);
1193                 break;
1194               }
1195           }
1196         if (conv_path_names[j] == NULL)
1197           strcpy (temp, env[i]);
1198
1199         temp += strlen (temp) + 1;
1200       }
1201
1202     /* Final nil string to terminate new env.  */
1203     *temp = 0;
1204   }
1205
1206   ret = CreateProcess (0,
1207                        args,    /* command line */
1208                        NULL,    /* Security */
1209                        NULL,    /* thread */
1210                        TRUE,    /* inherit handles */
1211                        flags,   /* start flags */
1212                        winenv,
1213                        NULL,    /* current directory */
1214                        &si,
1215                        &pi);
1216   if (!ret)
1217     error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1218
1219   CloseHandle (pi.hThread);
1220   CloseHandle (pi.hProcess);
1221   do_initial_child_stuff (pi.dwProcessId);
1222
1223   /* child_continue (DBG_CONTINUE, -1); */
1224   proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1225 }
1226
1227 static void
1228 child_mourn_inferior (void)
1229 {
1230   (void) child_continue (DBG_CONTINUE, -1);
1231   unpush_target (&child_ops);
1232   generic_mourn_inferior ();
1233 }
1234
1235 /* Send a SIGINT to the process group.  This acts just like the user typed a
1236    ^C on the controlling terminal. */
1237
1238 static void
1239 child_stop (void)
1240 {
1241   DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1242   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1243   registers_changed ();         /* refresh register state */
1244 }
1245
1246 int
1247 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1248                    int write, struct mem_attrib *mem ATTRIBUTE_UNUSED,
1249                    struct target_ops *target ATTRIBUTE_UNUSED)
1250 {
1251   DWORD done;
1252   if (write)
1253     {
1254       DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1255                   len, (DWORD) memaddr));
1256       WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1257                           len, &done);
1258       FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1259     }
1260   else
1261     {
1262       DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1263                   len, (DWORD) memaddr));
1264       ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1265                          &done);
1266     }
1267   return done;
1268 }
1269
1270 void
1271 child_kill_inferior (void)
1272 {
1273   CHECK (TerminateProcess (current_process_handle, 0));
1274
1275   for (;;)
1276     {
1277       if (!child_continue (DBG_CONTINUE, -1))
1278         break;
1279       if (!WaitForDebugEvent (&current_event, INFINITE))
1280         break;
1281       if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1282         break;
1283     }
1284
1285   CHECK (CloseHandle (current_process_handle));
1286
1287   /* this may fail in an attached process so don't check. */
1288   (void) CloseHandle (current_thread->h);
1289   target_mourn_inferior ();     /* or just child_mourn_inferior? */
1290 }
1291
1292 void
1293 child_resume (ptid_t ptid, int step, enum target_signal sig)
1294 {
1295   thread_info *th;
1296   DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1297   DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1298   int pid = PIDGET (ptid);
1299
1300   last_sig = 0;
1301
1302   DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1303                pid, step, sig));
1304
1305   /* Get context for currently selected thread */
1306   th = thread_rec (current_event.dwThreadId, FALSE);
1307   if (th)
1308     {
1309       if (step)
1310         {
1311           /* Single step by setting t bit */
1312           child_fetch_inferior_registers (PS_REGNUM);
1313           th->context.EFlags |= FLAG_TRACE_BIT;
1314         }
1315
1316       if (th->context.ContextFlags)
1317         {
1318           CHECK (SetThreadContext (th->h, &th->context));
1319           th->context.ContextFlags = 0;
1320         }
1321     }
1322
1323   /* Allow continuing with the same signal that interrupted us.
1324      Otherwise complain. */
1325
1326   child_continue (continue_status, pid);
1327 }
1328
1329 static void
1330 child_prepare_to_store (void)
1331 {
1332   /* Do nothing, since we can store individual regs */
1333 }
1334
1335 static int
1336 child_can_run (void)
1337 {
1338   return 1;
1339 }
1340
1341 static void
1342 child_close (int x ATTRIBUTE_UNUSED)
1343 {
1344   DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1345                 PIDGET (inferior_ptid)));
1346 }
1347
1348 struct target_ops child_ops;
1349
1350 static void
1351 init_child_ops (void)
1352 {
1353   child_ops.to_shortname = "child";
1354   child_ops.to_longname = "Win32 child process";
1355   child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1356   child_ops.to_open = child_open;
1357   child_ops.to_close = child_close;
1358   child_ops.to_attach = child_attach;
1359   child_ops.to_detach = child_detach;
1360   child_ops.to_resume = child_resume;
1361   child_ops.to_wait = child_wait;
1362   child_ops.to_fetch_registers = child_fetch_inferior_registers;
1363   child_ops.to_store_registers = child_store_inferior_registers;
1364   child_ops.to_prepare_to_store = child_prepare_to_store;
1365   child_ops.to_xfer_memory = child_xfer_memory;
1366   child_ops.to_files_info = child_files_info;
1367   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1368   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1369   child_ops.to_terminal_init = terminal_init_inferior;
1370   child_ops.to_terminal_inferior = terminal_inferior;
1371   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1372   child_ops.to_terminal_ours = terminal_ours;
1373   child_ops.to_terminal_info = child_terminal_info;
1374   child_ops.to_kill = child_kill_inferior;
1375   child_ops.to_load = 0;
1376   child_ops.to_lookup_symbol = 0;
1377   child_ops.to_create_inferior = child_create_inferior;
1378   child_ops.to_mourn_inferior = child_mourn_inferior;
1379   child_ops.to_can_run = child_can_run;
1380   child_ops.to_notice_signals = 0;
1381   child_ops.to_thread_alive = win32_child_thread_alive;
1382   child_ops.to_pid_to_str = cygwin_pid_to_str;
1383   child_ops.to_stop = child_stop;
1384   child_ops.to_stratum = process_stratum;
1385   child_ops.DONT_USE = 0;
1386   child_ops.to_has_all_memory = 1;
1387   child_ops.to_has_memory = 1;
1388   child_ops.to_has_stack = 1;
1389   child_ops.to_has_registers = 1;
1390   child_ops.to_has_execution = 1;
1391   child_ops.to_sections = 0;
1392   child_ops.to_sections_end = 0;
1393   child_ops.to_magic = OPS_MAGIC;
1394 }
1395
1396 void
1397 _initialize_inftarg (void)
1398 {
1399   struct cmd_list_element *c;
1400
1401   init_child_ops ();
1402
1403   c = add_com ("dll-symbols", class_files, dll_symbol_command,
1404                "Load dll library symbols from FILE.");
1405   c->completer = filename_completer;
1406
1407   auto_solib_add = 1;
1408   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1409
1410   add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1411                                   (char *) &new_console,
1412                  "Set creation of new console when creating child process.",
1413                                   &setlist),
1414                      &showlist);
1415
1416   add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1417                                   (char *) &new_group,
1418                    "Set creation of new group when creating child process.",
1419                                   &setlist),
1420                      &showlist);
1421
1422   add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1423                                   (char *) &debug_exec,
1424                        "Set whether to display execution in child process.",
1425                                   &setlist),
1426                      &showlist);
1427
1428   add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1429                                   (char *) &debug_events,
1430                    "Set whether to display kernel events in child process.",
1431                                   &setlist),
1432                      &showlist);
1433
1434   add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1435                                   (char *) &debug_memory,
1436                  "Set whether to display memory accesses in child process.",
1437                                   &setlist),
1438                      &showlist);
1439
1440   add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1441                                   (char *) &debug_exceptions,
1442                "Set whether to display kernel exceptions in child process.",
1443                                   &setlist),
1444                      &showlist);
1445
1446   add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1447   add_info_alias ("sharedlibrary", "dll", 1);
1448
1449   add_target (&child_ops);
1450 }
1451
1452 /* Determine if the thread referenced by "pid" is alive
1453    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
1454    it means that the pid has died.  Otherwise it is assumed to be alive. */
1455 static int
1456 win32_child_thread_alive (ptid_t ptid)
1457 {
1458   int pid = PIDGET (ptid);
1459
1460   return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1461     FALSE : TRUE;
1462 }
1463
1464 /* Convert pid to printable format. */
1465 char *
1466 cygwin_pid_to_str (ptid_t ptid)
1467 {
1468   static char buf[80];
1469   int pid = PIDGET (ptid);
1470
1471   if ((DWORD) pid == current_event.dwProcessId)
1472     sprintf (buf, "process %d", pid);
1473   else
1474     sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1475   return buf;
1476 }
1477
1478 static int
1479 core_dll_symbols_add (char *dll_name, DWORD base_addr)
1480 {
1481   struct objfile *objfile;
1482   char *objfile_basename;
1483   const char *dll_basename;
1484
1485   if (!(dll_basename = strrchr (dll_name, '/')))
1486     dll_basename = dll_name;
1487   else
1488     dll_basename++;
1489
1490   ALL_OBJFILES (objfile)
1491   {
1492     objfile_basename = strrchr (objfile->name, '/');
1493
1494     if (objfile_basename &&
1495         strcmp (dll_basename, objfile_basename + 1) == 0)
1496       {
1497         printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1498                            base_addr, dll_name);
1499         goto out;
1500       }
1501   }
1502
1503   register_loaded_dll (dll_name, base_addr + 0x1000);
1504   solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
1505
1506 out:
1507   return 1;
1508 }
1509
1510 typedef struct
1511 {
1512   struct target_ops *target;
1513   bfd_vma addr;
1514 }
1515 map_code_section_args;
1516
1517 static void
1518 map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
1519 {
1520   int old;
1521   int update_coreops;
1522   struct section_table *new_target_sect_ptr;
1523
1524   map_code_section_args *args = (map_code_section_args *) obj;
1525   struct target_ops *target = args->target;
1526   if (sect->flags & SEC_CODE)
1527     {
1528       update_coreops = core_ops.to_sections == target->to_sections;
1529
1530       if (target->to_sections)
1531         {
1532           old = target->to_sections_end - target->to_sections;
1533           target->to_sections = (struct section_table *)
1534             xrealloc ((char *) target->to_sections,
1535                       (sizeof (struct section_table)) * (1 + old));
1536         }
1537       else
1538         {
1539           old = 0;
1540           target->to_sections = (struct section_table *)
1541             xmalloc ((sizeof (struct section_table)));
1542         }
1543       target->to_sections_end = target->to_sections + (1 + old);
1544
1545       /* Update the to_sections field in the core_ops structure
1546          if needed.  */
1547       if (update_coreops)
1548         {
1549           core_ops.to_sections = target->to_sections;
1550           core_ops.to_sections_end = target->to_sections_end;
1551         }
1552       new_target_sect_ptr = target->to_sections + old;
1553       new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1554       new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1555         bfd_section_size (abfd, sect);;
1556       new_target_sect_ptr->the_bfd_section = sect;
1557       new_target_sect_ptr->bfd = abfd;
1558     }
1559 }
1560
1561 static int
1562 dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1563 {
1564   bfd *dll_bfd;
1565   map_code_section_args map_args;
1566   asection *lowest_sect;
1567   char *name;
1568   if (dll_name == NULL || target == NULL)
1569     return 0;
1570   name = xstrdup (dll_name);
1571   dll_bfd = bfd_openr (name, "pei-i386");
1572   if (dll_bfd == NULL)
1573     return 0;
1574
1575   if (bfd_check_format (dll_bfd, bfd_object))
1576     {
1577       lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1578       if (lowest_sect == NULL)
1579         return 0;
1580       map_args.target = target;
1581       map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1582
1583       bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
1584     }
1585
1586   return 1;
1587 }
1588
1589 static void
1590 core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
1591 {
1592   struct target_ops *target = (struct target_ops *) obj;
1593
1594   DWORD base_addr;
1595
1596   int dll_name_size;
1597   char *dll_name = NULL;
1598   char *buf = NULL;
1599   struct win32_pstatus *pstatus;
1600   char *p;
1601
1602   if (strncmp (sect->name, ".module", 7))
1603     return;
1604
1605   buf = (char *) xmalloc (sect->_raw_size + 1);
1606   if (!buf)
1607     {
1608       printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1609       goto out;
1610     }
1611   if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1612     goto out;
1613
1614   pstatus = (struct win32_pstatus *) buf;
1615
1616   memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1617   dll_name_size = pstatus->data.module_info.module_name_size;
1618   if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1619       goto out;
1620
1621   dll_name = (char *) xmalloc (dll_name_size + 1);
1622   if (!dll_name)
1623     {
1624       printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1625       goto out;
1626     }
1627   strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1628
1629   while ((p = strchr (dll_name, '\\')))
1630     *p = '/';
1631
1632   if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1633     printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1634
1635   if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1636     printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1637
1638 out:
1639   if (buf)
1640     xfree (buf);
1641   if (dll_name)
1642     xfree (dll_name);
1643   return;
1644 }
1645
1646 void
1647 child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty, struct target_ops *target)
1648 {
1649   if (core_bfd)
1650     {
1651       child_clear_solibs ();
1652       bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1653     }
1654   else
1655     {
1656       if (solib_end && solib_end->name)
1657         solib_symbols_add (solib_end->name, from_tty, solib_end->load_addr);
1658     }
1659 }
1660
1661 static void
1662 fetch_elf_core_registers (char *core_reg_sect,
1663                           unsigned core_reg_size,
1664                           int which,
1665                           CORE_ADDR reg_addr)
1666 {
1667   int r;
1668   if (core_reg_size < sizeof (CONTEXT))
1669     {
1670       error ("Core file register section too small (%u bytes).", core_reg_size);
1671       return;
1672     }
1673   for (r = 0; r < NUM_REGS; r++)
1674     supply_register (r, core_reg_sect + mappings[r]);
1675 }
1676
1677 static struct core_fns win32_elf_core_fns =
1678 {
1679   bfd_target_elf_flavour,
1680   default_check_format,
1681   default_core_sniffer,
1682   fetch_elf_core_registers,
1683   NULL
1684 };
1685
1686 void
1687 _initialize_core_win32 (void)
1688 {
1689   add_core_fns (&win32_elf_core_fns);
1690 }