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