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