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