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