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