* i386-tdep.c (get_longjmp_target): Fix compilation failure
[deliverable/binutils-gdb.git] / gdb / win32-nat.c
CommitLineData
c906108c 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.
c906108c
SS
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
c5aa993b 22 Foundation, Inc., 59 Temple Place - Suite 330,
4e052eda 23 Boston, MA 02111-1307, USA. */
c906108c 24
dfe7f3ac 25/* Originally by Steve Chamberlain, sac@cygnus.com */
c906108c
SS
26
27/* We assume we're being built with and will be used for cygwin. */
28
29#include "defs.h"
97da3b20 30#include "tm.h" /* required for SSE registers */
c906108c
SS
31#include "frame.h" /* required by inferior.h */
32#include "inferior.h"
33#include "target.h"
c906108c
SS
34#include "gdbcore.h"
35#include "command.h"
fa58ee11 36#include "completer.h"
4e052eda 37#include "regcache.h"
2a3d5645 38#include "top.h"
c25b74ac 39#include "i386-tdep.h"
c906108c
SS
40#include <signal.h>
41#include <sys/types.h>
42#include <fcntl.h>
43#include <stdlib.h>
c906108c 44#include <windows.h>
c2d11a7d 45#include <imagehlp.h>
29fe111d 46#include <sys/cygwin.h>
c906108c
SS
47
48#include "buildsym.h"
49#include "symfile.h"
50#include "objfiles.h"
51#include "gdb_string.h"
52#include "gdbthread.h"
53#include "gdbcmd.h"
54#include <sys/param.h>
c2d11a7d 55#include <unistd.h>
c906108c 56
7a292a7a 57/* The ui's event loop. */
507f3c78 58extern int (*ui_loop_hook) (int signo);
7a292a7a
SS
59
60/* If we're not using the old Cygwin header file set, define the
61 following which never should have been in the generic Win32 API
62 headers in the first place since they were our own invention... */
63#ifndef _GNU_H_WINDOWS_H
9d3789f7 64enum
8e860359
CF
65 {
66 FLAG_TRACE_BIT = 0x100,
67 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
68 };
7a292a7a 69#endif
8e860359
CF
70#include <sys/procfs.h>
71#include <psapi.h>
7a292a7a 72
97da3b20 73#ifdef HAVE_SSE_REGS
fa4ba8da
PM
74#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
75 | CONTEXT_EXTENDED_REGISTERS
97da3b20 76#else
fa4ba8da 77#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS
97da3b20
CF
78#endif
79
fa4ba8da
PM
80static unsigned dr[8];
81static int debug_registers_changed = 0;
82static int debug_registers_used = 0;
97da3b20 83
c906108c
SS
84/* The string sent by cygwin when it processes a signal.
85 FIXME: This should be in a cygwin include file. */
86#define CYGWIN_SIGNAL_STRING "cygwin: signal"
87
29fe111d 88#define CHECK(x) check (x, __FILE__,__LINE__)
dfe7f3ac 89#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
4e52d31c
PM
90#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
91#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
92#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
c906108c
SS
93
94/* Forward declaration */
95extern struct target_ops child_ops;
96
a14ed312 97static void child_stop (void);
39f77062 98static int win32_child_thread_alive (ptid_t);
a14ed312 99void child_kill_inferior (void);
c906108c 100
7393af7c
PM
101static enum target_signal last_sig = TARGET_SIGNAL_0;
102/* Set if a signal was received from the debugged process */
103
c906108c
SS
104/* Thread information structure used to track information that is
105 not available in gdb's thread structure. */
106typedef struct thread_info_struct
c5aa993b
JM
107 {
108 struct thread_info_struct *next;
109 DWORD id;
110 HANDLE h;
111 char *name;
112 int suspend_count;
113 CONTEXT context;
c2d11a7d 114 STACKFRAME sf;
8e860359
CF
115 }
116thread_info;
c2d11a7d 117
29fe111d 118static thread_info thread_head;
c906108c 119
c906108c
SS
120/* The process and thread handles for the above context. */
121
122static DEBUG_EVENT current_event; /* The current debug event from
123 WaitForDebugEvent */
124static HANDLE current_process_handle; /* Currently executing process */
125static thread_info *current_thread; /* Info on currently selected thread */
c5aa993b 126static DWORD main_thread_id; /* Thread ID of the main thread */
c906108c
SS
127
128/* Counts of things. */
129static int exception_count = 0;
130static int event_count = 0;
dfe7f3ac 131static int saw_create;
c906108c
SS
132
133/* User options. */
134static int new_console = 0;
c2d11a7d 135static int new_group = 1;
dfe7f3ac
CF
136static int debug_exec = 0; /* show execution */
137static int debug_events = 0; /* show events from kernel */
138static int debug_memory = 0; /* show target memory accesses */
c906108c 139static int debug_exceptions = 0; /* show target exceptions */
dfe7f3ac
CF
140static int useshell = 0; /* use shell for subprocesses */
141
142/* Path to shell */
143static char shell[MAX_PATH + 1];
c906108c
SS
144
145/* This vector maps GDB's idea of a register's number into an address
146 in the win32 exception context vector.
147
148 It also contains the bit mask needed to load the register in question.
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
158#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
159static const int mappings[] =
160{
c5aa993b
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]),
c2d11a7d
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),
ed9a39eb 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
c906108c
SS
206};
207
ed9a39eb
JM
208#undef context_offset
209
c906108c
SS
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
219static const struct xlate_exception
220 xlate[] =
221{
222 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
223 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
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},
c906108c
SS
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
c906108c
SS
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)
244{
245 thread_info *th;
246
c5aa993b 247 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
248 if (th->id == id)
249 {
250 if (!th->suspend_count && get_context)
251 {
8a892701 252 if (get_context > 0 && id != current_event.dwThreadId)
c906108c
SS
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;
c906108c 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 }
c906108c
SS
269 }
270 return th;
271 }
272
273 return NULL;
274}
275
276/* Add a thread to the thread list */
277static thread_info *
c5aa993b 278child_add_thread (DWORD id, HANDLE h)
c906108c
SS
279{
280 thread_info *th;
281
282 if ((th = thread_rec (id, FALSE)))
283 return th;
284
285 th = (thread_info *) xmalloc (sizeof (*th));
c5aa993b 286 memset (th, 0, sizeof (*th));
c906108c
SS
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 }
c906108c
SS
308 return th;
309}
310
311/* Clear out any old thread list and reintialize it to a
312 pristine state. */
313static void
fba45db2 314child_init_thread_list (void)
c906108c
SS
315{
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)
321 {
322 thread_info *here = th->next;
323 th->next = here->next;
324 (void) CloseHandle (here->h);
b8c9b27d 325 xfree (here);
c906108c
SS
326 }
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));
c906108c
SS
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)
345 {
346 thread_info *here = th->next;
347 th->next = here->next;
348 CloseHandle (here->h);
b8c9b27d 349 xfree (here);
c906108c
SS
350 }
351}
352
c906108c
SS
353static void
354do_child_fetch_inferior_registers (int r)
355{
c2d11a7d
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;
c2d11a7d
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);
c2d11a7d
JM
366 supply_register (r, (char *) &l);
367 }
368 else if (r >= 0)
ed9a39eb 369 supply_register (r, context_offset);
c906108c
SS
370 else
371 {
372 for (r = 0; r < NUM_REGS; r++)
373 do_child_fetch_inferior_registers (r);
374 }
375}
376
377static void
378child_fetch_inferior_registers (int r)
379{
39f77062 380 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
c906108c
SS
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]);
389 else
390 {
391 for (r = 0; r < NUM_REGS; r++)
392 do_child_store_inferior_registers (r);
393 }
394}
395
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);
c906108c
SS
401 do_child_store_inferior_registers (r);
402}
403
c2d11a7d
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;
c2d11a7d 409
3bccec63 410int
8e860359 411psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
c2d11a7d
JM
412{
413 DWORD len;
414 MODULEINFO mi;
415 int i;
8e860359
CF
416 HMODULE dh_buf[1];
417 HMODULE *DllHandle = dh_buf;
c2d11a7d
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)
c2d11a7d 425 {
8e860359
CF
426 if (psapi_loaded)
427 goto failed;
c2d11a7d
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");
c2d11a7d
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)
c2d11a7d
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);
c2d11a7d
JM
450
451 if (!ok || !cbNeeded)
452 goto failed;
453
8e860359 454 DllHandle = (HMODULE *) alloca (cbNeeded);
c2d11a7d
JM
455 if (!DllHandle)
456 goto failed;
457
458 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
459 DllHandle,
460 cbNeeded,
461 &cbNeeded);
c2d11a7d
JM
462 if (!ok)
463 goto failed;
464
29fe111d 465 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
c2d11a7d
JM
466 {
467 if (!(*psapi_GetModuleInformation) (current_process_handle,
8e860359
CF
468 DllHandle[i],
469 &mi,
470 sizeof (mi)))
c2d11a7d
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);
c2d11a7d 477 if (len == 0)
29fe111d 478 error ("Error getting dll name: %u\n", GetLastError ());
c2d11a7d
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
c906108c
SS
658/* Wait for child to do something. Return pid of child, or -1 in case
659 of error; store status through argument pointer OURSTATUS. */
c906108c 660static int
0a65a603 661handle_load_dll (void *dummy)
c906108c 662{
c5aa993b 663 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
c906108c 664 char dll_buf[MAX_PATH + 1];
450005e7 665 char *dll_name = NULL;
450005e7 666 char *p;
c906108c 667
c5aa993b 668 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 669
c2d11a7d 670 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
8e860359 671 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 672
c2d11a7d 673 dll_name = dll_buf;
c906108c 674
dfe7f3ac
CF
675 if (*dll_name == '\0')
676 dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
c906108c
SS
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
c906108c
SS
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. */
c906108c 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;
c906108c
SS
788}
789
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
c5aa993b 800 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
c906108c
SS
801 || !s || !*s)
802 return gotasig;
803
ed9a39eb 804 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
c906108c 805 {
ed9a39eb 806 if (strncmp (s, "cYg", 3) != 0)
29fe111d 807 warning ("%s", s);
c906108c 808 }
ed9a39eb 809 else
c906108c
SS
810 {
811 char *p;
c2d11a7d
JM
812 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
813 gotasig = target_signal_from_host (sig);
7a292a7a
SS
814 ourstatus->value.sig = gotasig;
815 if (gotasig)
c906108c
SS
816 ourstatus->kind = TARGET_WAITKIND_STOPPED;
817 }
818
b8c9b27d 819 xfree (s);
c906108c
SS
820 return gotasig;
821}
822
7393af7c 823#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
4e52d31c 824 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
7393af7c
PM
825 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
826
c906108c 827static int
450005e7 828handle_exception (struct target_waitstatus *ourstatus)
c906108c 829{
c906108c 830 thread_info *th;
29fe111d 831 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
c906108c 832
29fe111d 833 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 834
c906108c
SS
835 /* Record the context of the current thread */
836 th = thread_rec (current_event.dwThreadId, -1);
837
29fe111d 838 switch (code)
c906108c
SS
839 {
840 case EXCEPTION_ACCESS_VIOLATION:
7393af7c
PM
841 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
842 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
843 break;
844 case STATUS_STACK_OVERFLOW:
845 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
c906108c 846 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
7393af7c
PM
847 break;
848 case STATUS_FLOAT_DENORMAL_OPERAND:
849 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
850 ourstatus->value.sig = TARGET_SIGNAL_FPE;
851 break;
852 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
853 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
854 ourstatus->value.sig = TARGET_SIGNAL_FPE;
855 break;
856 case STATUS_FLOAT_INEXACT_RESULT:
857 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
858 ourstatus->value.sig = TARGET_SIGNAL_FPE;
859 break;
860 case STATUS_FLOAT_INVALID_OPERATION:
861 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
862 ourstatus->value.sig = TARGET_SIGNAL_FPE;
863 break;
864 case STATUS_FLOAT_OVERFLOW:
865 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
866 ourstatus->value.sig = TARGET_SIGNAL_FPE;
867 break;
868 case STATUS_FLOAT_STACK_CHECK:
869 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
870 ourstatus->value.sig = TARGET_SIGNAL_FPE;
c906108c 871 break;
0d06e24b 872 case STATUS_FLOAT_UNDERFLOW:
7393af7c
PM
873 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
874 ourstatus->value.sig = TARGET_SIGNAL_FPE;
875 break;
0d06e24b 876 case STATUS_FLOAT_DIVIDE_BY_ZERO:
7393af7c
PM
877 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
878 ourstatus->value.sig = TARGET_SIGNAL_FPE;
879 break;
0d06e24b 880 case STATUS_INTEGER_DIVIDE_BY_ZERO:
7393af7c 881 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
0d06e24b 882 ourstatus->value.sig = TARGET_SIGNAL_FPE;
0d06e24b 883 break;
7393af7c
PM
884 case STATUS_INTEGER_OVERFLOW:
885 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
886 ourstatus->value.sig = TARGET_SIGNAL_FPE;
c906108c
SS
887 break;
888 case EXCEPTION_BREAKPOINT:
7393af7c 889 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
c906108c
SS
890 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
891 break;
892 case DBG_CONTROL_C:
7393af7c 893 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
c906108c 894 ourstatus->value.sig = TARGET_SIGNAL_INT;
5b421780
PM
895 break;
896 case DBG_CONTROL_BREAK:
7393af7c 897 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
5b421780 898 ourstatus->value.sig = TARGET_SIGNAL_INT;
c906108c
SS
899 break;
900 case EXCEPTION_SINGLE_STEP:
7393af7c 901 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
c906108c
SS
902 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
903 break;
8227c82d 904 case EXCEPTION_ILLEGAL_INSTRUCTION:
7393af7c
PM
905 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
906 ourstatus->value.sig = TARGET_SIGNAL_ILL;
907 break;
908 case EXCEPTION_PRIV_INSTRUCTION:
909 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
910 ourstatus->value.sig = TARGET_SIGNAL_ILL;
911 break;
912 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
913 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
8227c82d
CF
914 ourstatus->value.sig = TARGET_SIGNAL_ILL;
915 break;
c906108c 916 default:
02e423b9
CF
917 if (current_event.u.Exception.dwFirstChance)
918 return 0;
29fe111d 919 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
c5aa993b 920 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 921 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
c906108c
SS
922 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
923 break;
924 }
925 exception_count++;
7393af7c 926 last_sig = ourstatus->value.sig;
c906108c
SS
927 return 1;
928}
929
930/* Resume all artificially suspended threads if we are continuing
931 execution */
932static BOOL
8a892701 933child_continue (DWORD continue_status, int id)
c906108c
SS
934{
935 int i;
936 thread_info *th;
937 BOOL res;
938
7393af7c
PM
939 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
940 current_event.dwProcessId, current_event.dwThreadId,
dfe7f3ac 941 continue_status == DBG_CONTINUE ?
7393af7c 942 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
7a292a7a
SS
943 res = ContinueDebugEvent (current_event.dwProcessId,
944 current_event.dwThreadId,
945 continue_status);
c2d11a7d 946 continue_status = 0;
7a292a7a 947 if (res)
c5aa993b 948 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 949 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
c906108c 950 {
fa4ba8da 951
c906108c
SS
952 for (i = 0; i < th->suspend_count; i++)
953 (void) ResumeThread (th->h);
954 th->suspend_count = 0;
fa4ba8da
PM
955 if (debug_registers_changed)
956 {
957 /* Only change the value of the debug reisters */
958 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
959 th->context.Dr0 = dr[0];
960 th->context.Dr1 = dr[1];
961 th->context.Dr2 = dr[2];
962 th->context.Dr3 = dr[3];
963 /* th->context.Dr6 = dr[6];
dfe7f3ac 964 FIXME: should we set dr6 also ?? */
fa4ba8da
PM
965 th->context.Dr7 = dr[7];
966 CHECK (SetThreadContext (th->h, &th->context));
967 th->context.ContextFlags = 0;
968 }
c906108c
SS
969 }
970
fa4ba8da 971 debug_registers_changed = 0;
c906108c
SS
972 return res;
973}
974
8a892701
CF
975/* Get the next event from the child. Return 1 if the event requires
976 handling by WFI (or whatever).
977 */
c2d11a7d 978static int
0a65a603 979get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
c2d11a7d
JM
980{
981 BOOL debug_event;
8a892701
CF
982 DWORD continue_status, event_code;
983 thread_info *th = NULL;
984 static thread_info dummy_thread_info;
450005e7 985 int retval = 0;
c2d11a7d 986
7393af7c 987 last_sig = TARGET_SIGNAL_0;
9d3789f7 988
8a892701 989 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 990 goto out;
c2d11a7d
JM
991
992 event_count++;
993 continue_status = DBG_CONTINUE;
c2d11a7d 994
8a892701 995 event_code = current_event.dwDebugEventCode;
450005e7 996 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
8a892701
CF
997
998 switch (event_code)
c2d11a7d
JM
999 {
1000 case CREATE_THREAD_DEBUG_EVENT:
1001 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
1002 (unsigned) current_event.dwProcessId,
1003 (unsigned) current_event.dwThreadId,
1004 "CREATE_THREAD_DEBUG_EVENT"));
dfe7f3ac
CF
1005 if (saw_create != 1)
1006 break;
c2d11a7d 1007 /* Record the existence of this thread */
8a892701
CF
1008 th = child_add_thread (current_event.dwThreadId,
1009 current_event.u.CreateThread.hThread);
c2d11a7d
JM
1010 if (info_verbose)
1011 printf_unfiltered ("[New %s]\n",
39f77062
KB
1012 target_pid_to_str (
1013 pid_to_ptid (current_event.dwThreadId)));
450005e7 1014 retval = current_event.dwThreadId;
c2d11a7d
JM
1015 break;
1016
1017 case EXIT_THREAD_DEBUG_EVENT:
1018 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1019 (unsigned) current_event.dwProcessId,
1020 (unsigned) current_event.dwThreadId,
1021 "EXIT_THREAD_DEBUG_EVENT"));
dfe7f3ac
CF
1022 if (saw_create != 1)
1023 break;
c2d11a7d 1024 child_delete_thread (current_event.dwThreadId);
8a892701 1025 th = &dummy_thread_info;
c2d11a7d
JM
1026 break;
1027
1028 case CREATE_PROCESS_DEBUG_EVENT:
1029 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1030 (unsigned) current_event.dwProcessId,
1031 (unsigned) current_event.dwThreadId,
1032 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 1033 CloseHandle (current_event.u.CreateProcessInfo.hFile);
dfe7f3ac
CF
1034 if (++saw_create != 1)
1035 {
1036 CloseHandle (current_event.u.CreateProcessInfo.hProcess);
1037 break;
1038 }
c2d11a7d 1039
dfe7f3ac 1040 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
9d3789f7 1041 main_thread_id = current_event.dwThreadId;
c2d11a7d 1042 /* Add the main thread */
9d3789f7 1043#if 0
450005e7
CF
1044 th = child_add_thread (current_event.dwProcessId,
1045 current_event.u.CreateProcessInfo.hProcess);
9d3789f7
CF
1046#endif
1047 th = child_add_thread (main_thread_id,
8a892701 1048 current_event.u.CreateProcessInfo.hThread);
9d3789f7 1049 retval = ourstatus->value.related_pid = current_event.dwThreadId;
c2d11a7d
JM
1050 break;
1051
1052 case EXIT_PROCESS_DEBUG_EVENT:
1053 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1054 (unsigned) current_event.dwProcessId,
1055 (unsigned) current_event.dwThreadId,
1056 "EXIT_PROCESS_DEBUG_EVENT"));
dfe7f3ac
CF
1057 if (saw_create != 1)
1058 break;
c2d11a7d
JM
1059 ourstatus->kind = TARGET_WAITKIND_EXITED;
1060 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1061 CloseHandle (current_process_handle);
9d3789f7 1062 retval = main_thread_id;
8a892701 1063 break;
c2d11a7d
JM
1064
1065 case LOAD_DLL_DEBUG_EVENT:
1066 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1067 (unsigned) current_event.dwProcessId,
1068 (unsigned) current_event.dwThreadId,
1069 "LOAD_DLL_DEBUG_EVENT"));
700b351b 1070 CloseHandle (current_event.u.LoadDll.hFile);
dfe7f3ac
CF
1071 if (saw_create != 1)
1072 break;
8a892701 1073 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
c2d11a7d 1074 registers_changed (); /* mark all regs invalid */
450005e7
CF
1075 ourstatus->kind = TARGET_WAITKIND_LOADED;
1076 ourstatus->value.integer = 0;
9d3789f7 1077 retval = main_thread_id;
c2d11a7d
JM
1078 break;
1079
1080 case UNLOAD_DLL_DEBUG_EVENT:
1081 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1082 (unsigned) current_event.dwProcessId,
1083 (unsigned) current_event.dwThreadId,
1084 "UNLOAD_DLL_DEBUG_EVENT"));
dfe7f3ac
CF
1085 if (saw_create != 1)
1086 break;
d3ff4a77
CF
1087 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1088 registers_changed (); /* mark all regs invalid */
1089 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
3bccec63 1090 does not exist yet. */
d3ff4a77 1091 break;
c2d11a7d
JM
1092
1093 case EXCEPTION_DEBUG_EVENT:
1094 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1095 (unsigned) current_event.dwProcessId,
1096 (unsigned) current_event.dwThreadId,
1097 "EXCEPTION_DEBUG_EVENT"));
dfe7f3ac
CF
1098 if (saw_create != 1)
1099 break;
02e423b9
CF
1100 if (handle_exception (ourstatus))
1101 retval = current_event.dwThreadId;
c2d11a7d
JM
1102 break;
1103
8a892701 1104 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
c2d11a7d 1105 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1106 (unsigned) current_event.dwProcessId,
1107 (unsigned) current_event.dwThreadId,
1108 "OUTPUT_DEBUG_STRING_EVENT"));
dfe7f3ac
CF
1109 if (saw_create != 1)
1110 break;
8e860359 1111 if (handle_output_debug_string (ourstatus))
9d3789f7 1112 retval = main_thread_id;
c2d11a7d 1113 break;
9d3789f7 1114
c2d11a7d 1115 default:
dfe7f3ac
CF
1116 if (saw_create != 1)
1117 break;
29fe111d
CF
1118 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1119 (DWORD) current_event.dwProcessId,
1120 (DWORD) current_event.dwThreadId);
1121 printf_unfiltered (" unknown event code %ld\n",
c2d11a7d
JM
1122 current_event.dwDebugEventCode);
1123 break;
1124 }
1125
dfe7f3ac 1126 if (!retval || saw_create != 1)
8a892701 1127 CHECK (child_continue (continue_status, -1));
450005e7 1128 else
9d3789f7 1129 {
8e860359 1130 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
39f77062 1131 inferior_ptid = pid_to_ptid (retval);
9d3789f7 1132 }
c2d11a7d
JM
1133
1134out:
450005e7 1135 return retval;
c2d11a7d
JM
1136}
1137
c2d11a7d 1138/* Wait for interesting events to occur in the target process. */
39f77062
KB
1139static ptid_t
1140child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
c906108c 1141{
39f77062
KB
1142 int pid = PIDGET (ptid);
1143
c906108c
SS
1144 /* We loop when we get a non-standard exception rather than return
1145 with a SPURIOUS because resume can try and step or modify things,
1146 which needs a current_thread->h. But some of these exceptions mark
1147 the birth or death of threads, which mean that the current thread
1148 isn't necessarily what you think it is. */
1149
1150 while (1)
450005e7
CF
1151 {
1152 int retval = get_child_debug_event (pid, ourstatus);
1153 if (retval)
39f77062 1154 return pid_to_ptid (retval);
450005e7
CF
1155 else
1156 {
1157 int detach = 0;
c906108c 1158
450005e7
CF
1159 if (ui_loop_hook != NULL)
1160 detach = ui_loop_hook (0);
7a292a7a 1161
450005e7
CF
1162 if (detach)
1163 child_kill_inferior ();
1164 }
1165 }
c906108c
SS
1166}
1167
9d3789f7
CF
1168static void
1169do_initial_child_stuff (DWORD pid)
1170{
1171 extern int stop_after_trap;
fa4ba8da 1172 int i;
9d3789f7 1173
7393af7c 1174 last_sig = TARGET_SIGNAL_0;
9d3789f7
CF
1175 event_count = 0;
1176 exception_count = 0;
fa4ba8da 1177 debug_registers_changed = 0;
dfe7f3ac 1178 debug_registers_used = 0;
fa4ba8da
PM
1179 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1180 dr[i] = 0;
9d3789f7
CF
1181 current_event.dwProcessId = pid;
1182 memset (&current_event, 0, sizeof (current_event));
1183 push_target (&child_ops);
1184 child_init_thread_list ();
1185 child_clear_solibs ();
1186 clear_proceed_status ();
1187 init_wait_for_inferior ();
1188
1189 target_terminal_init ();
1190 target_terminal_inferior ();
1191
1192 while (1)
1193 {
1194 stop_after_trap = 1;
1195 wait_for_inferior ();
1196 if (stop_signal != TARGET_SIGNAL_TRAP)
1197 resume (0, stop_signal);
1198 else
1199 break;
1200 }
1201 stop_after_trap = 0;
1202 return;
1203}
1204
02cc9f49
CV
1205/* Since Windows XP, detaching from a process is supported by Windows.
1206 The following code tries loading the appropriate functions dynamically.
1207 If loading these functions succeeds use them to actually detach from
1208 the inferior process, otherwise behave as usual, pretending that
1209 detach has worked. */
1210static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1211static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1212
1213static int
1214has_detach_ability ()
1215{
1216 static HMODULE kernel32 = NULL;
1217
1218 if (!kernel32)
1219 kernel32 = LoadLibrary ("kernel32.dll");
1220 if (kernel32)
1221 {
1222 if (!DebugSetProcessKillOnExit)
1223 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1224 "DebugSetProcessKillOnExit");
1225 if (!DebugActiveProcessStop)
1226 DebugActiveProcessStop = GetProcAddress (kernel32,
1227 "DebugActiveProcessStop");
1228 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1229 return 1;
1230 }
1231 return 0;
1232}
c906108c 1233
02cc9f49 1234/* Attach to process PID, then initialize for debugging it. */
c906108c 1235static void
fba45db2 1236child_attach (char *args, int from_tty)
c906108c
SS
1237{
1238 BOOL ok;
559e75c0 1239 DWORD pid;
c906108c
SS
1240
1241 if (!args)
1242 error_no_arg ("process-id to attach");
1243
559e75c0 1244 pid = strtoul (args, 0, 0);
9d3789f7 1245 ok = DebugActiveProcess (pid);
c906108c
SS
1246
1247 if (!ok)
1248 error ("Can't attach to process.");
1249
02cc9f49
CV
1250 if (has_detach_ability ())
1251 {
1252 attach_flag = 1;
1253 DebugSetProcessKillOnExit (FALSE);
1254 }
1255
c906108c
SS
1256 if (from_tty)
1257 {
1258 char *exec_file = (char *) get_exec_file (0);
1259
1260 if (exec_file)
1261 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1262 target_pid_to_str (pid_to_ptid (pid)));
c906108c
SS
1263 else
1264 printf_unfiltered ("Attaching to %s\n",
39f77062 1265 target_pid_to_str (pid_to_ptid (pid)));
c906108c
SS
1266
1267 gdb_flush (gdb_stdout);
1268 }
1269
9d3789f7
CF
1270 do_initial_child_stuff (pid);
1271 target_terminal_ours ();
c906108c
SS
1272}
1273
1274static void
0a65a603 1275child_detach (char *args, int from_tty)
c906108c 1276{
02cc9f49
CV
1277 int detached = 1;
1278
1279 if (has_detach_ability ())
1280 {
1281 delete_command (NULL, 0);
1282 child_continue (DBG_CONTINUE, -1);
1283 if (!DebugActiveProcessStop (current_event.dwProcessId))
3bccec63 1284 {
02cc9f49
CV
1285 error ("Can't detach process %lu (error %lu)",
1286 current_event.dwProcessId, GetLastError ());
1287 detached = 0;
3bccec63 1288 }
02cc9f49
CV
1289 DebugSetProcessKillOnExit (FALSE);
1290 }
1291 if (detached && from_tty)
c906108c
SS
1292 {
1293 char *exec_file = get_exec_file (0);
1294 if (exec_file == 0)
1295 exec_file = "";
02cc9f49
CV
1296 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1297 current_event.dwProcessId);
c906108c
SS
1298 gdb_flush (gdb_stdout);
1299 }
39f77062 1300 inferior_ptid = null_ptid;
c906108c
SS
1301 unpush_target (&child_ops);
1302}
1303
1304/* Print status information about what we're accessing. */
1305
1306static void
0a65a603 1307child_files_info (struct target_ops *ignore)
c906108c
SS
1308{
1309 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1310 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
c906108c
SS
1311}
1312
1313/* ARGSUSED */
1314static void
0a65a603 1315child_open (char *arg, int from_tty)
c906108c
SS
1316{
1317 error ("Use the \"run\" command to start a Unix child process.");
1318}
1319
39f77062 1320/* Start an inferior win32 child process and sets inferior_ptid to its pid.
c906108c
SS
1321 EXEC_FILE is the file to run.
1322 ALLARGS is a string containing the arguments to the program.
1323 ENV is the environment vector to pass. Errors reported with error(). */
1324
1325static void
fba45db2 1326child_create_inferior (char *exec_file, char *allargs, char **env)
c906108c 1327{
c906108c
SS
1328 char *winenv;
1329 char *temp;
c5aa993b 1330 int envlen;
c906108c 1331 int i;
c906108c
SS
1332 STARTUPINFO si;
1333 PROCESS_INFORMATION pi;
c906108c
SS
1334 BOOL ret;
1335 DWORD flags;
1336 char *args;
dfe7f3ac
CF
1337 char real_path[MAXPATHLEN];
1338 char *toexec;
c906108c
SS
1339
1340 if (!exec_file)
450005e7 1341 error ("No executable specified, use `target exec'.\n");
c906108c
SS
1342
1343 memset (&si, 0, sizeof (si));
1344 si.cb = sizeof (si);
1345
dfe7f3ac 1346 flags = 0;
c906108c
SS
1347
1348 if (new_group)
1349 flags |= CREATE_NEW_PROCESS_GROUP;
1350
1351 if (new_console)
1352 flags |= CREATE_NEW_CONSOLE;
1353
dfe7f3ac
CF
1354 if (!useshell || !shell[0])
1355 {
1356 flags = DEBUG_ONLY_THIS_PROCESS;
1357 cygwin_conv_to_win32_path (exec_file, real_path);
1358 toexec = real_path;
1359 }
1360 else
1361 {
1362 char *newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file) + strlen (allargs) + 2);
1363 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1364 allargs = newallargs;
1365 toexec = shell;
1366 flags = DEBUG_PROCESS;
1367 }
c906108c 1368
dfe7f3ac
CF
1369 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1370 strcpy (args, toexec);
c906108c
SS
1371 strcat (args, " ");
1372 strcat (args, allargs);
1373
1374 /* Prepare the environment vars for CreateProcess. */
1375 {
1376 /* This code use to assume all env vars were file names and would
1377 translate them all to win32 style. That obviously doesn't work in the
1378 general case. The current rule is that we only translate PATH.
1379 We need to handle PATH because we're about to call CreateProcess and
1380 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1381 in both posix and win32 environments. cygwin.dll will change it back
1382 to posix style if necessary. */
1383
1384 static const char *conv_path_names[] =
c5aa993b
JM
1385 {
1386 "PATH=",
1387 0
1388 };
c906108c
SS
1389
1390 /* CreateProcess takes the environment list as a null terminated set of
1391 strings (i.e. two nulls terminate the list). */
1392
1393 /* Get total size for env strings. */
1394 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1395 {
1396 int j, len;
1397
1398 for (j = 0; conv_path_names[j]; j++)
1399 {
1400 len = strlen (conv_path_names[j]);
1401 if (strncmp (conv_path_names[j], env[i], len) == 0)
1402 {
29fe111d 1403 if (cygwin_posix_path_list_p (env[i] + len))
c906108c 1404 envlen += len
29fe111d 1405 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
c906108c
SS
1406 else
1407 envlen += strlen (env[i]) + 1;
1408 break;
1409 }
1410 }
1411 if (conv_path_names[j] == NULL)
1412 envlen += strlen (env[i]) + 1;
1413 }
1414
1415 winenv = alloca (envlen + 1);
1416
1417 /* Copy env strings into new buffer. */
1418 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1419 {
1420 int j, len;
1421
1422 for (j = 0; conv_path_names[j]; j++)
1423 {
1424 len = strlen (conv_path_names[j]);
1425 if (strncmp (conv_path_names[j], env[i], len) == 0)
1426 {
29fe111d 1427 if (cygwin_posix_path_list_p (env[i] + len))
c906108c
SS
1428 {
1429 memcpy (temp, env[i], len);
29fe111d 1430 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
c906108c
SS
1431 }
1432 else
1433 strcpy (temp, env[i]);
1434 break;
1435 }
1436 }
1437 if (conv_path_names[j] == NULL)
1438 strcpy (temp, env[i]);
1439
1440 temp += strlen (temp) + 1;
1441 }
1442
1443 /* Final nil string to terminate new env. */
1444 *temp = 0;
1445 }
1446
1447 ret = CreateProcess (0,
c5aa993b 1448 args, /* command line */
c906108c
SS
1449 NULL, /* Security */
1450 NULL, /* thread */
1451 TRUE, /* inherit handles */
1452 flags, /* start flags */
1453 winenv,
1454 NULL, /* current directory */
1455 &si,
1456 &pi);
1457 if (!ret)
c5aa993b 1458 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
c906108c 1459
700b351b
CF
1460 CloseHandle (pi.hThread);
1461 CloseHandle (pi.hProcess);
dfe7f3ac
CF
1462
1463 if (useshell && shell[0] != '\0')
1464 saw_create = -1;
1465 else
1466 saw_create = 0;
1467
9d3789f7 1468 do_initial_child_stuff (pi.dwProcessId);
ed9a39eb 1469
8e860359 1470 /* child_continue (DBG_CONTINUE, -1); */
c2d11a7d 1471 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
c906108c
SS
1472}
1473
1474static void
fba45db2 1475child_mourn_inferior (void)
c906108c 1476{
8a892701 1477 (void) child_continue (DBG_CONTINUE, -1);
fa4ba8da 1478 i386_cleanup_dregs();
c906108c
SS
1479 unpush_target (&child_ops);
1480 generic_mourn_inferior ();
1481}
1482
1483/* Send a SIGINT to the process group. This acts just like the user typed a
1484 ^C on the controlling terminal. */
1485
1486static void
fba45db2 1487child_stop (void)
c906108c
SS
1488{
1489 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
c2d11a7d 1490 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
c5aa993b 1491 registers_changed (); /* refresh register state */
c906108c
SS
1492}
1493
1494int
1495child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
0a65a603
AC
1496 int write, struct mem_attrib *mem,
1497 struct target_ops *target)
c906108c
SS
1498{
1499 DWORD done;
1500 if (write)
1501 {
29fe111d
CF
1502 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1503 len, (DWORD) memaddr));
c906108c
SS
1504 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1505 len, &done);
1506 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1507 }
1508 else
1509 {
29fe111d
CF
1510 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1511 len, (DWORD) memaddr));
c906108c
SS
1512 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1513 &done);
1514 }
1515 return done;
1516}
1517
1518void
1519child_kill_inferior (void)
1520{
1521 CHECK (TerminateProcess (current_process_handle, 0));
1522
1523 for (;;)
1524 {
8a892701 1525 if (!child_continue (DBG_CONTINUE, -1))
c906108c
SS
1526 break;
1527 if (!WaitForDebugEvent (&current_event, INFINITE))
1528 break;
1529 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1530 break;
1531 }
1532
1533 CHECK (CloseHandle (current_process_handle));
1534
1535 /* this may fail in an attached process so don't check. */
1536 (void) CloseHandle (current_thread->h);
c5aa993b 1537 target_mourn_inferior (); /* or just child_mourn_inferior? */
c906108c
SS
1538}
1539
1540void
39f77062 1541child_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c 1542{
c906108c 1543 thread_info *th;
7393af7c
PM
1544 DWORD continue_status = DBG_CONTINUE;
1545
39f77062 1546 int pid = PIDGET (ptid);
8a892701 1547
7393af7c
PM
1548 if (sig != TARGET_SIGNAL_0)
1549 {
1550 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1551 {
1552 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1553 }
1554 else if (sig == last_sig)
1555 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1556 else
1557#if 0
1558/* This code does not seem to work, because
1559 the kernel does probably not consider changes in the ExceptionRecord
dfe7f3ac 1560 structure when passing the exception to the inferior.
7393af7c
PM
1561 Note that this seems possible in the exception handler itself. */
1562 {
1563 int i;
1564 for (i = 0; xlate[i].them != -1; i++)
1565 if (xlate[i].us == sig)
1566 {
1567 current_event.u.Exception.ExceptionRecord.ExceptionCode =
1568 xlate[i].them;
1569 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1570 break;
1571 }
1572 if (continue_status == DBG_CONTINUE)
1573 {
1574 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1575 }
1576 }
1577#endif
dfe7f3ac 1578 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
7393af7c
PM
1579 last_sig));
1580 }
1581
1582 last_sig = TARGET_SIGNAL_0;
c906108c
SS
1583
1584 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1585 pid, step, sig));
1586
1587 /* Get context for currently selected thread */
1588 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 1589 if (th)
c906108c 1590 {
450005e7
CF
1591 if (step)
1592 {
1593 /* Single step by setting t bit */
1594 child_fetch_inferior_registers (PS_REGNUM);
1595 th->context.EFlags |= FLAG_TRACE_BIT;
1596 }
c906108c 1597
450005e7
CF
1598 if (th->context.ContextFlags)
1599 {
fa4ba8da
PM
1600 if (debug_registers_changed)
1601 {
dfe7f3ac
CF
1602 th->context.Dr0 = dr[0];
1603 th->context.Dr1 = dr[1];
1604 th->context.Dr2 = dr[2];
1605 th->context.Dr3 = dr[3];
1606 /* th->context.Dr6 = dr[6];
1607 FIXME: should we set dr6 also ?? */
1608 th->context.Dr7 = dr[7];
fa4ba8da 1609 }
450005e7
CF
1610 CHECK (SetThreadContext (th->h, &th->context));
1611 th->context.ContextFlags = 0;
1612 }
c906108c
SS
1613 }
1614
1615 /* Allow continuing with the same signal that interrupted us.
1616 Otherwise complain. */
c906108c 1617
8a892701 1618 child_continue (continue_status, pid);
c906108c
SS
1619}
1620
1621static void
fba45db2 1622child_prepare_to_store (void)
c906108c
SS
1623{
1624 /* Do nothing, since we can store individual regs */
1625}
1626
1627static int
fba45db2 1628child_can_run (void)
c906108c
SS
1629{
1630 return 1;
1631}
1632
1633static void
0a65a603 1634child_close (int x)
c906108c 1635{
39f77062 1636 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
3bccec63 1637 PIDGET (inferior_ptid)));
c906108c
SS
1638}
1639
c5aa993b 1640struct target_ops child_ops;
c906108c 1641
c5aa993b
JM
1642static void
1643init_child_ops (void)
c906108c 1644{
c5aa993b
JM
1645 child_ops.to_shortname = "child";
1646 child_ops.to_longname = "Win32 child process";
1647 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1648 child_ops.to_open = child_open;
1649 child_ops.to_close = child_close;
1650 child_ops.to_attach = child_attach;
1651 child_ops.to_detach = child_detach;
1652 child_ops.to_resume = child_resume;
1653 child_ops.to_wait = child_wait;
1654 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1655 child_ops.to_store_registers = child_store_inferior_registers;
1656 child_ops.to_prepare_to_store = child_prepare_to_store;
1657 child_ops.to_xfer_memory = child_xfer_memory;
1658 child_ops.to_files_info = child_files_info;
1659 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1660 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1661 child_ops.to_terminal_init = terminal_init_inferior;
1662 child_ops.to_terminal_inferior = terminal_inferior;
1663 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1664 child_ops.to_terminal_ours = terminal_ours;
1665 child_ops.to_terminal_info = child_terminal_info;
1666 child_ops.to_kill = child_kill_inferior;
1667 child_ops.to_load = 0;
1668 child_ops.to_lookup_symbol = 0;
1669 child_ops.to_create_inferior = child_create_inferior;
1670 child_ops.to_mourn_inferior = child_mourn_inferior;
1671 child_ops.to_can_run = child_can_run;
1672 child_ops.to_notice_signals = 0;
1673 child_ops.to_thread_alive = win32_child_thread_alive;
ed9a39eb 1674 child_ops.to_pid_to_str = cygwin_pid_to_str;
c5aa993b
JM
1675 child_ops.to_stop = child_stop;
1676 child_ops.to_stratum = process_stratum;
1677 child_ops.DONT_USE = 0;
1678 child_ops.to_has_all_memory = 1;
1679 child_ops.to_has_memory = 1;
1680 child_ops.to_has_stack = 1;
1681 child_ops.to_has_registers = 1;
1682 child_ops.to_has_execution = 1;
1683 child_ops.to_sections = 0;
1684 child_ops.to_sections_end = 0;
1685 child_ops.to_magic = OPS_MAGIC;
c906108c
SS
1686}
1687
1688void
fba45db2 1689_initialize_inftarg (void)
c906108c 1690{
fa58ee11 1691 struct cmd_list_element *c;
dfe7f3ac 1692 const char *sh;
fa58ee11 1693
c5aa993b 1694 init_child_ops ();
c906108c 1695
fa58ee11
EZ
1696 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1697 "Load dll library symbols from FILE.");
1698 c->completer = filename_completer;
450005e7 1699
dfe7f3ac
CF
1700 sh = getenv ("SHELL");
1701 if (!sh)
1702 sh = "/bin/sh";
1703 if (access (sh, X_OK) != 0)
1704 {
1705 shell[0] = '\0';
1706 useshell = 0;
1707 }
1708 else
1709 {
1710 cygwin_conv_to_win32_path (sh, shell);
1711 useshell = 1;
1712 }
1713
450005e7
CF
1714 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1715
dfe7f3ac
CF
1716 add_show_from_set (add_set_cmd ("shell", class_support, var_boolean,
1717 (char *) &useshell,
1718 "Set use of shell to start subprocess.",
1719 &setlist),
1720 &showlist);
1721
450005e7 1722 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
8e860359
CF
1723 (char *) &new_console,
1724 "Set creation of new console when creating child process.",
1725 &setlist),
1726 &showlist);
c906108c 1727
450005e7 1728 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
8e860359
CF
1729 (char *) &new_group,
1730 "Set creation of new group when creating child process.",
1731 &setlist),
1732 &showlist);
c906108c 1733
450005e7 1734 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
8e860359
CF
1735 (char *) &debug_exec,
1736 "Set whether to display execution in child process.",
1737 &setlist),
1738 &showlist);
c906108c 1739
450005e7 1740 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
8e860359
CF
1741 (char *) &debug_events,
1742 "Set whether to display kernel events in child process.",
1743 &setlist),
1744 &showlist);
c906108c 1745
450005e7 1746 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
8e860359
CF
1747 (char *) &debug_memory,
1748 "Set whether to display memory accesses in child process.",
1749 &setlist),
1750 &showlist);
c906108c 1751
450005e7 1752 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
8e860359
CF
1753 (char *) &debug_exceptions,
1754 "Set whether to display kernel exceptions in child process.",
1755 &setlist),
1756 &showlist);
c906108c 1757
450005e7
CF
1758 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1759 add_info_alias ("sharedlibrary", "dll", 1);
1760
c906108c
SS
1761 add_target (&child_ops);
1762}
1763
fa4ba8da
PM
1764/* Hardware watchpoint support, adapted from go32-nat.c code. */
1765
1766/* Pass the address ADDR to the inferior in the I'th debug register.
1767 Here we just store the address in dr array, the registers will be
1768 actually set up when child_continue is called. */
1769void
1770cygwin_set_dr (int i, CORE_ADDR addr)
1771{
1772 if (i < 0 || i > 3)
1773 internal_error (__FILE__, __LINE__,
1774 "Invalid register %d in cygwin_set_dr.\n", i);
1775 dr[i] = (unsigned) addr;
1776 debug_registers_changed = 1;
1777 debug_registers_used = 1;
1778}
1779
1780/* Pass the value VAL to the inferior in the DR7 debug control
1781 register. Here we just store the address in D_REGS, the watchpoint
1782 will be actually set up in child_wait. */
1783void
1784cygwin_set_dr7 (unsigned val)
1785{
1786 dr[7] = val;
1787 debug_registers_changed = 1;
1788 debug_registers_used = 1;
1789}
1790
1791/* Get the value of the DR6 debug status register from the inferior.
1792 Here we just return the value stored in dr[6]
1793 by the last call to thread_rec for current_event.dwThreadId id. */
1794unsigned
1795cygwin_get_dr6 (void)
1796{
1797 return dr[6];
1798}
1799
1800
c906108c
SS
1801/* Determine if the thread referenced by "pid" is alive
1802 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1803 it means that the pid has died. Otherwise it is assumed to be alive. */
1804static int
39f77062 1805win32_child_thread_alive (ptid_t ptid)
c906108c 1806{
39f77062
KB
1807 int pid = PIDGET (ptid);
1808
c5aa993b
JM
1809 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1810 FALSE : TRUE;
c906108c
SS
1811}
1812
1813/* Convert pid to printable format. */
1814char *
39f77062 1815cygwin_pid_to_str (ptid_t ptid)
c906108c
SS
1816{
1817 static char buf[80];
39f77062
KB
1818 int pid = PIDGET (ptid);
1819
29fe111d 1820 if ((DWORD) pid == current_event.dwProcessId)
b69571f5 1821 sprintf (buf, "process %d", pid);
c906108c 1822 else
b69571f5 1823 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
c906108c
SS
1824 return buf;
1825}
8e860359
CF
1826
1827static int
1828core_dll_symbols_add (char *dll_name, DWORD base_addr)
1829{
1830 struct objfile *objfile;
1831 char *objfile_basename;
1832 const char *dll_basename;
1833
1834 if (!(dll_basename = strrchr (dll_name, '/')))
1835 dll_basename = dll_name;
1836 else
1837 dll_basename++;
1838
1839 ALL_OBJFILES (objfile)
1840 {
1841 objfile_basename = strrchr (objfile->name, '/');
1842
1843 if (objfile_basename &&
1844 strcmp (dll_basename, objfile_basename + 1) == 0)
1845 {
1846 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1847 base_addr, dll_name);
1848 goto out;
1849 }
1850 }
1851
1852 register_loaded_dll (dll_name, base_addr + 0x1000);
02e423b9 1853 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
8e860359
CF
1854
1855out:
1856 return 1;
1857}
1858
1859typedef struct
1860{
1861 struct target_ops *target;
1862 bfd_vma addr;
1863}
1864map_code_section_args;
1865
1866static void
554cb486 1867map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1868{
1869 int old;
1870 int update_coreops;
1871 struct section_table *new_target_sect_ptr;
1872
1873 map_code_section_args *args = (map_code_section_args *) obj;
1874 struct target_ops *target = args->target;
1875 if (sect->flags & SEC_CODE)
1876 {
1877 update_coreops = core_ops.to_sections == target->to_sections;
1878
1879 if (target->to_sections)
1880 {
1881 old = target->to_sections_end - target->to_sections;
1882 target->to_sections = (struct section_table *)
1883 xrealloc ((char *) target->to_sections,
1884 (sizeof (struct section_table)) * (1 + old));
1885 }
1886 else
1887 {
1888 old = 0;
1889 target->to_sections = (struct section_table *)
1890 xmalloc ((sizeof (struct section_table)));
1891 }
1892 target->to_sections_end = target->to_sections + (1 + old);
1893
1894 /* Update the to_sections field in the core_ops structure
3bccec63 1895 if needed. */
8e860359
CF
1896 if (update_coreops)
1897 {
1898 core_ops.to_sections = target->to_sections;
1899 core_ops.to_sections_end = target->to_sections_end;
1900 }
1901 new_target_sect_ptr = target->to_sections + old;
1902 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1903 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1904 bfd_section_size (abfd, sect);;
1905 new_target_sect_ptr->the_bfd_section = sect;
1906 new_target_sect_ptr->bfd = abfd;
1907 }
1908}
1909
1910static int
1911dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1912{
1913 bfd *dll_bfd;
1914 map_code_section_args map_args;
1915 asection *lowest_sect;
1916 char *name;
1917 if (dll_name == NULL || target == NULL)
1918 return 0;
66ed1d85 1919 name = xstrdup (dll_name);
8e860359
CF
1920 dll_bfd = bfd_openr (name, "pei-i386");
1921 if (dll_bfd == NULL)
1922 return 0;
1923
1924 if (bfd_check_format (dll_bfd, bfd_object))
1925 {
1926 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1927 if (lowest_sect == NULL)
1928 return 0;
1929 map_args.target = target;
1930 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1931
554cb486 1932 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
1933 }
1934
1935 return 1;
1936}
1937
1938static void
554cb486 1939core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1940{
1941 struct target_ops *target = (struct target_ops *) obj;
1942
1943 DWORD base_addr;
1944
1945 int dll_name_size;
1946 char *dll_name = NULL;
1947 char *buf = NULL;
1948 struct win32_pstatus *pstatus;
1949 char *p;
1950
1951 if (strncmp (sect->name, ".module", 7))
1952 return;
1953
1954 buf = (char *) xmalloc (sect->_raw_size + 1);
1955 if (!buf)
1956 {
1957 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1958 goto out;
1959 }
1960 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1961 goto out;
1962
1963 pstatus = (struct win32_pstatus *) buf;
1964
1965 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1966 dll_name_size = pstatus->data.module_info.module_name_size;
1967 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1968 goto out;
1969
1970 dll_name = (char *) xmalloc (dll_name_size + 1);
1971 if (!dll_name)
1972 {
1973 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1974 goto out;
1975 }
1976 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1977
1978 while ((p = strchr (dll_name, '\\')))
1979 *p = '/';
1980
1981 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1982 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1983
1984 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1985 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1986
1987out:
1988 if (buf)
b8c9b27d 1989 xfree (buf);
8e860359 1990 if (dll_name)
b8c9b27d 1991 xfree (dll_name);
8e860359
CF
1992 return;
1993}
1994
1995void
0a65a603
AC
1996child_solib_add (char *filename, int from_tty, struct target_ops *target,
1997 int readsyms)
8e860359 1998{
990f9fe3
FF
1999 if (!readsyms)
2000 return;
8e860359
CF
2001 if (core_bfd)
2002 {
2003 child_clear_solibs ();
2004 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
2005 }
2006 else
2007 {
2008 if (solib_end && solib_end->name)
d3ff4a77 2009 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
3bccec63 2010 solib_end->load_addr);
8e860359
CF
2011 }
2012}
2013
2014static void
2015fetch_elf_core_registers (char *core_reg_sect,
2016 unsigned core_reg_size,
2017 int which,
2018 CORE_ADDR reg_addr)
2019{
2020 int r;
2021 if (core_reg_size < sizeof (CONTEXT))
2022 {
2023 error ("Core file register section too small (%u bytes).", core_reg_size);
2024 return;
2025 }
2026 for (r = 0; r < NUM_REGS; r++)
2027 supply_register (r, core_reg_sect + mappings[r]);
2028}
2029
2030static struct core_fns win32_elf_core_fns =
2031{
2032 bfd_target_elf_flavour,
2033 default_check_format,
2034 default_core_sniffer,
2035 fetch_elf_core_registers,
2036 NULL
2037};
2038
2039void
0613c401 2040_initialize_core_win32 (void)
8e860359
CF
2041{
2042 add_core_fns (&win32_elf_core_fns);
2043}
2a3d5645
CF
2044
2045void
2046_initialize_check_for_gdb_ini (void)
2047{
2048 char *homedir;
2049 if (inhibit_gdbinit)
2050 return;
2051
2052 homedir = getenv ("HOME");
2053 if (homedir)
2054 {
2055 char *p;
2056 char *oldini = (char *) alloca (strlen (homedir) +
2057 sizeof ("/gdb.ini"));
2058 strcpy (oldini, homedir);
2059 p = strchr (oldini, '\0');
2060 if (p > oldini && p[-1] != '/')
2061 *p++ = '/';
2062 strcpy (p, "gdb.ini");
2063 if (access (oldini, 0) == 0)
2064 {
2065 int len = strlen (oldini);
2066 char *newini = alloca (len + 1);
dfe7f3ac 2067 sprintf (newini, "%.*s.gdbinit",
58fa08f0 2068 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2a3d5645
CF
2069 warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
2070 }
2071 }
2072}
This page took 0.298351 seconds and 4 git commands to generate.