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