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