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