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