2002-11-02 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / win32-nat.c
1 /* Target-vector operations for controlling win32 child processes, for GDB.
2
3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
4 Software Foundation, Inc.
5
6 Contributed by Cygnus Solutions, A Red Hat Company.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25 /* Originally by Steve Chamberlain, sac@cygnus.com */
26
27 /* We assume we're being built with and will be used for cygwin. */
28
29 #include "defs.h"
30 #include "tm.h" /* required for SSE registers */
31 #include "frame.h" /* required by inferior.h */
32 #include "inferior.h"
33 #include "target.h"
34 #include "gdbcore.h"
35 #include "command.h"
36 #include "completer.h"
37 #include "regcache.h"
38 #include "top.h"
39 #include "i386-tdep.h"
40 #include <signal.h>
41 #include <sys/types.h>
42 #include <fcntl.h>
43 #include <stdlib.h>
44 #include <windows.h>
45 #include <imagehlp.h>
46 #include <sys/cygwin.h>
47
48 #include "buildsym.h"
49 #include "symfile.h"
50 #include "objfiles.h"
51 #include "gdb_string.h"
52 #include "gdbthread.h"
53 #include "gdbcmd.h"
54 #include <sys/param.h>
55 #include <unistd.h>
56
57 /* The ui's event loop. */
58 extern int (*ui_loop_hook) (int signo);
59
60 /* If we're not using the old Cygwin header file set, define the
61 following which never should have been in the generic Win32 API
62 headers in the first place since they were our own invention... */
63 #ifndef _GNU_H_WINDOWS_H
64 enum
65 {
66 FLAG_TRACE_BIT = 0x100,
67 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
68 };
69 #endif
70 #include <sys/procfs.h>
71 #include <psapi.h>
72
73 #ifdef HAVE_SSE_REGS
74 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
75 | CONTEXT_EXTENDED_REGISTERS
76 #else
77 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS
78 #endif
79
80 static unsigned dr[8];
81 static int debug_registers_changed = 0;
82 static int debug_registers_used = 0;
83
84 /* The string sent by cygwin when it processes a signal.
85 FIXME: This should be in a cygwin include file. */
86 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
87
88 #define CHECK(x) check (x, __FILE__,__LINE__)
89 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
90 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
91 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
92 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
93
94 /* Forward declaration */
95 extern struct target_ops child_ops;
96
97 static void child_stop (void);
98 static int win32_child_thread_alive (ptid_t);
99 void child_kill_inferior (void);
100
101 static enum target_signal last_sig = TARGET_SIGNAL_0;
102 /* Set if a signal was received from the debugged process */
103
104 /* Thread information structure used to track information that is
105 not available in gdb's thread structure. */
106 typedef struct thread_info_struct
107 {
108 struct thread_info_struct *next;
109 DWORD id;
110 HANDLE h;
111 char *name;
112 int suspend_count;
113 CONTEXT context;
114 STACKFRAME sf;
115 }
116 thread_info;
117
118 static thread_info thread_head;
119
120 /* The process and thread handles for the above context. */
121
122 static DEBUG_EVENT current_event; /* The current debug event from
123 WaitForDebugEvent */
124 static HANDLE current_process_handle; /* Currently executing process */
125 static thread_info *current_thread; /* Info on currently selected thread */
126 static DWORD main_thread_id; /* Thread ID of the main thread */
127 static pid_t cygwin_pid; /* pid of cygwin process */
128
129 /* Counts of things. */
130 static int exception_count = 0;
131 static int event_count = 0;
132 static int saw_create;
133
134 /* User options. */
135 static int new_console = 0;
136 static int new_group = 1;
137 static int debug_exec = 0; /* show execution */
138 static int debug_events = 0; /* show events from kernel */
139 static int debug_memory = 0; /* show target memory accesses */
140 static int debug_exceptions = 0; /* show target exceptions */
141 static int useshell = 0; /* use shell for subprocesses */
142
143 /* This vector maps GDB's idea of a register's number into an address
144 in the win32 exception context vector.
145
146 It also contains the bit mask needed to load the register in question.
147
148 One day we could read a reg, we could inspect the context we
149 already have loaded, if it doesn't have the bit set that we need,
150 we read that set of registers in using GetThreadContext. If the
151 context already contains what we need, we just unpack it. Then to
152 write a register, first we have to ensure that the context contains
153 the other regs of the group, and then we copy the info in and set
154 out bit. */
155
156 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
157 static const int mappings[] =
158 {
159 context_offset (Eax),
160 context_offset (Ecx),
161 context_offset (Edx),
162 context_offset (Ebx),
163 context_offset (Esp),
164 context_offset (Ebp),
165 context_offset (Esi),
166 context_offset (Edi),
167 context_offset (Eip),
168 context_offset (EFlags),
169 context_offset (SegCs),
170 context_offset (SegSs),
171 context_offset (SegDs),
172 context_offset (SegEs),
173 context_offset (SegFs),
174 context_offset (SegGs),
175 context_offset (FloatSave.RegisterArea[0 * 10]),
176 context_offset (FloatSave.RegisterArea[1 * 10]),
177 context_offset (FloatSave.RegisterArea[2 * 10]),
178 context_offset (FloatSave.RegisterArea[3 * 10]),
179 context_offset (FloatSave.RegisterArea[4 * 10]),
180 context_offset (FloatSave.RegisterArea[5 * 10]),
181 context_offset (FloatSave.RegisterArea[6 * 10]),
182 context_offset (FloatSave.RegisterArea[7 * 10]),
183 context_offset (FloatSave.ControlWord),
184 context_offset (FloatSave.StatusWord),
185 context_offset (FloatSave.TagWord),
186 context_offset (FloatSave.ErrorSelector),
187 context_offset (FloatSave.ErrorOffset),
188 context_offset (FloatSave.DataSelector),
189 context_offset (FloatSave.DataOffset),
190 context_offset (FloatSave.ErrorSelector)
191 #ifdef HAVE_SSE_REGS
192 /* XMM0-7 */ ,
193 context_offset (ExtendedRegisters[10*16]),
194 context_offset (ExtendedRegisters[11*16]),
195 context_offset (ExtendedRegisters[12*16]),
196 context_offset (ExtendedRegisters[13*16]),
197 context_offset (ExtendedRegisters[14*16]),
198 context_offset (ExtendedRegisters[15*16]),
199 context_offset (ExtendedRegisters[16*16]),
200 context_offset (ExtendedRegisters[17*16]),
201 /* MXCSR */
202 context_offset (ExtendedRegisters[24])
203 #endif
204 };
205
206 #undef context_offset
207
208 /* This vector maps the target's idea of an exception (extracted
209 from the DEBUG_EVENT structure) to GDB's idea. */
210
211 struct xlate_exception
212 {
213 int them;
214 enum target_signal us;
215 };
216
217 static const struct xlate_exception
218 xlate[] =
219 {
220 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
221 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
222 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
223 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
224 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
225 {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
226 {-1, -1}};
227
228 static void
229 check (BOOL ok, const char *file, int line)
230 {
231 if (!ok)
232 printf_filtered ("error return %s:%d was %lu\n", file, line,
233 GetLastError ());
234 }
235
236
237 /* Find a thread record given a thread id.
238 If get_context then also retrieve the context for this
239 thread. */
240 static thread_info *
241 thread_rec (DWORD id, int get_context)
242 {
243 thread_info *th;
244
245 for (th = &thread_head; (th = th->next) != NULL;)
246 if (th->id == id)
247 {
248 if (!th->suspend_count && get_context)
249 {
250 if (get_context > 0 && id != current_event.dwThreadId)
251 th->suspend_count = SuspendThread (th->h) + 1;
252 else if (get_context < 0)
253 th->suspend_count = -1;
254
255 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
256 GetThreadContext (th->h, &th->context);
257 if (id == current_event.dwThreadId)
258 {
259 /* Copy dr values from that thread. */
260 dr[0] = th->context.Dr0;
261 dr[1] = th->context.Dr1;
262 dr[2] = th->context.Dr2;
263 dr[3] = th->context.Dr3;
264 dr[6] = th->context.Dr6;
265 dr[7] = th->context.Dr7;
266 }
267 }
268 return th;
269 }
270
271 return NULL;
272 }
273
274 /* Add a thread to the thread list */
275 static thread_info *
276 child_add_thread (DWORD id, HANDLE h)
277 {
278 thread_info *th;
279
280 if ((th = thread_rec (id, FALSE)))
281 return th;
282
283 th = (thread_info *) xmalloc (sizeof (*th));
284 memset (th, 0, sizeof (*th));
285 th->id = id;
286 th->h = h;
287 th->next = thread_head.next;
288 thread_head.next = th;
289 add_thread (pid_to_ptid (id));
290 /* Set the debug registers for the new thread in they are used. */
291 if (debug_registers_used)
292 {
293 /* Only change the value of the debug registers. */
294 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
295 CHECK (GetThreadContext (th->h, &th->context));
296 th->context.Dr0 = dr[0];
297 th->context.Dr1 = dr[1];
298 th->context.Dr2 = dr[2];
299 th->context.Dr3 = dr[3];
300 /* th->context.Dr6 = dr[6];
301 FIXME: should we set dr6 also ?? */
302 th->context.Dr7 = dr[7];
303 CHECK (SetThreadContext (th->h, &th->context));
304 th->context.ContextFlags = 0;
305 }
306 return th;
307 }
308
309 /* Clear out any old thread list and reintialize it to a
310 pristine state. */
311 static void
312 child_init_thread_list (void)
313 {
314 thread_info *th = &thread_head;
315
316 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
317 init_thread_list ();
318 while (th->next != NULL)
319 {
320 thread_info *here = th->next;
321 th->next = here->next;
322 (void) CloseHandle (here->h);
323 xfree (here);
324 }
325 }
326
327 /* Delete a thread from the list of threads */
328 static void
329 child_delete_thread (DWORD id)
330 {
331 thread_info *th;
332
333 if (info_verbose)
334 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
335 delete_thread (pid_to_ptid (id));
336
337 for (th = &thread_head;
338 th->next != NULL && th->next->id != id;
339 th = th->next)
340 continue;
341
342 if (th->next != NULL)
343 {
344 thread_info *here = th->next;
345 th->next = here->next;
346 CloseHandle (here->h);
347 xfree (here);
348 }
349 }
350
351 static void
352 do_child_fetch_inferior_registers (int r)
353 {
354 char *context_offset = ((char *) &current_thread->context) + mappings[r];
355 long l;
356 if (r == FCS_REGNUM)
357 {
358 l = *((long *) context_offset) & 0xffff;
359 supply_register (r, (char *) &l);
360 }
361 else if (r == FOP_REGNUM)
362 {
363 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
364 supply_register (r, (char *) &l);
365 }
366 else if (r >= 0)
367 supply_register (r, context_offset);
368 else
369 {
370 for (r = 0; r < NUM_REGS; r++)
371 do_child_fetch_inferior_registers (r);
372 }
373 }
374
375 static void
376 child_fetch_inferior_registers (int r)
377 {
378 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
379 do_child_fetch_inferior_registers (r);
380 }
381
382 static void
383 do_child_store_inferior_registers (int r)
384 {
385 if (r >= 0)
386 deprecated_read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
387 else
388 {
389 for (r = 0; r < NUM_REGS; r++)
390 do_child_store_inferior_registers (r);
391 }
392 }
393
394 /* Store a new register value into the current thread context */
395 static void
396 child_store_inferior_registers (int r)
397 {
398 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
399 do_child_store_inferior_registers (r);
400 }
401
402 static int psapi_loaded = 0;
403 static HMODULE psapi_module_handle = NULL;
404 static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
405 static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
406 static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
407
408 int
409 psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
410 {
411 DWORD len;
412 MODULEINFO mi;
413 int i;
414 HMODULE dh_buf[1];
415 HMODULE *DllHandle = dh_buf;
416 DWORD cbNeeded;
417 BOOL ok;
418
419 if (!psapi_loaded ||
420 psapi_EnumProcessModules == NULL ||
421 psapi_GetModuleInformation == NULL ||
422 psapi_GetModuleFileNameExA == NULL)
423 {
424 if (psapi_loaded)
425 goto failed;
426 psapi_loaded = 1;
427 psapi_module_handle = LoadLibrary ("psapi.dll");
428 if (!psapi_module_handle)
429 {
430 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
431 goto failed;
432 }
433 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
434 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
435 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
436 "GetModuleFileNameExA");
437 if (psapi_EnumProcessModules == NULL ||
438 psapi_GetModuleInformation == NULL ||
439 psapi_GetModuleFileNameExA == NULL)
440 goto failed;
441 }
442
443 cbNeeded = 0;
444 ok = (*psapi_EnumProcessModules) (current_process_handle,
445 DllHandle,
446 sizeof (HMODULE),
447 &cbNeeded);
448
449 if (!ok || !cbNeeded)
450 goto failed;
451
452 DllHandle = (HMODULE *) alloca (cbNeeded);
453 if (!DllHandle)
454 goto failed;
455
456 ok = (*psapi_EnumProcessModules) (current_process_handle,
457 DllHandle,
458 cbNeeded,
459 &cbNeeded);
460 if (!ok)
461 goto failed;
462
463 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
464 {
465 if (!(*psapi_GetModuleInformation) (current_process_handle,
466 DllHandle[i],
467 &mi,
468 sizeof (mi)))
469 error ("Can't get module info");
470
471 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
472 DllHandle[i],
473 dll_name_ret,
474 MAX_PATH);
475 if (len == 0)
476 error ("Error getting dll name: %u\n", GetLastError ());
477
478 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
479 return 1;
480 }
481
482 failed:
483 dll_name_ret[0] = '\0';
484 return 0;
485 }
486
487 /* Encapsulate the information required in a call to
488 symbol_file_add_args */
489 struct safe_symbol_file_add_args
490 {
491 char *name;
492 int from_tty;
493 struct section_addr_info *addrs;
494 int mainline;
495 int flags;
496 struct ui_file *err, *out;
497 struct objfile *ret;
498 };
499
500 /* Maintain a linked list of "so" information. */
501 struct so_stuff
502 {
503 struct so_stuff *next;
504 DWORD load_addr;
505 int loaded;
506 struct objfile *objfile;
507 char name[1];
508 } solib_start, *solib_end;
509
510 /* Call symbol_file_add with stderr redirected. We don't care if there
511 are errors. */
512 static int
513 safe_symbol_file_add_stub (void *argv)
514 {
515 #define p ((struct safe_symbol_file_add_args *)argv)
516 struct so_stuff *so = &solib_start;
517
518 while ((so = so->next))
519 if (so->loaded && strcasecmp (so->name, p->name) == 0)
520 return 0;
521 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
522 return !!p->ret;
523 #undef p
524 }
525
526 /* Restore gdb's stderr after calling symbol_file_add */
527 static void
528 safe_symbol_file_add_cleanup (void *p)
529 {
530 #define sp ((struct safe_symbol_file_add_args *)p)
531 gdb_flush (gdb_stderr);
532 gdb_flush (gdb_stdout);
533 ui_file_delete (gdb_stderr);
534 ui_file_delete (gdb_stdout);
535 gdb_stderr = sp->err;
536 gdb_stdout = sp->out;
537 #undef sp
538 }
539
540 /* symbol_file_add wrapper that prevents errors from being displayed. */
541 static struct objfile *
542 safe_symbol_file_add (char *name, int from_tty,
543 struct section_addr_info *addrs,
544 int mainline, int flags)
545 {
546 struct safe_symbol_file_add_args p;
547 struct cleanup *cleanup;
548
549 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
550
551 p.err = gdb_stderr;
552 p.out = gdb_stdout;
553 gdb_flush (gdb_stderr);
554 gdb_flush (gdb_stdout);
555 gdb_stderr = ui_file_new ();
556 gdb_stdout = ui_file_new ();
557 p.name = name;
558 p.from_tty = from_tty;
559 p.addrs = addrs;
560 p.mainline = mainline;
561 p.flags = flags;
562 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
563
564 do_cleanups (cleanup);
565 return p.ret;
566 }
567
568 /* Remember the maximum DLL length for printing in info dll command. */
569 int max_dll_name_len;
570
571 static void
572 register_loaded_dll (const char *name, DWORD load_addr)
573 {
574 struct so_stuff *so;
575 char ppath[MAX_PATH + 1];
576 char buf[MAX_PATH + 1];
577 char cwd[MAX_PATH + 1];
578 char *p;
579 WIN32_FIND_DATA w32_fd;
580 HANDLE h = FindFirstFile(name, &w32_fd);
581 size_t len;
582
583 if (h == INVALID_HANDLE_VALUE)
584 strcpy (buf, name);
585 else
586 {
587 FindClose (h);
588 strcpy (buf, name);
589 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
590 {
591 p = strrchr (buf, '\\');
592 if (p)
593 p[1] = '\0';
594 SetCurrentDirectory (buf);
595 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
596 SetCurrentDirectory (cwd);
597 }
598 }
599
600 cygwin_conv_to_posix_path (buf, ppath);
601 so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
602 so->loaded = 0;
603 so->load_addr = load_addr;
604 so->next = NULL;
605 so->objfile = NULL;
606 strcpy (so->name, ppath);
607
608 solib_end->next = so;
609 solib_end = so;
610 len = strlen (ppath);
611 if (len > max_dll_name_len)
612 max_dll_name_len = len;
613 }
614
615 char *
616 get_image_name (HANDLE h, void *address, int unicode)
617 {
618 static char buf[(2 * MAX_PATH) + 1];
619 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
620 char *address_ptr;
621 int len = 0;
622 char b[2];
623 DWORD done;
624
625 /* Attempt to read the name of the dll that was detected.
626 This is documented to work only when actively debugging
627 a program. It will not work for attached processes. */
628 if (address == NULL)
629 return NULL;
630
631 ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done);
632
633 /* See if we could read the address of a string, and that the
634 address isn't null. */
635
636 if (done != sizeof (address_ptr) || !address_ptr)
637 return NULL;
638
639 /* Find the length of the string */
640 do
641 {
642 ReadProcessMemory (h, address_ptr + len * size, &b, size, &done);
643 len++;
644 }
645 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
646
647 if (!unicode)
648 ReadProcessMemory (h, address_ptr, buf, len, &done);
649 else
650 {
651 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
652 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
653 &done);
654
655 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
656 }
657
658 return buf;
659 }
660
661 /* Wait for child to do something. Return pid of child, or -1 in case
662 of error; store status through argument pointer OURSTATUS. */
663 static int
664 handle_load_dll (void *dummy)
665 {
666 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
667 char dll_buf[MAX_PATH + 1];
668 char *dll_name = NULL;
669 char *p;
670
671 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
672
673 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
674 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
675
676 dll_name = dll_buf;
677
678 if (*dll_name == '\0')
679 dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
680 if (!dll_name)
681 return 1;
682
683 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
684
685 return 1;
686 }
687
688 static int
689 handle_unload_dll (void *dummy)
690 {
691 DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
692 struct so_stuff *so;
693
694 for (so = &solib_start; so->next != NULL; so = so->next)
695 if (so->next->load_addr == lpBaseOfDll)
696 {
697 struct so_stuff *sodel = so->next;
698 so->next = sodel->next;
699 if (!so->next)
700 solib_end = so;
701 if (sodel->objfile)
702 free_objfile (sodel->objfile);
703 xfree(sodel);
704 return 1;
705 }
706 error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll);
707
708 return 0;
709 }
710
711 /* Return name of last loaded DLL. */
712 char *
713 child_solib_loaded_library_pathname (int pid)
714 {
715 return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
716 }
717
718 /* Clear list of loaded DLLs. */
719 void
720 child_clear_solibs (void)
721 {
722 struct so_stuff *so, *so1 = solib_start.next;
723
724 while ((so = so1) != NULL)
725 {
726 so1 = so->next;
727 xfree (so);
728 }
729
730 solib_start.next = NULL;
731 solib_start.objfile = NULL;
732 solib_end = &solib_start;
733 max_dll_name_len = sizeof ("DLL Name") - 1;
734 }
735
736 /* Add DLL symbol information. */
737 static struct objfile *
738 solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
739 {
740 struct section_addr_info section_addrs;
741
742 /* The symbols in a dll are offset by 0x1000, which is the
743 the offset from 0 of the first byte in an image - because
744 of the file header and the section alignment. */
745
746 if (!name || !name[0])
747 return NULL;
748
749 memset (&section_addrs, 0, sizeof (section_addrs));
750 section_addrs.other[0].name = ".text";
751 section_addrs.other[0].addr = load_addr;
752 return safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
753 }
754
755 /* Load DLL symbol info. */
756 void
757 dll_symbol_command (char *args, int from_tty)
758 {
759 int n;
760 dont_repeat ();
761
762 if (args == NULL)
763 error ("dll-symbols requires a file name");
764
765 n = strlen (args);
766 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
767 {
768 char *newargs = (char *) alloca (n + 4 + 1);
769 strcpy (newargs, args);
770 strcat (newargs, ".dll");
771 args = newargs;
772 }
773
774 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
775 }
776
777 /* List currently loaded DLLs. */
778 void
779 info_dll_command (char *ignore, int from_tty)
780 {
781 struct so_stuff *so = &solib_start;
782
783 if (!so->next)
784 return;
785
786 printf_filtered ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
787 while ((so = so->next) != NULL)
788 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
789
790 return;
791 }
792
793 /* Handle DEBUG_STRING output from child process.
794 Cygwin prepends its messages with a "cygwin:". Interpret this as
795 a Cygwin signal. Otherwise just print the string as a warning. */
796 static int
797 handle_output_debug_string (struct target_waitstatus *ourstatus)
798 {
799 char *s;
800 int gotasig = FALSE;
801
802 if (!target_read_string
803 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
804 || !s || !*s)
805 return gotasig;
806
807 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
808 {
809 if (strncmp (s, "cYg", 3) != 0)
810 warning ("%s", s);
811 }
812 else
813 {
814 char *p;
815 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
816 gotasig = target_signal_from_host (sig);
817 ourstatus->value.sig = gotasig;
818 if (gotasig)
819 ourstatus->kind = TARGET_WAITKIND_STOPPED;
820 }
821
822 xfree (s);
823 return gotasig;
824 }
825
826 static int
827 display_selector (HANDLE thread, DWORD sel)
828 {
829 LDT_ENTRY info;
830 if (GetThreadSelectorEntry (thread, sel, &info))
831 {
832 int base, limit;
833 printf_filtered ("0x%03lx: ", sel);
834 if (!info.HighWord.Bits.Pres)
835 {
836 puts_filtered ("Segment not present\n");
837 return 0;
838 }
839 base = (info.HighWord.Bits.BaseHi << 24) +
840 (info.HighWord.Bits.BaseMid << 16)
841 + info.BaseLow;
842 limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
843 if (info.HighWord.Bits.Granularity)
844 limit = (limit << 12) | 0xfff;
845 printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
846 if (info.HighWord.Bits.Default_Big)
847 puts_filtered(" 32-bit ");
848 else
849 puts_filtered(" 16-bit ");
850 switch ((info.HighWord.Bits.Type & 0xf) >> 1)
851 {
852 case 0:
853 puts_filtered ("Data (Read-Only, Exp-up");
854 break;
855 case 1:
856 puts_filtered ("Data (Read/Write, Exp-up");
857 break;
858 case 2:
859 puts_filtered ("Unused segment (");
860 break;
861 case 3:
862 puts_filtered ("Data (Read/Write, Exp-down");
863 break;
864 case 4:
865 puts_filtered ("Code (Exec-Only, N.Conf");
866 break;
867 case 5:
868 puts_filtered ("Code (Exec/Read, N.Conf");
869 break;
870 case 6:
871 puts_filtered ("Code (Exec-Only, Conf");
872 break;
873 case 7:
874 puts_filtered ("Code (Exec/Read, Conf");
875 break;
876 default:
877 printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
878 }
879 if ((info.HighWord.Bits.Type & 0x1) == 0)
880 puts_filtered(", N.Acc");
881 puts_filtered (")\n");
882 if ((info.HighWord.Bits.Type & 0x10) == 0)
883 puts_filtered("System selector ");
884 printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
885 if (info.HighWord.Bits.Granularity)
886 puts_filtered ("Page granular.\n");
887 else
888 puts_filtered ("Byte granular.\n");
889 return 1;
890 }
891 else
892 {
893 printf_filtered ("Invalid selector 0x%lx.\n",sel);
894 return 0;
895 }
896 }
897
898 static void
899 display_selectors (char * args, int from_tty)
900 {
901 if (!current_thread)
902 {
903 puts_filtered ("Impossible to display selectors now.\n");
904 return;
905 }
906 if (!args)
907 {
908
909 puts_filtered ("Selector $cs\n");
910 display_selector (current_thread->h,
911 current_thread->context.SegCs);
912 puts_filtered ("Selector $ds\n");
913 display_selector (current_thread->h,
914 current_thread->context.SegDs);
915 puts_filtered ("Selector $es\n");
916 display_selector (current_thread->h,
917 current_thread->context.SegEs);
918 puts_filtered ("Selector $ss\n");
919 display_selector (current_thread->h,
920 current_thread->context.SegSs);
921 puts_filtered ("Selector $fs\n");
922 display_selector (current_thread->h,
923 current_thread->context.SegFs);
924 puts_filtered ("Selector $gs\n");
925 display_selector (current_thread->h,
926 current_thread->context.SegGs);
927 }
928 else
929 {
930 int sel;
931 sel = parse_and_eval_long (args);
932 printf_filtered ("Selector \"%s\"\n",args);
933 display_selector (current_thread->h, sel);
934 }
935 }
936
937 static struct cmd_list_element *info_w32_cmdlist = NULL;
938
939 static void
940 info_w32_command (char *args, int from_tty)
941 {
942 help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
943 }
944
945
946 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
947 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
948 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
949
950 static int
951 handle_exception (struct target_waitstatus *ourstatus)
952 {
953 thread_info *th;
954 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
955
956 ourstatus->kind = TARGET_WAITKIND_STOPPED;
957
958 /* Record the context of the current thread */
959 th = thread_rec (current_event.dwThreadId, -1);
960
961 switch (code)
962 {
963 case EXCEPTION_ACCESS_VIOLATION:
964 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
965 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
966 break;
967 case STATUS_STACK_OVERFLOW:
968 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
969 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
970 break;
971 case STATUS_FLOAT_DENORMAL_OPERAND:
972 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
973 ourstatus->value.sig = TARGET_SIGNAL_FPE;
974 break;
975 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
976 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
977 ourstatus->value.sig = TARGET_SIGNAL_FPE;
978 break;
979 case STATUS_FLOAT_INEXACT_RESULT:
980 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
981 ourstatus->value.sig = TARGET_SIGNAL_FPE;
982 break;
983 case STATUS_FLOAT_INVALID_OPERATION:
984 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
985 ourstatus->value.sig = TARGET_SIGNAL_FPE;
986 break;
987 case STATUS_FLOAT_OVERFLOW:
988 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
989 ourstatus->value.sig = TARGET_SIGNAL_FPE;
990 break;
991 case STATUS_FLOAT_STACK_CHECK:
992 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
993 ourstatus->value.sig = TARGET_SIGNAL_FPE;
994 break;
995 case STATUS_FLOAT_UNDERFLOW:
996 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
997 ourstatus->value.sig = TARGET_SIGNAL_FPE;
998 break;
999 case STATUS_FLOAT_DIVIDE_BY_ZERO:
1000 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1001 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1002 break;
1003 case STATUS_INTEGER_DIVIDE_BY_ZERO:
1004 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1005 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1006 break;
1007 case STATUS_INTEGER_OVERFLOW:
1008 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1009 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1010 break;
1011 case EXCEPTION_BREAKPOINT:
1012 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1013 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1014 break;
1015 case DBG_CONTROL_C:
1016 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1017 ourstatus->value.sig = TARGET_SIGNAL_INT;
1018 break;
1019 case DBG_CONTROL_BREAK:
1020 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1021 ourstatus->value.sig = TARGET_SIGNAL_INT;
1022 break;
1023 case EXCEPTION_SINGLE_STEP:
1024 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1025 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1026 break;
1027 case EXCEPTION_ILLEGAL_INSTRUCTION:
1028 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1029 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1030 break;
1031 case EXCEPTION_PRIV_INSTRUCTION:
1032 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1033 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1034 break;
1035 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1036 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1037 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1038 break;
1039 default:
1040 if (current_event.u.Exception.dwFirstChance)
1041 return 0;
1042 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1043 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1044 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1045 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1046 break;
1047 }
1048 exception_count++;
1049 last_sig = ourstatus->value.sig;
1050 return 1;
1051 }
1052
1053 /* Resume all artificially suspended threads if we are continuing
1054 execution */
1055 static BOOL
1056 child_continue (DWORD continue_status, int id)
1057 {
1058 int i;
1059 thread_info *th;
1060 BOOL res;
1061
1062 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1063 current_event.dwProcessId, current_event.dwThreadId,
1064 continue_status == DBG_CONTINUE ?
1065 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1066 res = ContinueDebugEvent (current_event.dwProcessId,
1067 current_event.dwThreadId,
1068 continue_status);
1069 continue_status = 0;
1070 if (res)
1071 for (th = &thread_head; (th = th->next) != NULL;)
1072 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
1073 {
1074
1075 for (i = 0; i < th->suspend_count; i++)
1076 (void) ResumeThread (th->h);
1077 th->suspend_count = 0;
1078 if (debug_registers_changed)
1079 {
1080 /* Only change the value of the debug reisters */
1081 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
1082 th->context.Dr0 = dr[0];
1083 th->context.Dr1 = dr[1];
1084 th->context.Dr2 = dr[2];
1085 th->context.Dr3 = dr[3];
1086 /* th->context.Dr6 = dr[6];
1087 FIXME: should we set dr6 also ?? */
1088 th->context.Dr7 = dr[7];
1089 CHECK (SetThreadContext (th->h, &th->context));
1090 th->context.ContextFlags = 0;
1091 }
1092 }
1093
1094 debug_registers_changed = 0;
1095 return res;
1096 }
1097
1098 /* Get the next event from the child. Return 1 if the event requires
1099 handling by WFI (or whatever).
1100 */
1101 static int
1102 get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
1103 {
1104 BOOL debug_event;
1105 DWORD continue_status, event_code;
1106 thread_info *th = NULL;
1107 static thread_info dummy_thread_info;
1108 int retval = 0;
1109
1110 last_sig = TARGET_SIGNAL_0;
1111
1112 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
1113 goto out;
1114
1115 event_count++;
1116 continue_status = DBG_CONTINUE;
1117
1118 event_code = current_event.dwDebugEventCode;
1119 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1120
1121 switch (event_code)
1122 {
1123 case CREATE_THREAD_DEBUG_EVENT:
1124 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1125 (unsigned) current_event.dwProcessId,
1126 (unsigned) current_event.dwThreadId,
1127 "CREATE_THREAD_DEBUG_EVENT"));
1128 if (saw_create != 1)
1129 break;
1130 /* Record the existence of this thread */
1131 th = child_add_thread (current_event.dwThreadId,
1132 current_event.u.CreateThread.hThread);
1133 if (info_verbose)
1134 printf_unfiltered ("[New %s]\n",
1135 target_pid_to_str (
1136 pid_to_ptid (current_event.dwThreadId)));
1137 retval = current_event.dwThreadId;
1138 break;
1139
1140 case EXIT_THREAD_DEBUG_EVENT:
1141 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1142 (unsigned) current_event.dwProcessId,
1143 (unsigned) current_event.dwThreadId,
1144 "EXIT_THREAD_DEBUG_EVENT"));
1145 if (saw_create != 1)
1146 break;
1147 child_delete_thread (current_event.dwThreadId);
1148 th = &dummy_thread_info;
1149 break;
1150
1151 case CREATE_PROCESS_DEBUG_EVENT:
1152 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1153 (unsigned) current_event.dwProcessId,
1154 (unsigned) current_event.dwThreadId,
1155 "CREATE_PROCESS_DEBUG_EVENT"));
1156 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1157 if (++saw_create != 1)
1158 {
1159 CloseHandle (current_event.u.CreateProcessInfo.hProcess);
1160 break;
1161 }
1162
1163 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1164 main_thread_id = current_event.dwThreadId;
1165 /* Add the main thread */
1166 #if 0
1167 th = child_add_thread (current_event.dwProcessId,
1168 current_event.u.CreateProcessInfo.hProcess);
1169 #endif
1170 th = child_add_thread (main_thread_id,
1171 current_event.u.CreateProcessInfo.hThread);
1172 retval = ourstatus->value.related_pid = current_event.dwThreadId;
1173 break;
1174
1175 case EXIT_PROCESS_DEBUG_EVENT:
1176 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1177 (unsigned) current_event.dwProcessId,
1178 (unsigned) current_event.dwThreadId,
1179 "EXIT_PROCESS_DEBUG_EVENT"));
1180 if (saw_create != 1)
1181 break;
1182 ourstatus->kind = TARGET_WAITKIND_EXITED;
1183 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1184 CloseHandle (current_process_handle);
1185 retval = main_thread_id;
1186 break;
1187
1188 case LOAD_DLL_DEBUG_EVENT:
1189 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1190 (unsigned) current_event.dwProcessId,
1191 (unsigned) current_event.dwThreadId,
1192 "LOAD_DLL_DEBUG_EVENT"));
1193 CloseHandle (current_event.u.LoadDll.hFile);
1194 if (saw_create != 1)
1195 break;
1196 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1197 registers_changed (); /* mark all regs invalid */
1198 ourstatus->kind = TARGET_WAITKIND_LOADED;
1199 ourstatus->value.integer = 0;
1200 retval = main_thread_id;
1201 break;
1202
1203 case UNLOAD_DLL_DEBUG_EVENT:
1204 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1205 (unsigned) current_event.dwProcessId,
1206 (unsigned) current_event.dwThreadId,
1207 "UNLOAD_DLL_DEBUG_EVENT"));
1208 if (saw_create != 1)
1209 break;
1210 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1211 registers_changed (); /* mark all regs invalid */
1212 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1213 does not exist yet. */
1214 break;
1215
1216 case EXCEPTION_DEBUG_EVENT:
1217 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1218 (unsigned) current_event.dwProcessId,
1219 (unsigned) current_event.dwThreadId,
1220 "EXCEPTION_DEBUG_EVENT"));
1221 if (saw_create != 1)
1222 break;
1223 if (handle_exception (ourstatus))
1224 retval = current_event.dwThreadId;
1225 break;
1226
1227 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1228 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1229 (unsigned) current_event.dwProcessId,
1230 (unsigned) current_event.dwThreadId,
1231 "OUTPUT_DEBUG_STRING_EVENT"));
1232 if (saw_create != 1)
1233 break;
1234 if (handle_output_debug_string (ourstatus))
1235 retval = main_thread_id;
1236 break;
1237
1238 default:
1239 if (saw_create != 1)
1240 break;
1241 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1242 (DWORD) current_event.dwProcessId,
1243 (DWORD) current_event.dwThreadId);
1244 printf_unfiltered (" unknown event code %ld\n",
1245 current_event.dwDebugEventCode);
1246 break;
1247 }
1248
1249 if (!retval || saw_create != 1)
1250 CHECK (child_continue (continue_status, -1));
1251 else
1252 {
1253 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
1254 inferior_ptid = pid_to_ptid (retval);
1255 }
1256
1257 out:
1258 return retval;
1259 }
1260
1261 /* Wait for interesting events to occur in the target process. */
1262 static ptid_t
1263 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1264 {
1265 int pid = PIDGET (ptid);
1266
1267 /* We loop when we get a non-standard exception rather than return
1268 with a SPURIOUS because resume can try and step or modify things,
1269 which needs a current_thread->h. But some of these exceptions mark
1270 the birth or death of threads, which mean that the current thread
1271 isn't necessarily what you think it is. */
1272
1273 while (1)
1274 {
1275 int retval = get_child_debug_event (pid, ourstatus);
1276 if (retval)
1277 return pid_to_ptid (retval);
1278 else
1279 {
1280 int detach = 0;
1281
1282 if (ui_loop_hook != NULL)
1283 detach = ui_loop_hook (0);
1284
1285 if (detach)
1286 child_kill_inferior ();
1287 }
1288 }
1289 }
1290
1291 static void
1292 do_initial_child_stuff (DWORD pid)
1293 {
1294 extern int stop_after_trap;
1295 int i;
1296
1297 last_sig = TARGET_SIGNAL_0;
1298 event_count = 0;
1299 exception_count = 0;
1300 debug_registers_changed = 0;
1301 debug_registers_used = 0;
1302 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1303 dr[i] = 0;
1304 current_event.dwProcessId = pid;
1305 memset (&current_event, 0, sizeof (current_event));
1306 push_target (&child_ops);
1307 child_init_thread_list ();
1308 child_clear_solibs ();
1309 clear_proceed_status ();
1310 init_wait_for_inferior ();
1311
1312 target_terminal_init ();
1313 target_terminal_inferior ();
1314
1315 while (1)
1316 {
1317 stop_after_trap = 1;
1318 wait_for_inferior ();
1319 if (stop_signal != TARGET_SIGNAL_TRAP)
1320 resume (0, stop_signal);
1321 else
1322 break;
1323 }
1324 stop_after_trap = 0;
1325 return;
1326 }
1327
1328 /* Since Windows XP, detaching from a process is supported by Windows.
1329 The following code tries loading the appropriate functions dynamically.
1330 If loading these functions succeeds use them to actually detach from
1331 the inferior process, otherwise behave as usual, pretending that
1332 detach has worked. */
1333 static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1334 static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1335
1336 static int
1337 has_detach_ability (void)
1338 {
1339 static HMODULE kernel32 = NULL;
1340
1341 if (!kernel32)
1342 kernel32 = LoadLibrary ("kernel32.dll");
1343 if (kernel32)
1344 {
1345 if (!DebugSetProcessKillOnExit)
1346 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1347 "DebugSetProcessKillOnExit");
1348 if (!DebugActiveProcessStop)
1349 DebugActiveProcessStop = GetProcAddress (kernel32,
1350 "DebugActiveProcessStop");
1351 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1352 return 1;
1353 }
1354 return 0;
1355 }
1356
1357 /* Attach to process PID, then initialize for debugging it. */
1358 static void
1359 child_attach (char *args, int from_tty)
1360 {
1361 BOOL ok;
1362 DWORD pid;
1363
1364 if (!args)
1365 error_no_arg ("process-id to attach");
1366
1367 pid = strtoul (args, 0, 0);
1368 ok = DebugActiveProcess (pid);
1369
1370 if (!ok)
1371 error ("Can't attach to process.");
1372
1373 if (has_detach_ability ())
1374 {
1375 attach_flag = 1;
1376 DebugSetProcessKillOnExit (FALSE);
1377 }
1378
1379 if (from_tty)
1380 {
1381 char *exec_file = (char *) get_exec_file (0);
1382
1383 if (exec_file)
1384 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1385 target_pid_to_str (pid_to_ptid (pid)));
1386 else
1387 printf_unfiltered ("Attaching to %s\n",
1388 target_pid_to_str (pid_to_ptid (pid)));
1389
1390 gdb_flush (gdb_stdout);
1391 }
1392
1393 do_initial_child_stuff (pid);
1394 target_terminal_ours ();
1395 }
1396
1397 static void
1398 child_detach (char *args, int from_tty)
1399 {
1400 int detached = 1;
1401
1402 if (has_detach_ability ())
1403 {
1404 delete_command (NULL, 0);
1405 child_continue (DBG_CONTINUE, -1);
1406 if (!DebugActiveProcessStop (current_event.dwProcessId))
1407 {
1408 error ("Can't detach process %lu (error %lu)",
1409 current_event.dwProcessId, GetLastError ());
1410 detached = 0;
1411 }
1412 DebugSetProcessKillOnExit (FALSE);
1413 }
1414 if (detached && from_tty)
1415 {
1416 char *exec_file = get_exec_file (0);
1417 if (exec_file == 0)
1418 exec_file = "";
1419 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1420 current_event.dwProcessId);
1421 gdb_flush (gdb_stdout);
1422 }
1423 inferior_ptid = null_ptid;
1424 unpush_target (&child_ops);
1425 }
1426
1427 /* Print status information about what we're accessing. */
1428
1429 static void
1430 child_files_info (struct target_ops *ignore)
1431 {
1432 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1433 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
1434 }
1435
1436 /* ARGSUSED */
1437 static void
1438 child_open (char *arg, int from_tty)
1439 {
1440 error ("Use the \"run\" command to start a Unix child process.");
1441 }
1442
1443 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1444 EXEC_FILE is the file to run.
1445 ALLARGS is a string containing the arguments to the program.
1446 ENV is the environment vector to pass. Errors reported with error(). */
1447
1448 static void
1449 child_create_inferior (char *exec_file, char *allargs, char **env)
1450 {
1451 char *winenv;
1452 char *temp;
1453 int envlen;
1454 int i;
1455 STARTUPINFO si;
1456 PROCESS_INFORMATION pi;
1457 BOOL ret;
1458 DWORD flags;
1459 char *args;
1460 char real_path[MAXPATHLEN];
1461 char *toexec;
1462 char shell[MAX_PATH + 1]; /* Path to shell */
1463 const char *sh;
1464 int tty;
1465 int ostdin, ostdout, ostderr;
1466
1467 if (!exec_file)
1468 error ("No executable specified, use `target exec'.\n");
1469
1470 memset (&si, 0, sizeof (si));
1471 si.cb = sizeof (si);
1472
1473 if (!useshell)
1474 {
1475 flags = DEBUG_ONLY_THIS_PROCESS;
1476 cygwin_conv_to_win32_path (exec_file, real_path);
1477 toexec = real_path;
1478 }
1479 else
1480 {
1481 char *newallargs;
1482 sh = getenv ("SHELL");
1483 if (!sh)
1484 sh = "/bin/sh";
1485 cygwin_conv_to_win32_path (sh, shell);
1486 newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
1487 + strlen (allargs) + 2);
1488 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1489 allargs = newallargs;
1490 toexec = shell;
1491 flags = DEBUG_PROCESS;
1492 }
1493
1494 if (new_group)
1495 flags |= CREATE_NEW_PROCESS_GROUP;
1496
1497 if (new_console)
1498 flags |= CREATE_NEW_CONSOLE;
1499
1500 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1501 strcpy (args, toexec);
1502 strcat (args, " ");
1503 strcat (args, allargs);
1504
1505 /* Prepare the environment vars for CreateProcess. */
1506 {
1507 /* This code used to assume all env vars were file names and would
1508 translate them all to win32 style. That obviously doesn't work in the
1509 general case. The current rule is that we only translate PATH.
1510 We need to handle PATH because we're about to call CreateProcess and
1511 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1512 in both posix and win32 environments. cygwin.dll will change it back
1513 to posix style if necessary. */
1514
1515 static const char *conv_path_names[] =
1516 {
1517 "PATH=",
1518 0
1519 };
1520
1521 /* CreateProcess takes the environment list as a null terminated set of
1522 strings (i.e. two nulls terminate the list). */
1523
1524 /* Get total size for env strings. */
1525 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1526 {
1527 int j, len;
1528
1529 for (j = 0; conv_path_names[j]; j++)
1530 {
1531 len = strlen (conv_path_names[j]);
1532 if (strncmp (conv_path_names[j], env[i], len) == 0)
1533 {
1534 if (cygwin_posix_path_list_p (env[i] + len))
1535 envlen += len
1536 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1537 else
1538 envlen += strlen (env[i]) + 1;
1539 break;
1540 }
1541 }
1542 if (conv_path_names[j] == NULL)
1543 envlen += strlen (env[i]) + 1;
1544 }
1545
1546 winenv = alloca (envlen + 1);
1547
1548 /* Copy env strings into new buffer. */
1549 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1550 {
1551 int j, len;
1552
1553 for (j = 0; conv_path_names[j]; j++)
1554 {
1555 len = strlen (conv_path_names[j]);
1556 if (strncmp (conv_path_names[j], env[i], len) == 0)
1557 {
1558 if (cygwin_posix_path_list_p (env[i] + len))
1559 {
1560 memcpy (temp, env[i], len);
1561 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1562 }
1563 else
1564 strcpy (temp, env[i]);
1565 break;
1566 }
1567 }
1568 if (conv_path_names[j] == NULL)
1569 strcpy (temp, env[i]);
1570
1571 temp += strlen (temp) + 1;
1572 }
1573
1574 /* Final nil string to terminate new env. */
1575 *temp = 0;
1576 }
1577
1578 if (!inferior_io_terminal)
1579 tty = ostdin = ostdout = ostderr = -1;
1580 else
1581 {
1582 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
1583 if (tty < 0)
1584 {
1585 print_sys_errmsg (inferior_io_terminal, errno);
1586 ostdin = ostdout = ostderr = -1;
1587 }
1588 else
1589 {
1590 ostdin = dup (0);
1591 ostdout = dup (1);
1592 ostderr = dup (2);
1593 dup2 (tty, 0);
1594 dup2 (tty, 1);
1595 dup2 (tty, 2);
1596 }
1597 }
1598
1599 ret = CreateProcess (0,
1600 args, /* command line */
1601 NULL, /* Security */
1602 NULL, /* thread */
1603 TRUE, /* inherit handles */
1604 flags, /* start flags */
1605 winenv,
1606 NULL, /* current directory */
1607 &si,
1608 &pi);
1609 if (tty >= 0)
1610 {
1611 close (tty);
1612 dup2 (ostdin, 0);
1613 dup2 (ostdout, 1);
1614 dup2 (ostderr, 2);
1615 close (ostdin);
1616 close (ostdout);
1617 close (ostderr);
1618 }
1619
1620 if (!ret)
1621 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1622
1623 CloseHandle (pi.hThread);
1624 CloseHandle (pi.hProcess);
1625
1626 if (useshell && shell[0] != '\0')
1627 saw_create = -1;
1628 else
1629 saw_create = 0;
1630
1631 do_initial_child_stuff (pi.dwProcessId);
1632
1633 /* child_continue (DBG_CONTINUE, -1); */
1634 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1635 }
1636
1637 static void
1638 child_mourn_inferior (void)
1639 {
1640 (void) child_continue (DBG_CONTINUE, -1);
1641 i386_cleanup_dregs();
1642 unpush_target (&child_ops);
1643 generic_mourn_inferior ();
1644 }
1645
1646 /* Send a SIGINT to the process group. This acts just like the user typed a
1647 ^C on the controlling terminal. */
1648
1649 static void
1650 child_stop (void)
1651 {
1652 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1653 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1654 registers_changed (); /* refresh register state */
1655 }
1656
1657 int
1658 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1659 int write, struct mem_attrib *mem,
1660 struct target_ops *target)
1661 {
1662 DWORD done;
1663 if (write)
1664 {
1665 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1666 len, (DWORD) memaddr));
1667 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1668 len, &done);
1669 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1670 }
1671 else
1672 {
1673 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1674 len, (DWORD) memaddr));
1675 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1676 &done);
1677 }
1678 return done;
1679 }
1680
1681 void
1682 child_kill_inferior (void)
1683 {
1684 CHECK (TerminateProcess (current_process_handle, 0));
1685
1686 for (;;)
1687 {
1688 if (!child_continue (DBG_CONTINUE, -1))
1689 break;
1690 if (!WaitForDebugEvent (&current_event, INFINITE))
1691 break;
1692 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1693 break;
1694 }
1695
1696 CHECK (CloseHandle (current_process_handle));
1697
1698 /* this may fail in an attached process so don't check. */
1699 (void) CloseHandle (current_thread->h);
1700 target_mourn_inferior (); /* or just child_mourn_inferior? */
1701 }
1702
1703 void
1704 child_resume (ptid_t ptid, int step, enum target_signal sig)
1705 {
1706 thread_info *th;
1707 DWORD continue_status = DBG_CONTINUE;
1708
1709 int pid = PIDGET (ptid);
1710
1711 if (sig != TARGET_SIGNAL_0)
1712 {
1713 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1714 {
1715 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1716 }
1717 else if (sig == last_sig)
1718 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1719 else
1720 #if 0
1721 /* This code does not seem to work, because
1722 the kernel does probably not consider changes in the ExceptionRecord
1723 structure when passing the exception to the inferior.
1724 Note that this seems possible in the exception handler itself. */
1725 {
1726 int i;
1727 for (i = 0; xlate[i].them != -1; i++)
1728 if (xlate[i].us == sig)
1729 {
1730 current_event.u.Exception.ExceptionRecord.ExceptionCode =
1731 xlate[i].them;
1732 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1733 break;
1734 }
1735 if (continue_status == DBG_CONTINUE)
1736 {
1737 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1738 }
1739 }
1740 #endif
1741 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1742 last_sig));
1743 }
1744
1745 last_sig = TARGET_SIGNAL_0;
1746
1747 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1748 pid, step, sig));
1749
1750 /* Get context for currently selected thread */
1751 th = thread_rec (current_event.dwThreadId, FALSE);
1752 if (th)
1753 {
1754 if (step)
1755 {
1756 /* Single step by setting t bit */
1757 child_fetch_inferior_registers (PS_REGNUM);
1758 th->context.EFlags |= FLAG_TRACE_BIT;
1759 }
1760
1761 if (th->context.ContextFlags)
1762 {
1763 if (debug_registers_changed)
1764 {
1765 th->context.Dr0 = dr[0];
1766 th->context.Dr1 = dr[1];
1767 th->context.Dr2 = dr[2];
1768 th->context.Dr3 = dr[3];
1769 /* th->context.Dr6 = dr[6];
1770 FIXME: should we set dr6 also ?? */
1771 th->context.Dr7 = dr[7];
1772 }
1773 CHECK (SetThreadContext (th->h, &th->context));
1774 th->context.ContextFlags = 0;
1775 }
1776 }
1777
1778 /* Allow continuing with the same signal that interrupted us.
1779 Otherwise complain. */
1780
1781 child_continue (continue_status, pid);
1782 }
1783
1784 static void
1785 child_prepare_to_store (void)
1786 {
1787 /* Do nothing, since we can store individual regs */
1788 }
1789
1790 static int
1791 child_can_run (void)
1792 {
1793 return 1;
1794 }
1795
1796 static void
1797 child_close (int x)
1798 {
1799 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1800 PIDGET (inferior_ptid)));
1801 }
1802
1803 struct target_ops child_ops;
1804
1805 static void
1806 init_child_ops (void)
1807 {
1808 child_ops.to_shortname = "child";
1809 child_ops.to_longname = "Win32 child process";
1810 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1811 child_ops.to_open = child_open;
1812 child_ops.to_close = child_close;
1813 child_ops.to_attach = child_attach;
1814 child_ops.to_detach = child_detach;
1815 child_ops.to_resume = child_resume;
1816 child_ops.to_wait = child_wait;
1817 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1818 child_ops.to_store_registers = child_store_inferior_registers;
1819 child_ops.to_prepare_to_store = child_prepare_to_store;
1820 child_ops.to_xfer_memory = child_xfer_memory;
1821 child_ops.to_files_info = child_files_info;
1822 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1823 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1824 child_ops.to_terminal_init = terminal_init_inferior;
1825 child_ops.to_terminal_inferior = terminal_inferior;
1826 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1827 child_ops.to_terminal_ours = terminal_ours;
1828 child_ops.to_terminal_save_ours = terminal_save_ours;
1829 child_ops.to_terminal_info = child_terminal_info;
1830 child_ops.to_kill = child_kill_inferior;
1831 child_ops.to_load = 0;
1832 child_ops.to_lookup_symbol = 0;
1833 child_ops.to_create_inferior = child_create_inferior;
1834 child_ops.to_mourn_inferior = child_mourn_inferior;
1835 child_ops.to_can_run = child_can_run;
1836 child_ops.to_notice_signals = 0;
1837 child_ops.to_thread_alive = win32_child_thread_alive;
1838 child_ops.to_pid_to_str = cygwin_pid_to_str;
1839 child_ops.to_stop = child_stop;
1840 child_ops.to_stratum = process_stratum;
1841 child_ops.DONT_USE = 0;
1842 child_ops.to_has_all_memory = 1;
1843 child_ops.to_has_memory = 1;
1844 child_ops.to_has_stack = 1;
1845 child_ops.to_has_registers = 1;
1846 child_ops.to_has_execution = 1;
1847 child_ops.to_sections = 0;
1848 child_ops.to_sections_end = 0;
1849 child_ops.to_magic = OPS_MAGIC;
1850 }
1851
1852 void
1853 _initialize_win32_nat (void)
1854 {
1855 struct cmd_list_element *c;
1856
1857 init_child_ops ();
1858
1859 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1860 "Load dll library symbols from FILE.");
1861 set_cmd_completer (c, filename_completer);
1862
1863 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1864
1865 add_show_from_set (add_set_cmd ("shell", class_support, var_boolean,
1866 (char *) &useshell,
1867 "Set use of shell to start subprocess.",
1868 &setlist),
1869 &showlist);
1870
1871 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1872 (char *) &new_console,
1873 "Set creation of new console when creating child process.",
1874 &setlist),
1875 &showlist);
1876
1877 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1878 (char *) &new_group,
1879 "Set creation of new group when creating child process.",
1880 &setlist),
1881 &showlist);
1882
1883 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1884 (char *) &debug_exec,
1885 "Set whether to display execution in child process.",
1886 &setlist),
1887 &showlist);
1888
1889 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1890 (char *) &debug_events,
1891 "Set whether to display kernel events in child process.",
1892 &setlist),
1893 &showlist);
1894
1895 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1896 (char *) &debug_memory,
1897 "Set whether to display memory accesses in child process.",
1898 &setlist),
1899 &showlist);
1900
1901 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1902 (char *) &debug_exceptions,
1903 "Set whether to display kernel exceptions in child process.",
1904 &setlist),
1905 &showlist);
1906
1907 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1908 add_info_alias ("sharedlibrary", "dll", 1);
1909
1910 add_prefix_cmd ("w32", class_info, info_w32_command,
1911 "Print information specific to Win32 debugging.",
1912 &info_w32_cmdlist, "info w32 ", 0, &infolist);
1913
1914 add_cmd ("selector", class_info, display_selectors,
1915 "Display selectors infos.",
1916 &info_w32_cmdlist);
1917
1918 add_target (&child_ops);
1919 }
1920
1921 /* Hardware watchpoint support, adapted from go32-nat.c code. */
1922
1923 /* Pass the address ADDR to the inferior in the I'th debug register.
1924 Here we just store the address in dr array, the registers will be
1925 actually set up when child_continue is called. */
1926 void
1927 cygwin_set_dr (int i, CORE_ADDR addr)
1928 {
1929 if (i < 0 || i > 3)
1930 internal_error (__FILE__, __LINE__,
1931 "Invalid register %d in cygwin_set_dr.\n", i);
1932 dr[i] = (unsigned) addr;
1933 debug_registers_changed = 1;
1934 debug_registers_used = 1;
1935 }
1936
1937 /* Pass the value VAL to the inferior in the DR7 debug control
1938 register. Here we just store the address in D_REGS, the watchpoint
1939 will be actually set up in child_wait. */
1940 void
1941 cygwin_set_dr7 (unsigned val)
1942 {
1943 dr[7] = val;
1944 debug_registers_changed = 1;
1945 debug_registers_used = 1;
1946 }
1947
1948 /* Get the value of the DR6 debug status register from the inferior.
1949 Here we just return the value stored in dr[6]
1950 by the last call to thread_rec for current_event.dwThreadId id. */
1951 unsigned
1952 cygwin_get_dr6 (void)
1953 {
1954 return dr[6];
1955 }
1956
1957
1958 /* Determine if the thread referenced by "pid" is alive
1959 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1960 it means that the pid has died. Otherwise it is assumed to be alive. */
1961 static int
1962 win32_child_thread_alive (ptid_t ptid)
1963 {
1964 int pid = PIDGET (ptid);
1965
1966 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1967 FALSE : TRUE;
1968 }
1969
1970 /* Convert pid to printable format. */
1971 char *
1972 cygwin_pid_to_str (ptid_t ptid)
1973 {
1974 static char buf[80];
1975 int pid = PIDGET (ptid);
1976
1977 if ((DWORD) pid == current_event.dwProcessId)
1978 sprintf (buf, "process %d", pid);
1979 else
1980 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1981 return buf;
1982 }
1983
1984 static int
1985 core_dll_symbols_add (char *dll_name, DWORD base_addr)
1986 {
1987 struct objfile *objfile;
1988 char *objfile_basename;
1989 const char *dll_basename;
1990
1991 if (!(dll_basename = strrchr (dll_name, '/')))
1992 dll_basename = dll_name;
1993 else
1994 dll_basename++;
1995
1996 ALL_OBJFILES (objfile)
1997 {
1998 objfile_basename = strrchr (objfile->name, '/');
1999
2000 if (objfile_basename &&
2001 strcmp (dll_basename, objfile_basename + 1) == 0)
2002 {
2003 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2004 base_addr, dll_name);
2005 goto out;
2006 }
2007 }
2008
2009 register_loaded_dll (dll_name, base_addr + 0x1000);
2010 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
2011
2012 out:
2013 return 1;
2014 }
2015
2016 typedef struct
2017 {
2018 struct target_ops *target;
2019 bfd_vma addr;
2020 }
2021 map_code_section_args;
2022
2023 static void
2024 map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
2025 {
2026 int old;
2027 int update_coreops;
2028 struct section_table *new_target_sect_ptr;
2029
2030 map_code_section_args *args = (map_code_section_args *) obj;
2031 struct target_ops *target = args->target;
2032 if (sect->flags & SEC_CODE)
2033 {
2034 update_coreops = core_ops.to_sections == target->to_sections;
2035
2036 if (target->to_sections)
2037 {
2038 old = target->to_sections_end - target->to_sections;
2039 target->to_sections = (struct section_table *)
2040 xrealloc ((char *) target->to_sections,
2041 (sizeof (struct section_table)) * (1 + old));
2042 }
2043 else
2044 {
2045 old = 0;
2046 target->to_sections = (struct section_table *)
2047 xmalloc ((sizeof (struct section_table)));
2048 }
2049 target->to_sections_end = target->to_sections + (1 + old);
2050
2051 /* Update the to_sections field in the core_ops structure
2052 if needed. */
2053 if (update_coreops)
2054 {
2055 core_ops.to_sections = target->to_sections;
2056 core_ops.to_sections_end = target->to_sections_end;
2057 }
2058 new_target_sect_ptr = target->to_sections + old;
2059 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
2060 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
2061 bfd_section_size (abfd, sect);;
2062 new_target_sect_ptr->the_bfd_section = sect;
2063 new_target_sect_ptr->bfd = abfd;
2064 }
2065 }
2066
2067 static int
2068 dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
2069 {
2070 bfd *dll_bfd;
2071 map_code_section_args map_args;
2072 asection *lowest_sect;
2073 char *name;
2074 if (dll_name == NULL || target == NULL)
2075 return 0;
2076 name = xstrdup (dll_name);
2077 dll_bfd = bfd_openr (name, "pei-i386");
2078 if (dll_bfd == NULL)
2079 return 0;
2080
2081 if (bfd_check_format (dll_bfd, bfd_object))
2082 {
2083 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
2084 if (lowest_sect == NULL)
2085 return 0;
2086 map_args.target = target;
2087 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
2088
2089 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
2090 }
2091
2092 return 1;
2093 }
2094
2095 static void
2096 core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
2097 {
2098 struct target_ops *target = (struct target_ops *) obj;
2099
2100 DWORD base_addr;
2101
2102 int dll_name_size;
2103 char *dll_name = NULL;
2104 char *buf = NULL;
2105 struct win32_pstatus *pstatus;
2106 char *p;
2107
2108 if (strncmp (sect->name, ".module", 7))
2109 return;
2110
2111 buf = (char *) xmalloc (sect->_raw_size + 1);
2112 if (!buf)
2113 {
2114 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2115 goto out;
2116 }
2117 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
2118 goto out;
2119
2120 pstatus = (struct win32_pstatus *) buf;
2121
2122 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
2123 dll_name_size = pstatus->data.module_info.module_name_size;
2124 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
2125 goto out;
2126
2127 dll_name = (char *) xmalloc (dll_name_size + 1);
2128 if (!dll_name)
2129 {
2130 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2131 goto out;
2132 }
2133 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
2134
2135 while ((p = strchr (dll_name, '\\')))
2136 *p = '/';
2137
2138 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
2139 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
2140
2141 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
2142 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
2143
2144 out:
2145 if (buf)
2146 xfree (buf);
2147 if (dll_name)
2148 xfree (dll_name);
2149 return;
2150 }
2151
2152 void
2153 child_solib_add (char *filename, int from_tty, struct target_ops *target,
2154 int readsyms)
2155 {
2156 if (!readsyms)
2157 return;
2158 if (core_bfd)
2159 {
2160 child_clear_solibs ();
2161 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
2162 }
2163 else
2164 {
2165 if (solib_end && solib_end->name)
2166 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
2167 solib_end->load_addr);
2168 }
2169 }
2170
2171 static void
2172 fetch_elf_core_registers (char *core_reg_sect,
2173 unsigned core_reg_size,
2174 int which,
2175 CORE_ADDR reg_addr)
2176 {
2177 int r;
2178 if (core_reg_size < sizeof (CONTEXT))
2179 {
2180 error ("Core file register section too small (%u bytes).", core_reg_size);
2181 return;
2182 }
2183 for (r = 0; r < NUM_REGS; r++)
2184 supply_register (r, core_reg_sect + mappings[r]);
2185 }
2186
2187 static struct core_fns win32_elf_core_fns =
2188 {
2189 bfd_target_elf_flavour,
2190 default_check_format,
2191 default_core_sniffer,
2192 fetch_elf_core_registers,
2193 NULL
2194 };
2195
2196 void
2197 _initialize_core_win32 (void)
2198 {
2199 add_core_fns (&win32_elf_core_fns);
2200 }
2201
2202 void
2203 _initialize_check_for_gdb_ini (void)
2204 {
2205 char *homedir;
2206 if (inhibit_gdbinit)
2207 return;
2208
2209 homedir = getenv ("HOME");
2210 if (homedir)
2211 {
2212 char *p;
2213 char *oldini = (char *) alloca (strlen (homedir) +
2214 sizeof ("/gdb.ini"));
2215 strcpy (oldini, homedir);
2216 p = strchr (oldini, '\0');
2217 if (p > oldini && p[-1] != '/')
2218 *p++ = '/';
2219 strcpy (p, "gdb.ini");
2220 if (access (oldini, 0) == 0)
2221 {
2222 int len = strlen (oldini);
2223 char *newini = alloca (len + 1);
2224 sprintf (newini, "%.*s.gdbinit",
2225 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2226 warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
2227 }
2228 }
2229 }
This page took 0.072523 seconds and 5 git commands to generate.