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