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