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 
82 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
83 					    DWORD, PTOKEN_PRIVILEGES, PDWORD);
84 static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
85 static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
86 static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
87 static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
88 					  LPDWORD);
89 static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
90 					    DWORD);
91 static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
92 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
93 static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL,
94 					     CONSOLE_FONT_INFO *);
95 static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
96 
97 static 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 
141 static int have_saved_context;	/* True if we've saved context from a
142 				   cygwin signal.  */
143 static 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
150 enum
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 
166 static uintptr_t dr[8];
167 static int debug_registers_changed;
168 static int debug_registers_used;
169 
170 static 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 
185 static void windows_stop (ptid_t);
186 static int windows_thread_alive (struct target_ops *, ptid_t);
187 static void windows_kill_inferior (struct target_ops *);
188 
189 static void cygwin_set_dr (int i, CORE_ADDR addr);
190 static void cygwin_set_dr7 (unsigned long val);
191 static unsigned long cygwin_get_dr6 (void);
192 
193 static 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.  */
198 typedef 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   }
210 thread_info;
211 
212 static thread_info thread_head;
213 
214 /* The process and thread handles for the above context.  */
215 
216 static DEBUG_EVENT current_event;	/* The current debug event from
217 					   WaitForDebugEvent */
218 static HANDLE current_process_handle;	/* Currently executing process */
219 static thread_info *current_thread;	/* Info on currently selected thread */
220 static DWORD main_thread_id;		/* Thread ID of the main thread */
221 
222 /* Counts of things.  */
223 static int exception_count = 0;
224 static int event_count = 0;
225 static int saw_create;
226 static int open_process_used = 0;
227 
228 /* User options.  */
229 static int new_console = 0;
230 #ifdef __CYGWIN__
231 static int cygwin_exceptions = 0;
232 #endif
233 static int new_group = 1;
234 static int debug_exec = 0;		/* show execution */
235 static int debug_events = 0;		/* show events from kernel */
236 static int debug_memory = 0;		/* show target memory accesses */
237 static int debug_exceptions = 0;	/* show target exceptions */
238 static 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 
258 static 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 
263 struct xlate_exception
264   {
265     int them;
266     enum target_signal us;
267   };
268 
269 static 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 
283 void
windows_set_context_register_offsets(const int * offsets)284 windows_set_context_register_offsets (const int *offsets)
285 {
286   mappings = offsets;
287 }
288 
289 static void
check(BOOL ok,const char * file,int line)290 check (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.  */
300 static thread_info *
thread_rec(DWORD id,int get_context)301 thread_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.  */
332 static thread_info *
windows_add_thread(ptid_t ptid,HANDLE h,void * tlb)333 windows_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.  */
372 static void
windows_init_thread_list(void)373 windows_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.  */
389 static void
windows_delete_thread(ptid_t ptid)390 windows_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 
416 static void
do_windows_fetch_inferior_registers(struct regcache * regcache,int r)417 do_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 
482 static void
windows_fetch_inferior_registers(struct target_ops * ops,struct regcache * regcache,int r)483 windows_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 
493 static void
do_windows_store_inferior_registers(const struct regcache * regcache,int r)494 do_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.  */
509 static void
windows_store_inferior_registers(struct target_ops * ops,struct regcache * regcache,int r)510 windows_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).  */
523 static int
get_module_name(LPVOID base_address,char * dll_name_ret)524 get_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 
587 failed:
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.  */
594 struct 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.  */
606 struct lm_info
607 {
608   LPVOID load_addr;
609 };
610 
611 static 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.  */
615 static int
safe_symbol_file_add_stub(void * argv)616 safe_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.  */
627 static void
safe_symbol_file_add_cleanup(void * p)628 safe_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.  */
641 static struct objfile *
safe_symbol_file_add(char * name,int from_tty,struct section_addr_info * addrs,int mainline,int flags)642 safe_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 
668 static struct so_list *
windows_make_so(const char * name,LPVOID load_addr)669 windows_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 
777 static char *
get_image_name(HANDLE h,void * address,int unicode)778 get_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.  */
829 static int
handle_load_dll(void * dummy)830 handle_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 
858 static void
windows_free_so(struct so_list * so)859 windows_free_so (struct so_list *so)
860 {
861   if (so->lm_info)
862     xfree (so->lm_info);
863   xfree (so);
864 }
865 
866 static int
handle_unload_dll(void * dummy)867 handle_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.  */
900 static void
windows_clear_solib(void)901 windows_clear_solib (void)
902 {
903   solib_start.next = NULL;
904   solib_end = &solib_start;
905 }
906 
907 /* Load DLL symbol info.  */
908 void
dll_symbol_command(char * args,int from_tty)909 dll_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.  */
932 static int
handle_output_debug_string(struct target_waitstatus * ourstatus)933 handle_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 
989 static int
display_selector(HANDLE thread,DWORD sel)990 display_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 
1065 static void
display_selectors(char * args,int from_tty)1066 display_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 
1109 static int
handle_exception(struct target_waitstatus * ourstatus)1110 handle_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.  */
1238 static BOOL
windows_continue(DWORD continue_status,int id)1239 windows_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.  */
1284 static DWORD
fake_create_process(void)1285 fake_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 
1306 static void
windows_resume(struct target_ops * ops,ptid_t ptid,int step,enum target_signal sig)1307 windows_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.  */
1403 BOOL WINAPI
ctrl_c_handler(DWORD event_type)1404 ctrl_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).  */
1427 static int
get_windows_debug_event(struct target_ops * ops,int pid,struct target_waitstatus * ourstatus)1428 get_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 
1621 out:
1622   return retval;
1623 }
1624 
1625 /* Wait for interesting events to occur in the target process.  */
1626 static ptid_t
windows_wait(struct target_ops * ops,ptid_t ptid,struct target_waitstatus * ourstatus,int options)1627 windows_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 
1689 static void
do_initial_windows_stuff(struct target_ops * ops,DWORD pid,int attaching)1690 do_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.  */
1754 static int
set_process_privilege(const char * privilege,BOOL enable)1755 set_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 
1790 out:
1791   if (token_hdl)
1792     CloseHandle (token_hdl);
1793 
1794   return ret;
1795 }
1796 
1797 /* Attach to process PID, then initialize for debugging it.  */
1798 static void
windows_attach(struct target_ops * ops,char * args,int from_tty)1799 windows_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 
1851 static void
windows_detach(struct target_ops * ops,char * args,int from_tty)1852 windows_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 
1883 static char *
windows_pid_to_exec_file(int pid)1884 windows_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 
1910 static void
windows_files_info(struct target_ops * ignore)1911 windows_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 
1920 static void
windows_open(char * arg,int from_tty)1921 windows_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 
1939 static void
windows_set_console_info(STARTUPINFO * si,DWORD * flags)1940 windows_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 
1976 static void
windows_create_inferior(struct target_ops * ops,char * exec_file,char * allargs,char ** in_env,int from_tty)1977 windows_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 
2176 static void
windows_mourn_inferior(struct target_ops * ops)2177 windows_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 
2193 static void
windows_stop(ptid_t ptid)2194 windows_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 
2201 static int
windows_xfer_memory(CORE_ADDR memaddr,gdb_byte * our,int len,int write,struct mem_attrib * mem,struct target_ops * target)2202 windows_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 
2230 static void
windows_kill_inferior(struct target_ops * ops)2231 windows_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 
2248 static void
windows_prepare_to_store(struct regcache * regcache)2249 windows_prepare_to_store (struct regcache *regcache)
2250 {
2251   /* Do nothing, since we can store individual regs.  */
2252 }
2253 
2254 static int
windows_can_run(void)2255 windows_can_run (void)
2256 {
2257   return 1;
2258 }
2259 
2260 static void
windows_close(int x)2261 windows_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.  */
2268 static char *
windows_pid_to_str(struct target_ops * ops,ptid_t ptid)2269 windows_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 
2283 static LONGEST
windows_xfer_shared_libraries(struct target_ops * ops,enum target_object object,const char * annex,gdb_byte * readbuf,const gdb_byte * writebuf,ULONGEST offset,LONGEST len)2284 windows_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 
2318 static LONGEST
windows_xfer_partial(struct target_ops * ops,enum target_object object,const char * annex,gdb_byte * readbuf,const gdb_byte * writebuf,ULONGEST offset,LONGEST len)2319 windows_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 
2349 static int
windows_get_tib_address(ptid_t ptid,CORE_ADDR * addr)2350 windows_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 
2364 static ptid_t
windows_get_ada_task_ptid(long lwp,long thread)2365 windows_get_ada_task_ptid (long lwp, long thread)
2366 {
2367   return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
2368 }
2369 
2370 static void
init_windows_ops(void)2371 init_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 
2428 static void
set_windows_aliases(char * argv0)2429 set_windows_aliases (char *argv0)
2430 {
2431   add_info_alias ("dll", "sharedlibrary", 1);
2432 }
2433 
2434 void
_initialize_windows_nat(void)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, _("\
2457 Set use of shell to start subprocess."), _("\
2458 Show 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, _("\
2465 Break when an exception is detected in the Cygwin DLL itself."), _("\
2466 Show 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, _("\
2473 Set creation of new console when creating child process."), _("\
2474 Show 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, _("\
2480 Set creation of new group when creating child process."), _("\
2481 Show 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, _("\
2487 Set whether to display execution in child process."), _("\
2488 Show 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, _("\
2494 Set whether to display kernel events in child process."), _("\
2495 Show 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, _("\
2501 Set whether to display memory accesses in child process."), _("\
2502 Show 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, _("\
2509 Set whether to display kernel exceptions in child process."), _("\
2510 Show 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.  */
2529 static void
cygwin_set_dr(int i,CORE_ADDR addr)2530 cygwin_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.  */
2543 static void
cygwin_set_dr7(unsigned long val)2544 cygwin_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.  */
2554 static unsigned long
cygwin_get_dr6(void)2555 cygwin_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.  */
2563 static int
windows_thread_alive(struct target_ops * ops,ptid_t ptid)2564 windows_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 
2575 void
_initialize_check_for_gdb_ini(void)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.  */
2606 static BOOL WINAPI
bad_DebugActiveProcessStop(DWORD w)2607 bad_DebugActiveProcessStop (DWORD w)
2608 {
2609   return FALSE;
2610 }
2611 static BOOL WINAPI
bad_DebugBreakProcess(HANDLE w)2612 bad_DebugBreakProcess (HANDLE w)
2613 {
2614   return FALSE;
2615 }
2616 static BOOL WINAPI
bad_DebugSetProcessKillOnExit(BOOL w)2617 bad_DebugSetProcessKillOnExit (BOOL w)
2618 {
2619   return FALSE;
2620 }
2621 static BOOL WINAPI
bad_EnumProcessModules(HANDLE w,HMODULE * x,DWORD y,LPDWORD z)2622 bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
2623 {
2624   return FALSE;
2625 }
2626 
2627 #ifdef __USEWIDE
2628 static DWORD WINAPI
bad_GetModuleFileNameExW(HANDLE w,HMODULE x,LPWSTR y,DWORD z)2629 bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
2630 {
2631   return 0;
2632 }
2633 #else
2634 static DWORD WINAPI
bad_GetModuleFileNameExA(HANDLE w,HMODULE x,LPSTR y,DWORD z)2635 bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
2636 {
2637   return 0;
2638 }
2639 #endif
2640 
2641 static BOOL WINAPI
bad_GetModuleInformation(HANDLE w,HMODULE x,LPMODULEINFO y,DWORD z)2642 bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
2643 {
2644   return FALSE;
2645 }
2646 
2647 static BOOL WINAPI
bad_OpenProcessToken(HANDLE w,DWORD x,PHANDLE y)2648 bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
2649 {
2650   return FALSE;
2651 }
2652 
2653 static BOOL WINAPI
bad_GetCurrentConsoleFont(HANDLE w,BOOL bMaxWindow,CONSOLE_FONT_INFO * f)2654 bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
2655 {
2656   f->nFont = 0;
2657   return 1;
2658 }
2659 static COORD WINAPI
bad_GetConsoleFontSize(HANDLE w,DWORD nFont)2660 bad_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.  */
2670 void
_initialize_loadable(void)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(_("\
2727 cannot automatically find executable file or library to read symbols.\n\
2728 Use \"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