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