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