guile: Add 'history-append!' procedure.
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
CommitLineData
dc05df57 1/* Target-vector operations for controlling windows child processes, for GDB.
0a65a603 2
ecd75fc8 3 Copyright (C) 1995-2014 Free Software Foundation, Inc.
0a65a603 4
e6433c28 5 Contributed by Cygnus Solutions, A Red Hat Company.
e88c49c3 6
24e60978
SC
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
24e60978
SC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
a9762ec7 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
24e60978
SC
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24e60978 21
dfe7f3ac 22/* Originally by Steve Chamberlain, sac@cygnus.com */
24e60978
SC
23
24#include "defs.h"
25#include "frame.h" /* required by inferior.h */
26#include "inferior.h"
27#include "target.h"
60250e8b 28#include "exceptions.h"
24e60978
SC
29#include "gdbcore.h"
30#include "command.h"
fa58ee11 31#include "completer.h"
4e052eda 32#include "regcache.h"
2a3d5645 33#include "top.h"
403d9909
CF
34#include <signal.h>
35#include <sys/types.h>
36#include <fcntl.h>
37#include <stdlib.h>
38#include <windows.h>
39#include <imagehlp.h>
2b008701 40#include <psapi.h>
10325bc5 41#ifdef __CYGWIN__
b7ff339d 42#include <wchar.h>
403d9909 43#include <sys/cygwin.h>
b7ff339d 44#include <cygwin/version.h>
10325bc5 45#endif
cad9cd60 46
24e60978 47#include "buildsym.h"
0ba1096a 48#include "filenames.h"
1ef980b9
SC
49#include "symfile.h"
50#include "objfiles.h"
92107356 51#include "gdb_bfd.h"
de1b3c3d 52#include "gdb_obstack.h"
0e9f083f 53#include <string.h>
fdfa3315 54#include "gdbthread.h"
24e60978 55#include "gdbcmd.h"
1e37c281 56#include <unistd.h>
4646aa9d 57#include "exec.h"
3ee6f623 58#include "solist.h"
3cb8e7f6 59#include "solib.h"
de1b3c3d 60#include "xml-support.h"
24e60978 61
6c7de422
MK
62#include "i386-tdep.h"
63#include "i387-tdep.h"
64
31b060a2
CF
65#include "windows-tdep.h"
66#include "windows-nat.h"
9bb9e8ad 67#include "i386-nat.h"
ecc13e53 68#include "complaints.h"
de1b3c3d 69
418c6cb3 70#define AdjustTokenPrivileges dyn_AdjustTokenPrivileges
2b008701
CF
71#define DebugActiveProcessStop dyn_DebugActiveProcessStop
72#define DebugBreakProcess dyn_DebugBreakProcess
73#define DebugSetProcessKillOnExit dyn_DebugSetProcessKillOnExit
74#define EnumProcessModules dyn_EnumProcessModules
2b008701 75#define GetModuleInformation dyn_GetModuleInformation
418c6cb3
CF
76#define LookupPrivilegeValueA dyn_LookupPrivilegeValueA
77#define OpenProcessToken dyn_OpenProcessToken
cd44747c
PM
78#define GetConsoleFontSize dyn_GetConsoleFontSize
79#define GetCurrentConsoleFont dyn_GetCurrentConsoleFont
2b008701 80
418c6cb3
CF
81static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
82 DWORD, PTOKEN_PRIVILEGES, PDWORD);
2b008701
CF
83static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
84static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
85static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
86static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
87 LPDWORD);
2b008701
CF
88static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
89 DWORD);
418c6cb3
CF
90static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
91static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
581e13c1
MS
92static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL,
93 CONSOLE_FONT_INFO *);
cd44747c 94static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
2b008701 95
dc05df57 96static struct target_ops windows_ops;
3ee6f623 97
b3c613f2
CF
98#undef STARTUPINFO
99#undef CreateProcess
100#undef GetModuleFileNameEx
101
102#ifndef __CYGWIN__
103# define __PMAX (MAX_PATH + 1)
104 static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD);
105# define STARTUPINFO STARTUPINFOA
106# define CreateProcess CreateProcessA
107# define GetModuleFileNameEx_name "GetModuleFileNameExA"
108# define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
109#else
110# define __PMAX PATH_MAX
581e13c1 111/* The starting and ending address of the cygwin1.dll text segment. */
b3c613f2
CF
112 static CORE_ADDR cygwin_load_start;
113 static CORE_ADDR cygwin_load_end;
b3c613f2
CF
114# define __USEWIDE
115 typedef wchar_t cygwin_buf_t;
581e13c1
MS
116 static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE,
117 LPWSTR, DWORD);
b3c613f2
CF
118# define STARTUPINFO STARTUPINFOW
119# define CreateProcess CreateProcessW
120# define GetModuleFileNameEx_name "GetModuleFileNameExW"
121# define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
10325bc5 122#endif
a244bdca 123
581e13c1
MS
124static int have_saved_context; /* True if we've saved context from a
125 cygwin signal. */
126static CONTEXT saved_context; /* Containes the saved context from a
127 cygwin signal. */
a244bdca 128
0714f9bf
SS
129/* If we're not using the old Cygwin header file set, define the
130 following which never should have been in the generic Win32 API
581e13c1 131 headers in the first place since they were our own invention... */
0714f9bf 132#ifndef _GNU_H_WINDOWS_H
9d3789f7 133enum
8e860359
CF
134 {
135 FLAG_TRACE_BIT = 0x100,
136 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
137 };
0714f9bf
SS
138#endif
139
5851ab76
JB
140#ifndef CONTEXT_EXTENDED_REGISTERS
141/* This macro is only defined on ia32. It only makes sense on this target,
142 so define it as zero if not already defined. */
143#define CONTEXT_EXTENDED_REGISTERS 0
144#endif
145
fa4ba8da
PM
146#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
147 | CONTEXT_EXTENDED_REGISTERS
97da3b20 148
41b4aadc 149static uintptr_t dr[8];
87a45c96
CF
150static int debug_registers_changed;
151static int debug_registers_used;
16d905e2
CF
152
153static int windows_initialization_done;
6537bb24 154#define DR6_CLEAR_VALUE 0xffff0ff0
97da3b20 155
3cee93ac 156/* The string sent by cygwin when it processes a signal.
581e13c1 157 FIXME: This should be in a cygwin include file. */
3929abe9
CF
158#ifndef _CYGWIN_SIGNAL_STRING
159#define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
160#endif
3cee93ac 161
29fe111d 162#define CHECK(x) check (x, __FILE__,__LINE__)
dfe7f3ac 163#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
4e52d31c
PM
164#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
165#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
166#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
24e60978 167
1eab8a48 168static void windows_stop (struct target_ops *self, ptid_t);
02529b48 169static int windows_thread_alive (struct target_ops *, ptid_t);
7d85a9c0 170static void windows_kill_inferior (struct target_ops *);
3cee93ac 171
9bb9e8ad
PM
172static void cygwin_set_dr (int i, CORE_ADDR addr);
173static void cygwin_set_dr7 (unsigned long val);
a961bc18 174static CORE_ADDR cygwin_get_dr (int i);
9bb9e8ad 175static unsigned long cygwin_get_dr6 (void);
a961bc18 176static unsigned long cygwin_get_dr7 (void);
9bb9e8ad 177
a493e3e2 178static enum gdb_signal last_sig = GDB_SIGNAL_0;
581e13c1 179/* Set if a signal was received from the debugged process. */
7393af7c 180
3cee93ac 181/* Thread information structure used to track information that is
6537bb24 182 not available in gdb's thread structure. */
3cee93ac 183typedef struct thread_info_struct
3a4b77d8
JM
184 {
185 struct thread_info_struct *next;
186 DWORD id;
187 HANDLE h;
711e434b 188 CORE_ADDR thread_local_base;
3a4b77d8 189 char *name;
6537bb24 190 int suspended;
3ade5333 191 int reload_context;
3a4b77d8 192 CONTEXT context;
1e37c281 193 STACKFRAME sf;
8e860359
CF
194 }
195thread_info;
1e37c281 196
29fe111d 197static thread_info thread_head;
24e60978 198
581e13c1 199/* The process and thread handles for the above context. */
24e60978 200
3cee93ac
CF
201static DEBUG_EVENT current_event; /* The current debug event from
202 WaitForDebugEvent */
203static HANDLE current_process_handle; /* Currently executing process */
204static thread_info *current_thread; /* Info on currently selected thread */
349b409f 205static DWORD main_thread_id; /* Thread ID of the main thread */
24e60978 206
581e13c1 207/* Counts of things. */
24e60978
SC
208static int exception_count = 0;
209static int event_count = 0;
dfe7f3ac 210static int saw_create;
bf25528d 211static int open_process_used = 0;
24e60978 212
581e13c1 213/* User options. */
24e60978 214static int new_console = 0;
10325bc5 215#ifdef __CYGWIN__
09280ddf 216static int cygwin_exceptions = 0;
10325bc5 217#endif
1e37c281 218static int new_group = 1;
dfe7f3ac
CF
219static int debug_exec = 0; /* show execution */
220static int debug_events = 0; /* show events from kernel */
221static int debug_memory = 0; /* show target memory accesses */
1ef980b9 222static int debug_exceptions = 0; /* show target exceptions */
dfe7f3ac
CF
223static int useshell = 0; /* use shell for subprocesses */
224
7e63b4e4 225/* This vector maps GDB's idea of a register's number into an offset
dc05df57 226 in the windows exception context vector.
24e60978 227
3cee93ac 228 It also contains the bit mask needed to load the register in question.
24e60978 229
7e63b4e4
JB
230 The contents of this table can only be computed by the units
231 that provide CPU-specific support for Windows native debugging.
232 These units should set the table by calling
dc05df57 233 windows_set_context_register_offsets.
7e63b4e4 234
24e60978
SC
235 One day we could read a reg, we could inspect the context we
236 already have loaded, if it doesn't have the bit set that we need,
237 we read that set of registers in using GetThreadContext. If the
581e13c1 238 context already contains what we need, we just unpack it. Then to
24e60978
SC
239 write a register, first we have to ensure that the context contains
240 the other regs of the group, and then we copy the info in and set
581e13c1 241 out bit. */
24e60978 242
7e63b4e4 243static const int *mappings;
d3a09475 244
d40dc7a8
JB
245/* The function to use in order to determine whether a register is
246 a segment register or not. */
247static segment_register_p_ftype *segment_register_p;
248
24e60978 249/* This vector maps the target's idea of an exception (extracted
581e13c1 250 from the DEBUG_EVENT structure) to GDB's idea. */
24e60978
SC
251
252struct xlate_exception
253 {
254 int them;
2ea28649 255 enum gdb_signal us;
24e60978
SC
256 };
257
24e60978
SC
258static const struct xlate_exception
259 xlate[] =
260{
a493e3e2
PA
261 {EXCEPTION_ACCESS_VIOLATION, GDB_SIGNAL_SEGV},
262 {STATUS_STACK_OVERFLOW, GDB_SIGNAL_SEGV},
263 {EXCEPTION_BREAKPOINT, GDB_SIGNAL_TRAP},
264 {DBG_CONTROL_C, GDB_SIGNAL_INT},
265 {EXCEPTION_SINGLE_STEP, GDB_SIGNAL_TRAP},
266 {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE},
24e60978
SC
267 {-1, -1}};
268
7e63b4e4
JB
269/* Set the MAPPINGS static global to OFFSETS.
270 See the description of MAPPINGS for more details. */
271
272void
dc05df57 273windows_set_context_register_offsets (const int *offsets)
7e63b4e4
JB
274{
275 mappings = offsets;
276}
277
d40dc7a8
JB
278/* See windows-nat.h. */
279
280void
281windows_set_segment_register_p (segment_register_p_ftype *fun)
282{
283 segment_register_p = fun;
284}
285
fa4ba8da
PM
286static void
287check (BOOL ok, const char *file, int line)
288{
289 if (!ok)
d50a0ce2
CV
290 printf_filtered ("error return %s:%d was %u\n", file, line,
291 (unsigned) GetLastError ());
fa4ba8da
PM
292}
293
6537bb24
PA
294/* Find a thread record given a thread id. If GET_CONTEXT is not 0,
295 then also retrieve the context for this thread. If GET_CONTEXT is
296 negative, then don't suspend the thread. */
3cee93ac
CF
297static thread_info *
298thread_rec (DWORD id, int get_context)
24e60978 299{
3cee93ac
CF
300 thread_info *th;
301
3a4b77d8 302 for (th = &thread_head; (th = th->next) != NULL;)
3cee93ac
CF
303 if (th->id == id)
304 {
6537bb24 305 if (!th->suspended && get_context)
3cee93ac 306 {
8a892701 307 if (get_context > 0 && id != current_event.dwThreadId)
6537bb24
PA
308 {
309 if (SuspendThread (th->h) == (DWORD) -1)
310 {
311 DWORD err = GetLastError ();
22128028 312
80e88e1a 313 warning (_("SuspendThread (tid=0x%x) failed."
2ed3e009 314 " (winerr %u)"),
80e88e1a 315 (unsigned) id, (unsigned) err);
6537bb24
PA
316 return NULL;
317 }
318 th->suspended = 1;
319 }
3cee93ac 320 else if (get_context < 0)
6537bb24 321 th->suspended = -1;
3ade5333 322 th->reload_context = 1;
3cee93ac
CF
323 }
324 return th;
325 }
326
327 return NULL;
328}
329
2dc38344 330/* Add a thread to the thread list. */
3cee93ac 331static thread_info *
711e434b 332windows_add_thread (ptid_t ptid, HANDLE h, void *tlb)
3cee93ac
CF
333{
334 thread_info *th;
2dc38344
PA
335 DWORD id;
336
337 gdb_assert (ptid_get_tid (ptid) != 0);
338
339 id = ptid_get_tid (ptid);
3cee93ac
CF
340
341 if ((th = thread_rec (id, FALSE)))
342 return th;
343
41bf6aca 344 th = XCNEW (thread_info);
3cee93ac
CF
345 th->id = id;
346 th->h = h;
711e434b 347 th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
3cee93ac
CF
348 th->next = thread_head.next;
349 thread_head.next = th;
2dc38344
PA
350 add_thread (ptid);
351 /* Set the debug registers for the new thread if they are used. */
fa4ba8da
PM
352 if (debug_registers_used)
353 {
354 /* Only change the value of the debug registers. */
355 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
356 CHECK (GetThreadContext (th->h, &th->context));
357 th->context.Dr0 = dr[0];
358 th->context.Dr1 = dr[1];
359 th->context.Dr2 = dr[2];
360 th->context.Dr3 = dr[3];
6537bb24 361 th->context.Dr6 = DR6_CLEAR_VALUE;
fa4ba8da
PM
362 th->context.Dr7 = dr[7];
363 CHECK (SetThreadContext (th->h, &th->context));
364 th->context.ContextFlags = 0;
365 }
3cee93ac 366 return th;
24e60978
SC
367}
368
3cee93ac 369/* Clear out any old thread list and reintialize it to a
581e13c1 370 pristine state. */
24e60978 371static void
dc05df57 372windows_init_thread_list (void)
24e60978 373{
3cee93ac
CF
374 thread_info *th = &thread_head;
375
dc05df57 376 DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
3cee93ac
CF
377 init_thread_list ();
378 while (th->next != NULL)
24e60978 379 {
3cee93ac
CF
380 thread_info *here = th->next;
381 th->next = here->next;
b8c9b27d 382 xfree (here);
24e60978 383 }
059198c1 384 thread_head.next = NULL;
3cee93ac
CF
385}
386
581e13c1 387/* Delete a thread from the list of threads. */
3cee93ac 388static void
e0ea48a0 389windows_delete_thread (ptid_t ptid, DWORD exit_code)
3cee93ac
CF
390{
391 thread_info *th;
2dc38344
PA
392 DWORD id;
393
394 gdb_assert (ptid_get_tid (ptid) != 0);
395
396 id = ptid_get_tid (ptid);
3cee93ac
CF
397
398 if (info_verbose)
2dc38344 399 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid));
e0ea48a0
EZ
400 else if (print_thread_events && id != main_thread_id)
401 printf_unfiltered (_("[%s exited with code %u]\n"),
564eac42 402 target_pid_to_str (ptid), (unsigned) exit_code);
2dc38344 403 delete_thread (ptid);
3cee93ac
CF
404
405 for (th = &thread_head;
406 th->next != NULL && th->next->id != id;
407 th = th->next)
408 continue;
409
410 if (th->next != NULL)
24e60978 411 {
3cee93ac
CF
412 thread_info *here = th->next;
413 th->next = here->next;
b8c9b27d 414 xfree (here);
24e60978
SC
415 }
416}
417
3cee93ac 418static void
dc05df57 419do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
24e60978 420{
1e37c281 421 char *context_offset = ((char *) &current_thread->context) + mappings[r];
20a6ec49
MD
422 struct gdbarch *gdbarch = get_regcache_arch (regcache);
423 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1e37c281 424 long l;
6c7de422 425
3ade5333 426 if (!current_thread)
d6dc8049 427 return; /* Windows sometimes uses a non-existent thread id in its
581e13c1 428 events. */
3ade5333
CF
429
430 if (current_thread->reload_context)
431 {
cb832706 432#ifdef __COPY_CONTEXT_SIZE
a244bdca
CF
433 if (have_saved_context)
434 {
581e13c1
MS
435 /* Lie about where the program actually is stopped since
436 cygwin has informed us that we should consider the signal
437 to have occurred at another location which is stored in
438 "saved_context. */
439 memcpy (&current_thread->context, &saved_context,
440 __COPY_CONTEXT_SIZE);
a244bdca
CF
441 have_saved_context = 0;
442 }
443 else
cb832706 444#endif
a244bdca
CF
445 {
446 thread_info *th = current_thread;
447 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
448 GetThreadContext (th->h, &th->context);
2b008701 449 /* Copy dr values from that thread.
581e13c1
MS
450 But only if there were not modified since last stop.
451 PR gdb/2388 */
88616312
PM
452 if (!debug_registers_changed)
453 {
454 dr[0] = th->context.Dr0;
455 dr[1] = th->context.Dr1;
456 dr[2] = th->context.Dr2;
457 dr[3] = th->context.Dr3;
458 dr[6] = th->context.Dr6;
459 dr[7] = th->context.Dr7;
460 }
a244bdca 461 }
3ade5333
CF
462 current_thread->reload_context = 0;
463 }
464
20a6ec49 465 if (r == I387_FISEG_REGNUM (tdep))
1e37c281 466 {
8e860359 467 l = *((long *) context_offset) & 0xffff;
56be3814 468 regcache_raw_supply (regcache, r, (char *) &l);
1e37c281 469 }
20a6ec49 470 else if (r == I387_FOP_REGNUM (tdep))
1e37c281 471 {
8e860359 472 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
56be3814 473 regcache_raw_supply (regcache, r, (char *) &l);
1e37c281 474 }
d40dc7a8
JB
475 else if (segment_register_p (r))
476 {
477 /* GDB treats segment registers as 32bit registers, but they are
478 in fact only 16 bits long. Make sure we do not read extra
479 bits from our source buffer. */
480 l = *((long *) context_offset) & 0xffff;
481 regcache_raw_supply (regcache, r, (char *) &l);
482 }
1e37c281 483 else if (r >= 0)
56be3814 484 regcache_raw_supply (regcache, r, context_offset);
3cee93ac 485 else
24e60978 486 {
20a6ec49 487 for (r = 0; r < gdbarch_num_regs (gdbarch); r++)
dc05df57 488 do_windows_fetch_inferior_registers (regcache, r);
24e60978 489 }
3cee93ac
CF
490}
491
492static void
28439f5e
PA
493windows_fetch_inferior_registers (struct target_ops *ops,
494 struct regcache *regcache, int r)
3cee93ac 495{
2dc38344 496 current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
d6dc8049 497 /* Check if current_thread exists. Windows sometimes uses a non-existent
581e13c1 498 thread id in its events. */
3ade5333 499 if (current_thread)
dc05df57 500 do_windows_fetch_inferior_registers (regcache, r);
3cee93ac
CF
501}
502
503static void
dc05df57 504do_windows_store_inferior_registers (const struct regcache *regcache, int r)
3cee93ac 505{
3ade5333 506 if (!current_thread)
581e13c1 507 /* Windows sometimes uses a non-existent thread id in its events. */;
3ade5333 508 else if (r >= 0)
56be3814 509 regcache_raw_collect (regcache, r,
822c9732 510 ((char *) &current_thread->context) + mappings[r]);
24e60978
SC
511 else
512 {
40a6adc1 513 for (r = 0; r < gdbarch_num_regs (get_regcache_arch (regcache)); r++)
dc05df57 514 do_windows_store_inferior_registers (regcache, r);
24e60978
SC
515 }
516}
517
581e13c1 518/* Store a new register value into the current thread context. */
3cee93ac 519static void
28439f5e
PA
520windows_store_inferior_registers (struct target_ops *ops,
521 struct regcache *regcache, int r)
3cee93ac 522{
2dc38344 523 current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
d6dc8049 524 /* Check if current_thread exists. Windows sometimes uses a non-existent
581e13c1 525 thread id in its events. */
3ade5333 526 if (current_thread)
dc05df57 527 do_windows_store_inferior_registers (regcache, r);
3cee93ac 528}
24e60978 529
450005e7 530/* Encapsulate the information required in a call to
581e13c1 531 symbol_file_add_args. */
8a892701
CF
532struct safe_symbol_file_add_args
533{
534 char *name;
535 int from_tty;
536 struct section_addr_info *addrs;
537 int mainline;
538 int flags;
7c5c87c0 539 struct ui_file *err, *out;
8a892701
CF
540 struct objfile *ret;
541};
542
581e13c1 543/* Maintain a linked list of "so" information. */
3ee6f623 544struct lm_info
02e423b9 545{
d3653bf6 546 LPVOID load_addr;
3ee6f623
CF
547};
548
549static struct so_list solib_start, *solib_end;
02e423b9 550
450005e7 551/* Call symbol_file_add with stderr redirected. We don't care if there
581e13c1 552 are errors. */
8a892701
CF
553static int
554safe_symbol_file_add_stub (void *argv)
555{
3ee6f623 556#define p ((struct safe_symbol_file_add_args *) argv)
7eedccfa
PP
557 const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0)
558 | (p->mainline ? SYMFILE_MAINLINE : 0));
559 p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags);
8a892701
CF
560 return !!p->ret;
561#undef p
562}
563
581e13c1 564/* Restore gdb's stderr after calling symbol_file_add. */
8a892701 565static void
7c5c87c0 566safe_symbol_file_add_cleanup (void *p)
8a892701 567{
8e860359 568#define sp ((struct safe_symbol_file_add_args *)p)
450005e7 569 gdb_flush (gdb_stderr);
7c5c87c0 570 gdb_flush (gdb_stdout);
d3ff4a77 571 ui_file_delete (gdb_stderr);
7c5c87c0 572 ui_file_delete (gdb_stdout);
d3ff4a77 573 gdb_stderr = sp->err;
9d3789f7 574 gdb_stdout = sp->out;
8e860359 575#undef sp
8a892701
CF
576}
577
581e13c1 578/* symbol_file_add wrapper that prevents errors from being displayed. */
8a892701
CF
579static struct objfile *
580safe_symbol_file_add (char *name, int from_tty,
581 struct section_addr_info *addrs,
582 int mainline, int flags)
8a892701
CF
583{
584 struct safe_symbol_file_add_args p;
585 struct cleanup *cleanup;
586
7c5c87c0 587 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
8a892701 588
7c5c87c0
CF
589 p.err = gdb_stderr;
590 p.out = gdb_stdout;
450005e7 591 gdb_flush (gdb_stderr);
7c5c87c0 592 gdb_flush (gdb_stdout);
d3ff4a77 593 gdb_stderr = ui_file_new ();
7c5c87c0 594 gdb_stdout = ui_file_new ();
8a892701
CF
595 p.name = name;
596 p.from_tty = from_tty;
597 p.addrs = addrs;
598 p.mainline = mainline;
599 p.flags = flags;
600 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
601
602 do_cleanups (cleanup);
603 return p.ret;
604}
605
de1b3c3d 606static struct so_list *
dc05df57 607windows_make_so (const char *name, LPVOID load_addr)
8e860359 608{
3ee6f623 609 struct so_list *so;
d0d0ab16
CV
610 char *p;
611#ifndef __CYGWIN__
b3c613f2
CF
612 char buf[__PMAX];
613 char cwd[__PMAX];
3f8ad85b
CF
614 WIN32_FIND_DATA w32_fd;
615 HANDLE h = FindFirstFile(name, &w32_fd);
3f8ad85b 616
6badb179
CF
617 if (h == INVALID_HANDLE_VALUE)
618 strcpy (buf, name);
619 else
3f8ad85b 620 {
c914e0cc
CF
621 FindClose (h);
622 strcpy (buf, name);
623 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
624 {
625 p = strrchr (buf, '\\');
626 if (p)
627 p[1] = '\0';
628 SetCurrentDirectory (buf);
629 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
630 SetCurrentDirectory (cwd);
631 }
3f8ad85b 632 }
3ee6f623
CF
633 if (strcasecmp (buf, "ntdll.dll") == 0)
634 {
635 GetSystemDirectory (buf, sizeof (buf));
636 strcat (buf, "\\ntdll.dll");
637 }
d0d0ab16 638#else
b3c613f2 639 cygwin_buf_t buf[__PMAX];
d0d0ab16 640
b3c613f2 641 buf[0] = 0;
d0d0ab16
CV
642 if (access (name, F_OK) != 0)
643 {
644 if (strcasecmp (name, "ntdll.dll") == 0)
b3c613f2 645#ifdef __USEWIDE
d0d0ab16
CV
646 {
647 GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t));
648 wcscat (buf, L"\\ntdll.dll");
649 }
b3c613f2
CF
650#else
651 {
652 GetSystemDirectoryA (buf, sizeof (buf) / sizeof (wchar_t));
653 strcat (buf, "\\ntdll.dll");
654 }
655#endif
d0d0ab16
CV
656 }
657#endif
41bf6aca 658 so = XCNEW (struct so_list);
3ee6f623
CF
659 so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
660 so->lm_info->load_addr = load_addr;
de1b3c3d 661 strcpy (so->so_original_name, name);
10325bc5
PA
662#ifndef __CYGWIN__
663 strcpy (so->so_name, buf);
664#else
d0d0ab16
CV
665 if (buf[0])
666 cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
667 SO_NAME_MAX_PATH_SIZE);
668 else
669 {
60c5c021 670 char *rname = realpath (name, NULL);
d0d0ab16
CV
671 if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
672 {
673 strcpy (so->so_name, rname);
674 free (rname);
675 }
676 else
677 error (_("dll path too long"));
678 }
de1b3c3d
PA
679 /* Record cygwin1.dll .text start/end. */
680 p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
681 if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
682 {
683 bfd *abfd;
684 asection *text = NULL;
685 CORE_ADDR text_vma;
8e860359 686
1c00ec6b 687 abfd = gdb_bfd_open (so->so_name, "pei-i386", -1);
a244bdca 688
de1b3c3d
PA
689 if (!abfd)
690 return so;
691
692 if (bfd_check_format (abfd, bfd_object))
693 text = bfd_get_section_by_name (abfd, ".text");
694
695 if (!text)
696 {
cbb099e8 697 gdb_bfd_unref (abfd);
de1b3c3d
PA
698 return so;
699 }
700
7a9dd1b2 701 /* The symbols in a dll are offset by 0x1000, which is the
de1b3c3d 702 offset from 0 of the first byte in an image - because of the
581e13c1
MS
703 file header and the section alignment. */
704 cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *)
705 load_addr + 0x1000);
dc05df57 706 cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text);
de1b3c3d 707
cbb099e8 708 gdb_bfd_unref (abfd);
de1b3c3d 709 }
10325bc5 710#endif
de1b3c3d
PA
711
712 return so;
8e860359
CF
713}
714
3ee6f623 715static char *
dfe7f3ac
CF
716get_image_name (HANDLE h, void *address, int unicode)
717{
d0d0ab16 718#ifdef __CYGWIN__
b3c613f2 719 static char buf[__PMAX];
d0d0ab16 720#else
b3c613f2 721 static char buf[(2 * __PMAX) + 1];
d0d0ab16 722#endif
dfe7f3ac
CF
723 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
724 char *address_ptr;
725 int len = 0;
726 char b[2];
5732a500 727 SIZE_T done;
dfe7f3ac
CF
728
729 /* Attempt to read the name of the dll that was detected.
730 This is documented to work only when actively debugging
581e13c1 731 a program. It will not work for attached processes. */
dfe7f3ac
CF
732 if (address == NULL)
733 return NULL;
734
dfe7f3ac 735 /* See if we could read the address of a string, and that the
581e13c1
MS
736 address isn't null. */
737 if (!ReadProcessMemory (h, address, &address_ptr,
738 sizeof (address_ptr), &done)
6f17862b 739 || done != sizeof (address_ptr) || !address_ptr)
dfe7f3ac
CF
740 return NULL;
741
581e13c1 742 /* Find the length of the string. */
6f17862b
CF
743 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
744 && (b[0] != 0 || b[size - 1] != 0) && done == size)
745 continue;
dfe7f3ac
CF
746
747 if (!unicode)
748 ReadProcessMemory (h, address_ptr, buf, len, &done);
749 else
750 {
751 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
752 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
753 &done);
d0d0ab16 754#ifdef __CYGWIN__
b3c613f2 755 wcstombs (buf, unicode_address, __PMAX);
d0d0ab16
CV
756#else
757 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
758 0, 0);
759#endif
dfe7f3ac
CF
760 }
761
762 return buf;
763}
764
1cd9feab
JB
765/* Handle a DLL load event, and return 1.
766
767 This function assumes that this event did not occur during inferior
768 initialization, where their event info may be incomplete (see
769 do_initial_windows_stuff and windows_add_all_dlls for more info
770 on how we handle DLL loading during that phase). */
771
1750a5ef 772static int
0a65a603 773handle_load_dll (void *dummy)
24e60978 774{
3a4b77d8 775 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1cd9feab 776 char *dll_name;
24e60978 777
94481b8c
JB
778 /* Try getting the DLL name via the lpImageName field of the event.
779 Note that Microsoft documents this fields as strictly optional,
780 in the sense that it might be NULL. And the first DLL event in
781 particular is explicitly documented as "likely not pass[ed]"
782 (source: MSDN LOAD_DLL_DEBUG_INFO structure). */
1cd9feab
JB
783 dll_name = get_image_name (current_process_handle,
784 event->lpImageName, event->fUnicode);
3cee93ac
CF
785 if (!dll_name)
786 return 1;
787
dc05df57 788 solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
de1b3c3d 789 solib_end = solib_end->next;
450005e7 790
a74ce742
PM
791 DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
792 host_address_to_string (solib_end->lm_info->load_addr)));
7488902c 793
450005e7
CF
794 return 1;
795}
796
3ee6f623 797static void
dc05df57 798windows_free_so (struct so_list *so)
3ee6f623 799{
3ee6f623
CF
800 if (so->lm_info)
801 xfree (so->lm_info);
de1b3c3d 802 xfree (so);
3cb8e7f6
CF
803}
804
3be75f87
JB
805/* Handle a DLL unload event.
806 Return 1 if successful, or zero otherwise.
807
808 This function assumes that this event did not occur during inferior
809 initialization, where their event info may be incomplete (see
810 do_initial_windows_stuff and windows_add_all_dlls for more info
811 on how we handle DLL loading during that phase). */
812
d3ff4a77 813static int
0a65a603 814handle_unload_dll (void *dummy)
d3ff4a77 815{
d3653bf6 816 LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
3ee6f623 817 struct so_list *so;
d3ff4a77
CF
818
819 for (so = &solib_start; so->next != NULL; so = so->next)
3ee6f623 820 if (so->next->lm_info->load_addr == lpBaseOfDll)
d3ff4a77 821 {
3ee6f623 822 struct so_list *sodel = so->next;
a25cd31f 823
d3ff4a77
CF
824 so->next = sodel->next;
825 if (!so->next)
826 solib_end = so;
7488902c
PM
827 DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
828
dc05df57 829 windows_free_so (sodel);
d3ff4a77
CF
830 return 1;
831 }
3929abe9 832
ecc13e53
JB
833 /* We did not find any DLL that was previously loaded at this address,
834 so register a complaint. We do not report an error, because we have
835 observed that this may be happening under some circumstances. For
836 instance, running 32bit applications on x64 Windows causes us to receive
837 4 mysterious UNLOAD_DLL_DEBUG_EVENTs during the startup phase (these
838 events are apparently caused by the WOW layer, the interface between
839 32bit and 64bit worlds). */
840 complaint (&symfile_complaints, _("dll starting at %s not found."),
841 host_address_to_string (lpBaseOfDll));
d3ff4a77
CF
842
843 return 0;
844}
845
581e13c1 846/* Clear list of loaded DLLs. */
3ee6f623 847static void
dc05df57 848windows_clear_solib (void)
450005e7 849{
450005e7
CF
850 solib_start.next = NULL;
851 solib_end = &solib_start;
450005e7 852}
295732ea 853
581e13c1 854/* Load DLL symbol info. */
d603d4b3 855static void
7470a420 856dll_symbol_command (char *args, int from_tty)
450005e7 857{
8e860359 858 int n;
450005e7 859 dont_repeat ();
8e860359 860
450005e7 861 if (args == NULL)
8a3fe4f8 862 error (_("dll-symbols requires a file name"));
450005e7 863
8e860359
CF
864 n = strlen (args);
865 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
866 {
867 char *newargs = (char *) alloca (n + 4 + 1);
868 strcpy (newargs, args);
869 strcat (newargs, ".dll");
870 args = newargs;
871 }
872
7470a420 873 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
8e860359 874}
450005e7 875
3cee93ac
CF
876/* Handle DEBUG_STRING output from child process.
877 Cygwin prepends its messages with a "cygwin:". Interpret this as
581e13c1 878 a Cygwin signal. Otherwise just print the string as a warning. */
3cee93ac
CF
879static int
880handle_output_debug_string (struct target_waitstatus *ourstatus)
881{
a244bdca
CF
882 char *s = NULL;
883 int retval = 0;
3cee93ac
CF
884
885 if (!target_read_string
2c647436
PM
886 ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
887 &s, 1024, 0)
3cee93ac 888 || !s || !*s)
a244bdca 889 /* nothing to do */;
581e13c1
MS
890 else if (strncmp (s, _CYGWIN_SIGNAL_STRING,
891 sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
3cee93ac 892 {
10325bc5 893#ifdef __CYGWIN__
d3a09475 894 if (strncmp (s, "cYg", 3) != 0)
10325bc5 895#endif
8a3fe4f8 896 warning (("%s"), s);
3cee93ac 897 }
cb832706 898#ifdef __COPY_CONTEXT_SIZE
d3a09475 899 else
3cee93ac 900 {
581e13c1
MS
901 /* Got a cygwin signal marker. A cygwin signal is followed by
902 the signal number itself and then optionally followed by the
903 thread id and address to saved context within the DLL. If
904 these are supplied, then the given thread is assumed to have
905 issued the signal and the context from the thread is assumed
906 to be stored at the given address in the inferior. Tell gdb
907 to treat this like a real signal. */
3cee93ac 908 char *p;
3929abe9 909 int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
2ea28649 910 int gotasig = gdb_signal_from_host (sig);
c62fa0e2 911
0714f9bf
SS
912 ourstatus->value.sig = gotasig;
913 if (gotasig)
a244bdca
CF
914 {
915 LPCVOID x;
2c15ef43 916 SIZE_T n;
c62fa0e2 917
a244bdca
CF
918 ourstatus->kind = TARGET_WAITKIND_STOPPED;
919 retval = strtoul (p, &p, 0);
920 if (!retval)
921 retval = main_thread_id;
40653b35 922 else if ((x = (LPCVOID) (uintptr_t) strtoull (p, NULL, 0))
a244bdca 923 && ReadProcessMemory (current_process_handle, x,
581e13c1
MS
924 &saved_context,
925 __COPY_CONTEXT_SIZE, &n)
a244bdca
CF
926 && n == __COPY_CONTEXT_SIZE)
927 have_saved_context = 1;
928 current_event.dwThreadId = retval;
929 }
3cee93ac 930 }
cb832706 931#endif
3cee93ac 932
a244bdca
CF
933 if (s)
934 xfree (s);
935 return retval;
3cee93ac 936}
24e60978 937
c1748f97
PM
938static int
939display_selector (HANDLE thread, DWORD sel)
940{
941 LDT_ENTRY info;
942 if (GetThreadSelectorEntry (thread, sel, &info))
943 {
944 int base, limit;
d50a0ce2 945 printf_filtered ("0x%03x: ", (unsigned) sel);
c1748f97 946 if (!info.HighWord.Bits.Pres)
baa93fa6
CF
947 {
948 puts_filtered ("Segment not present\n");
949 return 0;
950 }
c1748f97
PM
951 base = (info.HighWord.Bits.BaseHi << 24) +
952 (info.HighWord.Bits.BaseMid << 16)
953 + info.BaseLow;
954 limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
955 if (info.HighWord.Bits.Granularity)
caad7706 956 limit = (limit << 12) | 0xfff;
c1748f97
PM
957 printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
958 if (info.HighWord.Bits.Default_Big)
baa93fa6 959 puts_filtered(" 32-bit ");
c1748f97 960 else
baa93fa6 961 puts_filtered(" 16-bit ");
c1748f97
PM
962 switch ((info.HighWord.Bits.Type & 0xf) >> 1)
963 {
964 case 0:
baa93fa6
CF
965 puts_filtered ("Data (Read-Only, Exp-up");
966 break;
c1748f97 967 case 1:
baa93fa6
CF
968 puts_filtered ("Data (Read/Write, Exp-up");
969 break;
c1748f97 970 case 2:
baa93fa6
CF
971 puts_filtered ("Unused segment (");
972 break;
c1748f97 973 case 3:
baa93fa6
CF
974 puts_filtered ("Data (Read/Write, Exp-down");
975 break;
c1748f97 976 case 4:
baa93fa6
CF
977 puts_filtered ("Code (Exec-Only, N.Conf");
978 break;
c1748f97 979 case 5:
baa93fa6 980 puts_filtered ("Code (Exec/Read, N.Conf");
c1748f97
PM
981 break;
982 case 6:
baa93fa6 983 puts_filtered ("Code (Exec-Only, Conf");
c1748f97
PM
984 break;
985 case 7:
baa93fa6 986 puts_filtered ("Code (Exec/Read, Conf");
c1748f97
PM
987 break;
988 default:
989 printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
990 }
991 if ((info.HighWord.Bits.Type & 0x1) == 0)
baa93fa6 992 puts_filtered(", N.Acc");
c1748f97
PM
993 puts_filtered (")\n");
994 if ((info.HighWord.Bits.Type & 0x10) == 0)
995 puts_filtered("System selector ");
996 printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
997 if (info.HighWord.Bits.Granularity)
baa93fa6 998 puts_filtered ("Page granular.\n");
c1748f97
PM
999 else
1000 puts_filtered ("Byte granular.\n");
1001 return 1;
1002 }
1003 else
1004 {
5572ce1f
PM
1005 DWORD err = GetLastError ();
1006 if (err == ERROR_NOT_SUPPORTED)
1007 printf_filtered ("Function not supported\n");
1008 else
d50a0ce2 1009 printf_filtered ("Invalid selector 0x%x.\n", (unsigned) sel);
c1748f97
PM
1010 return 0;
1011 }
1012}
1013
1014static void
1015display_selectors (char * args, int from_tty)
1016{
1017 if (!current_thread)
1018 {
1019 puts_filtered ("Impossible to display selectors now.\n");
1020 return;
1021 }
1022 if (!args)
1023 {
1024
1025 puts_filtered ("Selector $cs\n");
1026 display_selector (current_thread->h,
baa93fa6 1027 current_thread->context.SegCs);
c1748f97
PM
1028 puts_filtered ("Selector $ds\n");
1029 display_selector (current_thread->h,
baa93fa6 1030 current_thread->context.SegDs);
c1748f97
PM
1031 puts_filtered ("Selector $es\n");
1032 display_selector (current_thread->h,
baa93fa6 1033 current_thread->context.SegEs);
c1748f97
PM
1034 puts_filtered ("Selector $ss\n");
1035 display_selector (current_thread->h,
baa93fa6 1036 current_thread->context.SegSs);
c1748f97
PM
1037 puts_filtered ("Selector $fs\n");
1038 display_selector (current_thread->h,
1039 current_thread->context.SegFs);
1040 puts_filtered ("Selector $gs\n");
1041 display_selector (current_thread->h,
baa93fa6 1042 current_thread->context.SegGs);
c1748f97
PM
1043 }
1044 else
1045 {
1046 int sel;
1047 sel = parse_and_eval_long (args);
1048 printf_filtered ("Selector \"%s\"\n",args);
1049 display_selector (current_thread->h, sel);
1050 }
1051}
1052
7393af7c 1053#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
a74ce742
PM
1054 printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
1055 host_address_to_string (\
1056 current_event.u.Exception.ExceptionRecord.ExceptionAddress))
7393af7c 1057
36339ecd 1058static int
450005e7 1059handle_exception (struct target_waitstatus *ourstatus)
24e60978 1060{
3cee93ac 1061 thread_info *th;
29fe111d 1062 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
3cee93ac 1063
29fe111d 1064 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 1065
581e13c1 1066 /* Record the context of the current thread. */
3cee93ac 1067 th = thread_rec (current_event.dwThreadId, -1);
24e60978 1068
29fe111d 1069 switch (code)
24e60978 1070 {
1ef980b9 1071 case EXCEPTION_ACCESS_VIOLATION:
7393af7c 1072 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
a493e3e2 1073 ourstatus->value.sig = GDB_SIGNAL_SEGV;
10325bc5 1074#ifdef __CYGWIN__
8da8e0b3 1075 {
581e13c1
MS
1076 /* See if the access violation happened within the cygwin DLL
1077 itself. Cygwin uses a kind of exception handling to deal
1078 with passed-in invalid addresses. gdb should not treat
1079 these as real SEGVs since they will be silently handled by
1080 cygwin. A real SEGV will (theoretically) be caught by
1081 cygwin later in the process and will be sent as a
1082 cygwin-specific-signal. So, ignore SEGVs if they show up
1083 within the text segment of the DLL itself. */
2c02bd72 1084 const char *fn;
581e13c1
MS
1085 CORE_ADDR addr = (CORE_ADDR) (uintptr_t)
1086 current_event.u.Exception.ExceptionRecord.ExceptionAddress;
1087
1088 if ((!cygwin_exceptions && (addr >= cygwin_load_start
1089 && addr < cygwin_load_end))
a244bdca 1090 || (find_pc_partial_function (addr, &fn, NULL, NULL)
581e13c1
MS
1091 && strncmp (fn, "KERNEL32!IsBad",
1092 strlen ("KERNEL32!IsBad")) == 0))
8da8e0b3
CF
1093 return 0;
1094 }
10325bc5 1095#endif
7393af7c
PM
1096 break;
1097 case STATUS_STACK_OVERFLOW:
1098 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
a493e3e2 1099 ourstatus->value.sig = GDB_SIGNAL_SEGV;
7393af7c
PM
1100 break;
1101 case STATUS_FLOAT_DENORMAL_OPERAND:
1102 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
a493e3e2 1103 ourstatus->value.sig = GDB_SIGNAL_FPE;
7393af7c
PM
1104 break;
1105 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1106 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
a493e3e2 1107 ourstatus->value.sig = GDB_SIGNAL_FPE;
7393af7c
PM
1108 break;
1109 case STATUS_FLOAT_INEXACT_RESULT:
1110 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
a493e3e2 1111 ourstatus->value.sig = GDB_SIGNAL_FPE;
7393af7c
PM
1112 break;
1113 case STATUS_FLOAT_INVALID_OPERATION:
1114 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
a493e3e2 1115 ourstatus->value.sig = GDB_SIGNAL_FPE;
7393af7c
PM
1116 break;
1117 case STATUS_FLOAT_OVERFLOW:
1118 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
a493e3e2 1119 ourstatus->value.sig = GDB_SIGNAL_FPE;
7393af7c
PM
1120 break;
1121 case STATUS_FLOAT_STACK_CHECK:
1122 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
a493e3e2 1123 ourstatus->value.sig = GDB_SIGNAL_FPE;
1ef980b9 1124 break;
3b7c8b74 1125 case STATUS_FLOAT_UNDERFLOW:
7393af7c 1126 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
a493e3e2 1127 ourstatus->value.sig = GDB_SIGNAL_FPE;
7393af7c 1128 break;
3b7c8b74 1129 case STATUS_FLOAT_DIVIDE_BY_ZERO:
7393af7c 1130 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
a493e3e2 1131 ourstatus->value.sig = GDB_SIGNAL_FPE;
7393af7c 1132 break;
3b7c8b74 1133 case STATUS_INTEGER_DIVIDE_BY_ZERO:
7393af7c 1134 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
a493e3e2 1135 ourstatus->value.sig = GDB_SIGNAL_FPE;
3b7c8b74 1136 break;
7393af7c
PM
1137 case STATUS_INTEGER_OVERFLOW:
1138 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
a493e3e2 1139 ourstatus->value.sig = GDB_SIGNAL_FPE;
1ef980b9
SC
1140 break;
1141 case EXCEPTION_BREAKPOINT:
7393af7c 1142 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
a493e3e2 1143 ourstatus->value.sig = GDB_SIGNAL_TRAP;
1ef980b9
SC
1144 break;
1145 case DBG_CONTROL_C:
7393af7c 1146 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
a493e3e2 1147 ourstatus->value.sig = GDB_SIGNAL_INT;
5b421780
PM
1148 break;
1149 case DBG_CONTROL_BREAK:
7393af7c 1150 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
a493e3e2 1151 ourstatus->value.sig = GDB_SIGNAL_INT;
1ef980b9
SC
1152 break;
1153 case EXCEPTION_SINGLE_STEP:
7393af7c 1154 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
a493e3e2 1155 ourstatus->value.sig = GDB_SIGNAL_TRAP;
1ef980b9 1156 break;
8227c82d 1157 case EXCEPTION_ILLEGAL_INSTRUCTION:
7393af7c 1158 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
a493e3e2 1159 ourstatus->value.sig = GDB_SIGNAL_ILL;
7393af7c
PM
1160 break;
1161 case EXCEPTION_PRIV_INSTRUCTION:
1162 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
a493e3e2 1163 ourstatus->value.sig = GDB_SIGNAL_ILL;
7393af7c
PM
1164 break;
1165 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1166 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
a493e3e2 1167 ourstatus->value.sig = GDB_SIGNAL_ILL;
8227c82d 1168 break;
1ef980b9 1169 default:
581e13c1 1170 /* Treat unhandled first chance exceptions specially. */
02e423b9 1171 if (current_event.u.Exception.dwFirstChance)
a244bdca 1172 return -1;
d50a0ce2
CV
1173 printf_unfiltered ("gdb: unknown target exception 0x%08x at %s\n",
1174 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
a74ce742
PM
1175 host_address_to_string (
1176 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
a493e3e2 1177 ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
1ef980b9 1178 break;
24e60978 1179 }
24e60978 1180 exception_count++;
7393af7c 1181 last_sig = ourstatus->value.sig;
36339ecd 1182 return 1;
24e60978
SC
1183}
1184
3cee93ac 1185/* Resume all artificially suspended threads if we are continuing
581e13c1 1186 execution. */
3cee93ac 1187static BOOL
dc05df57 1188windows_continue (DWORD continue_status, int id)
3cee93ac
CF
1189{
1190 int i;
1191 thread_info *th;
1192 BOOL res;
1193
0c3d84be 1194 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n",
d50a0ce2
CV
1195 (unsigned) current_event.dwProcessId,
1196 (unsigned) current_event.dwThreadId,
dfe7f3ac 1197 continue_status == DBG_CONTINUE ?
7393af7c 1198 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
6537bb24
PA
1199
1200 for (th = &thread_head; (th = th->next) != NULL;)
1201 if ((id == -1 || id == (int) th->id)
1202 && th->suspended)
1203 {
1204 if (debug_registers_changed)
1205 {
1206 th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
1207 th->context.Dr0 = dr[0];
1208 th->context.Dr1 = dr[1];
1209 th->context.Dr2 = dr[2];
1210 th->context.Dr3 = dr[3];
1211 th->context.Dr6 = DR6_CLEAR_VALUE;
1212 th->context.Dr7 = dr[7];
1213 }
1214 if (th->context.ContextFlags)
1215 {
1216 CHECK (SetThreadContext (th->h, &th->context));
1217 th->context.ContextFlags = 0;
1218 }
1219 if (th->suspended > 0)
1220 (void) ResumeThread (th->h);
1221 th->suspended = 0;
1222 }
1223
0714f9bf
SS
1224 res = ContinueDebugEvent (current_event.dwProcessId,
1225 current_event.dwThreadId,
1226 continue_status);
3cee93ac 1227
fa4ba8da 1228 debug_registers_changed = 0;
3cee93ac
CF
1229 return res;
1230}
1231
d6dc8049
CF
1232/* Called in pathological case where Windows fails to send a
1233 CREATE_PROCESS_DEBUG_EVENT after an attach. */
3ee6f623 1234static DWORD
5439edaa 1235fake_create_process (void)
3ade5333
CF
1236{
1237 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
1238 current_event.dwProcessId);
bf25528d
CF
1239 if (current_process_handle != NULL)
1240 open_process_used = 1;
1241 else
1242 {
d50a0ce2
CV
1243 error (_("OpenProcess call failed, GetLastError = %u"),
1244 (unsigned) GetLastError ());
bf25528d
CF
1245 /* We can not debug anything in that case. */
1246 }
3ade5333 1247 main_thread_id = current_event.dwThreadId;
711e434b
PM
1248 current_thread = windows_add_thread (
1249 ptid_build (current_event.dwProcessId, 0,
1250 current_event.dwThreadId),
1251 current_event.u.CreateThread.hThread,
1252 current_event.u.CreateThread.lpThreadLocalBase);
3ade5333
CF
1253 return main_thread_id;
1254}
1255
a244bdca 1256static void
28439f5e 1257windows_resume (struct target_ops *ops,
2ea28649 1258 ptid_t ptid, int step, enum gdb_signal sig)
a244bdca
CF
1259{
1260 thread_info *th;
1261 DWORD continue_status = DBG_CONTINUE;
1262
2dc38344
PA
1263 /* A specific PTID means `step only this thread id'. */
1264 int resume_all = ptid_equal (ptid, minus_one_ptid);
1265
1266 /* If we're continuing all threads, it's the current inferior that
1267 should be handled specially. */
1268 if (resume_all)
1269 ptid = inferior_ptid;
a244bdca 1270
a493e3e2 1271 if (sig != GDB_SIGNAL_0)
a244bdca
CF
1272 {
1273 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1274 {
1275 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1276 }
1277 else if (sig == last_sig)
1278 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1279 else
1280#if 0
1281/* This code does not seem to work, because
1282 the kernel does probably not consider changes in the ExceptionRecord
1283 structure when passing the exception to the inferior.
1284 Note that this seems possible in the exception handler itself. */
1285 {
1286 int i;
1287 for (i = 0; xlate[i].them != -1; i++)
1288 if (xlate[i].us == sig)
1289 {
581e13c1
MS
1290 current_event.u.Exception.ExceptionRecord.ExceptionCode
1291 = xlate[i].them;
a244bdca
CF
1292 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1293 break;
1294 }
1295 if (continue_status == DBG_CONTINUE)
1296 {
1297 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1298 }
1299 }
1300#endif
1301 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1302 last_sig));
1303 }
1304
a493e3e2 1305 last_sig = GDB_SIGNAL_0;
a244bdca 1306
dc05df57 1307 DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n",
2dc38344 1308 ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig));
a244bdca 1309
581e13c1 1310 /* Get context for currently selected thread. */
2dc38344 1311 th = thread_rec (ptid_get_tid (inferior_ptid), FALSE);
a244bdca
CF
1312 if (th)
1313 {
1314 if (step)
1315 {
581e13c1 1316 /* Single step by setting t bit. */
a97b0ac8
UW
1317 struct regcache *regcache = get_current_regcache ();
1318 struct gdbarch *gdbarch = get_regcache_arch (regcache);
1319 windows_fetch_inferior_registers (ops, regcache,
1320 gdbarch_ps_regnum (gdbarch));
a244bdca
CF
1321 th->context.EFlags |= FLAG_TRACE_BIT;
1322 }
1323
1324 if (th->context.ContextFlags)
1325 {
1326 if (debug_registers_changed)
1327 {
1328 th->context.Dr0 = dr[0];
1329 th->context.Dr1 = dr[1];
1330 th->context.Dr2 = dr[2];
1331 th->context.Dr3 = dr[3];
6537bb24 1332 th->context.Dr6 = DR6_CLEAR_VALUE;
a244bdca
CF
1333 th->context.Dr7 = dr[7];
1334 }
1335 CHECK (SetThreadContext (th->h, &th->context));
1336 th->context.ContextFlags = 0;
1337 }
1338 }
1339
1340 /* Allow continuing with the same signal that interrupted us.
581e13c1 1341 Otherwise complain. */
a244bdca 1342
2dc38344 1343 if (resume_all)
dc05df57 1344 windows_continue (continue_status, -1);
2dc38344 1345 else
dc05df57 1346 windows_continue (continue_status, ptid_get_tid (ptid));
a244bdca
CF
1347}
1348
695de547
CF
1349/* Ctrl-C handler used when the inferior is not run in the same console. The
1350 handler is in charge of interrupting the inferior using DebugBreakProcess.
1351 Note that this function is not available prior to Windows XP. In this case
1352 we emit a warning. */
d603d4b3 1353static BOOL WINAPI
695de547
CF
1354ctrl_c_handler (DWORD event_type)
1355{
1356 const int attach_flag = current_inferior ()->attach_flag;
1357
bb0613a5
PM
1358 /* Only handle Ctrl-C and Ctrl-Break events. Ignore others. */
1359 if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT)
695de547
CF
1360 return FALSE;
1361
1362 /* If the inferior and the debugger share the same console, do nothing as
1363 the inferior has also received the Ctrl-C event. */
1364 if (!new_console && !attach_flag)
1365 return TRUE;
1366
1367 if (!DebugBreakProcess (current_process_handle))
581e13c1
MS
1368 warning (_("Could not interrupt program. "
1369 "Press Ctrl-c in the program console."));
695de547
CF
1370
1371 /* Return true to tell that Ctrl-C has been handled. */
1372 return TRUE;
1373}
1374
8a892701 1375/* Get the next event from the child. Return 1 if the event requires
695de547 1376 handling by WFI (or whatever). */
1e37c281 1377static int
28439f5e
PA
1378get_windows_debug_event (struct target_ops *ops,
1379 int pid, struct target_waitstatus *ourstatus)
1e37c281
JM
1380{
1381 BOOL debug_event;
8a892701 1382 DWORD continue_status, event_code;
87a45c96 1383 thread_info *th;
8a892701 1384 static thread_info dummy_thread_info;
450005e7 1385 int retval = 0;
1e37c281 1386
a493e3e2 1387 last_sig = GDB_SIGNAL_0;
9d3789f7 1388
8a892701 1389 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 1390 goto out;
1e37c281
JM
1391
1392 event_count++;
1393 continue_status = DBG_CONTINUE;
1e37c281 1394
8a892701 1395 event_code = current_event.dwDebugEventCode;
450005e7 1396 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
87a45c96 1397 th = NULL;
a244bdca 1398 have_saved_context = 0;
8a892701
CF
1399
1400 switch (event_code)
1e37c281
JM
1401 {
1402 case CREATE_THREAD_DEBUG_EVENT:
0c3d84be 1403 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1404 (unsigned) current_event.dwProcessId,
1405 (unsigned) current_event.dwThreadId,
1406 "CREATE_THREAD_DEBUG_EVENT"));
dfe7f3ac 1407 if (saw_create != 1)
3ade5333 1408 {
181e7f93
PA
1409 struct inferior *inf;
1410 inf = find_inferior_pid (current_event.dwProcessId);
1411 if (!saw_create && inf->attach_flag)
3ade5333 1412 {
d6dc8049
CF
1413 /* Kludge around a Windows bug where first event is a create
1414 thread event. Caused when attached process does not have
581e13c1 1415 a main thread. */
3a3e9ee3 1416 retval = fake_create_process ();
181e7f93
PA
1417 if (retval)
1418 saw_create++;
3ade5333
CF
1419 }
1420 break;
1421 }
581e13c1 1422 /* Record the existence of this thread. */
450005e7 1423 retval = current_event.dwThreadId;
dc05df57 1424 th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
2dc38344 1425 current_event.dwThreadId),
711e434b
PM
1426 current_event.u.CreateThread.hThread,
1427 current_event.u.CreateThread.lpThreadLocalBase);
1428
1e37c281
JM
1429 break;
1430
1431 case EXIT_THREAD_DEBUG_EVENT:
0c3d84be 1432 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1433 (unsigned) current_event.dwProcessId,
1434 (unsigned) current_event.dwThreadId,
1435 "EXIT_THREAD_DEBUG_EVENT"));
b3c613f2 1436
87a45c96
CF
1437 if (current_event.dwThreadId != main_thread_id)
1438 {
dc05df57 1439 windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
e0ea48a0
EZ
1440 current_event.dwThreadId),
1441 current_event.u.ExitThread.dwExitCode);
87a45c96
CF
1442 th = &dummy_thread_info;
1443 }
1e37c281
JM
1444 break;
1445
1446 case CREATE_PROCESS_DEBUG_EVENT:
0c3d84be 1447 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1448 (unsigned) current_event.dwProcessId,
1449 (unsigned) current_event.dwThreadId,
1450 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 1451 CloseHandle (current_event.u.CreateProcessInfo.hFile);
dfe7f3ac 1452 if (++saw_create != 1)
bf25528d 1453 break;
1e37c281 1454
dfe7f3ac 1455 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
87a45c96 1456 if (main_thread_id)
695de547 1457 windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
e0ea48a0
EZ
1458 main_thread_id),
1459 0);
9d3789f7 1460 main_thread_id = current_event.dwThreadId;
581e13c1 1461 /* Add the main thread. */
dc05df57 1462 th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
695de547 1463 current_event.dwThreadId),
711e434b
PM
1464 current_event.u.CreateProcessInfo.hThread,
1465 current_event.u.CreateProcessInfo.lpThreadLocalBase);
3a3e9ee3 1466 retval = current_event.dwThreadId;
1e37c281
JM
1467 break;
1468
1469 case EXIT_PROCESS_DEBUG_EVENT:
0c3d84be 1470 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1471 (unsigned) current_event.dwProcessId,
1472 (unsigned) current_event.dwThreadId,
1473 "EXIT_PROCESS_DEBUG_EVENT"));
16d905e2
CF
1474 if (!windows_initialization_done)
1475 {
1476 target_terminal_ours ();
1477 target_mourn_inferior ();
1478 error (_("During startup program exited with code 0x%x."),
1479 (unsigned int) current_event.u.ExitProcess.dwExitCode);
1480 }
1481 else if (saw_create == 1)
1482 {
1483 ourstatus->kind = TARGET_WAITKIND_EXITED;
1484 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1485 retval = main_thread_id;
1486 }
8a892701 1487 break;
1e37c281
JM
1488
1489 case LOAD_DLL_DEBUG_EVENT:
0c3d84be 1490 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1491 (unsigned) current_event.dwProcessId,
1492 (unsigned) current_event.dwThreadId,
1493 "LOAD_DLL_DEBUG_EVENT"));
700b351b 1494 CloseHandle (current_event.u.LoadDll.hFile);
ea39ad35 1495 if (saw_create != 1 || ! windows_initialization_done)
dfe7f3ac 1496 break;
8a892701 1497 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
450005e7
CF
1498 ourstatus->kind = TARGET_WAITKIND_LOADED;
1499 ourstatus->value.integer = 0;
9d3789f7 1500 retval = main_thread_id;
1e37c281
JM
1501 break;
1502
1503 case UNLOAD_DLL_DEBUG_EVENT:
0c3d84be 1504 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1505 (unsigned) current_event.dwProcessId,
1506 (unsigned) current_event.dwThreadId,
1507 "UNLOAD_DLL_DEBUG_EVENT"));
ea39ad35 1508 if (saw_create != 1 || ! windows_initialization_done)
dfe7f3ac 1509 break;
d3ff4a77 1510 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
de1b3c3d
PA
1511 ourstatus->kind = TARGET_WAITKIND_LOADED;
1512 ourstatus->value.integer = 0;
1513 retval = main_thread_id;
d3ff4a77 1514 break;
1e37c281
JM
1515
1516 case EXCEPTION_DEBUG_EVENT:
0c3d84be 1517 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1518 (unsigned) current_event.dwProcessId,
1519 (unsigned) current_event.dwThreadId,
1520 "EXCEPTION_DEBUG_EVENT"));
dfe7f3ac
CF
1521 if (saw_create != 1)
1522 break;
a244bdca
CF
1523 switch (handle_exception (ourstatus))
1524 {
1525 case 0:
1526 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1527 break;
1528 case 1:
1529 retval = current_event.dwThreadId;
1530 break;
1531 case -1:
1532 last_sig = 1;
1533 continue_status = -1;
1534 break;
1535 }
1e37c281
JM
1536 break;
1537
581e13c1 1538 case OUTPUT_DEBUG_STRING_EVENT: /* Message from the kernel. */
0c3d84be 1539 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
8a892701
CF
1540 (unsigned) current_event.dwProcessId,
1541 (unsigned) current_event.dwThreadId,
1542 "OUTPUT_DEBUG_STRING_EVENT"));
dfe7f3ac
CF
1543 if (saw_create != 1)
1544 break;
a244bdca 1545 retval = handle_output_debug_string (ourstatus);
1e37c281 1546 break;
9d3789f7 1547
1e37c281 1548 default:
dfe7f3ac
CF
1549 if (saw_create != 1)
1550 break;
0c3d84be 1551 printf_unfiltered ("gdb: kernel event for pid=%u tid=0x%x\n",
d50a0ce2
CV
1552 (unsigned) current_event.dwProcessId,
1553 (unsigned) current_event.dwThreadId);
1554 printf_unfiltered (" unknown event code %u\n",
1555 (unsigned) current_event.dwDebugEventCode);
1e37c281
JM
1556 break;
1557 }
1558
dfe7f3ac 1559 if (!retval || saw_create != 1)
a244bdca
CF
1560 {
1561 if (continue_status == -1)
02529b48 1562 windows_resume (ops, minus_one_ptid, 0, 1);
a244bdca 1563 else
dc05df57 1564 CHECK (windows_continue (continue_status, -1));
a244bdca 1565 }
450005e7 1566 else
9d3789f7 1567 {
2dc38344
PA
1568 inferior_ptid = ptid_build (current_event.dwProcessId, 0,
1569 retval);
3ade5333 1570 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
9d3789f7 1571 }
1e37c281
JM
1572
1573out:
450005e7 1574 return retval;
1e37c281
JM
1575}
1576
2dc38344 1577/* Wait for interesting events to occur in the target process. */
39f77062 1578static ptid_t
117de6a9 1579windows_wait (struct target_ops *ops,
47608cb1 1580 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
24e60978 1581{
2dc38344 1582 int pid = -1;
39f77062 1583
c44537cf
CV
1584 target_terminal_ours ();
1585
24e60978
SC
1586 /* We loop when we get a non-standard exception rather than return
1587 with a SPURIOUS because resume can try and step or modify things,
3cee93ac 1588 which needs a current_thread->h. But some of these exceptions mark
24e60978 1589 the birth or death of threads, which mean that the current thread
581e13c1 1590 isn't necessarily what you think it is. */
24e60978
SC
1591
1592 while (1)
450005e7 1593 {
c57918b2 1594 int retval;
2b008701 1595
695de547
CF
1596 /* If the user presses Ctrl-c while the debugger is waiting
1597 for an event, he expects the debugger to interrupt his program
1598 and to get the prompt back. There are two possible situations:
1599
1600 - The debugger and the program do not share the console, in
1601 which case the Ctrl-c event only reached the debugger.
1602 In that case, the ctrl_c handler will take care of interrupting
581e13c1
MS
1603 the inferior. Note that this case is working starting with
1604 Windows XP. For Windows 2000, Ctrl-C should be pressed in the
695de547
CF
1605 inferior console.
1606
1607 - The debugger and the program share the same console, in which
1608 case both debugger and inferior will receive the Ctrl-c event.
1609 In that case the ctrl_c handler will ignore the event, as the
1610 Ctrl-c event generated inside the inferior will trigger the
1611 expected debug event.
1612
1613 FIXME: brobecker/2008-05-20: If the inferior receives the
1614 signal first and the delay until GDB receives that signal
1615 is sufficiently long, GDB can sometimes receive the SIGINT
1616 after we have unblocked the CTRL+C handler. This would
1617 lead to the debugger stopping prematurely while handling
1618 the new-thread event that comes with the handling of the SIGINT
1619 inside the inferior, and then stop again immediately when
1620 the user tries to resume the execution in the inferior.
1621 This is a classic race that we should try to fix one day. */
1622 SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
28439f5e 1623 retval = get_windows_debug_event (ops, pid, ourstatus);
695de547 1624 SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
c57918b2 1625
450005e7 1626 if (retval)
2dc38344 1627 return ptid_build (current_event.dwProcessId, 0, retval);
450005e7
CF
1628 else
1629 {
1630 int detach = 0;
3cee93ac 1631
98bbd631
AC
1632 if (deprecated_ui_loop_hook != NULL)
1633 detach = deprecated_ui_loop_hook (0);
0714f9bf 1634
450005e7 1635 if (detach)
7d85a9c0 1636 windows_kill_inferior (ops);
450005e7
CF
1637 }
1638 }
24e60978
SC
1639}
1640
ea39ad35
JB
1641/* Iterate over all DLLs currently mapped by our inferior, and
1642 add them to our list of solibs. */
94481b8c
JB
1643
1644static void
ea39ad35 1645windows_add_all_dlls (void)
94481b8c
JB
1646{
1647 struct so_list *so;
1648 HMODULE dummy_hmodule;
1649 DWORD cb_needed;
1650 HMODULE *hmodules;
1651 int i;
1652
94481b8c
JB
1653 if (EnumProcessModules (current_process_handle, &dummy_hmodule,
1654 sizeof (HMODULE), &cb_needed) == 0)
1655 return;
1656
1657 if (cb_needed < 1)
1658 return;
1659
1660 hmodules = (HMODULE *) alloca (cb_needed);
1661 if (EnumProcessModules (current_process_handle, hmodules,
1662 cb_needed, &cb_needed) == 0)
1663 return;
1664
ea39ad35 1665 for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
94481b8c
JB
1666 {
1667 MODULEINFO mi;
774f74c2
PM
1668#ifdef __USEWIDE
1669 wchar_t dll_name[__PMAX];
1670 char name[__PMAX];
1671#else
94481b8c 1672 char dll_name[__PMAX];
774f74c2
PM
1673 char *name;
1674#endif
94481b8c
JB
1675 if (GetModuleInformation (current_process_handle, hmodules[i],
1676 &mi, sizeof (mi)) == 0)
1677 continue;
1678 if (GetModuleFileNameEx (current_process_handle, hmodules[i],
1679 dll_name, sizeof (dll_name)) == 0)
1680 continue;
774f74c2
PM
1681#ifdef __USEWIDE
1682 wcstombs (name, dll_name, __PMAX);
1683#else
1684 name = dll_name;
1685#endif
ea39ad35
JB
1686
1687 solib_end->next = windows_make_so (name, mi.lpBaseOfDll);
1688 solib_end = solib_end->next;
94481b8c
JB
1689 }
1690}
1691
9d3789f7 1692static void
dc05df57 1693do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
9d3789f7
CF
1694{
1695 extern int stop_after_trap;
fa4ba8da 1696 int i;
d6b48e9c 1697 struct inferior *inf;
2020b7ab 1698 struct thread_info *tp;
9d3789f7 1699
a493e3e2 1700 last_sig = GDB_SIGNAL_0;
9d3789f7
CF
1701 event_count = 0;
1702 exception_count = 0;
bf25528d 1703 open_process_used = 0;
fa4ba8da 1704 debug_registers_changed = 0;
dfe7f3ac 1705 debug_registers_used = 0;
fa4ba8da
PM
1706 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1707 dr[i] = 0;
10325bc5 1708#ifdef __CYGWIN__
de1b3c3d 1709 cygwin_load_start = cygwin_load_end = 0;
10325bc5 1710#endif
9d3789f7
CF
1711 current_event.dwProcessId = pid;
1712 memset (&current_event, 0, sizeof (current_event));
0795be10 1713 push_target (ops);
cb851954 1714 disable_breakpoints_in_shlibs ();
dc05df57 1715 windows_clear_solib ();
9d3789f7
CF
1716 clear_proceed_status ();
1717 init_wait_for_inferior ();
1718
6c95b8df
PA
1719 inf = current_inferior ();
1720 inferior_appeared (inf, pid);
181e7f93 1721 inf->attach_flag = attaching;
7f9f62ba 1722
9f9d052e
PM
1723 /* Make the new process the current inferior, so terminal handling
1724 can rely on it. When attaching, we don't know about any thread
1725 id here, but that's OK --- nothing should be referencing the
dc05df57 1726 current thread until we report an event out of windows_wait. */
9f9d052e
PM
1727 inferior_ptid = pid_to_ptid (pid);
1728
c44537cf 1729 terminal_init_inferior_with_pgrp (pid);
9d3789f7
CF
1730 target_terminal_inferior ();
1731
16d905e2 1732 windows_initialization_done = 0;
16c381f0 1733 inf->control.stop_soon = STOP_QUIETLY;
9d3789f7
CF
1734 while (1)
1735 {
1736 stop_after_trap = 1;
e4c8541f 1737 wait_for_inferior ();
2020b7ab 1738 tp = inferior_thread ();
a493e3e2 1739 if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP)
16c381f0 1740 resume (0, tp->suspend.stop_signal);
9d3789f7
CF
1741 else
1742 break;
1743 }
eff8332b 1744
ea39ad35 1745 /* Now that the inferior has been started and all DLLs have been mapped,
3be75f87
JB
1746 we can iterate over all DLLs and load them in.
1747
1748 We avoid doing it any earlier because, on certain versions of Windows,
1749 LOAD_DLL_DEBUG_EVENTs are sometimes not complete. In particular,
1750 we have seen on Windows 8.1 that the ntdll.dll load event does not
1751 include the DLL name, preventing us from creating an associated SO.
1752 A possible explanation is that ntdll.dll might be mapped before
1753 the SO info gets created by the Windows system -- ntdll.dll is
1754 the first DLL to be reported via LOAD_DLL_DEBUG_EVENT and other DLLs
1755 do not seem to suffer from that problem.
1756
1757 Rather than try to work around this sort of issue, it is much
1758 simpler to just ignore DLL load/unload events during the startup
1759 phase, and then process them all in one batch now. */
ea39ad35 1760 windows_add_all_dlls ();
94481b8c 1761
16d905e2 1762 windows_initialization_done = 1;
16c381f0 1763 inf->control.stop_soon = NO_STOP_QUIETLY;
9d3789f7
CF
1764 stop_after_trap = 0;
1765 return;
1766}
1767
616a9dc4
CV
1768/* Try to set or remove a user privilege to the current process. Return -1
1769 if that fails, the previous setting of that privilege otherwise.
1770
1771 This code is copied from the Cygwin source code and rearranged to allow
1772 dynamically loading of the needed symbols from advapi32 which is only
581e13c1 1773 available on NT/2K/XP. */
616a9dc4
CV
1774static int
1775set_process_privilege (const char *privilege, BOOL enable)
1776{
616a9dc4
CV
1777 HANDLE token_hdl = NULL;
1778 LUID restore_priv;
1779 TOKEN_PRIVILEGES new_priv, orig_priv;
1780 int ret = -1;
1781 DWORD size;
1782
616a9dc4
CV
1783 if (!OpenProcessToken (GetCurrentProcess (),
1784 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1785 &token_hdl))
1786 goto out;
1787
418c6cb3 1788 if (!LookupPrivilegeValueA (NULL, privilege, &restore_priv))
616a9dc4
CV
1789 goto out;
1790
1791 new_priv.PrivilegeCount = 1;
1792 new_priv.Privileges[0].Luid = restore_priv;
1793 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1794
1795 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
295732ea 1796 sizeof orig_priv, &orig_priv, &size))
616a9dc4
CV
1797 goto out;
1798#if 0
1799 /* Disabled, otherwise every `attach' in an unprivileged user session
1800 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
581e13c1 1801 windows_attach(). */
616a9dc4 1802 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
581e13c1 1803 be enabled. GetLastError () returns an correct error code, though. */
616a9dc4
CV
1804 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1805 goto out;
1806#endif
1807
1808 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1809
1810out:
1811 if (token_hdl)
1812 CloseHandle (token_hdl);
1813
1814 return ret;
1815}
1816
02cc9f49 1817/* Attach to process PID, then initialize for debugging it. */
24e60978 1818static void
dc05df57 1819windows_attach (struct target_ops *ops, char *args, int from_tty)
24e60978
SC
1820{
1821 BOOL ok;
559e75c0 1822 DWORD pid;
24e60978 1823
74164c56 1824 pid = parse_pid_to_attach (args);
24e60978 1825
616a9dc4
CV
1826 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1827 {
1828 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
581e13c1
MS
1829 printf_unfiltered ("This can cause attach to "
1830 "fail on Windows NT/2K/XP\n");
616a9dc4
CV
1831 }
1832
dc05df57 1833 windows_init_thread_list ();
9d3789f7 1834 ok = DebugActiveProcess (pid);
91a175b3 1835 saw_create = 0;
24e60978 1836
10325bc5 1837#ifdef __CYGWIN__
24e60978 1838 if (!ok)
baa93fa6 1839 {
581e13c1 1840 /* Try fall back to Cygwin pid. */
baa93fa6
CF
1841 pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1842
1843 if (pid > 0)
1844 ok = DebugActiveProcess (pid);
10325bc5
PA
1845 }
1846#endif
baa93fa6 1847
10325bc5
PA
1848 if (!ok)
1849 error (_("Can't attach to process."));
24e60978 1850
2b008701 1851 DebugSetProcessKillOnExit (FALSE);
3ade5333 1852
24e60978
SC
1853 if (from_tty)
1854 {
1855 char *exec_file = (char *) get_exec_file (0);
1856
1857 if (exec_file)
1858 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1859 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1860 else
1861 printf_unfiltered ("Attaching to %s\n",
39f77062 1862 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1863
1864 gdb_flush (gdb_stdout);
1865 }
1866
dc05df57 1867 do_initial_windows_stuff (ops, pid, 1);
9d3789f7 1868 target_terminal_ours ();
24e60978
SC
1869}
1870
24e60978 1871static void
52554a0e 1872windows_detach (struct target_ops *ops, const char *args, int from_tty)
24e60978 1873{
02cc9f49
CV
1874 int detached = 1;
1875
2b008701 1876 ptid_t ptid = {-1};
a493e3e2 1877 windows_resume (ops, ptid, 0, GDB_SIGNAL_0);
96998ce7 1878
2b008701
CF
1879 if (!DebugActiveProcessStop (current_event.dwProcessId))
1880 {
d50a0ce2
CV
1881 error (_("Can't detach process %u (error %u)"),
1882 (unsigned) current_event.dwProcessId, (unsigned) GetLastError ());
2b008701 1883 detached = 0;
02cc9f49 1884 }
2b008701
CF
1885 DebugSetProcessKillOnExit (FALSE);
1886
02cc9f49 1887 if (detached && from_tty)
24e60978
SC
1888 {
1889 char *exec_file = get_exec_file (0);
1890 if (exec_file == 0)
1891 exec_file = "";
d50a0ce2
CV
1892 printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file,
1893 (unsigned) current_event.dwProcessId);
24e60978
SC
1894 gdb_flush (gdb_stdout);
1895 }
7f9f62ba 1896
26cb8b7c 1897 i386_cleanup_dregs ();
39f77062 1898 inferior_ptid = null_ptid;
7f9f62ba
PA
1899 detach_inferior (current_event.dwProcessId);
1900
0795be10 1901 unpush_target (ops);
24e60978
SC
1902}
1903
47f7ffdb
JB
1904/* Try to determine the executable filename.
1905
1906 EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.
1907
1908 Upon success, the filename is stored inside EXE_NAME_RET, and
1909 this function returns nonzero.
1910
1911 Otherwise, this function returns zero and the contents of
1912 EXE_NAME_RET is undefined. */
1913
1914static int
1915windows_get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len)
1916{
1917 DWORD len;
1918 HMODULE dh_buf;
1919 DWORD cbNeeded;
1920
1921 cbNeeded = 0;
1922 if (!EnumProcessModules (current_process_handle, &dh_buf,
1923 sizeof (HMODULE), &cbNeeded) || !cbNeeded)
1924 return 0;
1925
1926 /* We know the executable is always first in the list of modules,
1927 which we just fetched. So no need to fetch more. */
1928
1929#ifdef __CYGWIN__
1930 {
1931 /* Cygwin prefers that the path be in /x/y/z format, so extract
1932 the filename into a temporary buffer first, and then convert it
1933 to POSIX format into the destination buffer. */
1934 cygwin_buf_t *pathbuf = alloca (exe_name_max_len * sizeof (cygwin_buf_t));
1935
1936 len = GetModuleFileNameEx (current_process_handle,
1937 dh_buf, pathbuf, exe_name_max_len);
1938 if (len == 0)
1939 error (_("Error getting executable filename: %u."),
1940 (unsigned) GetLastError ());
1941 if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, exe_name_ret,
1942 exe_name_max_len) < 0)
1943 error (_("Error converting executable filename to POSIX: %d."), errno);
1944 }
1945#else
1946 len = GetModuleFileNameEx (current_process_handle,
1947 dh_buf, exe_name_ret, exe_name_max_len);
1948 if (len == 0)
1949 error (_("Error getting executable filename: %u."),
1950 (unsigned) GetLastError ());
1951#endif
1952
1953 return 1; /* success */
1954}
1955
1956/* The pid_to_exec_file target_ops method for this platform. */
1957
3ee6f623 1958static char *
8dd27370 1959windows_pid_to_exec_file (struct target_ops *self, int pid)
47216e51 1960{
b3c613f2 1961 static char path[__PMAX];
10325bc5 1962#ifdef __CYGWIN__
581e13c1 1963 /* Try to find exe name as symlink target of /proc/<pid>/exe. */
33605d39
CF
1964 int nchars;
1965 char procexe[sizeof ("/proc/4294967295/exe")];
08850b56
PM
1966
1967 xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid);
33605d39
CF
1968 nchars = readlink (procexe, path, sizeof(path));
1969 if (nchars > 0 && nchars < sizeof (path))
47216e51 1970 {
33605d39
CF
1971 path[nchars] = '\0'; /* Got it */
1972 return path;
47216e51 1973 }
10325bc5
PA
1974#endif
1975
33605d39 1976 /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
581e13c1 1977 of gdb, or we're trying to debug a non-Cygwin windows executable. */
47f7ffdb 1978 if (!windows_get_exec_module_filename (path, sizeof (path)))
33605d39
CF
1979 path[0] = '\0';
1980
1981 return path;
47216e51
CV
1982}
1983
24e60978
SC
1984/* Print status information about what we're accessing. */
1985
1986static void
dc05df57 1987windows_files_info (struct target_ops *ignore)
24e60978 1988{
181e7f93
PA
1989 struct inferior *inf = current_inferior ();
1990
24e60978 1991 printf_unfiltered ("\tUsing the running image of %s %s.\n",
181e7f93
PA
1992 inf->attach_flag ? "attached" : "child",
1993 target_pid_to_str (inferior_ptid));
24e60978
SC
1994}
1995
24e60978 1996static void
dc05df57 1997windows_open (char *arg, int from_tty)
24e60978 1998{
8a3fe4f8 1999 error (_("Use the \"run\" command to start a Unix child process."));
24e60978
SC
2000}
2001
cd44747c
PM
2002/* Modify CreateProcess parameters for use of a new separate console.
2003 Parameters are:
2004 *FLAGS: DWORD parameter for general process creation flags.
2005 *SI: STARTUPINFO structure, for which the console window size and
2006 console buffer size is filled in if GDB is running in a console.
2007 to create the new console.
2008 The size of the used font is not available on all versions of
2009 Windows OS. Furthermore, the current font might not be the default
2010 font, but this is still better than before.
2011 If the windows and buffer sizes are computed,
2012 SI->DWFLAGS is changed so that this information is used
2013 by CreateProcess function. */
2014
2015static void
2016windows_set_console_info (STARTUPINFO *si, DWORD *flags)
2017{
2018 HANDLE hconsole = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
2019 FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2020
2021 if (hconsole != INVALID_HANDLE_VALUE)
2022 {
2023 CONSOLE_SCREEN_BUFFER_INFO sbinfo;
2024 COORD font_size;
2025 CONSOLE_FONT_INFO cfi;
2026
2027 GetCurrentConsoleFont (hconsole, FALSE, &cfi);
2028 font_size = GetConsoleFontSize (hconsole, cfi.nFont);
2029 GetConsoleScreenBufferInfo(hconsole, &sbinfo);
2030 si->dwXSize = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1;
2031 si->dwYSize = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1;
2032 if (font_size.X)
2033 si->dwXSize *= font_size.X;
2034 else
2035 si->dwXSize *= 8;
2036 if (font_size.Y)
2037 si->dwYSize *= font_size.Y;
2038 else
2039 si->dwYSize *= 12;
2040 si->dwXCountChars = sbinfo.dwSize.X;
2041 si->dwYCountChars = sbinfo.dwSize.Y;
2042 si->dwFlags |= STARTF_USESIZE | STARTF_USECOUNTCHARS;
2043 }
2044 *flags |= CREATE_NEW_CONSOLE;
2045}
2046
c93dbcba
EZ
2047#ifndef __CYGWIN__
2048/* Function called by qsort to sort environment strings. */
2049
2050static int
2051envvar_cmp (const void *a, const void *b)
2052{
2053 const char **p = (const char **) a;
2054 const char **q = (const char **) b;
2055 return strcasecmp (*p, *q);
2056}
2057#endif
2058
b7ff339d
CV
2059#ifdef __CYGWIN__
2060static void
2061clear_win32_environment (char **env)
2062{
2063 int i;
2064 size_t len;
2065 wchar_t *copy = NULL, *equalpos;
2066
2067 for (i = 0; env[i] && *env[i]; i++)
2068 {
2069 len = mbstowcs (NULL, env[i], 0) + 1;
2070 copy = (wchar_t *) xrealloc (copy, len * sizeof (wchar_t));
2071 mbstowcs (copy, env[i], len);
2072 equalpos = wcschr (copy, L'=');
2073 if (equalpos)
2074 *equalpos = L'\0';
2075 SetEnvironmentVariableW (copy, NULL);
2076 }
2077 xfree (copy);
2078}
2079#endif
2080
dc05df57 2081/* Start an inferior windows child process and sets inferior_ptid to its pid.
24e60978
SC
2082 EXEC_FILE is the file to run.
2083 ALLARGS is a string containing the arguments to the program.
2084 ENV is the environment vector to pass. Errors reported with error(). */
2085
24e60978 2086static void
dc05df57 2087windows_create_inferior (struct target_ops *ops, char *exec_file,
136d6dae 2088 char *allargs, char **in_env, int from_tty)
24e60978 2089{
b3c613f2 2090 STARTUPINFO si;
41b4aadc 2091#ifdef __CYGWIN__
b3c613f2
CF
2092 cygwin_buf_t real_path[__PMAX];
2093 cygwin_buf_t shell[__PMAX]; /* Path to shell */
d0d0ab16 2094 const char *sh;
b3c613f2
CF
2095 cygwin_buf_t *toexec;
2096 cygwin_buf_t *cygallargs;
2097 cygwin_buf_t *args;
b7ff339d
CV
2098 char **old_env = NULL;
2099 PWCHAR w32_env;
d0d0ab16 2100 size_t len;
2becadee
CF
2101 int tty;
2102 int ostdin, ostdout, ostderr;
41b4aadc 2103#else
b3c613f2
CF
2104 char real_path[__PMAX];
2105 char shell[__PMAX]; /* Path to shell */
d0d0ab16
CV
2106 char *toexec;
2107 char *args;
8f205f9c 2108 size_t args_len;
41b4aadc 2109 HANDLE tty;
c93dbcba
EZ
2110 char *w32env;
2111 char *temp;
2112 size_t envlen;
2113 int i;
2114 size_t envsize;
2115 char **env;
41b4aadc 2116#endif
d0d0ab16
CV
2117 PROCESS_INFORMATION pi;
2118 BOOL ret;
2119 DWORD flags = 0;
3cb3b8df 2120 const char *inferior_io_terminal = get_inferior_io_terminal ();
24e60978
SC
2121
2122 if (!exec_file)
8a3fe4f8 2123 error (_("No executable specified, use `target exec'."));
24e60978
SC
2124
2125 memset (&si, 0, sizeof (si));
2126 si.cb = sizeof (si);
2127
d0d0ab16
CV
2128 if (new_group)
2129 flags |= CREATE_NEW_PROCESS_GROUP;
2130
2131 if (new_console)
cd44747c 2132 windows_set_console_info (&si, &flags);
d0d0ab16 2133
10325bc5 2134#ifdef __CYGWIN__
349b409f 2135 if (!useshell)
dfe7f3ac 2136 {
d0d0ab16
CV
2137 flags |= DEBUG_ONLY_THIS_PROCESS;
2138 if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
b3c613f2 2139 __PMAX * sizeof (cygwin_buf_t)) < 0)
d0d0ab16 2140 error (_("Error starting executable: %d"), errno);
dfe7f3ac 2141 toexec = real_path;
b3c613f2 2142#ifdef __USEWIDE
d0d0ab16
CV
2143 len = mbstowcs (NULL, allargs, 0) + 1;
2144 if (len == (size_t) -1)
2145 error (_("Error starting executable: %d"), errno);
2146 cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
2147 mbstowcs (cygallargs, allargs, len);
60c5c021
CF
2148#else
2149 cygallargs = allargs;
b3c613f2 2150#endif
dfe7f3ac
CF
2151 }
2152 else
2153 {
349b409f
CF
2154 sh = getenv ("SHELL");
2155 if (!sh)
2156 sh = "/bin/sh";
b3c613f2 2157 if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0)
d0d0ab16 2158 error (_("Error starting executable via shell: %d"), errno);
b3c613f2 2159#ifdef __USEWIDE
d0d0ab16
CV
2160 len = sizeof (L" -c 'exec '") + mbstowcs (NULL, exec_file, 0)
2161 + mbstowcs (NULL, allargs, 0) + 2;
2162 cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
2163 swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
b3c613f2 2164#else
08850b56
PM
2165 len = (sizeof (" -c 'exec '") + strlen (exec_file)
2166 + strlen (allargs) + 2);
2167 cygallargs = (char *) alloca (len);
2168 xsnprintf (cygallargs, len, " -c 'exec %s %s'", exec_file, allargs);
b3c613f2 2169#endif
dfe7f3ac 2170 toexec = shell;
d0d0ab16 2171 flags |= DEBUG_PROCESS;
dfe7f3ac 2172 }
b3c613f2
CF
2173
2174#ifdef __USEWIDE
2175 args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
2176 * sizeof (wchar_t));
d0d0ab16
CV
2177 wcscpy (args, toexec);
2178 wcscat (args, L" ");
2179 wcscat (args, cygallargs);
b3c613f2
CF
2180#else
2181 args = (cygwin_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2);
2182 strcpy (args, toexec);
2183 strcat (args, " ");
2184 strcat (args, cygallargs);
2185#endif
2186
b7ff339d
CV
2187#ifdef CW_CVT_ENV_TO_WINENV
2188 /* First try to create a direct Win32 copy of the POSIX environment. */
2189 w32_env = (PWCHAR) cygwin_internal (CW_CVT_ENV_TO_WINENV, in_env);
2190 if (w32_env != (PWCHAR) -1)
2191 flags |= CREATE_UNICODE_ENVIRONMENT;
2192 else
2193 /* If that fails, fall back to old method tweaking GDB's environment. */
2194#endif
2195 {
2196 /* Reset all Win32 environment variables to avoid leftover on next run. */
2197 clear_win32_environment (environ);
2198 /* Prepare the environment vars for CreateProcess. */
2199 old_env = environ;
2200 environ = in_env;
2201 cygwin_internal (CW_SYNC_WINENV);
2202 w32_env = NULL;
2203 }
1750a5ef 2204
2becadee
CF
2205 if (!inferior_io_terminal)
2206 tty = ostdin = ostdout = ostderr = -1;
2207 else
2208 {
2209 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
2210 if (tty < 0)
2211 {
2212 print_sys_errmsg (inferior_io_terminal, errno);
2213 ostdin = ostdout = ostderr = -1;
2214 }
2215 else
2216 {
2217 ostdin = dup (0);
2218 ostdout = dup (1);
2219 ostderr = dup (2);
2220 dup2 (tty, 0);
2221 dup2 (tty, 1);
2222 dup2 (tty, 2);
2223 }
2224 }
d0d0ab16
CV
2225
2226 windows_init_thread_list ();
b3c613f2
CF
2227 ret = CreateProcess (0,
2228 args, /* command line */
2229 NULL, /* Security */
2230 NULL, /* thread */
2231 TRUE, /* inherit handles */
2232 flags, /* start flags */
b7ff339d 2233 w32_env, /* environment */
b3c613f2
CF
2234 NULL, /* current directory */
2235 &si,
2236 &pi);
b7ff339d
CV
2237 if (w32_env)
2238 /* Just free the Win32 environment, if it could be created. */
2239 free (w32_env);
2240 else
2241 {
2242 /* Reset all environment variables to avoid leftover on next run. */
2243 clear_win32_environment (in_env);
2244 /* Restore normal GDB environment variables. */
2245 environ = old_env;
2246 cygwin_internal (CW_SYNC_WINENV);
2247 }
2248
d0d0ab16
CV
2249 if (tty >= 0)
2250 {
2251 close (tty);
2252 dup2 (ostdin, 0);
2253 dup2 (ostdout, 1);
2254 dup2 (ostderr, 2);
2255 close (ostdin);
2256 close (ostdout);
2257 close (ostderr);
2258 }
41b4aadc 2259#else
b3c613f2 2260 toexec = exec_file;
8f205f9c
JB
2261 /* Build the command line, a space-separated list of tokens where
2262 the first token is the name of the module to be executed.
2263 To avoid ambiguities introduced by spaces in the module name,
2264 we quote it. */
2265 args_len = strlen (toexec) + 2 /* quotes */ + strlen (allargs) + 2;
2266 args = alloca (args_len);
2267 xsnprintf (args, args_len, "\"%s\" %s", toexec, allargs);
d0d0ab16 2268
d0d0ab16
CV
2269 flags |= DEBUG_ONLY_THIS_PROCESS;
2270
41b4aadc
CF
2271 if (!inferior_io_terminal)
2272 tty = INVALID_HANDLE_VALUE;
2273 else
2274 {
2275 SECURITY_ATTRIBUTES sa;
2276 sa.nLength = sizeof(sa);
2277 sa.lpSecurityDescriptor = 0;
2278 sa.bInheritHandle = TRUE;
2279 tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE,
2280 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
2281 if (tty == INVALID_HANDLE_VALUE)
2282 warning (_("Warning: Failed to open TTY %s, error %#x."),
2283 inferior_io_terminal, (unsigned) GetLastError ());
2284 else
2285 {
2286 si.hStdInput = tty;
2287 si.hStdOutput = tty;
2288 si.hStdError = tty;
2289 si.dwFlags |= STARTF_USESTDHANDLES;
2290 }
2291 }
2becadee 2292
c93dbcba
EZ
2293 /* CreateProcess takes the environment list as a null terminated set of
2294 strings (i.e. two nulls terminate the list). */
2295
2296 /* Get total size for env strings. */
2297 for (envlen = 0, i = 0; in_env[i] && *in_env[i]; i++)
2298 envlen += strlen (in_env[i]) + 1;
2299
2300 envsize = sizeof (in_env[0]) * (i + 1);
2301 env = (char **) alloca (envsize);
2302 memcpy (env, in_env, envsize);
2303 /* Windows programs expect the environment block to be sorted. */
2304 qsort (env, i, sizeof (char *), envvar_cmp);
2305
2306 w32env = alloca (envlen + 1);
2307
2308 /* Copy env strings into new buffer. */
2309 for (temp = w32env, i = 0; env[i] && *env[i]; i++)
2310 {
2311 strcpy (temp, env[i]);
2312 temp += strlen (temp) + 1;
2313 }
2314
2315 /* Final nil string to terminate new env. */
2316 *temp = 0;
2317
dc05df57 2318 windows_init_thread_list ();
d0d0ab16
CV
2319 ret = CreateProcessA (0,
2320 args, /* command line */
2321 NULL, /* Security */
2322 NULL, /* thread */
2323 TRUE, /* inherit handles */
2324 flags, /* start flags */
c93dbcba 2325 w32env, /* environment */
d0d0ab16
CV
2326 NULL, /* current directory */
2327 &si,
2328 &pi);
41b4aadc
CF
2329 if (tty != INVALID_HANDLE_VALUE)
2330 CloseHandle (tty);
10325bc5 2331#endif
2becadee 2332
24e60978 2333 if (!ret)
d50a0ce2 2334 error (_("Error creating process %s, (error %u)."),
8a3fe4f8 2335 exec_file, (unsigned) GetLastError ());
24e60978 2336
c1766e7d
PM
2337 CloseHandle (pi.hThread);
2338 CloseHandle (pi.hProcess);
2339
dfe7f3ac
CF
2340 if (useshell && shell[0] != '\0')
2341 saw_create = -1;
2342 else
2343 saw_create = 0;
2344
dc05df57 2345 do_initial_windows_stuff (ops, pi.dwProcessId, 0);
d3a09475 2346
dc05df57 2347 /* windows_continue (DBG_CONTINUE, -1); */
24e60978
SC
2348}
2349
2350static void
dc05df57 2351windows_mourn_inferior (struct target_ops *ops)
24e60978 2352{
dc05df57 2353 (void) windows_continue (DBG_CONTINUE, -1);
fa4ba8da 2354 i386_cleanup_dregs();
bf25528d
CF
2355 if (open_process_used)
2356 {
2357 CHECK (CloseHandle (current_process_handle));
2358 open_process_used = 0;
2359 }
0795be10 2360 unpush_target (ops);
24e60978
SC
2361 generic_mourn_inferior ();
2362}
2363
24e60978 2364/* Send a SIGINT to the process group. This acts just like the user typed a
581e13c1 2365 ^C on the controlling terminal. */
24e60978 2366
b607efe7 2367static void
1eab8a48 2368windows_stop (struct target_ops *self, ptid_t ptid)
24e60978 2369{
1ef980b9 2370 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1e37c281 2371 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
3a4b77d8 2372 registers_changed (); /* refresh register state */
24e60978
SC
2373}
2374
44f38867
PA
2375/* Helper for windows_xfer_partial that handles memory transfers.
2376 Arguments are like target_xfer_partial. */
2377
9b409511 2378static enum target_xfer_status
44f38867 2379windows_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
9b409511 2380 ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
24e60978 2381{
5732a500 2382 SIZE_T done = 0;
44f38867 2383 BOOL success;
9e52adf9 2384 DWORD lasterror = 0;
44f38867
PA
2385
2386 if (writebuf != NULL)
24e60978 2387 {
a2388568 2388 DEBUG_MEM (("gdb: write target memory, %s bytes at %s\n",
b55e14c7 2389 pulongest (len), core_addr_to_string (memaddr)));
44f38867
PA
2390 success = WriteProcessMemory (current_process_handle,
2391 (LPVOID) (uintptr_t) memaddr, writebuf,
2392 len, &done);
9e52adf9 2393 if (!success)
7126d5c8 2394 lasterror = GetLastError ();
2b008701 2395 FlushInstructionCache (current_process_handle,
2c647436 2396 (LPCVOID) (uintptr_t) memaddr, len);
24e60978
SC
2397 }
2398 else
2399 {
a2388568 2400 DEBUG_MEM (("gdb: read target memory, %s bytes at %s\n",
b55e14c7 2401 pulongest (len), core_addr_to_string (memaddr)));
44f38867
PA
2402 success = ReadProcessMemory (current_process_handle,
2403 (LPCVOID) (uintptr_t) memaddr, readbuf,
2404 len, &done);
9e52adf9 2405 if (!success)
7126d5c8 2406 lasterror = GetLastError ();
24e60978 2407 }
9b409511 2408 *xfered_len = (ULONGEST) done;
9e52adf9 2409 if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0)
9b409511 2410 return TARGET_XFER_OK;
9e52adf9 2411 else
9b409511 2412 return success ? TARGET_XFER_OK : TARGET_XFER_E_IO;
24e60978
SC
2413}
2414
3ee6f623 2415static void
7d85a9c0 2416windows_kill_inferior (struct target_ops *ops)
24e60978 2417{
3cee93ac
CF
2418 CHECK (TerminateProcess (current_process_handle, 0));
2419
b5edcb45
ILT
2420 for (;;)
2421 {
dc05df57 2422 if (!windows_continue (DBG_CONTINUE, -1))
b5edcb45 2423 break;
3cee93ac 2424 if (!WaitForDebugEvent (&current_event, INFINITE))
b5edcb45 2425 break;
3cee93ac 2426 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
b5edcb45
ILT
2427 break;
2428 }
2429
581e13c1 2430 target_mourn_inferior (); /* Or just windows_mourn_inferior? */
24e60978
SC
2431}
2432
24e60978 2433static void
f32dbf8c 2434windows_prepare_to_store (struct target_ops *self, struct regcache *regcache)
24e60978 2435{
581e13c1 2436 /* Do nothing, since we can store individual regs. */
24e60978
SC
2437}
2438
2439static int
da82bd6b 2440windows_can_run (struct target_ops *self)
24e60978
SC
2441{
2442 return 1;
2443}
2444
2445static void
de90e03d 2446windows_close (struct target_ops *self)
24e60978 2447{
dc05df57 2448 DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
dfd4cc63 2449 ptid_get_pid (inferior_ptid)));
24e60978 2450}
1ef980b9 2451
581e13c1 2452/* Convert pid to printable format. */
3ee6f623 2453static char *
117de6a9 2454windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
24e60978 2455{
3ee6f623 2456 static char buf[80];
3ee6f623 2457
2dc38344
PA
2458 if (ptid_get_tid (ptid) != 0)
2459 {
2460 snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
2461 ptid_get_pid (ptid), ptid_get_tid (ptid));
2462 return buf;
2463 }
2464
2465 return normal_pid_to_str (ptid);
3ee6f623
CF
2466}
2467
9b409511 2468static enum target_xfer_status
dc05df57 2469windows_xfer_shared_libraries (struct target_ops *ops,
9b409511
YQ
2470 enum target_object object, const char *annex,
2471 gdb_byte *readbuf, const gdb_byte *writebuf,
2472 ULONGEST offset, ULONGEST len,
2473 ULONGEST *xfered_len)
3cb8e7f6 2474{
de1b3c3d
PA
2475 struct obstack obstack;
2476 const char *buf;
2477 LONGEST len_avail;
3cb8e7f6 2478 struct so_list *so;
3cb8e7f6 2479
de1b3c3d 2480 if (writebuf)
2ed4b548 2481 return TARGET_XFER_E_IO;
3cb8e7f6 2482
de1b3c3d
PA
2483 obstack_init (&obstack);
2484 obstack_grow_str (&obstack, "<library-list>\n");
2485 for (so = solib_start.next; so; so = so->next)
581e13c1
MS
2486 windows_xfer_shared_library (so->so_name, (CORE_ADDR)
2487 (uintptr_t) so->lm_info->load_addr,
f5656ead 2488 target_gdbarch (), &obstack);
de1b3c3d 2489 obstack_grow_str0 (&obstack, "</library-list>\n");
3cb8e7f6 2490
de1b3c3d
PA
2491 buf = obstack_finish (&obstack);
2492 len_avail = strlen (buf);
2493 if (offset >= len_avail)
49dc7f4b
PM
2494 len= 0;
2495 else
2496 {
2497 if (len > len_avail - offset)
2498 len = len_avail - offset;
2499 memcpy (readbuf, buf + offset, len);
2500 }
3cb8e7f6 2501
de1b3c3d 2502 obstack_free (&obstack, NULL);
9b409511 2503 *xfered_len = (ULONGEST) len;
0837c976 2504 return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
3cb8e7f6
CF
2505}
2506
9b409511 2507static enum target_xfer_status
dc05df57 2508windows_xfer_partial (struct target_ops *ops, enum target_object object,
9b409511
YQ
2509 const char *annex, gdb_byte *readbuf,
2510 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
2511 ULONGEST *xfered_len)
3cb8e7f6 2512{
de1b3c3d 2513 switch (object)
3cb8e7f6 2514 {
de1b3c3d 2515 case TARGET_OBJECT_MEMORY:
9b409511 2516 return windows_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
de1b3c3d
PA
2517
2518 case TARGET_OBJECT_LIBRARIES:
dc05df57 2519 return windows_xfer_shared_libraries (ops, object, annex, readbuf,
9b409511 2520 writebuf, offset, len, xfered_len);
3929abe9 2521
de1b3c3d
PA
2522 default:
2523 if (ops->beneath != NULL)
2524 return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
9b409511
YQ
2525 readbuf, writebuf, offset, len,
2526 xfered_len);
2ed4b548 2527 return TARGET_XFER_E_IO;
3929abe9 2528 }
02c5aecd
CF
2529}
2530
711e434b
PM
2531/* Provide thread local base, i.e. Thread Information Block address.
2532 Returns 1 if ptid is found and sets *ADDR to thread_local_base. */
2533
2534static int
bd7ae0f5
TT
2535windows_get_tib_address (struct target_ops *self,
2536 ptid_t ptid, CORE_ADDR *addr)
711e434b
PM
2537{
2538 thread_info *th;
2539
2540 th = thread_rec (ptid_get_tid (ptid), 0);
2541 if (th == NULL)
2542 return 0;
2543
2544 if (addr != NULL)
2545 *addr = th->thread_local_base;
2546
2547 return 1;
2548}
2549
1e2f1c5c 2550static ptid_t
1e6b91a4 2551windows_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
1e2f1c5c
JB
2552{
2553 return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
2554}
2555
3ee6f623 2556static void
dc05df57 2557init_windows_ops (void)
3ee6f623 2558{
dc05df57
CF
2559 windows_ops.to_shortname = "child";
2560 windows_ops.to_longname = "Win32 child process";
2561 windows_ops.to_doc = "Win32 child process (started by the \"run\" command).";
2562 windows_ops.to_open = windows_open;
2563 windows_ops.to_close = windows_close;
2564 windows_ops.to_attach = windows_attach;
2565 windows_ops.to_attach_no_wait = 1;
2566 windows_ops.to_detach = windows_detach;
2567 windows_ops.to_resume = windows_resume;
2568 windows_ops.to_wait = windows_wait;
2569 windows_ops.to_fetch_registers = windows_fetch_inferior_registers;
2570 windows_ops.to_store_registers = windows_store_inferior_registers;
2571 windows_ops.to_prepare_to_store = windows_prepare_to_store;
dc05df57
CF
2572 windows_ops.to_xfer_partial = windows_xfer_partial;
2573 windows_ops.to_files_info = windows_files_info;
2574 windows_ops.to_insert_breakpoint = memory_insert_breakpoint;
2575 windows_ops.to_remove_breakpoint = memory_remove_breakpoint;
2576 windows_ops.to_terminal_init = terminal_init_inferior;
2577 windows_ops.to_terminal_inferior = terminal_inferior;
2578 windows_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2579 windows_ops.to_terminal_ours = terminal_ours;
2580 windows_ops.to_terminal_save_ours = terminal_save_ours;
2581 windows_ops.to_terminal_info = child_terminal_info;
2582 windows_ops.to_kill = windows_kill_inferior;
2583 windows_ops.to_create_inferior = windows_create_inferior;
2584 windows_ops.to_mourn_inferior = windows_mourn_inferior;
2585 windows_ops.to_can_run = windows_can_run;
2586 windows_ops.to_thread_alive = windows_thread_alive;
2587 windows_ops.to_pid_to_str = windows_pid_to_str;
2588 windows_ops.to_stop = windows_stop;
2589 windows_ops.to_stratum = process_stratum;
c35b1492
PA
2590 windows_ops.to_has_all_memory = default_child_has_all_memory;
2591 windows_ops.to_has_memory = default_child_has_memory;
2592 windows_ops.to_has_stack = default_child_has_stack;
2593 windows_ops.to_has_registers = default_child_has_registers;
2594 windows_ops.to_has_execution = default_child_has_execution;
dc05df57 2595 windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
1e2f1c5c 2596 windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid;
711e434b 2597 windows_ops.to_get_tib_address = windows_get_tib_address;
9bb9e8ad 2598
5aca5a82
PM
2599 i386_use_watchpoints (&windows_ops);
2600
9bb9e8ad
PM
2601 i386_dr_low.set_control = cygwin_set_dr7;
2602 i386_dr_low.set_addr = cygwin_set_dr;
7b50312a 2603 i386_dr_low.get_addr = cygwin_get_dr;
9bb9e8ad 2604 i386_dr_low.get_status = cygwin_get_dr6;
7b50312a 2605 i386_dr_low.get_control = cygwin_get_dr7;
9bb9e8ad
PM
2606
2607 /* i386_dr_low.debug_register_length field is set by
2608 calling i386_set_debug_register_length function
2609 in processor windows specific native file. */
2610
dc05df57 2611 windows_ops.to_magic = OPS_MAGIC;
c719b714 2612}
24e60978 2613
3929abe9 2614static void
dc05df57 2615set_windows_aliases (char *argv0)
3929abe9
CF
2616{
2617 add_info_alias ("dll", "sharedlibrary", 1);
2618}
2619
d603d4b3
JK
2620/* -Wmissing-prototypes */
2621extern initialize_file_ftype _initialize_windows_nat;
2622
24e60978 2623void
dc05df57 2624_initialize_windows_nat (void)
24e60978 2625{
fa58ee11
EZ
2626 struct cmd_list_element *c;
2627
dc05df57 2628 init_windows_ops ();
1ef980b9 2629
d0d0ab16
CV
2630#ifdef __CYGWIN__
2631 cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
2632#endif
2633
fa58ee11 2634 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1bedd215 2635 _("Load dll library symbols from FILE."));
5ba2abeb 2636 set_cmd_completer (c, filename_completer);
95060284 2637 deprecate_cmd (c, "sharedlibrary");
450005e7 2638
95060284
JB
2639 c = add_com ("add-shared-symbol-files", class_files, dll_symbol_command,
2640 _("Load dll library symbols from FILE."));
2641 set_cmd_completer (c, filename_completer);
2642 deprecate_cmd (c, "sharedlibrary");
70992597 2643
95060284
JB
2644 c = add_com ("assf", class_files, dll_symbol_command,
2645 _("Load dll library symbols from FILE."));
2646 set_cmd_completer (c, filename_completer);
2647 deprecate_cmd (c, "sharedlibrary");
70992597 2648
10325bc5 2649#ifdef __CYGWIN__
5bf193a2
AC
2650 add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
2651Set use of shell to start subprocess."), _("\
2652Show use of shell to start subprocess."), NULL,
2653 NULL,
2654 NULL, /* FIXME: i18n: */
2655 &setlist, &showlist);
2656
581e13c1
MS
2657 add_setshow_boolean_cmd ("cygwin-exceptions", class_support,
2658 &cygwin_exceptions, _("\
09280ddf
CF
2659Break when an exception is detected in the Cygwin DLL itself."), _("\
2660Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL,
2661 NULL,
2662 NULL, /* FIXME: i18n: */
2663 &setlist, &showlist);
10325bc5 2664#endif
09280ddf 2665
5bf193a2
AC
2666 add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
2667Set creation of new console when creating child process."), _("\
2668Show creation of new console when creating child process."), NULL,
2669 NULL,
2670 NULL, /* FIXME: i18n: */
2671 &setlist, &showlist);
2672
2673 add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
2674Set creation of new group when creating child process."), _("\
2675Show creation of new group when creating child process."), NULL,
2676 NULL,
2677 NULL, /* FIXME: i18n: */
2678 &setlist, &showlist);
2679
2680 add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
2681Set whether to display execution in child process."), _("\
2682Show whether to display execution in child process."), NULL,
2683 NULL,
2684 NULL, /* FIXME: i18n: */
2685 &setlist, &showlist);
2686
2687 add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
2688Set whether to display kernel events in child process."), _("\
2689Show whether to display kernel events in child process."), NULL,
2690 NULL,
2691 NULL, /* FIXME: i18n: */
2692 &setlist, &showlist);
2693
2694 add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
2695Set whether to display memory accesses in child process."), _("\
2696Show whether to display memory accesses in child process."), NULL,
2697 NULL,
2698 NULL, /* FIXME: i18n: */
2699 &setlist, &showlist);
2700
2701 add_setshow_boolean_cmd ("debugexceptions", class_support,
2702 &debug_exceptions, _("\
2703Set whether to display kernel exceptions in child process."), _("\
2704Show whether to display kernel exceptions in child process."), NULL,
2705 NULL,
2706 NULL, /* FIXME: i18n: */
2707 &setlist, &showlist);
1ef980b9 2708
711e434b 2709 init_w32_command_list ();
c1748f97
PM
2710
2711 add_cmd ("selector", class_info, display_selectors,
1a966eab 2712 _("Display selectors infos."),
c1748f97 2713 &info_w32_cmdlist);
dc05df57
CF
2714 add_target (&windows_ops);
2715 deprecated_init_ui_hook = set_windows_aliases;
24e60978 2716}
3cee93ac 2717
fa4ba8da
PM
2718/* Hardware watchpoint support, adapted from go32-nat.c code. */
2719
2720/* Pass the address ADDR to the inferior in the I'th debug register.
2721 Here we just store the address in dr array, the registers will be
dc05df57 2722 actually set up when windows_continue is called. */
9bb9e8ad 2723static void
fa4ba8da
PM
2724cygwin_set_dr (int i, CORE_ADDR addr)
2725{
2726 if (i < 0 || i > 3)
2727 internal_error (__FILE__, __LINE__,
e2e0b3e5 2728 _("Invalid register %d in cygwin_set_dr.\n"), i);
41b4aadc 2729 dr[i] = addr;
fa4ba8da
PM
2730 debug_registers_changed = 1;
2731 debug_registers_used = 1;
2732}
2733
2734/* Pass the value VAL to the inferior in the DR7 debug control
2735 register. Here we just store the address in D_REGS, the watchpoint
dc05df57 2736 will be actually set up in windows_wait. */
9bb9e8ad
PM
2737static void
2738cygwin_set_dr7 (unsigned long val)
fa4ba8da 2739{
9bb9e8ad 2740 dr[7] = (CORE_ADDR) val;
fa4ba8da
PM
2741 debug_registers_changed = 1;
2742 debug_registers_used = 1;
2743}
2744
7b50312a
PA
2745/* Get the value of debug register I from the inferior. */
2746
2747static CORE_ADDR
2748cygwin_get_dr (int i)
2749{
2750 return dr[i];
2751}
2752
fa4ba8da
PM
2753/* Get the value of the DR6 debug status register from the inferior.
2754 Here we just return the value stored in dr[6]
2755 by the last call to thread_rec for current_event.dwThreadId id. */
9bb9e8ad 2756static unsigned long
fa4ba8da
PM
2757cygwin_get_dr6 (void)
2758{
9bb9e8ad 2759 return (unsigned long) dr[6];
fa4ba8da
PM
2760}
2761
7b50312a
PA
2762/* Get the value of the DR7 debug status register from the inferior.
2763 Here we just return the value stored in dr[7] by the last call to
2764 thread_rec for current_event.dwThreadId id. */
2765
2766static unsigned long
2767cygwin_get_dr7 (void)
2768{
2769 return (unsigned long) dr[7];
2770}
2771
2dc38344 2772/* Determine if the thread referenced by "ptid" is alive
3cee93ac 2773 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
581e13c1 2774 it means that the thread has died. Otherwise it is assumed to be alive. */
3cee93ac 2775static int
28439f5e 2776windows_thread_alive (struct target_ops *ops, ptid_t ptid)
3cee93ac 2777{
2dc38344
PA
2778 int tid;
2779
2780 gdb_assert (ptid_get_tid (ptid) != 0);
2781 tid = ptid_get_tid (ptid);
39f77062 2782
581e13c1
MS
2783 return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0
2784 ? FALSE : TRUE;
3cee93ac
CF
2785}
2786
d603d4b3
JK
2787/* -Wmissing-prototypes */
2788extern initialize_file_ftype _initialize_check_for_gdb_ini;
2789
2a3d5645
CF
2790void
2791_initialize_check_for_gdb_ini (void)
2792{
2793 char *homedir;
2794 if (inhibit_gdbinit)
2795 return;
2796
2797 homedir = getenv ("HOME");
2798 if (homedir)
2799 {
2800 char *p;
2801 char *oldini = (char *) alloca (strlen (homedir) +
2802 sizeof ("/gdb.ini"));
2803 strcpy (oldini, homedir);
2804 p = strchr (oldini, '\0');
0ba1096a 2805 if (p > oldini && !IS_DIR_SEPARATOR (p[-1]))
2a3d5645
CF
2806 *p++ = '/';
2807 strcpy (p, "gdb.ini");
2808 if (access (oldini, 0) == 0)
2809 {
2810 int len = strlen (oldini);
2811 char *newini = alloca (len + 1);
08850b56
PM
2812
2813 xsnprintf (newini, len + 1, "%.*s.gdbinit",
2814 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
8a3fe4f8 2815 warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
2a3d5645
CF
2816 }
2817 }
2818}
33605d39 2819
2b008701 2820/* Define dummy functions which always return error for the rare cases where
581e13c1 2821 these functions could not be found. */
2b008701
CF
2822static BOOL WINAPI
2823bad_DebugActiveProcessStop (DWORD w)
2824{
2825 return FALSE;
2826}
2827static BOOL WINAPI
2828bad_DebugBreakProcess (HANDLE w)
2829{
2830 return FALSE;
2831}
2832static BOOL WINAPI
2833bad_DebugSetProcessKillOnExit (BOOL w)
2834{
2835 return FALSE;
2836}
2837static BOOL WINAPI
2838bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
2839{
2840 return FALSE;
2841}
b3c613f2
CF
2842
2843#ifdef __USEWIDE
2b008701 2844static DWORD WINAPI
b3c613f2 2845bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
2b008701
CF
2846{
2847 return 0;
2848}
d0d0ab16
CV
2849#else
2850static DWORD WINAPI
b3c613f2 2851bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
d0d0ab16
CV
2852{
2853 return 0;
2854}
2855#endif
b3c613f2 2856
2b008701
CF
2857static BOOL WINAPI
2858bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
2859{
2860 return FALSE;
2861}
2862
418c6cb3
CF
2863static BOOL WINAPI
2864bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
2865{
2866 return FALSE;
2867}
2868
cd44747c
PM
2869static BOOL WINAPI
2870bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
2871{
2872 f->nFont = 0;
2873 return 1;
2874}
2875static COORD WINAPI
2876bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
2877{
2878 COORD size;
2879 size.X = 8;
2880 size.Y = 12;
2881 return size;
2882}
2883
d603d4b3
JK
2884/* -Wmissing-prototypes */
2885extern initialize_file_ftype _initialize_loadable;
2886
2b008701 2887/* Load any functions which may not be available in ancient versions
581e13c1 2888 of Windows. */
d603d4b3 2889
33605d39 2890void
2b008701 2891_initialize_loadable (void)
33605d39 2892{
2b008701
CF
2893 HMODULE hm = NULL;
2894
2895 hm = LoadLibrary ("kernel32.dll");
2896 if (hm)
33605d39 2897 {
b3c613f2 2898 DebugActiveProcessStop = (void *)
2b008701 2899 GetProcAddress (hm, "DebugActiveProcessStop");
b3c613f2 2900 DebugBreakProcess = (void *)
2b008701 2901 GetProcAddress (hm, "DebugBreakProcess");
b3c613f2 2902 DebugSetProcessKillOnExit = (void *)
2b008701 2903 GetProcAddress (hm, "DebugSetProcessKillOnExit");
cd44747c
PM
2904 GetConsoleFontSize = (void *)
2905 GetProcAddress (hm, "GetConsoleFontSize");
2906 GetCurrentConsoleFont = (void *)
2907 GetProcAddress (hm, "GetCurrentConsoleFont");
2b008701 2908 }
33605d39 2909
2b008701 2910 /* Set variables to dummy versions of these processes if the function
581e13c1 2911 wasn't found in kernel32.dll. */
b3c613f2
CF
2912 if (!DebugBreakProcess)
2913 DebugBreakProcess = bad_DebugBreakProcess;
2914 if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
2b008701 2915 {
b3c613f2
CF
2916 DebugActiveProcessStop = bad_DebugActiveProcessStop;
2917 DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
2b008701 2918 }
cd44747c
PM
2919 if (!GetConsoleFontSize)
2920 GetConsoleFontSize = bad_GetConsoleFontSize;
2921 if (!GetCurrentConsoleFont)
2922 GetCurrentConsoleFont = bad_GetCurrentConsoleFont;
33605d39 2923
2b008701 2924 /* Load optional functions used for retrieving filename information
581e13c1 2925 associated with the currently debugged process or its dlls. */
2b008701
CF
2926 hm = LoadLibrary ("psapi.dll");
2927 if (hm)
2928 {
b3c613f2 2929 EnumProcessModules = (void *)
2b008701 2930 GetProcAddress (hm, "EnumProcessModules");
b3c613f2 2931 GetModuleInformation = (void *)
2b008701 2932 GetProcAddress (hm, "GetModuleInformation");
b3c613f2
CF
2933 GetModuleFileNameEx = (void *)
2934 GetProcAddress (hm, GetModuleFileNameEx_name);
33605d39
CF
2935 }
2936
b3c613f2 2937 if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx)
2b008701
CF
2938 {
2939 /* Set variables to dummy versions of these processes if the function
581e13c1 2940 wasn't found in psapi.dll. */
b3c613f2
CF
2941 EnumProcessModules = bad_EnumProcessModules;
2942 GetModuleInformation = bad_GetModuleInformation;
2943 GetModuleFileNameEx = bad_GetModuleFileNameEx;
581e13c1
MS
2944 /* This will probably fail on Windows 9x/Me. Let the user know
2945 that we're missing some functionality. */
2946 warning(_("\
2947cannot automatically find executable file or library to read symbols.\n\
2948Use \"file\" or \"dll\" command to load executable/libraries directly."));
418c6cb3
CF
2949 }
2950
2951 hm = LoadLibrary ("advapi32.dll");
2952 if (hm)
2953 {
b3c613f2
CF
2954 OpenProcessToken = (void *) GetProcAddress (hm, "OpenProcessToken");
2955 LookupPrivilegeValueA = (void *)
418c6cb3 2956 GetProcAddress (hm, "LookupPrivilegeValueA");
b3c613f2 2957 AdjustTokenPrivileges = (void *)
418c6cb3
CF
2958 GetProcAddress (hm, "AdjustTokenPrivileges");
2959 /* Only need to set one of these since if OpenProcessToken fails nothing
581e13c1
MS
2960 else is needed. */
2961 if (!OpenProcessToken || !LookupPrivilegeValueA
2962 || !AdjustTokenPrivileges)
b3c613f2 2963 OpenProcessToken = bad_OpenProcessToken;
2b008701 2964 }
33605d39 2965}
This page took 1.927869 seconds and 4 git commands to generate.