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