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