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