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