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