1/* Target-vector operations for controlling windows child processes, for GDB.
2
3   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4   2005, 2006, 2007, 2008, 2009, 2010, 2011 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 3 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 even the 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, see <http://www.gnu.org/licenses/>.  */
22
23/* Originally by Steve Chamberlain, sac@cygnus.com */
24
25#include "defs.h"
26#include "frame.h"		/* required by inferior.h */
27#include "inferior.h"
28#include "target.h"
29#include "exceptions.h"
30#include "gdbcore.h"
31#include "command.h"
32#include "completer.h"
33#include "regcache.h"
34#include "top.h"
35#include <signal.h>
36#include <sys/types.h>
37#include <fcntl.h>
38#include <stdlib.h>
39#include <windows.h>
40#include <imagehlp.h>
41#include <psapi.h>
42#ifdef __CYGWIN__
43#include <sys/cygwin.h>
44#include <cygwin/version.h>
45#endif
46#include <signal.h>
47
48#include "buildsym.h"
49#include "filenames.h"
50#include "symfile.h"
51#include "objfiles.h"
52#include "gdb_obstack.h"
53#include "gdb_string.h"
54#include "gdbthread.h"
55#include "gdbcmd.h"
56#include <sys/param.h>
57#include <unistd.h>
58#include "exec.h"
59#include "solist.h"
60#include "solib.h"
61#include "xml-support.h"
62
63#include "i386-tdep.h"
64#include "i387-tdep.h"
65
66#include "windows-tdep.h"
67#include "windows-nat.h"
68#include "i386-nat.h"
69#include "complaints.h"
70
71#define AdjustTokenPrivileges		dyn_AdjustTokenPrivileges
72#define DebugActiveProcessStop		dyn_DebugActiveProcessStop
73#define DebugBreakProcess		dyn_DebugBreakProcess
74#define DebugSetProcessKillOnExit	dyn_DebugSetProcessKillOnExit
75#define EnumProcessModules		dyn_EnumProcessModules
76#define GetModuleInformation		dyn_GetModuleInformation
77#define LookupPrivilegeValueA		dyn_LookupPrivilegeValueA
78#define OpenProcessToken		dyn_OpenProcessToken
79#define GetConsoleFontSize		dyn_GetConsoleFontSize
80#define GetCurrentConsoleFont		dyn_GetCurrentConsoleFont
81
82static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
83					    DWORD, PTOKEN_PRIVILEGES, PDWORD);
84static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
85static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
86static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
87static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
88					  LPDWORD);
89static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
90					    DWORD);
91static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
92static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
93static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL,
94					     CONSOLE_FONT_INFO *);
95static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
96
97static struct target_ops windows_ops;
98
99#undef STARTUPINFO
100#undef CreateProcess
101#undef GetModuleFileNameEx
102
103#ifndef __CYGWIN__
104# define __PMAX	(MAX_PATH + 1)
105  static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD);
106# define STARTUPINFO STARTUPINFOA
107# define CreateProcess CreateProcessA
108# define GetModuleFileNameEx_name "GetModuleFileNameExA"
109# define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
110#else
111# define __PMAX	PATH_MAX
112/* The starting and ending address of the cygwin1.dll text segment.  */
113  static CORE_ADDR cygwin_load_start;
114  static CORE_ADDR cygwin_load_end;
115# if CYGWIN_VERSION_DLL_MAKE_COMBINED(CYGWIN_VERSION_API_MAJOR,CYGWIN_VERSION_API_MINOR) >= 181
116#   define __USEWIDE
117    typedef wchar_t cygwin_buf_t;
118    static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE,
119						LPWSTR, DWORD);
120#   define STARTUPINFO STARTUPINFOW
121#   define CreateProcess CreateProcessW
122#   define GetModuleFileNameEx_name "GetModuleFileNameExW"
123#   define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
124# else
125#   define CCP_POSIX_TO_WIN_W 1
126#   define CCP_WIN_W_TO_POSIX 3
127#   define cygwin_conv_path(op, from, to, size)  \
128         (op == CCP_WIN_W_TO_POSIX) ? \
129         cygwin_conv_to_full_posix_path (from, to) : \
130         cygwin_conv_to_win32_path (from, to)
131    typedef char cygwin_buf_t;
132    static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD);
133#   define STARTUPINFO STARTUPINFOA
134#   define CreateProcess CreateProcessA
135#   define GetModuleFileNameEx_name "GetModuleFileNameExA"
136#   define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
137#   define CW_SET_DOS_FILE_WARNING -1	/* no-op this for older Cygwin */
138# endif
139#endif
140
141static int have_saved_context;	/* True if we've saved context from a
142				   cygwin signal.  */
143static CONTEXT saved_context;	/* Containes the saved context from a
144				   cygwin signal.  */
145
146/* If we're not using the old Cygwin header file set, define the
147   following which never should have been in the generic Win32 API
148   headers in the first place since they were our own invention...  */
149#ifndef _GNU_H_WINDOWS_H
150enum
151  {
152    FLAG_TRACE_BIT = 0x100,
153    CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
154  };
155#endif
156
157#ifndef CONTEXT_EXTENDED_REGISTERS
158/* This macro is only defined on ia32.  It only makes sense on this target,
159   so define it as zero if not already defined.  */
160#define CONTEXT_EXTENDED_REGISTERS 0
161#endif
162
163#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
164	| CONTEXT_EXTENDED_REGISTERS
165
166static uintptr_t dr[8];
167static int debug_registers_changed;
168static int debug_registers_used;
169
170static int windows_initialization_done;
171#define DR6_CLEAR_VALUE 0xffff0ff0
172
173/* The string sent by cygwin when it processes a signal.
174   FIXME: This should be in a cygwin include file.  */
175#ifndef _CYGWIN_SIGNAL_STRING
176#define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
177#endif
178
179#define CHECK(x)	check (x, __FILE__,__LINE__)
180#define DEBUG_EXEC(x)	if (debug_exec)		printf_unfiltered x
181#define DEBUG_EVENTS(x)	if (debug_events)	printf_unfiltered x
182#define DEBUG_MEM(x)	if (debug_memory)	printf_unfiltered x
183#define DEBUG_EXCEPT(x)	if (debug_exceptions)	printf_unfiltered x
184
185static void windows_stop (ptid_t);
186static int windows_thread_alive (struct target_ops *, ptid_t);
187static void windows_kill_inferior (struct target_ops *);
188
189static void cygwin_set_dr (int i, CORE_ADDR addr);
190static void cygwin_set_dr7 (unsigned long val);
191static unsigned long cygwin_get_dr6 (void);
192
193static enum target_signal last_sig = TARGET_SIGNAL_0;
194/* Set if a signal was received from the debugged process.  */
195
196/* Thread information structure used to track information that is
197   not available in gdb's thread structure.  */
198typedef struct thread_info_struct
199  {
200    struct thread_info_struct *next;
201    DWORD id;
202    HANDLE h;
203    CORE_ADDR thread_local_base;
204    char *name;
205    int suspended;
206    int reload_context;
207    CONTEXT context;
208    STACKFRAME sf;
209  }
210thread_info;
211
212static thread_info thread_head;
213
214/* The process and thread handles for the above context.  */
215
216static DEBUG_EVENT current_event;	/* The current debug event from
217					   WaitForDebugEvent */
218static HANDLE current_process_handle;	/* Currently executing process */
219static thread_info *current_thread;	/* Info on currently selected thread */
220static DWORD main_thread_id;		/* Thread ID of the main thread */
221
222/* Counts of things.  */
223static int exception_count = 0;
224static int event_count = 0;
225static int saw_create;
226static int open_process_used = 0;
227
228/* User options.  */
229static int new_console = 0;
230#ifdef __CYGWIN__
231static int cygwin_exceptions = 0;
232#endif
233static int new_group = 1;
234static int debug_exec = 0;		/* show execution */
235static int debug_events = 0;		/* show events from kernel */
236static int debug_memory = 0;		/* show target memory accesses */
237static int debug_exceptions = 0;	/* show target exceptions */
238static int useshell = 0;		/* use shell for subprocesses */
239
240/* This vector maps GDB's idea of a register's number into an offset
241   in the windows exception context vector.
242
243   It also contains the bit mask needed to load the register in question.
244
245   The contents of this table can only be computed by the units
246   that provide CPU-specific support for Windows native debugging.
247   These units should set the table by calling
248   windows_set_context_register_offsets.
249
250   One day we could read a reg, we could inspect the context we
251   already have loaded, if it doesn't have the bit set that we need,
252   we read that set of registers in using GetThreadContext.  If the
253   context already contains what we need, we just unpack it.  Then to
254   write a register, first we have to ensure that the context contains
255   the other regs of the group, and then we copy the info in and set
256   out bit.  */
257
258static const int *mappings;
259
260/* This vector maps the target's idea of an exception (extracted
261   from the DEBUG_EVENT structure) to GDB's idea.  */
262
263struct xlate_exception
264  {
265    int them;
266    enum target_signal us;
267  };
268
269static const struct xlate_exception
270  xlate[] =
271{
272  {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
273  {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
274  {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
275  {DBG_CONTROL_C, TARGET_SIGNAL_INT},
276  {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
277  {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
278  {-1, -1}};
279
280/* Set the MAPPINGS static global to OFFSETS.
281   See the description of MAPPINGS for more details.  */
282
283void
284windows_set_context_register_offsets (const int *offsets)
285{
286  mappings = offsets;
287}
288
289static void
290check (BOOL ok, const char *file, int line)
291{
292  if (!ok)
293    printf_filtered ("error return %s:%d was %lu\n", file, line,
294		     GetLastError ());
295}
296
297/* Find a thread record given a thread id.  If GET_CONTEXT is not 0,
298   then also retrieve the context for this thread.  If GET_CONTEXT is
299   negative, then don't suspend the thread.  */
300static thread_info *
301thread_rec (DWORD id, int get_context)
302{
303  thread_info *th;
304
305  for (th = &thread_head; (th = th->next) != NULL;)
306    if (th->id == id)
307      {
308	if (!th->suspended && get_context)
309	  {
310	    if (get_context > 0 && id != current_event.dwThreadId)
311	      {
312		if (SuspendThread (th->h) == (DWORD) -1)
313		  {
314		    DWORD err = GetLastError ();
315		    warning (_("SuspendThread failed. (winerr %d)"),
316			     (int) err);
317		    return NULL;
318		  }
319		th->suspended = 1;
320	      }
321	    else if (get_context < 0)
322	      th->suspended = -1;
323	    th->reload_context = 1;
324	  }
325	return th;
326      }
327
328  return NULL;
329}
330
331/* Add a thread to the thread list.  */
332static thread_info *
333windows_add_thread (ptid_t ptid, HANDLE h, void *tlb)
334{
335  thread_info *th;
336  DWORD id;
337
338  gdb_assert (ptid_get_tid (ptid) != 0);
339
340  id = ptid_get_tid (ptid);
341
342  if ((th = thread_rec (id, FALSE)))
343    return th;
344
345  th = XZALLOC (thread_info);
346  th->id = id;
347  th->h = h;
348  th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
349  th->next = thread_head.next;
350  thread_head.next = th;
351  add_thread (ptid);
352  /* Set the debug registers for the new thread if they are used.  */
353  if (debug_registers_used)
354    {
355      /* Only change the value of the debug registers.  */
356      th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
357      CHECK (GetThreadContext (th->h, &th->context));
358      th->context.Dr0 = dr[0];
359      th->context.Dr1 = dr[1];
360      th->context.Dr2 = dr[2];
361      th->context.Dr3 = dr[3];
362      th->context.Dr6 = DR6_CLEAR_VALUE;
363      th->context.Dr7 = dr[7];
364      CHECK (SetThreadContext (th->h, &th->context));
365      th->context.ContextFlags = 0;
366    }
367  return th;
368}
369
370/* Clear out any old thread list and reintialize it to a
371   pristine state.  */
372static void
373windows_init_thread_list (void)
374{
375  thread_info *th = &thread_head;
376
377  DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
378  init_thread_list ();
379  while (th->next != NULL)
380    {
381      thread_info *here = th->next;
382      th->next = here->next;
383      xfree (here);
384    }
385  thread_head.next = NULL;
386}
387
388/* Delete a thread from the list of threads.  */
389static void
390windows_delete_thread (ptid_t ptid)
391{
392  thread_info *th;
393  DWORD id;
394
395  gdb_assert (ptid_get_tid (ptid) != 0);
396
397  id = ptid_get_tid (ptid);
398
399  if (info_verbose)
400    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid));
401  delete_thread (ptid);
402
403  for (th = &thread_head;
404       th->next != NULL && th->next->id != id;
405       th = th->next)
406    continue;
407
408  if (th->next != NULL)
409    {
410      thread_info *here = th->next;
411      th->next = here->next;
412      xfree (here);
413    }
414}
415
416static void
417do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
418{
419  char *context_offset = ((char *) &current_thread->context) + mappings[r];
420  struct gdbarch *gdbarch = get_regcache_arch (regcache);
421  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
422  long l;
423
424  if (!current_thread)
425    return;	/* Windows sometimes uses a non-existent thread id in its
426		   events.  */
427
428  if (current_thread->reload_context)
429    {
430#ifdef __COPY_CONTEXT_SIZE
431      if (have_saved_context)
432	{
433	  /* Lie about where the program actually is stopped since
434	     cygwin has informed us that we should consider the signal
435	     to have occurred at another location which is stored in
436	     "saved_context.  */
437	  memcpy (&current_thread->context, &saved_context,
438		  __COPY_CONTEXT_SIZE);
439	  have_saved_context = 0;
440	}
441      else
442#endif
443	{
444	  thread_info *th = current_thread;
445	  th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
446	  GetThreadContext (th->h, &th->context);
447	  /* Copy dr values from that thread.
448	     But only if there were not modified since last stop.
449	     PR gdb/2388 */
450	  if (!debug_registers_changed)
451	    {
452	      dr[0] = th->context.Dr0;
453	      dr[1] = th->context.Dr1;
454	      dr[2] = th->context.Dr2;
455	      dr[3] = th->context.Dr3;
456	      dr[6] = th->context.Dr6;
457	      dr[7] = th->context.Dr7;
458	    }
459	}
460      current_thread->reload_context = 0;
461    }
462
463  if (r == I387_FISEG_REGNUM (tdep))
464    {
465      l = *((long *) context_offset) & 0xffff;
466      regcache_raw_supply (regcache, r, (char *) &l);
467    }
468  else if (r == I387_FOP_REGNUM (tdep))
469    {
470      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
471      regcache_raw_supply (regcache, r, (char *) &l);
472    }
473  else if (r >= 0)
474    regcache_raw_supply (regcache, r, context_offset);
475  else
476    {
477      for (r = 0; r < gdbarch_num_regs (gdbarch); r++)
478	do_windows_fetch_inferior_registers (regcache, r);
479    }
480}
481
482static void
483windows_fetch_inferior_registers (struct target_ops *ops,
484				  struct regcache *regcache, int r)
485{
486  current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
487  /* Check if current_thread exists.  Windows sometimes uses a non-existent
488     thread id in its events.  */
489  if (current_thread)
490    do_windows_fetch_inferior_registers (regcache, r);
491}
492
493static void
494do_windows_store_inferior_registers (const struct regcache *regcache, int r)
495{
496  if (!current_thread)
497    /* Windows sometimes uses a non-existent thread id in its events.  */;
498  else if (r >= 0)
499    regcache_raw_collect (regcache, r,
500			  ((char *) &current_thread->context) + mappings[r]);
501  else
502    {
503      for (r = 0; r < gdbarch_num_regs (get_regcache_arch (regcache)); r++)
504	do_windows_store_inferior_registers (regcache, r);
505    }
506}
507
508/* Store a new register value into the current thread context.  */
509static void
510windows_store_inferior_registers (struct target_ops *ops,
511				  struct regcache *regcache, int r)
512{
513  current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
514  /* Check if current_thread exists.  Windows sometimes uses a non-existent
515     thread id in its events.  */
516  if (current_thread)
517    do_windows_store_inferior_registers (regcache, r);
518}
519
520/* Get the name of a given module at at given base address.  If base_address
521   is zero return the first loaded module (which is always the name of the
522   executable).  */
523static int
524get_module_name (LPVOID base_address, char *dll_name_ret)
525{
526  DWORD len;
527  MODULEINFO mi;
528  int i;
529  HMODULE dh_buf[1];
530  HMODULE *DllHandle = dh_buf;	/* Set to temporary storage for
531				   initial query.  */
532  DWORD cbNeeded;
533#ifdef __CYGWIN__
534  cygwin_buf_t pathbuf[__PMAX];	/* Temporary storage prior to converting to
535				   posix form.  __PMAX is always enough
536				   as long as SO_NAME_MAX_PATH_SIZE is defined
537				   as 512.  */
538#endif
539
540  cbNeeded = 0;
541  /* Find size of buffer needed to handle list of modules loaded in
542     inferior.  */
543  if (!EnumProcessModules (current_process_handle, DllHandle,
544			   sizeof (HMODULE), &cbNeeded) || !cbNeeded)
545    goto failed;
546
547  /* Allocate correct amount of space for module list.  */
548  DllHandle = (HMODULE *) alloca (cbNeeded);
549  if (!DllHandle)
550    goto failed;
551
552  /* Get the list of modules.  */
553  if (!EnumProcessModules (current_process_handle, DllHandle, cbNeeded,
554				 &cbNeeded))
555    goto failed;
556
557  for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
558    {
559      /* Get information on this module.  */
560      if (!GetModuleInformation (current_process_handle, DllHandle[i],
561				 &mi, sizeof (mi)))
562	error (_("Can't get module info"));
563
564      if (!base_address || mi.lpBaseOfDll == base_address)
565	{
566	  /* Try to find the name of the given module.  */
567#ifdef __CYGWIN__
568	  /* Cygwin prefers that the path be in /x/y/z format.  */
569	  len = GetModuleFileNameEx (current_process_handle,
570				      DllHandle[i], pathbuf, __PMAX);
571	  if (len == 0)
572	    error (_("Error getting dll name: %lu."), GetLastError ());
573	  if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret,
574				__PMAX) < 0)
575	    error (_("Error converting dll name to POSIX: %d."), errno);
576#else
577	  len = GetModuleFileNameEx (current_process_handle,
578				      DllHandle[i], dll_name_ret, __PMAX);
579	  if (len == 0)
580	    error (_("Error getting dll name: %u."),
581		   (unsigned) GetLastError ());
582#endif
583	  return 1;	/* success */
584	}
585    }
586
587failed:
588  dll_name_ret[0] = '\0';
589  return 0;		/* failure */
590}
591
592/* Encapsulate the information required in a call to
593   symbol_file_add_args.  */
594struct safe_symbol_file_add_args
595{
596  char *name;
597  int from_tty;
598  struct section_addr_info *addrs;
599  int mainline;
600  int flags;
601  struct ui_file *err, *out;
602  struct objfile *ret;
603};
604
605/* Maintain a linked list of "so" information.  */
606struct lm_info
607{
608  LPVOID load_addr;
609};
610
611static struct so_list solib_start, *solib_end;
612
613/* Call symbol_file_add with stderr redirected.  We don't care if there
614   are errors.  */
615static int
616safe_symbol_file_add_stub (void *argv)
617{
618#define p ((struct safe_symbol_file_add_args *) argv)
619  const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0)
620                         | (p->mainline ? SYMFILE_MAINLINE : 0));
621  p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags);
622  return !!p->ret;
623#undef p
624}
625
626/* Restore gdb's stderr after calling symbol_file_add.  */
627static void
628safe_symbol_file_add_cleanup (void *p)
629{
630#define sp ((struct safe_symbol_file_add_args *)p)
631  gdb_flush (gdb_stderr);
632  gdb_flush (gdb_stdout);
633  ui_file_delete (gdb_stderr);
634  ui_file_delete (gdb_stdout);
635  gdb_stderr = sp->err;
636  gdb_stdout = sp->out;
637#undef sp
638}
639
640/* symbol_file_add wrapper that prevents errors from being displayed.  */
641static struct objfile *
642safe_symbol_file_add (char *name, int from_tty,
643		      struct section_addr_info *addrs,
644		      int mainline, int flags)
645{
646  struct safe_symbol_file_add_args p;
647  struct cleanup *cleanup;
648
649  cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
650
651  p.err = gdb_stderr;
652  p.out = gdb_stdout;
653  gdb_flush (gdb_stderr);
654  gdb_flush (gdb_stdout);
655  gdb_stderr = ui_file_new ();
656  gdb_stdout = ui_file_new ();
657  p.name = name;
658  p.from_tty = from_tty;
659  p.addrs = addrs;
660  p.mainline = mainline;
661  p.flags = flags;
662  catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
663
664  do_cleanups (cleanup);
665  return p.ret;
666}
667
668static struct so_list *
669windows_make_so (const char *name, LPVOID load_addr)
670{
671  struct so_list *so;
672  char *p;
673#ifndef __CYGWIN__
674  char buf[__PMAX];
675  char cwd[__PMAX];
676  WIN32_FIND_DATA w32_fd;
677  HANDLE h = FindFirstFile(name, &w32_fd);
678
679  if (h == INVALID_HANDLE_VALUE)
680    strcpy (buf, name);
681  else
682    {
683      FindClose (h);
684      strcpy (buf, name);
685      if (GetCurrentDirectory (MAX_PATH + 1, cwd))
686	{
687	  p = strrchr (buf, '\\');
688	  if (p)
689	    p[1] = '\0';
690	  SetCurrentDirectory (buf);
691	  GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
692	  SetCurrentDirectory (cwd);
693	}
694    }
695  if (strcasecmp (buf, "ntdll.dll") == 0)
696    {
697      GetSystemDirectory (buf, sizeof (buf));
698      strcat (buf, "\\ntdll.dll");
699    }
700#else
701  cygwin_buf_t buf[__PMAX];
702
703  buf[0] = 0;
704  if (access (name, F_OK) != 0)
705    {
706      if (strcasecmp (name, "ntdll.dll") == 0)
707#ifdef __USEWIDE
708	{
709	  GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t));
710	  wcscat (buf, L"\\ntdll.dll");
711	}
712#else
713	{
714	  GetSystemDirectoryA (buf, sizeof (buf) / sizeof (wchar_t));
715	  strcat (buf, "\\ntdll.dll");
716	}
717#endif
718    }
719#endif
720  so = XZALLOC (struct so_list);
721  so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
722  so->lm_info->load_addr = load_addr;
723  strcpy (so->so_original_name, name);
724#ifndef __CYGWIN__
725  strcpy (so->so_name, buf);
726#else
727  if (buf[0])
728    cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
729		      SO_NAME_MAX_PATH_SIZE);
730  else
731    {
732      char *rname = realpath (name, NULL);
733      if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
734	{
735	  strcpy (so->so_name, rname);
736	  free (rname);
737	}
738      else
739	error (_("dll path too long"));
740    }
741  /* Record cygwin1.dll .text start/end.  */
742  p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
743  if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
744    {
745      bfd *abfd;
746      asection *text = NULL;
747      CORE_ADDR text_vma;
748
749      abfd = bfd_openr (so->so_name, "pei-i386");
750
751      if (!abfd)
752	return so;
753
754      if (bfd_check_format (abfd, bfd_object))
755	text = bfd_get_section_by_name (abfd, ".text");
756
757      if (!text)
758	{
759	  bfd_close (abfd);
760	  return so;
761	}
762
763      /* The symbols in a dll are offset by 0x1000, which is the the
764	 offset from 0 of the first byte in an image - because of the
765	 file header and the section alignment.  */
766      cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *)
767						   load_addr + 0x1000);
768      cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text);
769
770      bfd_close (abfd);
771    }
772#endif
773
774  return so;
775}
776
777static char *
778get_image_name (HANDLE h, void *address, int unicode)
779{
780#ifdef __CYGWIN__
781  static char buf[__PMAX];
782#else
783  static char buf[(2 * __PMAX) + 1];
784#endif
785  DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
786  char *address_ptr;
787  int len = 0;
788  char b[2];
789  SIZE_T done;
790
791  /* Attempt to read the name of the dll that was detected.
792     This is documented to work only when actively debugging
793     a program.  It will not work for attached processes.  */
794  if (address == NULL)
795    return NULL;
796
797  /* See if we could read the address of a string, and that the
798     address isn't null.  */
799  if (!ReadProcessMemory (h, address,  &address_ptr,
800			  sizeof (address_ptr), &done)
801      || done != sizeof (address_ptr) || !address_ptr)
802    return NULL;
803
804  /* Find the length of the string.  */
805  while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
806	 && (b[0] != 0 || b[size - 1] != 0) && done == size)
807    continue;
808
809  if (!unicode)
810    ReadProcessMemory (h, address_ptr, buf, len, &done);
811  else
812    {
813      WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
814      ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
815			 &done);
816#ifdef __CYGWIN__
817      wcstombs (buf, unicode_address, __PMAX);
818#else
819      WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
820			   0, 0);
821#endif
822    }
823
824  return buf;
825}
826
827/* Wait for child to do something.  Return pid of child, or -1 in case
828   of error; store status through argument pointer OURSTATUS.  */
829static int
830handle_load_dll (void *dummy)
831{
832  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
833  char dll_buf[__PMAX];
834  char *dll_name = NULL;
835
836  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
837
838  if (!get_module_name (event->lpBaseOfDll, dll_buf))
839    dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
840
841  dll_name = dll_buf;
842
843  if (*dll_name == '\0')
844    dll_name = get_image_name (current_process_handle,
845			       event->lpImageName, event->fUnicode);
846  if (!dll_name)
847    return 1;
848
849  solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
850  solib_end = solib_end->next;
851
852  DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
853		 host_address_to_string (solib_end->lm_info->load_addr)));
854
855  return 1;
856}
857
858static void
859windows_free_so (struct so_list *so)
860{
861  if (so->lm_info)
862    xfree (so->lm_info);
863  xfree (so);
864}
865
866static int
867handle_unload_dll (void *dummy)
868{
869  LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
870  struct so_list *so;
871
872  for (so = &solib_start; so->next != NULL; so = so->next)
873    if (so->next->lm_info->load_addr == lpBaseOfDll)
874      {
875	struct so_list *sodel = so->next;
876	so->next = sodel->next;
877	if (!so->next)
878	  solib_end = so;
879	DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
880
881	windows_free_so (sodel);
882	solib_add (NULL, 0, NULL, auto_solib_add);
883	return 1;
884      }
885
886  /* We did not find any DLL that was previously loaded at this address,
887     so register a complaint.  We do not report an error, because we have
888     observed that this may be happening under some circumstances.  For
889     instance, running 32bit applications on x64 Windows causes us to receive
890     4 mysterious UNLOAD_DLL_DEBUG_EVENTs during the startup phase (these
891     events are apparently caused by the WOW layer, the interface between
892     32bit and 64bit worlds).  */
893  complaint (&symfile_complaints, _("dll starting at %s not found."),
894	     host_address_to_string (lpBaseOfDll));
895
896  return 0;
897}
898
899/* Clear list of loaded DLLs.  */
900static void
901windows_clear_solib (void)
902{
903  solib_start.next = NULL;
904  solib_end = &solib_start;
905}
906
907/* Load DLL symbol info.  */
908void
909dll_symbol_command (char *args, int from_tty)
910{
911  int n;
912  dont_repeat ();
913
914  if (args == NULL)
915    error (_("dll-symbols requires a file name"));
916
917  n = strlen (args);
918  if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
919    {
920      char *newargs = (char *) alloca (n + 4 + 1);
921      strcpy (newargs, args);
922      strcat (newargs, ".dll");
923      args = newargs;
924    }
925
926  safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
927}
928
929/* Handle DEBUG_STRING output from child process.
930   Cygwin prepends its messages with a "cygwin:".  Interpret this as
931   a Cygwin signal.  Otherwise just print the string as a warning.  */
932static int
933handle_output_debug_string (struct target_waitstatus *ourstatus)
934{
935  char *s = NULL;
936  int retval = 0;
937
938  if (!target_read_string
939	((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
940	&s, 1024, 0)
941      || !s || !*s)
942    /* nothing to do */;
943  else if (strncmp (s, _CYGWIN_SIGNAL_STRING,
944		    sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
945    {
946#ifdef __CYGWIN__
947      if (strncmp (s, "cYg", 3) != 0)
948#endif
949	warning (("%s"), s);
950    }
951#ifdef __COPY_CONTEXT_SIZE
952  else
953    {
954      /* Got a cygwin signal marker.  A cygwin signal is followed by
955	 the signal number itself and then optionally followed by the
956	 thread id and address to saved context within the DLL.  If
957	 these are supplied, then the given thread is assumed to have
958	 issued the signal and the context from the thread is assumed
959	 to be stored at the given address in the inferior.  Tell gdb
960	 to treat this like a real signal.  */
961      char *p;
962      int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
963      int gotasig = target_signal_from_host (sig);
964      ourstatus->value.sig = gotasig;
965      if (gotasig)
966	{
967	  LPCVOID x;
968	  DWORD n;
969	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
970	  retval = strtoul (p, &p, 0);
971	  if (!retval)
972	    retval = main_thread_id;
973	  else if ((x = (LPCVOID) strtoul (p, &p, 0))
974		   && ReadProcessMemory (current_process_handle, x,
975					 &saved_context,
976					 __COPY_CONTEXT_SIZE, &n)
977		   && n == __COPY_CONTEXT_SIZE)
978	    have_saved_context = 1;
979	  current_event.dwThreadId = retval;
980	}
981    }
982#endif
983
984  if (s)
985    xfree (s);
986  return retval;
987}
988
989static int
990display_selector (HANDLE thread, DWORD sel)
991{
992  LDT_ENTRY info;
993  if (GetThreadSelectorEntry (thread, sel, &info))
994    {
995      int base, limit;
996      printf_filtered ("0x%03lx: ", sel);
997      if (!info.HighWord.Bits.Pres)
998	{
999	  puts_filtered ("Segment not present\n");
1000	  return 0;
1001	}
1002      base = (info.HighWord.Bits.BaseHi << 24) +
1003	     (info.HighWord.Bits.BaseMid << 16)
1004	     + info.BaseLow;
1005      limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
1006      if (info.HighWord.Bits.Granularity)
1007	limit = (limit << 12) | 0xfff;
1008      printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
1009      if (info.HighWord.Bits.Default_Big)
1010	puts_filtered(" 32-bit ");
1011      else
1012	puts_filtered(" 16-bit ");
1013      switch ((info.HighWord.Bits.Type & 0xf) >> 1)
1014	{
1015	case 0:
1016	  puts_filtered ("Data (Read-Only, Exp-up");
1017	  break;
1018	case 1:
1019	  puts_filtered ("Data (Read/Write, Exp-up");
1020	  break;
1021	case 2:
1022	  puts_filtered ("Unused segment (");
1023	  break;
1024	case 3:
1025	  puts_filtered ("Data (Read/Write, Exp-down");
1026	  break;
1027	case 4:
1028	  puts_filtered ("Code (Exec-Only, N.Conf");
1029	  break;
1030	case 5:
1031	  puts_filtered ("Code (Exec/Read, N.Conf");
1032	  break;
1033	case 6:
1034	  puts_filtered ("Code (Exec-Only, Conf");
1035	  break;
1036	case 7:
1037	  puts_filtered ("Code (Exec/Read, Conf");
1038	  break;
1039	default:
1040	  printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
1041	}
1042      if ((info.HighWord.Bits.Type & 0x1) == 0)
1043	puts_filtered(", N.Acc");
1044      puts_filtered (")\n");
1045      if ((info.HighWord.Bits.Type & 0x10) == 0)
1046	puts_filtered("System selector ");
1047      printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
1048      if (info.HighWord.Bits.Granularity)
1049	puts_filtered ("Page granular.\n");
1050      else
1051	puts_filtered ("Byte granular.\n");
1052      return 1;
1053    }
1054  else
1055    {
1056      DWORD err = GetLastError ();
1057      if (err == ERROR_NOT_SUPPORTED)
1058	printf_filtered ("Function not supported\n");
1059      else
1060	printf_filtered ("Invalid selector 0x%lx.\n",sel);
1061      return 0;
1062    }
1063}
1064
1065static void
1066display_selectors (char * args, int from_tty)
1067{
1068  if (!current_thread)
1069    {
1070      puts_filtered ("Impossible to display selectors now.\n");
1071      return;
1072    }
1073  if (!args)
1074    {
1075
1076      puts_filtered ("Selector $cs\n");
1077      display_selector (current_thread->h,
1078	current_thread->context.SegCs);
1079      puts_filtered ("Selector $ds\n");
1080      display_selector (current_thread->h,
1081	current_thread->context.SegDs);
1082      puts_filtered ("Selector $es\n");
1083      display_selector (current_thread->h,
1084	current_thread->context.SegEs);
1085      puts_filtered ("Selector $ss\n");
1086      display_selector (current_thread->h,
1087	current_thread->context.SegSs);
1088      puts_filtered ("Selector $fs\n");
1089      display_selector (current_thread->h,
1090	current_thread->context.SegFs);
1091      puts_filtered ("Selector $gs\n");
1092      display_selector (current_thread->h,
1093	current_thread->context.SegGs);
1094    }
1095  else
1096    {
1097      int sel;
1098      sel = parse_and_eval_long (args);
1099      printf_filtered ("Selector \"%s\"\n",args);
1100      display_selector (current_thread->h, sel);
1101    }
1102}
1103
1104#define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
1105  printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
1106    host_address_to_string (\
1107      current_event.u.Exception.ExceptionRecord.ExceptionAddress))
1108
1109static int
1110handle_exception (struct target_waitstatus *ourstatus)
1111{
1112  thread_info *th;
1113  DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
1114
1115  ourstatus->kind = TARGET_WAITKIND_STOPPED;
1116
1117  /* Record the context of the current thread.  */
1118  th = thread_rec (current_event.dwThreadId, -1);
1119
1120  switch (code)
1121    {
1122    case EXCEPTION_ACCESS_VIOLATION:
1123      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1124      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1125#ifdef __CYGWIN__
1126      {
1127	/* See if the access violation happened within the cygwin DLL
1128	   itself.  Cygwin uses a kind of exception handling to deal
1129	   with passed-in invalid addresses.  gdb should not treat
1130	   these as real SEGVs since they will be silently handled by
1131	   cygwin.  A real SEGV will (theoretically) be caught by
1132	   cygwin later in the process and will be sent as a
1133	   cygwin-specific-signal.  So, ignore SEGVs if they show up
1134	   within the text segment of the DLL itself.  */
1135	char *fn;
1136	CORE_ADDR addr = (CORE_ADDR) (uintptr_t)
1137	  current_event.u.Exception.ExceptionRecord.ExceptionAddress;
1138
1139	if ((!cygwin_exceptions && (addr >= cygwin_load_start
1140				    && addr < cygwin_load_end))
1141	    || (find_pc_partial_function (addr, &fn, NULL, NULL)
1142		&& strncmp (fn, "KERNEL32!IsBad",
1143			    strlen ("KERNEL32!IsBad")) == 0))
1144	  return 0;
1145      }
1146#endif
1147      break;
1148    case STATUS_STACK_OVERFLOW:
1149      DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1150      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1151      break;
1152    case STATUS_FLOAT_DENORMAL_OPERAND:
1153      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1154      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1155      break;
1156    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1157      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1158      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1159      break;
1160    case STATUS_FLOAT_INEXACT_RESULT:
1161      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1162      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1163      break;
1164    case STATUS_FLOAT_INVALID_OPERATION:
1165      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1166      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1167      break;
1168    case STATUS_FLOAT_OVERFLOW:
1169      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1170      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1171      break;
1172    case STATUS_FLOAT_STACK_CHECK:
1173      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1174      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1175      break;
1176    case STATUS_FLOAT_UNDERFLOW:
1177      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1178      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1179      break;
1180    case STATUS_FLOAT_DIVIDE_BY_ZERO:
1181      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1182      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1183      break;
1184    case STATUS_INTEGER_DIVIDE_BY_ZERO:
1185      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1186      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1187      break;
1188    case STATUS_INTEGER_OVERFLOW:
1189      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1190      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1191      break;
1192    case EXCEPTION_BREAKPOINT:
1193      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1194      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1195      break;
1196    case DBG_CONTROL_C:
1197      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1198      ourstatus->value.sig = TARGET_SIGNAL_INT;
1199      break;
1200    case DBG_CONTROL_BREAK:
1201      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1202      ourstatus->value.sig = TARGET_SIGNAL_INT;
1203      break;
1204    case EXCEPTION_SINGLE_STEP:
1205      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1206      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1207      break;
1208    case EXCEPTION_ILLEGAL_INSTRUCTION:
1209      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1210      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1211      break;
1212    case EXCEPTION_PRIV_INSTRUCTION:
1213      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1214      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1215      break;
1216    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1217      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1218      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1219      break;
1220    default:
1221      /* Treat unhandled first chance exceptions specially.  */
1222      if (current_event.u.Exception.dwFirstChance)
1223	return -1;
1224      printf_unfiltered ("gdb: unknown target exception 0x%08lx at %s\n",
1225	current_event.u.Exception.ExceptionRecord.ExceptionCode,
1226	host_address_to_string (
1227	  current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1228      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1229      break;
1230    }
1231  exception_count++;
1232  last_sig = ourstatus->value.sig;
1233  return 1;
1234}
1235
1236/* Resume all artificially suspended threads if we are continuing
1237   execution.  */
1238static BOOL
1239windows_continue (DWORD continue_status, int id)
1240{
1241  int i;
1242  thread_info *th;
1243  BOOL res;
1244
1245  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%lx, %s);\n",
1246		  current_event.dwProcessId, current_event.dwThreadId,
1247		  continue_status == DBG_CONTINUE ?
1248		  "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1249
1250  for (th = &thread_head; (th = th->next) != NULL;)
1251    if ((id == -1 || id == (int) th->id)
1252	&& th->suspended)
1253      {
1254	if (debug_registers_changed)
1255	  {
1256	    th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
1257	    th->context.Dr0 = dr[0];
1258	    th->context.Dr1 = dr[1];
1259	    th->context.Dr2 = dr[2];
1260	    th->context.Dr3 = dr[3];
1261	    th->context.Dr6 = DR6_CLEAR_VALUE;
1262	    th->context.Dr7 = dr[7];
1263	  }
1264	if (th->context.ContextFlags)
1265	  {
1266	    CHECK (SetThreadContext (th->h, &th->context));
1267	    th->context.ContextFlags = 0;
1268	  }
1269	if (th->suspended > 0)
1270	  (void) ResumeThread (th->h);
1271	th->suspended = 0;
1272      }
1273
1274  res = ContinueDebugEvent (current_event.dwProcessId,
1275			    current_event.dwThreadId,
1276			    continue_status);
1277
1278  debug_registers_changed = 0;
1279  return res;
1280}
1281
1282/* Called in pathological case where Windows fails to send a
1283   CREATE_PROCESS_DEBUG_EVENT after an attach.  */
1284static DWORD
1285fake_create_process (void)
1286{
1287  current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
1288					current_event.dwProcessId);
1289  if (current_process_handle != NULL)
1290    open_process_used = 1;
1291  else
1292    {
1293      error (_("OpenProcess call failed, GetLastError = %lud"),
1294       GetLastError ());
1295      /*  We can not debug anything in that case.  */
1296    }
1297  main_thread_id = current_event.dwThreadId;
1298  current_thread = windows_add_thread (
1299		     ptid_build (current_event.dwProcessId, 0,
1300				 current_event.dwThreadId),
1301		     current_event.u.CreateThread.hThread,
1302		     current_event.u.CreateThread.lpThreadLocalBase);
1303  return main_thread_id;
1304}
1305
1306static void
1307windows_resume (struct target_ops *ops,
1308		ptid_t ptid, int step, enum target_signal sig)
1309{
1310  thread_info *th;
1311  DWORD continue_status = DBG_CONTINUE;
1312
1313  /* A specific PTID means `step only this thread id'.  */
1314  int resume_all = ptid_equal (ptid, minus_one_ptid);
1315
1316  /* If we're continuing all threads, it's the current inferior that
1317     should be handled specially.  */
1318  if (resume_all)
1319    ptid = inferior_ptid;
1320
1321  if (sig != TARGET_SIGNAL_0)
1322    {
1323      if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1324	{
1325	  DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1326	}
1327      else if (sig == last_sig)
1328	continue_status = DBG_EXCEPTION_NOT_HANDLED;
1329      else
1330#if 0
1331/* This code does not seem to work, because
1332  the kernel does probably not consider changes in the ExceptionRecord
1333  structure when passing the exception to the inferior.
1334  Note that this seems possible in the exception handler itself.  */
1335	{
1336	  int i;
1337	  for (i = 0; xlate[i].them != -1; i++)
1338	    if (xlate[i].us == sig)
1339	      {
1340		current_event.u.Exception.ExceptionRecord.ExceptionCode
1341		  = xlate[i].them;
1342		continue_status = DBG_EXCEPTION_NOT_HANDLED;
1343		break;
1344	      }
1345	  if (continue_status == DBG_CONTINUE)
1346	    {
1347	      DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1348	    }
1349	}
1350#endif
1351	DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1352	  last_sig));
1353    }
1354
1355  last_sig = TARGET_SIGNAL_0;
1356
1357  DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n",
1358	       ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig));
1359
1360  /* Get context for currently selected thread.  */
1361  th = thread_rec (ptid_get_tid (inferior_ptid), FALSE);
1362  if (th)
1363    {
1364      if (step)
1365	{
1366	  /* Single step by setting t bit.  */
1367	  struct regcache *regcache = get_current_regcache ();
1368	  struct gdbarch *gdbarch = get_regcache_arch (regcache);
1369	  windows_fetch_inferior_registers (ops, regcache,
1370					    gdbarch_ps_regnum (gdbarch));
1371	  th->context.EFlags |= FLAG_TRACE_BIT;
1372	}
1373
1374      if (th->context.ContextFlags)
1375	{
1376	  if (debug_registers_changed)
1377	    {
1378	      th->context.Dr0 = dr[0];
1379	      th->context.Dr1 = dr[1];
1380	      th->context.Dr2 = dr[2];
1381	      th->context.Dr3 = dr[3];
1382	      th->context.Dr6 = DR6_CLEAR_VALUE;
1383	      th->context.Dr7 = dr[7];
1384	    }
1385	  CHECK (SetThreadContext (th->h, &th->context));
1386	  th->context.ContextFlags = 0;
1387	}
1388    }
1389
1390  /* Allow continuing with the same signal that interrupted us.
1391     Otherwise complain.  */
1392
1393  if (resume_all)
1394    windows_continue (continue_status, -1);
1395  else
1396    windows_continue (continue_status, ptid_get_tid (ptid));
1397}
1398
1399/* Ctrl-C handler used when the inferior is not run in the same console.  The
1400   handler is in charge of interrupting the inferior using DebugBreakProcess.
1401   Note that this function is not available prior to Windows XP.  In this case
1402   we emit a warning.  */
1403BOOL WINAPI
1404ctrl_c_handler (DWORD event_type)
1405{
1406  const int attach_flag = current_inferior ()->attach_flag;
1407
1408  /* Only handle Ctrl-C and Ctrl-Break events.  Ignore others.  */
1409  if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT)
1410    return FALSE;
1411
1412  /* If the inferior and the debugger share the same console, do nothing as
1413     the inferior has also received the Ctrl-C event.  */
1414  if (!new_console && !attach_flag)
1415    return TRUE;
1416
1417  if (!DebugBreakProcess (current_process_handle))
1418    warning (_("Could not interrupt program.  "
1419	       "Press Ctrl-c in the program console."));
1420
1421  /* Return true to tell that Ctrl-C has been handled.  */
1422  return TRUE;
1423}
1424
1425/* Get the next event from the child.  Return 1 if the event requires
1426   handling by WFI (or whatever).  */
1427static int
1428get_windows_debug_event (struct target_ops *ops,
1429			 int pid, struct target_waitstatus *ourstatus)
1430{
1431  BOOL debug_event;
1432  DWORD continue_status, event_code;
1433  thread_info *th;
1434  static thread_info dummy_thread_info;
1435  int retval = 0;
1436
1437  last_sig = TARGET_SIGNAL_0;
1438
1439  if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
1440    goto out;
1441
1442  event_count++;
1443  continue_status = DBG_CONTINUE;
1444
1445  event_code = current_event.dwDebugEventCode;
1446  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1447  th = NULL;
1448  have_saved_context = 0;
1449
1450  switch (event_code)
1451    {
1452    case CREATE_THREAD_DEBUG_EVENT:
1453      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1454		     (unsigned) current_event.dwProcessId,
1455		     (unsigned) current_event.dwThreadId,
1456		     "CREATE_THREAD_DEBUG_EVENT"));
1457      if (saw_create != 1)
1458	{
1459	  struct inferior *inf;
1460	  inf = find_inferior_pid (current_event.dwProcessId);
1461	  if (!saw_create && inf->attach_flag)
1462	    {
1463	      /* Kludge around a Windows bug where first event is a create
1464		 thread event.  Caused when attached process does not have
1465		 a main thread.  */
1466	      retval = fake_create_process ();
1467	      if (retval)
1468		saw_create++;
1469	    }
1470	  break;
1471	}
1472      /* Record the existence of this thread.  */
1473      retval = current_event.dwThreadId;
1474      th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
1475					 current_event.dwThreadId),
1476			     current_event.u.CreateThread.hThread,
1477			     current_event.u.CreateThread.lpThreadLocalBase);
1478
1479      break;
1480
1481    case EXIT_THREAD_DEBUG_EVENT:
1482      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1483		     (unsigned) current_event.dwProcessId,
1484		     (unsigned) current_event.dwThreadId,
1485		     "EXIT_THREAD_DEBUG_EVENT"));
1486
1487      if (current_event.dwThreadId != main_thread_id)
1488	{
1489	  windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
1490					   current_event.dwThreadId));
1491	  th = &dummy_thread_info;
1492	}
1493      break;
1494
1495    case CREATE_PROCESS_DEBUG_EVENT:
1496      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1497		     (unsigned) current_event.dwProcessId,
1498		     (unsigned) current_event.dwThreadId,
1499		     "CREATE_PROCESS_DEBUG_EVENT"));
1500      CloseHandle (current_event.u.CreateProcessInfo.hFile);
1501      if (++saw_create != 1)
1502	break;
1503
1504      current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1505      if (main_thread_id)
1506	windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
1507					   main_thread_id));
1508      main_thread_id = current_event.dwThreadId;
1509      /* Add the main thread.  */
1510      th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
1511					   current_event.dwThreadId),
1512	     current_event.u.CreateProcessInfo.hThread,
1513	     current_event.u.CreateProcessInfo.lpThreadLocalBase);
1514      retval = current_event.dwThreadId;
1515      break;
1516
1517    case EXIT_PROCESS_DEBUG_EVENT:
1518      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1519		     (unsigned) current_event.dwProcessId,
1520		     (unsigned) current_event.dwThreadId,
1521		     "EXIT_PROCESS_DEBUG_EVENT"));
1522      if (!windows_initialization_done)
1523	{
1524	  target_terminal_ours ();
1525	  target_mourn_inferior ();
1526	  error (_("During startup program exited with code 0x%x."),
1527		 (unsigned int) current_event.u.ExitProcess.dwExitCode);
1528	}
1529      else if (saw_create == 1)
1530	{
1531	  ourstatus->kind = TARGET_WAITKIND_EXITED;
1532	  ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1533	  retval = main_thread_id;
1534	}
1535      break;
1536
1537    case LOAD_DLL_DEBUG_EVENT:
1538      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1539		     (unsigned) current_event.dwProcessId,
1540		     (unsigned) current_event.dwThreadId,
1541		     "LOAD_DLL_DEBUG_EVENT"));
1542      CloseHandle (current_event.u.LoadDll.hFile);
1543      if (saw_create != 1)
1544	break;
1545      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1546      ourstatus->kind = TARGET_WAITKIND_LOADED;
1547      ourstatus->value.integer = 0;
1548      retval = main_thread_id;
1549      break;
1550
1551    case UNLOAD_DLL_DEBUG_EVENT:
1552      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1553		     (unsigned) current_event.dwProcessId,
1554		     (unsigned) current_event.dwThreadId,
1555		     "UNLOAD_DLL_DEBUG_EVENT"));
1556      if (saw_create != 1)
1557	break;
1558      catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1559      ourstatus->kind = TARGET_WAITKIND_LOADED;
1560      ourstatus->value.integer = 0;
1561      retval = main_thread_id;
1562      break;
1563
1564    case EXCEPTION_DEBUG_EVENT:
1565      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1566		     (unsigned) current_event.dwProcessId,
1567		     (unsigned) current_event.dwThreadId,
1568		     "EXCEPTION_DEBUG_EVENT"));
1569      if (saw_create != 1)
1570	break;
1571      switch (handle_exception (ourstatus))
1572	{
1573	case 0:
1574	  continue_status = DBG_EXCEPTION_NOT_HANDLED;
1575	  break;
1576	case 1:
1577	  retval = current_event.dwThreadId;
1578	  break;
1579	case -1:
1580	  last_sig = 1;
1581	  continue_status = -1;
1582	  break;
1583	}
1584      break;
1585
1586    case OUTPUT_DEBUG_STRING_EVENT:	/* Message from the kernel.  */
1587      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1588		     (unsigned) current_event.dwProcessId,
1589		     (unsigned) current_event.dwThreadId,
1590		     "OUTPUT_DEBUG_STRING_EVENT"));
1591      if (saw_create != 1)
1592	break;
1593      retval = handle_output_debug_string (ourstatus);
1594      break;
1595
1596    default:
1597      if (saw_create != 1)
1598	break;
1599      printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1600			 (DWORD) current_event.dwProcessId,
1601			 (DWORD) current_event.dwThreadId);
1602      printf_unfiltered ("                 unknown event code %ld\n",
1603			 current_event.dwDebugEventCode);
1604      break;
1605    }
1606
1607  if (!retval || saw_create != 1)
1608    {
1609      if (continue_status == -1)
1610	windows_resume (ops, minus_one_ptid, 0, 1);
1611      else
1612	CHECK (windows_continue (continue_status, -1));
1613    }
1614  else
1615    {
1616      inferior_ptid = ptid_build (current_event.dwProcessId, 0,
1617				  retval);
1618      current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1619    }
1620
1621out:
1622  return retval;
1623}
1624
1625/* Wait for interesting events to occur in the target process.  */
1626static ptid_t
1627windows_wait (struct target_ops *ops,
1628	      ptid_t ptid, struct target_waitstatus *ourstatus, int options)
1629{
1630  int pid = -1;
1631
1632  target_terminal_ours ();
1633
1634  /* We loop when we get a non-standard exception rather than return
1635     with a SPURIOUS because resume can try and step or modify things,
1636     which needs a current_thread->h.  But some of these exceptions mark
1637     the birth or death of threads, which mean that the current thread
1638     isn't necessarily what you think it is.  */
1639
1640  while (1)
1641    {
1642      int retval;
1643
1644      /* If the user presses Ctrl-c while the debugger is waiting
1645	 for an event, he expects the debugger to interrupt his program
1646	 and to get the prompt back.  There are two possible situations:
1647
1648	   - The debugger and the program do not share the console, in
1649	     which case the Ctrl-c event only reached the debugger.
1650	     In that case, the ctrl_c handler will take care of interrupting
1651	     the inferior.  Note that this case is working starting with
1652	     Windows XP.  For Windows 2000, Ctrl-C should be pressed in the
1653	     inferior console.
1654
1655	   - The debugger and the program share the same console, in which
1656	     case both debugger and inferior will receive the Ctrl-c event.
1657	     In that case the ctrl_c handler will ignore the event, as the
1658	     Ctrl-c event generated inside the inferior will trigger the
1659	     expected debug event.
1660
1661	     FIXME: brobecker/2008-05-20: If the inferior receives the
1662	     signal first and the delay until GDB receives that signal
1663	     is sufficiently long, GDB can sometimes receive the SIGINT
1664	     after we have unblocked the CTRL+C handler.  This would
1665	     lead to the debugger stopping prematurely while handling
1666	     the new-thread event that comes with the handling of the SIGINT
1667	     inside the inferior, and then stop again immediately when
1668	     the user tries to resume the execution in the inferior.
1669	     This is a classic race that we should try to fix one day.  */
1670      SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
1671      retval = get_windows_debug_event (ops, pid, ourstatus);
1672      SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
1673
1674      if (retval)
1675	return ptid_build (current_event.dwProcessId, 0, retval);
1676      else
1677	{
1678	  int detach = 0;
1679
1680	  if (deprecated_ui_loop_hook != NULL)
1681	    detach = deprecated_ui_loop_hook (0);
1682
1683	  if (detach)
1684	    windows_kill_inferior (ops);
1685	}
1686    }
1687}
1688
1689static void
1690do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
1691{
1692  extern int stop_after_trap;
1693  int i;
1694  struct inferior *inf;
1695  struct thread_info *tp;
1696
1697  last_sig = TARGET_SIGNAL_0;
1698  event_count = 0;
1699  exception_count = 0;
1700  open_process_used = 0;
1701  debug_registers_changed = 0;
1702  debug_registers_used = 0;
1703  for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1704    dr[i] = 0;
1705#ifdef __CYGWIN__
1706  cygwin_load_start = cygwin_load_end = 0;
1707#endif
1708  current_event.dwProcessId = pid;
1709  memset (&current_event, 0, sizeof (current_event));
1710  push_target (ops);
1711  disable_breakpoints_in_shlibs ();
1712  windows_clear_solib ();
1713  clear_proceed_status ();
1714  init_wait_for_inferior ();
1715
1716  inf = current_inferior ();
1717  inferior_appeared (inf, pid);
1718  inf->attach_flag = attaching;
1719
1720  /* Make the new process the current inferior, so terminal handling
1721     can rely on it.  When attaching, we don't know about any thread
1722     id here, but that's OK --- nothing should be referencing the
1723     current thread until we report an event out of windows_wait.  */
1724  inferior_ptid = pid_to_ptid (pid);
1725
1726  terminal_init_inferior_with_pgrp (pid);
1727  target_terminal_inferior ();
1728
1729  windows_initialization_done = 0;
1730  inf->control.stop_soon = STOP_QUIETLY;
1731  while (1)
1732    {
1733      stop_after_trap = 1;
1734      wait_for_inferior (0);
1735      tp = inferior_thread ();
1736      if (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP)
1737	resume (0, tp->suspend.stop_signal);
1738      else
1739	break;
1740    }
1741
1742  windows_initialization_done = 1;
1743  inf->control.stop_soon = NO_STOP_QUIETLY;
1744  stop_after_trap = 0;
1745  return;
1746}
1747
1748/* Try to set or remove a user privilege to the current process.  Return -1
1749   if that fails, the previous setting of that privilege otherwise.
1750
1751   This code is copied from the Cygwin source code and rearranged to allow
1752   dynamically loading of the needed symbols from advapi32 which is only
1753   available on NT/2K/XP.  */
1754static int
1755set_process_privilege (const char *privilege, BOOL enable)
1756{
1757  HANDLE token_hdl = NULL;
1758  LUID restore_priv;
1759  TOKEN_PRIVILEGES new_priv, orig_priv;
1760  int ret = -1;
1761  DWORD size;
1762
1763  if (!OpenProcessToken (GetCurrentProcess (),
1764			 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1765			 &token_hdl))
1766    goto out;
1767
1768  if (!LookupPrivilegeValueA (NULL, privilege, &restore_priv))
1769    goto out;
1770
1771  new_priv.PrivilegeCount = 1;
1772  new_priv.Privileges[0].Luid = restore_priv;
1773  new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1774
1775  if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
1776			      sizeof orig_priv, &orig_priv, &size))
1777    goto out;
1778#if 0
1779  /* Disabled, otherwise every `attach' in an unprivileged user session
1780     would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1781     windows_attach().  */
1782  /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1783     be enabled.  GetLastError () returns an correct error code, though.  */
1784  if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1785    goto out;
1786#endif
1787
1788  ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1789
1790out:
1791  if (token_hdl)
1792    CloseHandle (token_hdl);
1793
1794  return ret;
1795}
1796
1797/* Attach to process PID, then initialize for debugging it.  */
1798static void
1799windows_attach (struct target_ops *ops, char *args, int from_tty)
1800{
1801  BOOL ok;
1802  DWORD pid;
1803
1804  pid = parse_pid_to_attach (args);
1805
1806  if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1807    {
1808      printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1809      printf_unfiltered ("This can cause attach to "
1810			 "fail on Windows NT/2K/XP\n");
1811    }
1812
1813  windows_init_thread_list ();
1814  ok = DebugActiveProcess (pid);
1815  saw_create = 0;
1816
1817#ifdef __CYGWIN__
1818  if (!ok)
1819    {
1820      /* Try fall back to Cygwin pid.  */
1821      pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1822
1823      if (pid > 0)
1824	ok = DebugActiveProcess (pid);
1825  }
1826#endif
1827
1828  if (!ok)
1829    error (_("Can't attach to process."));
1830
1831  DebugSetProcessKillOnExit (FALSE);
1832
1833  if (from_tty)
1834    {
1835      char *exec_file = (char *) get_exec_file (0);
1836
1837      if (exec_file)
1838	printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1839			   target_pid_to_str (pid_to_ptid (pid)));
1840      else
1841	printf_unfiltered ("Attaching to %s\n",
1842			   target_pid_to_str (pid_to_ptid (pid)));
1843
1844      gdb_flush (gdb_stdout);
1845    }
1846
1847  do_initial_windows_stuff (ops, pid, 1);
1848  target_terminal_ours ();
1849}
1850
1851static void
1852windows_detach (struct target_ops *ops, char *args, int from_tty)
1853{
1854  int detached = 1;
1855
1856  ptid_t ptid = {-1};
1857  windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
1858
1859  if (!DebugActiveProcessStop (current_event.dwProcessId))
1860    {
1861      error (_("Can't detach process %lu (error %lu)"),
1862	     current_event.dwProcessId, GetLastError ());
1863      detached = 0;
1864    }
1865  DebugSetProcessKillOnExit (FALSE);
1866
1867  if (detached && from_tty)
1868    {
1869      char *exec_file = get_exec_file (0);
1870      if (exec_file == 0)
1871	exec_file = "";
1872      printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1873			 current_event.dwProcessId);
1874      gdb_flush (gdb_stdout);
1875    }
1876
1877  inferior_ptid = null_ptid;
1878  detach_inferior (current_event.dwProcessId);
1879
1880  unpush_target (ops);
1881}
1882
1883static char *
1884windows_pid_to_exec_file (int pid)
1885{
1886  static char path[__PMAX];
1887#ifdef __CYGWIN__
1888  /* Try to find exe name as symlink target of /proc/<pid>/exe.  */
1889  int nchars;
1890  char procexe[sizeof ("/proc/4294967295/exe")];
1891  sprintf (procexe, "/proc/%u/exe", pid);
1892  nchars = readlink (procexe, path, sizeof(path));
1893  if (nchars > 0 && nchars < sizeof (path))
1894    {
1895      path[nchars] = '\0';	/* Got it */
1896      return path;
1897    }
1898#endif
1899
1900  /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
1901     of gdb, or we're trying to debug a non-Cygwin windows executable.  */
1902  if (!get_module_name (0, path))
1903    path[0] = '\0';
1904
1905  return path;
1906}
1907
1908/* Print status information about what we're accessing.  */
1909
1910static void
1911windows_files_info (struct target_ops *ignore)
1912{
1913  struct inferior *inf = current_inferior ();
1914
1915  printf_unfiltered ("\tUsing the running image of %s %s.\n",
1916		     inf->attach_flag ? "attached" : "child",
1917		     target_pid_to_str (inferior_ptid));
1918}
1919
1920static void
1921windows_open (char *arg, int from_tty)
1922{
1923  error (_("Use the \"run\" command to start a Unix child process."));
1924}
1925
1926/* Modify CreateProcess parameters for use of a new separate console.
1927   Parameters are:
1928   *FLAGS: DWORD parameter for general process creation flags.
1929   *SI: STARTUPINFO structure, for which the console window size and
1930   console buffer size is filled in if GDB is running in a console.
1931   to create the new console.
1932   The size of the used font is not available on all versions of
1933   Windows OS.  Furthermore, the current font might not be the default
1934   font, but this is still better than before.
1935   If the windows and buffer sizes are computed,
1936   SI->DWFLAGS is changed so that this information is used
1937   by CreateProcess function.  */
1938
1939static void
1940windows_set_console_info (STARTUPINFO *si, DWORD *flags)
1941{
1942  HANDLE hconsole = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
1943				FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1944
1945  if (hconsole != INVALID_HANDLE_VALUE)
1946    {
1947      CONSOLE_SCREEN_BUFFER_INFO sbinfo;
1948      COORD font_size;
1949      CONSOLE_FONT_INFO cfi;
1950
1951      GetCurrentConsoleFont (hconsole, FALSE, &cfi);
1952      font_size = GetConsoleFontSize (hconsole, cfi.nFont);
1953      GetConsoleScreenBufferInfo(hconsole, &sbinfo);
1954      si->dwXSize = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1;
1955      si->dwYSize = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1;
1956      if (font_size.X)
1957	si->dwXSize *= font_size.X;
1958      else
1959	si->dwXSize *= 8;
1960      if (font_size.Y)
1961	si->dwYSize *= font_size.Y;
1962      else
1963	si->dwYSize *= 12;
1964      si->dwXCountChars = sbinfo.dwSize.X;
1965      si->dwYCountChars = sbinfo.dwSize.Y;
1966      si->dwFlags |= STARTF_USESIZE | STARTF_USECOUNTCHARS;
1967    }
1968  *flags |= CREATE_NEW_CONSOLE;
1969}
1970
1971/* Start an inferior windows child process and sets inferior_ptid to its pid.
1972   EXEC_FILE is the file to run.
1973   ALLARGS is a string containing the arguments to the program.
1974   ENV is the environment vector to pass.  Errors reported with error().  */
1975
1976static void
1977windows_create_inferior (struct target_ops *ops, char *exec_file,
1978		       char *allargs, char **in_env, int from_tty)
1979{
1980  STARTUPINFO si;
1981#ifdef __CYGWIN__
1982  cygwin_buf_t real_path[__PMAX];
1983  cygwin_buf_t shell[__PMAX]; /* Path to shell */
1984  const char *sh;
1985  cygwin_buf_t *toexec;
1986  cygwin_buf_t *cygallargs;
1987  cygwin_buf_t *args;
1988  size_t len;
1989  int tty;
1990  int ostdin, ostdout, ostderr;
1991#else
1992  char real_path[__PMAX];
1993  char shell[__PMAX]; /* Path to shell */
1994  char *toexec;
1995  char *args;
1996  HANDLE tty;
1997#endif
1998  PROCESS_INFORMATION pi;
1999  BOOL ret;
2000  DWORD flags = 0;
2001  const char *inferior_io_terminal = get_inferior_io_terminal ();
2002
2003  if (!exec_file)
2004    error (_("No executable specified, use `target exec'."));
2005
2006  memset (&si, 0, sizeof (si));
2007  si.cb = sizeof (si);
2008
2009  if (new_group)
2010    flags |= CREATE_NEW_PROCESS_GROUP;
2011
2012  if (new_console)
2013    windows_set_console_info (&si, &flags);
2014
2015#ifdef __CYGWIN__
2016  if (!useshell)
2017    {
2018      flags |= DEBUG_ONLY_THIS_PROCESS;
2019      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
2020			    __PMAX * sizeof (cygwin_buf_t)) < 0)
2021	error (_("Error starting executable: %d"), errno);
2022      toexec = real_path;
2023#ifdef __USEWIDE
2024      len = mbstowcs (NULL, allargs, 0) + 1;
2025      if (len == (size_t) -1)
2026	error (_("Error starting executable: %d"), errno);
2027      cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
2028      mbstowcs (cygallargs, allargs, len);
2029#else
2030      cygallargs = allargs;
2031#endif
2032    }
2033  else
2034    {
2035      sh = getenv ("SHELL");
2036      if (!sh)
2037	sh = "/bin/sh";
2038      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0)
2039      	error (_("Error starting executable via shell: %d"), errno);
2040#ifdef __USEWIDE
2041      len = sizeof (L" -c 'exec  '") + mbstowcs (NULL, exec_file, 0)
2042	    + mbstowcs (NULL, allargs, 0) + 2;
2043      cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
2044      swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
2045#else
2046      cygallargs = (char *)
2047	alloca (sizeof (" -c 'exec  '") + strlen (exec_file)
2048				    + strlen (allargs) + 2);
2049      sprintf (cygallargs, " -c 'exec %s %s'", exec_file, allargs);
2050#endif
2051      toexec = shell;
2052      flags |= DEBUG_PROCESS;
2053    }
2054
2055#ifdef __USEWIDE
2056  args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
2057				  * sizeof (wchar_t));
2058  wcscpy (args, toexec);
2059  wcscat (args, L" ");
2060  wcscat (args, cygallargs);
2061#else
2062  args = (cygwin_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2);
2063  strcpy (args, toexec);
2064  strcat (args, " ");
2065  strcat (args, cygallargs);
2066#endif
2067
2068  /* Prepare the environment vars for CreateProcess.  */
2069  cygwin_internal (CW_SYNC_WINENV);
2070
2071  if (!inferior_io_terminal)
2072    tty = ostdin = ostdout = ostderr = -1;
2073  else
2074    {
2075      tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
2076      if (tty < 0)
2077	{
2078	  print_sys_errmsg (inferior_io_terminal, errno);
2079	  ostdin = ostdout = ostderr = -1;
2080	}
2081      else
2082	{
2083	  ostdin = dup (0);
2084	  ostdout = dup (1);
2085	  ostderr = dup (2);
2086	  dup2 (tty, 0);
2087	  dup2 (tty, 1);
2088	  dup2 (tty, 2);
2089	}
2090    }
2091
2092  windows_init_thread_list ();
2093  ret = CreateProcess (0,
2094		       args,	/* command line */
2095		       NULL,	/* Security */
2096		       NULL,	/* thread */
2097		       TRUE,	/* inherit handles */
2098		       flags,	/* start flags */
2099		       NULL,	/* environment */
2100		       NULL,	/* current directory */
2101		       &si,
2102		       &pi);
2103  if (tty >= 0)
2104    {
2105      close (tty);
2106      dup2 (ostdin, 0);
2107      dup2 (ostdout, 1);
2108      dup2 (ostderr, 2);
2109      close (ostdin);
2110      close (ostdout);
2111      close (ostderr);
2112    }
2113#else
2114  toexec = exec_file;
2115  args = alloca (strlen (toexec) + strlen (allargs) + 2);
2116  strcpy (args, toexec);
2117  strcat (args, " ");
2118  strcat (args, allargs);
2119
2120  flags |= DEBUG_ONLY_THIS_PROCESS;
2121
2122  if (!inferior_io_terminal)
2123    tty = INVALID_HANDLE_VALUE;
2124  else
2125    {
2126      SECURITY_ATTRIBUTES sa;
2127      sa.nLength = sizeof(sa);
2128      sa.lpSecurityDescriptor = 0;
2129      sa.bInheritHandle = TRUE;
2130      tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE,
2131			 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
2132      if (tty == INVALID_HANDLE_VALUE)
2133	warning (_("Warning: Failed to open TTY %s, error %#x."),
2134		 inferior_io_terminal, (unsigned) GetLastError ());
2135      else
2136	{
2137	  si.hStdInput = tty;
2138	  si.hStdOutput = tty;
2139	  si.hStdError = tty;
2140	  si.dwFlags |= STARTF_USESTDHANDLES;
2141	}
2142    }
2143
2144  windows_init_thread_list ();
2145  ret = CreateProcessA (0,
2146			args,	/* command line */
2147			NULL,	/* Security */
2148			NULL,	/* thread */
2149			TRUE,	/* inherit handles */
2150			flags,	/* start flags */
2151			NULL,	/* environment */
2152			NULL,	/* current directory */
2153			&si,
2154			&pi);
2155  if (tty != INVALID_HANDLE_VALUE)
2156    CloseHandle (tty);
2157#endif
2158
2159  if (!ret)
2160    error (_("Error creating process %s, (error %d)."),
2161	   exec_file, (unsigned) GetLastError ());
2162
2163  CloseHandle (pi.hThread);
2164  CloseHandle (pi.hProcess);
2165
2166  if (useshell && shell[0] != '\0')
2167    saw_create = -1;
2168  else
2169    saw_create = 0;
2170
2171  do_initial_windows_stuff (ops, pi.dwProcessId, 0);
2172
2173  /* windows_continue (DBG_CONTINUE, -1); */
2174}
2175
2176static void
2177windows_mourn_inferior (struct target_ops *ops)
2178{
2179  (void) windows_continue (DBG_CONTINUE, -1);
2180  i386_cleanup_dregs();
2181  if (open_process_used)
2182    {
2183      CHECK (CloseHandle (current_process_handle));
2184      open_process_used = 0;
2185    }
2186  unpush_target (ops);
2187  generic_mourn_inferior ();
2188}
2189
2190/* Send a SIGINT to the process group.  This acts just like the user typed a
2191   ^C on the controlling terminal.  */
2192
2193static void
2194windows_stop (ptid_t ptid)
2195{
2196  DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
2197  CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
2198  registers_changed ();		/* refresh register state */
2199}
2200
2201static int
2202windows_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len,
2203		   int write, struct mem_attrib *mem,
2204		   struct target_ops *target)
2205{
2206  SIZE_T done = 0;
2207  if (write)
2208    {
2209      DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
2210		  len, (DWORD) (uintptr_t) memaddr));
2211      if (!WriteProcessMemory (current_process_handle,
2212			       (LPVOID) (uintptr_t) memaddr, our,
2213			       len, &done))
2214	done = 0;
2215      FlushInstructionCache (current_process_handle,
2216			     (LPCVOID) (uintptr_t) memaddr, len);
2217    }
2218  else
2219    {
2220      DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
2221		  len, (DWORD) (uintptr_t) memaddr));
2222      if (!ReadProcessMemory (current_process_handle,
2223			      (LPCVOID) (uintptr_t) memaddr, our,
2224			      len, &done))
2225	done = 0;
2226    }
2227  return done;
2228}
2229
2230static void
2231windows_kill_inferior (struct target_ops *ops)
2232{
2233  CHECK (TerminateProcess (current_process_handle, 0));
2234
2235  for (;;)
2236    {
2237      if (!windows_continue (DBG_CONTINUE, -1))
2238	break;
2239      if (!WaitForDebugEvent (&current_event, INFINITE))
2240	break;
2241      if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
2242	break;
2243    }
2244
2245  target_mourn_inferior ();	/* Or just windows_mourn_inferior?  */
2246}
2247
2248static void
2249windows_prepare_to_store (struct regcache *regcache)
2250{
2251  /* Do nothing, since we can store individual regs.  */
2252}
2253
2254static int
2255windows_can_run (void)
2256{
2257  return 1;
2258}
2259
2260static void
2261windows_close (int x)
2262{
2263  DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
2264		PIDGET (inferior_ptid)));
2265}
2266
2267/* Convert pid to printable format.  */
2268static char *
2269windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
2270{
2271  static char buf[80];
2272
2273  if (ptid_get_tid (ptid) != 0)
2274    {
2275      snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
2276		ptid_get_pid (ptid), ptid_get_tid (ptid));
2277      return buf;
2278    }
2279
2280  return normal_pid_to_str (ptid);
2281}
2282
2283static LONGEST
2284windows_xfer_shared_libraries (struct target_ops *ops,
2285			     enum target_object object, const char *annex,
2286			     gdb_byte *readbuf, const gdb_byte *writebuf,
2287			     ULONGEST offset, LONGEST len)
2288{
2289  struct obstack obstack;
2290  const char *buf;
2291  LONGEST len_avail;
2292  struct so_list *so;
2293
2294  if (writebuf)
2295    return -1;
2296
2297  obstack_init (&obstack);
2298  obstack_grow_str (&obstack, "<library-list>\n");
2299  for (so = solib_start.next; so; so = so->next)
2300    windows_xfer_shared_library (so->so_name, (CORE_ADDR)
2301				 (uintptr_t) so->lm_info->load_addr,
2302				 target_gdbarch, &obstack);
2303  obstack_grow_str0 (&obstack, "</library-list>\n");
2304
2305  buf = obstack_finish (&obstack);
2306  len_avail = strlen (buf);
2307  if (offset >= len_avail)
2308    return 0;
2309
2310  if (len > len_avail - offset)
2311    len = len_avail - offset;
2312  memcpy (readbuf, buf + offset, len);
2313
2314  obstack_free (&obstack, NULL);
2315  return len;
2316}
2317
2318static LONGEST
2319windows_xfer_partial (struct target_ops *ops, enum target_object object,
2320		    const char *annex, gdb_byte *readbuf,
2321		    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
2322{
2323  switch (object)
2324    {
2325    case TARGET_OBJECT_MEMORY:
2326      if (readbuf)
2327	return (*ops->deprecated_xfer_memory) (offset, readbuf,
2328					       len, 0/*read*/, NULL, ops);
2329      if (writebuf)
2330	return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
2331					       len, 1/*write*/, NULL, ops);
2332      return -1;
2333
2334    case TARGET_OBJECT_LIBRARIES:
2335      return windows_xfer_shared_libraries (ops, object, annex, readbuf,
2336					  writebuf, offset, len);
2337
2338    default:
2339      if (ops->beneath != NULL)
2340	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
2341					      readbuf, writebuf, offset, len);
2342      return -1;
2343    }
2344}
2345
2346/* Provide thread local base, i.e. Thread Information Block address.
2347   Returns 1 if ptid is found and sets *ADDR to thread_local_base.  */
2348
2349static int
2350windows_get_tib_address (ptid_t ptid, CORE_ADDR *addr)
2351{
2352  thread_info *th;
2353
2354  th = thread_rec (ptid_get_tid (ptid), 0);
2355  if (th == NULL)
2356    return 0;
2357
2358  if (addr != NULL)
2359    *addr = th->thread_local_base;
2360
2361  return 1;
2362}
2363
2364static ptid_t
2365windows_get_ada_task_ptid (long lwp, long thread)
2366{
2367  return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
2368}
2369
2370static void
2371init_windows_ops (void)
2372{
2373  windows_ops.to_shortname = "child";
2374  windows_ops.to_longname = "Win32 child process";
2375  windows_ops.to_doc = "Win32 child process (started by the \"run\" command).";
2376  windows_ops.to_open = windows_open;
2377  windows_ops.to_close = windows_close;
2378  windows_ops.to_attach = windows_attach;
2379  windows_ops.to_attach_no_wait = 1;
2380  windows_ops.to_detach = windows_detach;
2381  windows_ops.to_resume = windows_resume;
2382  windows_ops.to_wait = windows_wait;
2383  windows_ops.to_fetch_registers = windows_fetch_inferior_registers;
2384  windows_ops.to_store_registers = windows_store_inferior_registers;
2385  windows_ops.to_prepare_to_store = windows_prepare_to_store;
2386  windows_ops.deprecated_xfer_memory = windows_xfer_memory;
2387  windows_ops.to_xfer_partial = windows_xfer_partial;
2388  windows_ops.to_files_info = windows_files_info;
2389  windows_ops.to_insert_breakpoint = memory_insert_breakpoint;
2390  windows_ops.to_remove_breakpoint = memory_remove_breakpoint;
2391  windows_ops.to_terminal_init = terminal_init_inferior;
2392  windows_ops.to_terminal_inferior = terminal_inferior;
2393  windows_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2394  windows_ops.to_terminal_ours = terminal_ours;
2395  windows_ops.to_terminal_save_ours = terminal_save_ours;
2396  windows_ops.to_terminal_info = child_terminal_info;
2397  windows_ops.to_kill = windows_kill_inferior;
2398  windows_ops.to_create_inferior = windows_create_inferior;
2399  windows_ops.to_mourn_inferior = windows_mourn_inferior;
2400  windows_ops.to_can_run = windows_can_run;
2401  windows_ops.to_thread_alive = windows_thread_alive;
2402  windows_ops.to_pid_to_str = windows_pid_to_str;
2403  windows_ops.to_stop = windows_stop;
2404  windows_ops.to_stratum = process_stratum;
2405  windows_ops.to_has_all_memory = default_child_has_all_memory;
2406  windows_ops.to_has_memory = default_child_has_memory;
2407  windows_ops.to_has_stack = default_child_has_stack;
2408  windows_ops.to_has_registers = default_child_has_registers;
2409  windows_ops.to_has_execution = default_child_has_execution;
2410  windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
2411  windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid;
2412  windows_ops.to_get_tib_address = windows_get_tib_address;
2413
2414  i386_use_watchpoints (&windows_ops);
2415
2416  i386_dr_low.set_control = cygwin_set_dr7;
2417  i386_dr_low.set_addr = cygwin_set_dr;
2418  i386_dr_low.reset_addr = NULL;
2419  i386_dr_low.get_status = cygwin_get_dr6;
2420
2421  /* i386_dr_low.debug_register_length field is set by
2422     calling i386_set_debug_register_length function
2423     in processor windows specific native file.  */
2424
2425  windows_ops.to_magic = OPS_MAGIC;
2426}
2427
2428static void
2429set_windows_aliases (char *argv0)
2430{
2431  add_info_alias ("dll", "sharedlibrary", 1);
2432}
2433
2434void
2435_initialize_windows_nat (void)
2436{
2437  struct cmd_list_element *c;
2438
2439  init_windows_ops ();
2440
2441#ifdef __CYGWIN__
2442  cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
2443#endif
2444
2445  c = add_com ("dll-symbols", class_files, dll_symbol_command,
2446	       _("Load dll library symbols from FILE."));
2447  set_cmd_completer (c, filename_completer);
2448
2449  add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
2450
2451  add_com_alias ("add-shared-symbol-files", "dll-symbols", class_alias, 1);
2452
2453  add_com_alias ("assf", "dll-symbols", class_alias, 1);
2454
2455#ifdef __CYGWIN__
2456  add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
2457Set use of shell to start subprocess."), _("\
2458Show use of shell to start subprocess."), NULL,
2459			   NULL,
2460			   NULL, /* FIXME: i18n: */
2461			   &setlist, &showlist);
2462
2463  add_setshow_boolean_cmd ("cygwin-exceptions", class_support,
2464			   &cygwin_exceptions, _("\
2465Break when an exception is detected in the Cygwin DLL itself."), _("\
2466Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL,
2467			   NULL,
2468			   NULL, /* FIXME: i18n: */
2469			   &setlist, &showlist);
2470#endif
2471
2472  add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
2473Set creation of new console when creating child process."), _("\
2474Show creation of new console when creating child process."), NULL,
2475			   NULL,
2476			   NULL, /* FIXME: i18n: */
2477			   &setlist, &showlist);
2478
2479  add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
2480Set creation of new group when creating child process."), _("\
2481Show creation of new group when creating child process."), NULL,
2482			   NULL,
2483			   NULL, /* FIXME: i18n: */
2484			   &setlist, &showlist);
2485
2486  add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
2487Set whether to display execution in child process."), _("\
2488Show whether to display execution in child process."), NULL,
2489			   NULL,
2490			   NULL, /* FIXME: i18n: */
2491			   &setlist, &showlist);
2492
2493  add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
2494Set whether to display kernel events in child process."), _("\
2495Show whether to display kernel events in child process."), NULL,
2496			   NULL,
2497			   NULL, /* FIXME: i18n: */
2498			   &setlist, &showlist);
2499
2500  add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
2501Set whether to display memory accesses in child process."), _("\
2502Show whether to display memory accesses in child process."), NULL,
2503			   NULL,
2504			   NULL, /* FIXME: i18n: */
2505			   &setlist, &showlist);
2506
2507  add_setshow_boolean_cmd ("debugexceptions", class_support,
2508			   &debug_exceptions, _("\
2509Set whether to display kernel exceptions in child process."), _("\
2510Show whether to display kernel exceptions in child process."), NULL,
2511			   NULL,
2512			   NULL, /* FIXME: i18n: */
2513			   &setlist, &showlist);
2514
2515  init_w32_command_list ();
2516
2517  add_cmd ("selector", class_info, display_selectors,
2518	   _("Display selectors infos."),
2519	   &info_w32_cmdlist);
2520  add_target (&windows_ops);
2521  deprecated_init_ui_hook = set_windows_aliases;
2522}
2523
2524/* Hardware watchpoint support, adapted from go32-nat.c code.  */
2525
2526/* Pass the address ADDR to the inferior in the I'th debug register.
2527   Here we just store the address in dr array, the registers will be
2528   actually set up when windows_continue is called.  */
2529static void
2530cygwin_set_dr (int i, CORE_ADDR addr)
2531{
2532  if (i < 0 || i > 3)
2533    internal_error (__FILE__, __LINE__,
2534		    _("Invalid register %d in cygwin_set_dr.\n"), i);
2535  dr[i] = addr;
2536  debug_registers_changed = 1;
2537  debug_registers_used = 1;
2538}
2539
2540/* Pass the value VAL to the inferior in the DR7 debug control
2541   register.  Here we just store the address in D_REGS, the watchpoint
2542   will be actually set up in windows_wait.  */
2543static void
2544cygwin_set_dr7 (unsigned long val)
2545{
2546  dr[7] = (CORE_ADDR) val;
2547  debug_registers_changed = 1;
2548  debug_registers_used = 1;
2549}
2550
2551/* Get the value of the DR6 debug status register from the inferior.
2552   Here we just return the value stored in dr[6]
2553   by the last call to thread_rec for current_event.dwThreadId id.  */
2554static unsigned long
2555cygwin_get_dr6 (void)
2556{
2557  return (unsigned long) dr[6];
2558}
2559
2560/* Determine if the thread referenced by "ptid" is alive
2561   by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
2562   it means that the thread has died.  Otherwise it is assumed to be alive.  */
2563static int
2564windows_thread_alive (struct target_ops *ops, ptid_t ptid)
2565{
2566  int tid;
2567
2568  gdb_assert (ptid_get_tid (ptid) != 0);
2569  tid = ptid_get_tid (ptid);
2570
2571  return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0
2572    ? FALSE : TRUE;
2573}
2574
2575void
2576_initialize_check_for_gdb_ini (void)
2577{
2578  char *homedir;
2579  if (inhibit_gdbinit)
2580    return;
2581
2582  homedir = getenv ("HOME");
2583  if (homedir)
2584    {
2585      char *p;
2586      char *oldini = (char *) alloca (strlen (homedir) +
2587				      sizeof ("/gdb.ini"));
2588      strcpy (oldini, homedir);
2589      p = strchr (oldini, '\0');
2590      if (p > oldini && !IS_DIR_SEPARATOR (p[-1]))
2591	*p++ = '/';
2592      strcpy (p, "gdb.ini");
2593      if (access (oldini, 0) == 0)
2594	{
2595	  int len = strlen (oldini);
2596	  char *newini = alloca (len + 1);
2597	  sprintf (newini, "%.*s.gdbinit",
2598	    (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2599	  warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
2600	}
2601    }
2602}
2603
2604/* Define dummy functions which always return error for the rare cases where
2605   these functions could not be found.  */
2606static BOOL WINAPI
2607bad_DebugActiveProcessStop (DWORD w)
2608{
2609  return FALSE;
2610}
2611static BOOL WINAPI
2612bad_DebugBreakProcess (HANDLE w)
2613{
2614  return FALSE;
2615}
2616static BOOL WINAPI
2617bad_DebugSetProcessKillOnExit (BOOL w)
2618{
2619  return FALSE;
2620}
2621static BOOL WINAPI
2622bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
2623{
2624  return FALSE;
2625}
2626
2627#ifdef __USEWIDE
2628static DWORD WINAPI
2629bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
2630{
2631  return 0;
2632}
2633#else
2634static DWORD WINAPI
2635bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
2636{
2637  return 0;
2638}
2639#endif
2640
2641static BOOL WINAPI
2642bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
2643{
2644  return FALSE;
2645}
2646
2647static BOOL WINAPI
2648bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
2649{
2650  return FALSE;
2651}
2652
2653static BOOL WINAPI
2654bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
2655{
2656  f->nFont = 0;
2657  return 1;
2658}
2659static COORD WINAPI
2660bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
2661{
2662  COORD size;
2663  size.X = 8;
2664  size.Y = 12;
2665  return size;
2666}
2667
2668/* Load any functions which may not be available in ancient versions
2669   of Windows.  */
2670void
2671_initialize_loadable (void)
2672{
2673  HMODULE hm = NULL;
2674
2675  hm = LoadLibrary ("kernel32.dll");
2676  if (hm)
2677    {
2678      DebugActiveProcessStop = (void *)
2679	GetProcAddress (hm, "DebugActiveProcessStop");
2680      DebugBreakProcess = (void *)
2681	GetProcAddress (hm, "DebugBreakProcess");
2682      DebugSetProcessKillOnExit = (void *)
2683	GetProcAddress (hm, "DebugSetProcessKillOnExit");
2684      GetConsoleFontSize = (void *)
2685	GetProcAddress (hm, "GetConsoleFontSize");
2686      GetCurrentConsoleFont = (void *)
2687	GetProcAddress (hm, "GetCurrentConsoleFont");
2688    }
2689
2690  /* Set variables to dummy versions of these processes if the function
2691     wasn't found in kernel32.dll.  */
2692  if (!DebugBreakProcess)
2693    DebugBreakProcess = bad_DebugBreakProcess;
2694  if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
2695    {
2696      DebugActiveProcessStop = bad_DebugActiveProcessStop;
2697      DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
2698    }
2699  if (!GetConsoleFontSize)
2700    GetConsoleFontSize = bad_GetConsoleFontSize;
2701  if (!GetCurrentConsoleFont)
2702    GetCurrentConsoleFont = bad_GetCurrentConsoleFont;
2703
2704  /* Load optional functions used for retrieving filename information
2705     associated with the currently debugged process or its dlls.  */
2706  hm = LoadLibrary ("psapi.dll");
2707  if (hm)
2708    {
2709      EnumProcessModules = (void *)
2710	GetProcAddress (hm, "EnumProcessModules");
2711      GetModuleInformation = (void *)
2712	GetProcAddress (hm, "GetModuleInformation");
2713      GetModuleFileNameEx = (void *)
2714	GetProcAddress (hm, GetModuleFileNameEx_name);
2715    }
2716
2717  if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx)
2718    {
2719      /* Set variables to dummy versions of these processes if the function
2720	 wasn't found in psapi.dll.  */
2721      EnumProcessModules = bad_EnumProcessModules;
2722      GetModuleInformation = bad_GetModuleInformation;
2723      GetModuleFileNameEx = bad_GetModuleFileNameEx;
2724      /* This will probably fail on Windows 9x/Me.  Let the user know
2725	 that we're missing some functionality.  */
2726      warning(_("\
2727cannot automatically find executable file or library to read symbols.\n\
2728Use \"file\" or \"dll\" command to load executable/libraries directly."));
2729    }
2730
2731  hm = LoadLibrary ("advapi32.dll");
2732  if (hm)
2733    {
2734      OpenProcessToken = (void *) GetProcAddress (hm, "OpenProcessToken");
2735      LookupPrivilegeValueA = (void *)
2736	GetProcAddress (hm, "LookupPrivilegeValueA");
2737      AdjustTokenPrivileges = (void *)
2738	GetProcAddress (hm, "AdjustTokenPrivileges");
2739      /* Only need to set one of these since if OpenProcessToken fails nothing
2740	 else is needed.  */
2741      if (!OpenProcessToken || !LookupPrivilegeValueA
2742	  || !AdjustTokenPrivileges)
2743	OpenProcessToken = bad_OpenProcessToken;
2744    }
2745}
2746