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