]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/win32-nat.c
daily update
[thirdparty/binutils-gdb.git] / gdb / win32-nat.c
CommitLineData
c906108c 1/* Target-vector operations for controlling win32 child processes, for GDB.
b6ba6518
KB
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
e6433c28 4 Contributed by Cygnus Solutions, A Red Hat Company.
c906108c
SS
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
c5aa993b 20 Foundation, Inc., 59 Temple Place - Suite 330,
4e052eda 21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23/* by Steve Chamberlain, sac@cygnus.com */
24
25/* We assume we're being built with and will be used for cygwin. */
26
27#include "defs.h"
28#include "frame.h" /* required by inferior.h */
29#include "inferior.h"
30#include "target.h"
c906108c
SS
31#include "gdbcore.h"
32#include "command.h"
fa58ee11 33#include "completer.h"
4e052eda 34#include "regcache.h"
c906108c
SS
35#include <signal.h>
36#include <sys/types.h>
37#include <fcntl.h>
38#include <stdlib.h>
c906108c 39#include <windows.h>
c2d11a7d 40#include <imagehlp.h>
29fe111d 41#include <sys/cygwin.h>
c906108c
SS
42
43#include "buildsym.h"
44#include "symfile.h"
45#include "objfiles.h"
46#include "gdb_string.h"
47#include "gdbthread.h"
48#include "gdbcmd.h"
49#include <sys/param.h>
c2d11a7d 50#include <unistd.h>
c906108c 51
7a292a7a 52/* The ui's event loop. */
507f3c78 53extern int (*ui_loop_hook) (int signo);
7a292a7a
SS
54
55/* If we're not using the old Cygwin header file set, define the
56 following which never should have been in the generic Win32 API
57 headers in the first place since they were our own invention... */
58#ifndef _GNU_H_WINDOWS_H
9d3789f7 59enum
8e860359
CF
60 {
61 FLAG_TRACE_BIT = 0x100,
62 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
63 };
7a292a7a 64#endif
8e860359
CF
65#include <sys/procfs.h>
66#include <psapi.h>
7a292a7a 67
c906108c
SS
68/* The string sent by cygwin when it processes a signal.
69 FIXME: This should be in a cygwin include file. */
70#define CYGWIN_SIGNAL_STRING "cygwin: signal"
71
29fe111d 72#define CHECK(x) check (x, __FILE__,__LINE__)
c906108c
SS
73#define DEBUG_EXEC(x) if (debug_exec) printf x
74#define DEBUG_EVENTS(x) if (debug_events) printf x
75#define DEBUG_MEM(x) if (debug_memory) printf x
76#define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
77
78/* Forward declaration */
79extern struct target_ops child_ops;
80
a14ed312 81static void child_stop (void);
39f77062 82static int win32_child_thread_alive (ptid_t);
a14ed312 83void child_kill_inferior (void);
c906108c 84
8a892701
CF
85static int last_sig = 0; /* Set if a signal was received from the
86 debugged process */
c906108c
SS
87/* Thread information structure used to track information that is
88 not available in gdb's thread structure. */
89typedef struct thread_info_struct
c5aa993b
JM
90 {
91 struct thread_info_struct *next;
92 DWORD id;
93 HANDLE h;
94 char *name;
95 int suspend_count;
96 CONTEXT context;
c2d11a7d 97 STACKFRAME sf;
8e860359
CF
98 }
99thread_info;
c2d11a7d 100
29fe111d 101static thread_info thread_head;
c906108c 102
c906108c
SS
103/* The process and thread handles for the above context. */
104
105static DEBUG_EVENT current_event; /* The current debug event from
106 WaitForDebugEvent */
107static HANDLE current_process_handle; /* Currently executing process */
108static thread_info *current_thread; /* Info on currently selected thread */
c5aa993b 109static DWORD main_thread_id; /* Thread ID of the main thread */
c906108c
SS
110
111/* Counts of things. */
112static int exception_count = 0;
113static int event_count = 0;
114
115/* User options. */
116static int new_console = 0;
c2d11a7d 117static int new_group = 1;
c5aa993b
JM
118static int debug_exec = 0; /* show execution */
119static int debug_events = 0; /* show events from kernel */
120static int debug_memory = 0; /* show target memory accesses */
c906108c
SS
121static int debug_exceptions = 0; /* show target exceptions */
122
123/* This vector maps GDB's idea of a register's number into an address
124 in the win32 exception context vector.
125
126 It also contains the bit mask needed to load the register in question.
127
128 One day we could read a reg, we could inspect the context we
129 already have loaded, if it doesn't have the bit set that we need,
130 we read that set of registers in using GetThreadContext. If the
131 context already contains what we need, we just unpack it. Then to
132 write a register, first we have to ensure that the context contains
133 the other regs of the group, and then we copy the info in and set
134 out bit. */
135
136#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
137static const int mappings[] =
138{
c5aa993b
JM
139 context_offset (Eax),
140 context_offset (Ecx),
141 context_offset (Edx),
142 context_offset (Ebx),
143 context_offset (Esp),
144 context_offset (Ebp),
145 context_offset (Esi),
146 context_offset (Edi),
147 context_offset (Eip),
148 context_offset (EFlags),
149 context_offset (SegCs),
150 context_offset (SegSs),
151 context_offset (SegDs),
152 context_offset (SegEs),
153 context_offset (SegFs),
154 context_offset (SegGs),
155 context_offset (FloatSave.RegisterArea[0 * 10]),
156 context_offset (FloatSave.RegisterArea[1 * 10]),
157 context_offset (FloatSave.RegisterArea[2 * 10]),
158 context_offset (FloatSave.RegisterArea[3 * 10]),
159 context_offset (FloatSave.RegisterArea[4 * 10]),
160 context_offset (FloatSave.RegisterArea[5 * 10]),
161 context_offset (FloatSave.RegisterArea[6 * 10]),
162 context_offset (FloatSave.RegisterArea[7 * 10]),
c2d11a7d
JM
163 context_offset (FloatSave.ControlWord),
164 context_offset (FloatSave.StatusWord),
165 context_offset (FloatSave.TagWord),
166 context_offset (FloatSave.ErrorSelector),
167 context_offset (FloatSave.ErrorOffset),
168 context_offset (FloatSave.DataSelector),
169 context_offset (FloatSave.DataOffset),
ed9a39eb 170 context_offset (FloatSave.ErrorSelector)
c906108c
SS
171};
172
ed9a39eb
JM
173#undef context_offset
174
c906108c
SS
175/* This vector maps the target's idea of an exception (extracted
176 from the DEBUG_EVENT structure) to GDB's idea. */
177
178struct xlate_exception
179 {
180 int them;
181 enum target_signal us;
182 };
183
184static const struct xlate_exception
185 xlate[] =
186{
187 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
188 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
189 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
190 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
191 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
192 {-1, -1}};
193
194/* Find a thread record given a thread id.
195 If get_context then also retrieve the context for this
196 thread. */
197static thread_info *
198thread_rec (DWORD id, int get_context)
199{
200 thread_info *th;
201
c5aa993b 202 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
203 if (th->id == id)
204 {
205 if (!th->suspend_count && get_context)
206 {
8a892701 207 if (get_context > 0 && id != current_event.dwThreadId)
c906108c
SS
208 th->suspend_count = SuspendThread (th->h) + 1;
209 else if (get_context < 0)
210 th->suspend_count = -1;
211
212 th->context.ContextFlags = CONTEXT_DEBUGGER;
213 GetThreadContext (th->h, &th->context);
214 }
215 return th;
216 }
217
218 return NULL;
219}
220
221/* Add a thread to the thread list */
222static thread_info *
c5aa993b 223child_add_thread (DWORD id, HANDLE h)
c906108c
SS
224{
225 thread_info *th;
226
227 if ((th = thread_rec (id, FALSE)))
228 return th;
229
230 th = (thread_info *) xmalloc (sizeof (*th));
c5aa993b 231 memset (th, 0, sizeof (*th));
c906108c
SS
232 th->id = id;
233 th->h = h;
234 th->next = thread_head.next;
235 thread_head.next = th;
39f77062 236 add_thread (pid_to_ptid (id));
c906108c
SS
237 return th;
238}
239
240/* Clear out any old thread list and reintialize it to a
241 pristine state. */
242static void
fba45db2 243child_init_thread_list (void)
c906108c
SS
244{
245 thread_info *th = &thread_head;
246
247 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
248 init_thread_list ();
249 while (th->next != NULL)
250 {
251 thread_info *here = th->next;
252 th->next = here->next;
253 (void) CloseHandle (here->h);
b8c9b27d 254 xfree (here);
c906108c
SS
255 }
256}
257
258/* Delete a thread from the list of threads */
259static void
260child_delete_thread (DWORD id)
261{
262 thread_info *th;
263
264 if (info_verbose)
39f77062
KB
265 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
266 delete_thread (pid_to_ptid (id));
c906108c
SS
267
268 for (th = &thread_head;
269 th->next != NULL && th->next->id != id;
270 th = th->next)
271 continue;
272
273 if (th->next != NULL)
274 {
275 thread_info *here = th->next;
276 th->next = here->next;
277 CloseHandle (here->h);
b8c9b27d 278 xfree (here);
c906108c
SS
279 }
280}
281
282static void
283check (BOOL ok, const char *file, int line)
284{
285 if (!ok)
29fe111d 286 printf_filtered ("error return %s:%d was %lu\n", file, line, GetLastError ());
c906108c
SS
287}
288
289static void
290do_child_fetch_inferior_registers (int r)
291{
c2d11a7d
JM
292 char *context_offset = ((char *) &current_thread->context) + mappings[r];
293 long l;
294 if (r == FCS_REGNUM)
295 {
8e860359 296 l = *((long *) context_offset) & 0xffff;
c2d11a7d
JM
297 supply_register (r, (char *) &l);
298 }
299 else if (r == FOP_REGNUM)
300 {
8e860359 301 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
c2d11a7d
JM
302 supply_register (r, (char *) &l);
303 }
304 else if (r >= 0)
ed9a39eb 305 supply_register (r, context_offset);
c906108c
SS
306 else
307 {
308 for (r = 0; r < NUM_REGS; r++)
309 do_child_fetch_inferior_registers (r);
310 }
311}
312
313static void
314child_fetch_inferior_registers (int r)
315{
39f77062 316 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
c906108c
SS
317 do_child_fetch_inferior_registers (r);
318}
319
320static void
321do_child_store_inferior_registers (int r)
322{
323 if (r >= 0)
324 read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
325 else
326 {
327 for (r = 0; r < NUM_REGS; r++)
328 do_child_store_inferior_registers (r);
329 }
330}
331
332/* Store a new register value into the current thread context */
333static void
334child_store_inferior_registers (int r)
335{
39f77062 336 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
c906108c
SS
337 do_child_store_inferior_registers (r);
338}
339
c2d11a7d
JM
340static int psapi_loaded = 0;
341static HMODULE psapi_module_handle = NULL;
8e860359
CF
342static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
343static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
344static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
c2d11a7d 345
8e860359
CF
346int
347psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
c2d11a7d
JM
348{
349 DWORD len;
350 MODULEINFO mi;
351 int i;
8e860359
CF
352 HMODULE dh_buf[1];
353 HMODULE *DllHandle = dh_buf;
c2d11a7d
JM
354 DWORD cbNeeded;
355 BOOL ok;
356
357 if (!psapi_loaded ||
8e860359
CF
358 psapi_EnumProcessModules == NULL ||
359 psapi_GetModuleInformation == NULL ||
360 psapi_GetModuleFileNameExA == NULL)
c2d11a7d 361 {
8e860359
CF
362 if (psapi_loaded)
363 goto failed;
c2d11a7d
JM
364 psapi_loaded = 1;
365 psapi_module_handle = LoadLibrary ("psapi.dll");
366 if (!psapi_module_handle)
8e860359
CF
367 {
368 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
369 goto failed;
370 }
371 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
c2d11a7d
JM
372 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
373 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
8e860359
CF
374 "GetModuleFileNameExA");
375 if (psapi_EnumProcessModules == NULL ||
376 psapi_GetModuleInformation == NULL ||
377 psapi_GetModuleFileNameExA == NULL)
c2d11a7d
JM
378 goto failed;
379 }
380
381 cbNeeded = 0;
382 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
383 DllHandle,
384 sizeof (HMODULE),
385 &cbNeeded);
c2d11a7d
JM
386
387 if (!ok || !cbNeeded)
388 goto failed;
389
8e860359 390 DllHandle = (HMODULE *) alloca (cbNeeded);
c2d11a7d
JM
391 if (!DllHandle)
392 goto failed;
393
394 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
395 DllHandle,
396 cbNeeded,
397 &cbNeeded);
c2d11a7d
JM
398 if (!ok)
399 goto failed;
400
29fe111d 401 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
c2d11a7d
JM
402 {
403 if (!(*psapi_GetModuleInformation) (current_process_handle,
8e860359
CF
404 DllHandle[i],
405 &mi,
406 sizeof (mi)))
c2d11a7d
JM
407 error ("Can't get module info");
408
409 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
8e860359
CF
410 DllHandle[i],
411 dll_name_ret,
412 MAX_PATH);
c2d11a7d 413 if (len == 0)
29fe111d 414 error ("Error getting dll name: %u\n", GetLastError ());
c2d11a7d
JM
415
416 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
417 return 1;
418 }
419
420failed:
421 dll_name_ret[0] = '\0';
422 return 0;
423}
424
450005e7
CF
425/* Encapsulate the information required in a call to
426 symbol_file_add_args */
8a892701
CF
427struct safe_symbol_file_add_args
428{
429 char *name;
430 int from_tty;
431 struct section_addr_info *addrs;
432 int mainline;
433 int flags;
7c5c87c0 434 struct ui_file *err, *out;
8a892701
CF
435 struct objfile *ret;
436};
437
450005e7
CF
438/* Call symbol_file_add with stderr redirected. We don't care if there
439 are errors. */
8a892701
CF
440static int
441safe_symbol_file_add_stub (void *argv)
442{
443#define p ((struct safe_symbol_file_add_args *)argv)
444 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
445 return !!p->ret;
446#undef p
447}
448
450005e7 449/* Restore gdb's stderr after calling symbol_file_add */
8a892701 450static void
7c5c87c0 451safe_symbol_file_add_cleanup (void *p)
8a892701 452{
8e860359 453#define sp ((struct safe_symbol_file_add_args *)p)
450005e7 454 gdb_flush (gdb_stderr);
7c5c87c0 455 gdb_flush (gdb_stdout);
8a892701 456 ui_file_delete (gdb_stderr);
7c5c87c0
CF
457 ui_file_delete (gdb_stdout);
458 gdb_stderr = sp->err;
9d3789f7 459 gdb_stdout = sp->out;
8e860359 460#undef sp
8a892701
CF
461}
462
450005e7 463/* symbol_file_add wrapper that prevents errors from being displayed. */
8a892701
CF
464static struct objfile *
465safe_symbol_file_add (char *name, int from_tty,
466 struct section_addr_info *addrs,
467 int mainline, int flags)
8a892701
CF
468{
469 struct safe_symbol_file_add_args p;
470 struct cleanup *cleanup;
471
7c5c87c0 472 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
8a892701 473
7c5c87c0
CF
474 p.err = gdb_stderr;
475 p.out = gdb_stdout;
450005e7 476 gdb_flush (gdb_stderr);
7c5c87c0 477 gdb_flush (gdb_stdout);
8a892701 478 gdb_stderr = ui_file_new ();
7c5c87c0 479 gdb_stdout = ui_file_new ();
8a892701
CF
480 p.name = name;
481 p.from_tty = from_tty;
482 p.addrs = addrs;
483 p.mainline = mainline;
484 p.flags = flags;
485 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
486
487 do_cleanups (cleanup);
488 return p.ret;
489}
490
450005e7
CF
491/* Maintain a linked list of "so" information. */
492struct so_stuff
493{
494 struct so_stuff *next, **last;
495 DWORD load_addr;
496 char name[0];
8e860359
CF
497}
498solib_start, *solib_end;
450005e7
CF
499
500/* Remember the maximum DLL length for printing in info dll command. */
501int max_dll_name_len;
502
8e860359
CF
503static void
504register_loaded_dll (const char *name, DWORD load_addr)
505{
506 struct so_stuff *so;
507 so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (name) + 8 + 2);
508 so->load_addr = load_addr;
509 strcpy (so->name, name);
510
511 solib_end->next = so;
512 solib_end = so;
513 so->next = NULL;
514}
515
c906108c
SS
516/* Wait for child to do something. Return pid of child, or -1 in case
517 of error; store status through argument pointer OURSTATUS. */
c906108c 518static int
554cb486 519handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
c906108c 520{
c5aa993b 521 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
c906108c
SS
522 DWORD dll_name_ptr;
523 DWORD done;
524 char dll_buf[MAX_PATH + 1];
450005e7 525 char *dll_name = NULL;
450005e7
CF
526 int len;
527 char *p;
c906108c 528
c5aa993b 529 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 530
c2d11a7d 531 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
8e860359 532 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 533
c2d11a7d 534 dll_name = dll_buf;
c906108c
SS
535
536 /* Attempt to read the name of the dll that was detected.
537 This is documented to work only when actively debugging
538 a program. It will not work for attached processes. */
539 if (dll_name == NULL || *dll_name == '\0')
540 {
29fe111d 541 DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
c906108c
SS
542 int len = 0;
543 char b[2];
544
545 ReadProcessMemory (current_process_handle,
546 (LPCVOID) event->lpImageName,
547 (char *) &dll_name_ptr,
548 sizeof (dll_name_ptr), &done);
549
550 /* See if we could read the address of a string, and that the
c5aa993b 551 address isn't null. */
c906108c
SS
552
553 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
554 return 1;
555
556 do
557 {
558 ReadProcessMemory (current_process_handle,
559 (LPCVOID) (dll_name_ptr + len * size),
560 &b,
561 size,
562 &done);
563 len++;
564 }
565 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
566
567 dll_name = alloca (len);
568
569 if (event->fUnicode)
570 {
571 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
572 ReadProcessMemory (current_process_handle,
573 (LPCVOID) dll_name_ptr,
574 unicode_dll_name,
575 len * sizeof (WCHAR),
576 &done);
577
578 WideCharToMultiByte (CP_ACP, 0,
579 unicode_dll_name, len,
580 dll_name, len, 0, 0);
581 }
582 else
583 {
584 ReadProcessMemory (current_process_handle,
585 (LPCVOID) dll_name_ptr,
586 dll_name,
587 len,
588 &done);
589 }
590 }
591
592 if (!dll_name)
593 return 1;
594
29fe111d
CF
595 (void) strlwr (dll_name);
596
c906108c
SS
597 while ((p = strchr (dll_name, '\\')))
598 *p = '/';
599
8e860359 600 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
450005e7
CF
601 len = strlen (dll_name);
602 if (len > max_dll_name_len)
603 max_dll_name_len = len;
604
605 return 1;
606}
607
608/* Return name of last loaded DLL. */
609char *
9d3789f7 610child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED)
450005e7 611{
8e860359 612 return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
450005e7
CF
613}
614
615/* Clear list of loaded DLLs. */
616void
617child_clear_solibs (void)
618{
619 struct so_stuff *so, *so1 = solib_start.next;
620
621 while ((so = so1) != NULL)
622 {
623 so1 = so->next;
b8c9b27d 624 xfree (so);
450005e7
CF
625 }
626
627 solib_start.next = NULL;
628 solib_end = &solib_start;
629 max_dll_name_len = sizeof ("DLL Name") - 1;
630}
631
632/* Add DLL symbol information. */
633void
8e860359 634solib_symbols_add (char *name, CORE_ADDR load_addr)
450005e7
CF
635{
636 struct section_addr_info section_addrs;
637
c906108c
SS
638 /* The symbols in a dll are offset by 0x1000, which is the
639 the offset from 0 of the first byte in an image - because
8a892701 640 of the file header and the section alignment. */
c906108c 641
8e860359 642 if (!name || !name[0])
450005e7
CF
643 return;
644
645 memset (&section_addrs, 0, sizeof (section_addrs));
0aa9cf96 646 section_addrs.other[0].name = ".text";
8e860359
CF
647 section_addrs.other[0].addr = load_addr;
648 safe_symbol_file_add (name, 0, &section_addrs, 0, OBJF_SHARED);
c906108c 649
450005e7
CF
650 return;
651}
652
653/* Load DLL symbol info. */
654void
9d3789f7 655dll_symbol_command (char *args, int from_tty ATTRIBUTE_UNUSED)
450005e7 656{
8e860359 657 int n;
450005e7 658 dont_repeat ();
8e860359 659
450005e7
CF
660 if (args == NULL)
661 error ("dll-symbols requires a file name");
662
8e860359
CF
663 n = strlen (args);
664 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
665 {
666 char *newargs = (char *) alloca (n + 4 + 1);
667 strcpy (newargs, args);
668 strcat (newargs, ".dll");
669 args = newargs;
670 }
671
9d3789f7 672 safe_symbol_file_add (args, 0, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
8e860359 673}
450005e7
CF
674
675/* List currently loaded DLLs. */
676void
9d3789f7 677info_dll_command (char *ignore ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
450005e7
CF
678{
679 struct so_stuff *so = &solib_start;
680
681 if (!so->next)
682 return;
683
684 printf ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
685 while ((so = so->next) != NULL)
7c5c87c0 686 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
450005e7
CF
687
688 return;
c906108c
SS
689}
690
691/* Handle DEBUG_STRING output from child process.
692 Cygwin prepends its messages with a "cygwin:". Interpret this as
693 a Cygwin signal. Otherwise just print the string as a warning. */
694static int
695handle_output_debug_string (struct target_waitstatus *ourstatus)
696{
697 char *s;
698 int gotasig = FALSE;
699
700 if (!target_read_string
c5aa993b 701 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
c906108c
SS
702 || !s || !*s)
703 return gotasig;
704
ed9a39eb 705 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
c906108c 706 {
ed9a39eb 707 if (strncmp (s, "cYg", 3) != 0)
29fe111d 708 warning ("%s", s);
c906108c 709 }
ed9a39eb 710 else
c906108c
SS
711 {
712 char *p;
c2d11a7d
JM
713 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
714 gotasig = target_signal_from_host (sig);
7a292a7a
SS
715 ourstatus->value.sig = gotasig;
716 if (gotasig)
c906108c
SS
717 ourstatus->kind = TARGET_WAITKIND_STOPPED;
718 }
719
b8c9b27d 720 xfree (s);
c906108c
SS
721 return gotasig;
722}
723
724static int
450005e7 725handle_exception (struct target_waitstatus *ourstatus)
c906108c 726{
c906108c 727 thread_info *th;
29fe111d 728 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
c906108c 729
29fe111d 730 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 731
c906108c
SS
732 /* Record the context of the current thread */
733 th = thread_rec (current_event.dwThreadId, -1);
734
29fe111d 735 switch (code)
c906108c
SS
736 {
737 case EXCEPTION_ACCESS_VIOLATION:
29fe111d 738 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
8e860359 739 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c 740 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
8a892701 741 last_sig = SIGSEGV;
c906108c 742 break;
0d06e24b
JM
743 case STATUS_FLOAT_UNDERFLOW:
744 case STATUS_FLOAT_DIVIDE_BY_ZERO:
745 case STATUS_FLOAT_OVERFLOW:
746 case STATUS_INTEGER_DIVIDE_BY_ZERO:
29fe111d 747 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
8e860359 748 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
0d06e24b 749 ourstatus->value.sig = TARGET_SIGNAL_FPE;
29fe111d 750 last_sig = SIGFPE;
0d06e24b 751 break;
c906108c 752 case STATUS_STACK_OVERFLOW:
29fe111d 753 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
8e860359 754 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
755 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
756 break;
757 case EXCEPTION_BREAKPOINT:
29fe111d 758 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
8e860359 759 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
760 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
761 break;
762 case DBG_CONTROL_C:
29fe111d 763 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
8e860359 764 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c 765 ourstatus->value.sig = TARGET_SIGNAL_INT;
8a892701 766 last_sig = SIGINT; /* FIXME - should check pass state */
c906108c
SS
767 break;
768 case EXCEPTION_SINGLE_STEP:
29fe111d 769 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
8e860359 770 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
771 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
772 break;
8227c82d 773 case EXCEPTION_ILLEGAL_INSTRUCTION:
29fe111d 774 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
8e860359 775 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
8227c82d 776 ourstatus->value.sig = TARGET_SIGNAL_ILL;
8a892701 777 last_sig = SIGILL;
8227c82d 778 break;
c906108c 779 default:
29fe111d 780 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
c5aa993b 781 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 782 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
c906108c
SS
783 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
784 break;
785 }
786 exception_count++;
787 return 1;
788}
789
790/* Resume all artificially suspended threads if we are continuing
791 execution */
792static BOOL
8a892701 793child_continue (DWORD continue_status, int id)
c906108c
SS
794{
795 int i;
796 thread_info *th;
797 BOOL res;
798
29fe111d 799 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
c906108c 800 current_event.dwProcessId, current_event.dwThreadId));
7a292a7a
SS
801 res = ContinueDebugEvent (current_event.dwProcessId,
802 current_event.dwThreadId,
803 continue_status);
c2d11a7d 804 continue_status = 0;
7a292a7a 805 if (res)
c5aa993b 806 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 807 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
c906108c
SS
808 {
809 for (i = 0; i < th->suspend_count; i++)
810 (void) ResumeThread (th->h);
811 th->suspend_count = 0;
812 }
813
814 return res;
815}
816
8a892701
CF
817/* Get the next event from the child. Return 1 if the event requires
818 handling by WFI (or whatever).
819 */
c2d11a7d 820static int
450005e7 821get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
c2d11a7d
JM
822{
823 BOOL debug_event;
8a892701
CF
824 DWORD continue_status, event_code;
825 thread_info *th = NULL;
826 static thread_info dummy_thread_info;
450005e7 827 int retval = 0;
c2d11a7d 828
9d3789f7
CF
829 last_sig = 0;
830
8a892701 831 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 832 goto out;
c2d11a7d
JM
833
834 event_count++;
835 continue_status = DBG_CONTINUE;
c2d11a7d 836
8a892701 837 event_code = current_event.dwDebugEventCode;
450005e7 838 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
8a892701
CF
839
840 switch (event_code)
c2d11a7d
JM
841 {
842 case CREATE_THREAD_DEBUG_EVENT:
843 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
844 (unsigned) current_event.dwProcessId,
845 (unsigned) current_event.dwThreadId,
846 "CREATE_THREAD_DEBUG_EVENT"));
c2d11a7d 847 /* Record the existence of this thread */
8a892701
CF
848 th = child_add_thread (current_event.dwThreadId,
849 current_event.u.CreateThread.hThread);
c2d11a7d
JM
850 if (info_verbose)
851 printf_unfiltered ("[New %s]\n",
39f77062
KB
852 target_pid_to_str (
853 pid_to_ptid (current_event.dwThreadId)));
450005e7 854 retval = current_event.dwThreadId;
c2d11a7d
JM
855 break;
856
857 case EXIT_THREAD_DEBUG_EVENT:
858 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
859 (unsigned) current_event.dwProcessId,
860 (unsigned) current_event.dwThreadId,
861 "EXIT_THREAD_DEBUG_EVENT"));
c2d11a7d 862 child_delete_thread (current_event.dwThreadId);
8a892701 863 th = &dummy_thread_info;
c2d11a7d
JM
864 break;
865
866 case CREATE_PROCESS_DEBUG_EVENT:
867 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
868 (unsigned) current_event.dwProcessId,
869 (unsigned) current_event.dwThreadId,
870 "CREATE_PROCESS_DEBUG_EVENT"));
c2d11a7d
JM
871 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
872
9d3789f7 873 main_thread_id = current_event.dwThreadId;
c2d11a7d 874 /* Add the main thread */
9d3789f7 875#if 0
450005e7
CF
876 th = child_add_thread (current_event.dwProcessId,
877 current_event.u.CreateProcessInfo.hProcess);
9d3789f7
CF
878#endif
879 th = child_add_thread (main_thread_id,
8a892701 880 current_event.u.CreateProcessInfo.hThread);
9d3789f7 881 retval = ourstatus->value.related_pid = current_event.dwThreadId;
c2d11a7d
JM
882 break;
883
884 case EXIT_PROCESS_DEBUG_EVENT:
885 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
886 (unsigned) current_event.dwProcessId,
887 (unsigned) current_event.dwThreadId,
888 "EXIT_PROCESS_DEBUG_EVENT"));
c2d11a7d
JM
889 ourstatus->kind = TARGET_WAITKIND_EXITED;
890 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
891 CloseHandle (current_process_handle);
9d3789f7 892 retval = main_thread_id;
8a892701 893 break;
c2d11a7d
JM
894
895 case LOAD_DLL_DEBUG_EVENT:
896 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
897 (unsigned) current_event.dwProcessId,
898 (unsigned) current_event.dwThreadId,
899 "LOAD_DLL_DEBUG_EVENT"));
900 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
c2d11a7d 901 registers_changed (); /* mark all regs invalid */
450005e7
CF
902 ourstatus->kind = TARGET_WAITKIND_LOADED;
903 ourstatus->value.integer = 0;
9d3789f7 904 retval = main_thread_id;
c2d11a7d
JM
905 break;
906
907 case UNLOAD_DLL_DEBUG_EVENT:
908 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
909 (unsigned) current_event.dwProcessId,
910 (unsigned) current_event.dwThreadId,
911 "UNLOAD_DLL_DEBUG_EVENT"));
912 break; /* FIXME: don't know what to do here */
c2d11a7d
JM
913
914 case EXCEPTION_DEBUG_EVENT:
915 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
916 (unsigned) current_event.dwProcessId,
917 (unsigned) current_event.dwThreadId,
918 "EXCEPTION_DEBUG_EVENT"));
450005e7
CF
919 handle_exception (ourstatus);
920 retval = current_event.dwThreadId;
c2d11a7d
JM
921 break;
922
8a892701 923 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
c2d11a7d 924 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
925 (unsigned) current_event.dwProcessId,
926 (unsigned) current_event.dwThreadId,
927 "OUTPUT_DEBUG_STRING_EVENT"));
8e860359 928 if (handle_output_debug_string (ourstatus))
9d3789f7 929 retval = main_thread_id;
c2d11a7d 930 break;
9d3789f7 931
c2d11a7d 932 default:
29fe111d
CF
933 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
934 (DWORD) current_event.dwProcessId,
935 (DWORD) current_event.dwThreadId);
936 printf_unfiltered (" unknown event code %ld\n",
c2d11a7d
JM
937 current_event.dwDebugEventCode);
938 break;
939 }
940
450005e7 941 if (!retval)
8a892701 942 CHECK (child_continue (continue_status, -1));
450005e7 943 else
9d3789f7 944 {
8e860359 945 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
39f77062 946 inferior_ptid = pid_to_ptid (retval);
9d3789f7 947 }
c2d11a7d
JM
948
949out:
450005e7 950 return retval;
c2d11a7d
JM
951}
952
c2d11a7d 953/* Wait for interesting events to occur in the target process. */
39f77062
KB
954static ptid_t
955child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
c906108c 956{
39f77062
KB
957 int pid = PIDGET (ptid);
958
c906108c
SS
959 /* We loop when we get a non-standard exception rather than return
960 with a SPURIOUS because resume can try and step or modify things,
961 which needs a current_thread->h. But some of these exceptions mark
962 the birth or death of threads, which mean that the current thread
963 isn't necessarily what you think it is. */
964
965 while (1)
450005e7
CF
966 {
967 int retval = get_child_debug_event (pid, ourstatus);
968 if (retval)
39f77062 969 return pid_to_ptid (retval);
450005e7
CF
970 else
971 {
972 int detach = 0;
c906108c 973
450005e7
CF
974 if (ui_loop_hook != NULL)
975 detach = ui_loop_hook (0);
7a292a7a 976
450005e7
CF
977 if (detach)
978 child_kill_inferior ();
979 }
980 }
c906108c
SS
981}
982
9d3789f7
CF
983static void
984do_initial_child_stuff (DWORD pid)
985{
986 extern int stop_after_trap;
987
988 last_sig = 0;
989 event_count = 0;
990 exception_count = 0;
991 current_event.dwProcessId = pid;
992 memset (&current_event, 0, sizeof (current_event));
993 push_target (&child_ops);
994 child_init_thread_list ();
995 child_clear_solibs ();
996 clear_proceed_status ();
997 init_wait_for_inferior ();
998
999 target_terminal_init ();
1000 target_terminal_inferior ();
1001
1002 while (1)
1003 {
1004 stop_after_trap = 1;
1005 wait_for_inferior ();
1006 if (stop_signal != TARGET_SIGNAL_TRAP)
1007 resume (0, stop_signal);
1008 else
1009 break;
1010 }
1011 stop_after_trap = 0;
1012 return;
1013}
1014
c906108c
SS
1015/* Attach to process PID, then initialize for debugging it. */
1016
1017static void
fba45db2 1018child_attach (char *args, int from_tty)
c906108c
SS
1019{
1020 BOOL ok;
559e75c0 1021 DWORD pid;
c906108c
SS
1022
1023 if (!args)
1024 error_no_arg ("process-id to attach");
1025
559e75c0 1026 pid = strtoul (args, 0, 0);
9d3789f7 1027 ok = DebugActiveProcess (pid);
c906108c
SS
1028
1029 if (!ok)
1030 error ("Can't attach to process.");
1031
c906108c
SS
1032 if (from_tty)
1033 {
1034 char *exec_file = (char *) get_exec_file (0);
1035
1036 if (exec_file)
1037 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1038 target_pid_to_str (pid_to_ptid (pid)));
c906108c
SS
1039 else
1040 printf_unfiltered ("Attaching to %s\n",
39f77062 1041 target_pid_to_str (pid_to_ptid (pid)));
c906108c
SS
1042
1043 gdb_flush (gdb_stdout);
1044 }
1045
9d3789f7
CF
1046 do_initial_child_stuff (pid);
1047 target_terminal_ours ();
c906108c
SS
1048}
1049
1050static void
29fe111d 1051child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
c906108c
SS
1052{
1053 if (from_tty)
1054 {
1055 char *exec_file = get_exec_file (0);
1056 if (exec_file == 0)
1057 exec_file = "";
1058 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
39f77062 1059 target_pid_to_str (inferior_ptid));
c906108c
SS
1060 gdb_flush (gdb_stdout);
1061 }
39f77062 1062 inferior_ptid = null_ptid;
c906108c
SS
1063 unpush_target (&child_ops);
1064}
1065
1066/* Print status information about what we're accessing. */
1067
1068static void
29fe111d 1069child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
c906108c
SS
1070{
1071 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1072 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
c906108c
SS
1073}
1074
1075/* ARGSUSED */
1076static void
29fe111d 1077child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
c906108c
SS
1078{
1079 error ("Use the \"run\" command to start a Unix child process.");
1080}
1081
39f77062 1082/* Start an inferior win32 child process and sets inferior_ptid to its pid.
c906108c
SS
1083 EXEC_FILE is the file to run.
1084 ALLARGS is a string containing the arguments to the program.
1085 ENV is the environment vector to pass. Errors reported with error(). */
1086
1087static void
fba45db2 1088child_create_inferior (char *exec_file, char *allargs, char **env)
c906108c
SS
1089{
1090 char real_path[MAXPATHLEN];
1091 char *winenv;
1092 char *temp;
c5aa993b 1093 int envlen;
c906108c 1094 int i;
c906108c
SS
1095 STARTUPINFO si;
1096 PROCESS_INFORMATION pi;
c906108c
SS
1097 BOOL ret;
1098 DWORD flags;
1099 char *args;
1100
1101 if (!exec_file)
450005e7 1102 error ("No executable specified, use `target exec'.\n");
c906108c
SS
1103
1104 memset (&si, 0, sizeof (si));
1105 si.cb = sizeof (si);
1106
29fe111d 1107 cygwin_conv_to_win32_path (exec_file, real_path);
c906108c
SS
1108
1109 flags = DEBUG_ONLY_THIS_PROCESS;
1110
1111 if (new_group)
1112 flags |= CREATE_NEW_PROCESS_GROUP;
1113
1114 if (new_console)
1115 flags |= CREATE_NEW_CONSOLE;
1116
1117 args = alloca (strlen (real_path) + strlen (allargs) + 2);
1118
1119 strcpy (args, real_path);
1120
1121 strcat (args, " ");
1122 strcat (args, allargs);
1123
1124 /* Prepare the environment vars for CreateProcess. */
1125 {
1126 /* This code use to assume all env vars were file names and would
1127 translate them all to win32 style. That obviously doesn't work in the
1128 general case. The current rule is that we only translate PATH.
1129 We need to handle PATH because we're about to call CreateProcess and
1130 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1131 in both posix and win32 environments. cygwin.dll will change it back
1132 to posix style if necessary. */
1133
1134 static const char *conv_path_names[] =
c5aa993b
JM
1135 {
1136 "PATH=",
1137 0
1138 };
c906108c
SS
1139
1140 /* CreateProcess takes the environment list as a null terminated set of
1141 strings (i.e. two nulls terminate the list). */
1142
1143 /* Get total size for env strings. */
1144 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1145 {
1146 int j, len;
1147
1148 for (j = 0; conv_path_names[j]; j++)
1149 {
1150 len = strlen (conv_path_names[j]);
1151 if (strncmp (conv_path_names[j], env[i], len) == 0)
1152 {
29fe111d 1153 if (cygwin_posix_path_list_p (env[i] + len))
c906108c 1154 envlen += len
29fe111d 1155 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
c906108c
SS
1156 else
1157 envlen += strlen (env[i]) + 1;
1158 break;
1159 }
1160 }
1161 if (conv_path_names[j] == NULL)
1162 envlen += strlen (env[i]) + 1;
1163 }
1164
1165 winenv = alloca (envlen + 1);
1166
1167 /* Copy env strings into new buffer. */
1168 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1169 {
1170 int j, len;
1171
1172 for (j = 0; conv_path_names[j]; j++)
1173 {
1174 len = strlen (conv_path_names[j]);
1175 if (strncmp (conv_path_names[j], env[i], len) == 0)
1176 {
29fe111d 1177 if (cygwin_posix_path_list_p (env[i] + len))
c906108c
SS
1178 {
1179 memcpy (temp, env[i], len);
29fe111d 1180 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
c906108c
SS
1181 }
1182 else
1183 strcpy (temp, env[i]);
1184 break;
1185 }
1186 }
1187 if (conv_path_names[j] == NULL)
1188 strcpy (temp, env[i]);
1189
1190 temp += strlen (temp) + 1;
1191 }
1192
1193 /* Final nil string to terminate new env. */
1194 *temp = 0;
1195 }
1196
1197 ret = CreateProcess (0,
c5aa993b 1198 args, /* command line */
c906108c
SS
1199 NULL, /* Security */
1200 NULL, /* thread */
1201 TRUE, /* inherit handles */
1202 flags, /* start flags */
1203 winenv,
1204 NULL, /* current directory */
1205 &si,
1206 &pi);
1207 if (!ret)
c5aa993b 1208 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
c906108c 1209
9d3789f7 1210 do_initial_child_stuff (pi.dwProcessId);
ed9a39eb 1211
8e860359 1212 /* child_continue (DBG_CONTINUE, -1); */
c2d11a7d 1213 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
c906108c
SS
1214}
1215
1216static void
fba45db2 1217child_mourn_inferior (void)
c906108c 1218{
8a892701 1219 (void) child_continue (DBG_CONTINUE, -1);
c906108c
SS
1220 unpush_target (&child_ops);
1221 generic_mourn_inferior ();
1222}
1223
1224/* Send a SIGINT to the process group. This acts just like the user typed a
1225 ^C on the controlling terminal. */
1226
1227static void
fba45db2 1228child_stop (void)
c906108c
SS
1229{
1230 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
c2d11a7d 1231 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
c5aa993b 1232 registers_changed (); /* refresh register state */
c906108c
SS
1233}
1234
1235int
1236child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
56c40d46 1237 int write, struct mem_attrib *mem ATTRIBUTE_UNUSED,
aea02b6b 1238 struct target_ops *target ATTRIBUTE_UNUSED)
c906108c
SS
1239{
1240 DWORD done;
1241 if (write)
1242 {
29fe111d
CF
1243 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1244 len, (DWORD) memaddr));
c906108c
SS
1245 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1246 len, &done);
1247 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1248 }
1249 else
1250 {
29fe111d
CF
1251 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1252 len, (DWORD) memaddr));
c906108c
SS
1253 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1254 &done);
1255 }
1256 return done;
1257}
1258
1259void
1260child_kill_inferior (void)
1261{
1262 CHECK (TerminateProcess (current_process_handle, 0));
1263
1264 for (;;)
1265 {
8a892701 1266 if (!child_continue (DBG_CONTINUE, -1))
c906108c
SS
1267 break;
1268 if (!WaitForDebugEvent (&current_event, INFINITE))
1269 break;
1270 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1271 break;
1272 }
1273
1274 CHECK (CloseHandle (current_process_handle));
1275
1276 /* this may fail in an attached process so don't check. */
1277 (void) CloseHandle (current_thread->h);
c5aa993b 1278 target_mourn_inferior (); /* or just child_mourn_inferior? */
c906108c
SS
1279}
1280
1281void
39f77062 1282child_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c 1283{
c906108c 1284 thread_info *th;
8a892701 1285 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
8e860359 1286 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
39f77062 1287 int pid = PIDGET (ptid);
8a892701
CF
1288
1289 last_sig = 0;
c906108c
SS
1290
1291 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1292 pid, step, sig));
1293
1294 /* Get context for currently selected thread */
1295 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 1296 if (th)
c906108c 1297 {
450005e7
CF
1298 if (step)
1299 {
1300 /* Single step by setting t bit */
1301 child_fetch_inferior_registers (PS_REGNUM);
1302 th->context.EFlags |= FLAG_TRACE_BIT;
1303 }
c906108c 1304
450005e7
CF
1305 if (th->context.ContextFlags)
1306 {
1307 CHECK (SetThreadContext (th->h, &th->context));
1308 th->context.ContextFlags = 0;
1309 }
c906108c
SS
1310 }
1311
1312 /* Allow continuing with the same signal that interrupted us.
1313 Otherwise complain. */
c906108c 1314
8a892701 1315 child_continue (continue_status, pid);
c906108c
SS
1316}
1317
1318static void
fba45db2 1319child_prepare_to_store (void)
c906108c
SS
1320{
1321 /* Do nothing, since we can store individual regs */
1322}
1323
1324static int
fba45db2 1325child_can_run (void)
c906108c
SS
1326{
1327 return 1;
1328}
1329
1330static void
9d3789f7 1331child_close (int x ATTRIBUTE_UNUSED)
c906108c 1332{
39f77062
KB
1333 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1334 PIDGET (inferior_ptid)));
c906108c
SS
1335}
1336
c5aa993b 1337struct target_ops child_ops;
c906108c 1338
c5aa993b
JM
1339static void
1340init_child_ops (void)
c906108c 1341{
c5aa993b
JM
1342 child_ops.to_shortname = "child";
1343 child_ops.to_longname = "Win32 child process";
1344 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1345 child_ops.to_open = child_open;
1346 child_ops.to_close = child_close;
1347 child_ops.to_attach = child_attach;
1348 child_ops.to_detach = child_detach;
1349 child_ops.to_resume = child_resume;
1350 child_ops.to_wait = child_wait;
1351 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1352 child_ops.to_store_registers = child_store_inferior_registers;
1353 child_ops.to_prepare_to_store = child_prepare_to_store;
1354 child_ops.to_xfer_memory = child_xfer_memory;
1355 child_ops.to_files_info = child_files_info;
1356 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1357 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1358 child_ops.to_terminal_init = terminal_init_inferior;
1359 child_ops.to_terminal_inferior = terminal_inferior;
1360 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1361 child_ops.to_terminal_ours = terminal_ours;
1362 child_ops.to_terminal_info = child_terminal_info;
1363 child_ops.to_kill = child_kill_inferior;
1364 child_ops.to_load = 0;
1365 child_ops.to_lookup_symbol = 0;
1366 child_ops.to_create_inferior = child_create_inferior;
1367 child_ops.to_mourn_inferior = child_mourn_inferior;
1368 child_ops.to_can_run = child_can_run;
1369 child_ops.to_notice_signals = 0;
1370 child_ops.to_thread_alive = win32_child_thread_alive;
ed9a39eb 1371 child_ops.to_pid_to_str = cygwin_pid_to_str;
c5aa993b
JM
1372 child_ops.to_stop = child_stop;
1373 child_ops.to_stratum = process_stratum;
1374 child_ops.DONT_USE = 0;
1375 child_ops.to_has_all_memory = 1;
1376 child_ops.to_has_memory = 1;
1377 child_ops.to_has_stack = 1;
1378 child_ops.to_has_registers = 1;
1379 child_ops.to_has_execution = 1;
1380 child_ops.to_sections = 0;
1381 child_ops.to_sections_end = 0;
1382 child_ops.to_magic = OPS_MAGIC;
c906108c
SS
1383}
1384
1385void
fba45db2 1386_initialize_inftarg (void)
c906108c 1387{
fa58ee11
EZ
1388 struct cmd_list_element *c;
1389
c5aa993b 1390 init_child_ops ();
c906108c 1391
fa58ee11
EZ
1392 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1393 "Load dll library symbols from FILE.");
1394 c->completer = filename_completer;
450005e7 1395
8e860359 1396 auto_solib_add = 1;
450005e7
CF
1397 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1398
1399 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
8e860359
CF
1400 (char *) &new_console,
1401 "Set creation of new console when creating child process.",
1402 &setlist),
1403 &showlist);
c906108c 1404
450005e7 1405 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
8e860359
CF
1406 (char *) &new_group,
1407 "Set creation of new group when creating child process.",
1408 &setlist),
1409 &showlist);
c906108c 1410
450005e7 1411 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
8e860359
CF
1412 (char *) &debug_exec,
1413 "Set whether to display execution in child process.",
1414 &setlist),
1415 &showlist);
c906108c 1416
450005e7 1417 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
8e860359
CF
1418 (char *) &debug_events,
1419 "Set whether to display kernel events in child process.",
1420 &setlist),
1421 &showlist);
c906108c 1422
450005e7 1423 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
8e860359
CF
1424 (char *) &debug_memory,
1425 "Set whether to display memory accesses in child process.",
1426 &setlist),
1427 &showlist);
c906108c 1428
450005e7 1429 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
8e860359
CF
1430 (char *) &debug_exceptions,
1431 "Set whether to display kernel exceptions in child process.",
1432 &setlist),
1433 &showlist);
c906108c 1434
450005e7
CF
1435 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1436 add_info_alias ("sharedlibrary", "dll", 1);
1437
c906108c
SS
1438 add_target (&child_ops);
1439}
1440
1441/* Determine if the thread referenced by "pid" is alive
1442 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1443 it means that the pid has died. Otherwise it is assumed to be alive. */
1444static int
39f77062 1445win32_child_thread_alive (ptid_t ptid)
c906108c 1446{
39f77062
KB
1447 int pid = PIDGET (ptid);
1448
c5aa993b
JM
1449 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1450 FALSE : TRUE;
c906108c
SS
1451}
1452
1453/* Convert pid to printable format. */
1454char *
39f77062 1455cygwin_pid_to_str (ptid_t ptid)
c906108c
SS
1456{
1457 static char buf[80];
39f77062
KB
1458 int pid = PIDGET (ptid);
1459
29fe111d 1460 if ((DWORD) pid == current_event.dwProcessId)
c906108c
SS
1461 sprintf (buf, "process %d", pid);
1462 else
29fe111d 1463 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
c906108c
SS
1464 return buf;
1465}
8e860359
CF
1466
1467static int
1468core_dll_symbols_add (char *dll_name, DWORD base_addr)
1469{
1470 struct objfile *objfile;
1471 char *objfile_basename;
1472 const char *dll_basename;
1473
1474 if (!(dll_basename = strrchr (dll_name, '/')))
1475 dll_basename = dll_name;
1476 else
1477 dll_basename++;
1478
1479 ALL_OBJFILES (objfile)
1480 {
1481 objfile_basename = strrchr (objfile->name, '/');
1482
1483 if (objfile_basename &&
1484 strcmp (dll_basename, objfile_basename + 1) == 0)
1485 {
1486 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1487 base_addr, dll_name);
1488 goto out;
1489 }
1490 }
1491
1492 register_loaded_dll (dll_name, base_addr + 0x1000);
1493 solib_symbols_add (dll_name, (CORE_ADDR) base_addr + 0x1000);
1494
1495out:
1496 return 1;
1497}
1498
1499typedef struct
1500{
1501 struct target_ops *target;
1502 bfd_vma addr;
1503}
1504map_code_section_args;
1505
1506static void
554cb486 1507map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1508{
1509 int old;
1510 int update_coreops;
1511 struct section_table *new_target_sect_ptr;
1512
1513 map_code_section_args *args = (map_code_section_args *) obj;
1514 struct target_ops *target = args->target;
1515 if (sect->flags & SEC_CODE)
1516 {
1517 update_coreops = core_ops.to_sections == target->to_sections;
1518
1519 if (target->to_sections)
1520 {
1521 old = target->to_sections_end - target->to_sections;
1522 target->to_sections = (struct section_table *)
1523 xrealloc ((char *) target->to_sections,
1524 (sizeof (struct section_table)) * (1 + old));
1525 }
1526 else
1527 {
1528 old = 0;
1529 target->to_sections = (struct section_table *)
1530 xmalloc ((sizeof (struct section_table)));
1531 }
1532 target->to_sections_end = target->to_sections + (1 + old);
1533
1534 /* Update the to_sections field in the core_ops structure
1535 if needed. */
1536 if (update_coreops)
1537 {
1538 core_ops.to_sections = target->to_sections;
1539 core_ops.to_sections_end = target->to_sections_end;
1540 }
1541 new_target_sect_ptr = target->to_sections + old;
1542 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1543 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1544 bfd_section_size (abfd, sect);;
1545 new_target_sect_ptr->the_bfd_section = sect;
1546 new_target_sect_ptr->bfd = abfd;
1547 }
1548}
1549
1550static int
1551dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1552{
1553 bfd *dll_bfd;
1554 map_code_section_args map_args;
1555 asection *lowest_sect;
1556 char *name;
1557 if (dll_name == NULL || target == NULL)
1558 return 0;
66ed1d85 1559 name = xstrdup (dll_name);
8e860359
CF
1560 dll_bfd = bfd_openr (name, "pei-i386");
1561 if (dll_bfd == NULL)
1562 return 0;
1563
1564 if (bfd_check_format (dll_bfd, bfd_object))
1565 {
1566 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1567 if (lowest_sect == NULL)
1568 return 0;
1569 map_args.target = target;
1570 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1571
554cb486 1572 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
1573 }
1574
1575 return 1;
1576}
1577
1578static void
554cb486 1579core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1580{
1581 struct target_ops *target = (struct target_ops *) obj;
1582
1583 DWORD base_addr;
1584
1585 int dll_name_size;
1586 char *dll_name = NULL;
1587 char *buf = NULL;
1588 struct win32_pstatus *pstatus;
1589 char *p;
1590
1591 if (strncmp (sect->name, ".module", 7))
1592 return;
1593
1594 buf = (char *) xmalloc (sect->_raw_size + 1);
1595 if (!buf)
1596 {
1597 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1598 goto out;
1599 }
1600 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1601 goto out;
1602
1603 pstatus = (struct win32_pstatus *) buf;
1604
1605 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1606 dll_name_size = pstatus->data.module_info.module_name_size;
1607 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1608 goto out;
1609
1610 dll_name = (char *) xmalloc (dll_name_size + 1);
1611 if (!dll_name)
1612 {
1613 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1614 goto out;
1615 }
1616 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1617
1618 while ((p = strchr (dll_name, '\\')))
1619 *p = '/';
1620
1621 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1622 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1623
1624 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1625 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1626
1627out:
1628 if (buf)
b8c9b27d 1629 xfree (buf);
8e860359 1630 if (dll_name)
b8c9b27d 1631 xfree (dll_name);
8e860359
CF
1632 return;
1633}
1634
1635void
1636child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED, struct target_ops *target)
1637{
1638 if (core_bfd)
1639 {
1640 child_clear_solibs ();
1641 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1642 }
1643 else
1644 {
1645 if (solib_end && solib_end->name)
1646 solib_symbols_add (solib_end->name, solib_end->load_addr);
1647 }
1648}
1649
1650static void
1651fetch_elf_core_registers (char *core_reg_sect,
1652 unsigned core_reg_size,
1653 int which,
1654 CORE_ADDR reg_addr)
1655{
1656 int r;
1657 if (core_reg_size < sizeof (CONTEXT))
1658 {
1659 error ("Core file register section too small (%u bytes).", core_reg_size);
1660 return;
1661 }
1662 for (r = 0; r < NUM_REGS; r++)
1663 supply_register (r, core_reg_sect + mappings[r]);
1664}
1665
1666static struct core_fns win32_elf_core_fns =
1667{
1668 bfd_target_elf_flavour,
1669 default_check_format,
1670 default_core_sniffer,
1671 fetch_elf_core_registers,
1672 NULL
1673};
1674
1675void
0613c401 1676_initialize_core_win32 (void)
8e860359
CF
1677{
1678 add_core_fns (&win32_elf_core_fns);
1679}