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