2011-05-09 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.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 ();
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 }
This page took 0.084681 seconds and 5 git commands to generate.