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