]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/windows-nat.c
2002-02-04 Pierre Muller <muller@ics.u-strasbg.fr>
[thirdparty/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;
8a892701 868 last_sig = SIGINT; /* FIXME - should check pass state */
1ef980b9
SC
869 break;
870 case EXCEPTION_SINGLE_STEP:
29fe111d 871 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
8e860359 872 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1ef980b9
SC
873 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
874 break;
8227c82d 875 case EXCEPTION_ILLEGAL_INSTRUCTION:
29fe111d 876 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
8e860359 877 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
8227c82d 878 ourstatus->value.sig = TARGET_SIGNAL_ILL;
8a892701 879 last_sig = SIGILL;
8227c82d 880 break;
1ef980b9 881 default:
02e423b9
CF
882 if (current_event.u.Exception.dwFirstChance)
883 return 0;
29fe111d 884 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
3a4b77d8 885 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 886 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
24e60978 887 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1ef980b9 888 break;
24e60978 889 }
24e60978 890 exception_count++;
36339ecd 891 return 1;
24e60978
SC
892}
893
3cee93ac
CF
894/* Resume all artificially suspended threads if we are continuing
895 execution */
896static BOOL
8a892701 897child_continue (DWORD continue_status, int id)
3cee93ac
CF
898{
899 int i;
900 thread_info *th;
901 BOOL res;
902
29fe111d 903 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
3cee93ac 904 current_event.dwProcessId, current_event.dwThreadId));
0714f9bf
SS
905 res = ContinueDebugEvent (current_event.dwProcessId,
906 current_event.dwThreadId,
907 continue_status);
1e37c281 908 continue_status = 0;
0714f9bf 909 if (res)
3a4b77d8 910 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 911 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
3cee93ac 912 {
fa4ba8da 913
3cee93ac
CF
914 for (i = 0; i < th->suspend_count; i++)
915 (void) ResumeThread (th->h);
916 th->suspend_count = 0;
fa4ba8da
PM
917 if (debug_registers_changed)
918 {
919 /* Only change the value of the debug reisters */
920 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
921 th->context.Dr0 = dr[0];
922 th->context.Dr1 = dr[1];
923 th->context.Dr2 = dr[2];
924 th->context.Dr3 = dr[3];
925 /* th->context.Dr6 = dr[6];
926 FIXME: should we set dr6 also ?? */
927 th->context.Dr7 = dr[7];
928 CHECK (SetThreadContext (th->h, &th->context));
929 th->context.ContextFlags = 0;
930 }
3cee93ac
CF
931 }
932
fa4ba8da 933 debug_registers_changed = 0;
3cee93ac
CF
934 return res;
935}
936
8a892701
CF
937/* Get the next event from the child. Return 1 if the event requires
938 handling by WFI (or whatever).
939 */
1e37c281 940static int
0a65a603 941get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
1e37c281
JM
942{
943 BOOL debug_event;
8a892701
CF
944 DWORD continue_status, event_code;
945 thread_info *th = NULL;
946 static thread_info dummy_thread_info;
450005e7 947 int retval = 0;
1e37c281 948
9d3789f7
CF
949 last_sig = 0;
950
8a892701 951 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 952 goto out;
1e37c281
JM
953
954 event_count++;
955 continue_status = DBG_CONTINUE;
1e37c281 956
8a892701 957 event_code = current_event.dwDebugEventCode;
450005e7 958 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
8a892701
CF
959
960 switch (event_code)
1e37c281
JM
961 {
962 case CREATE_THREAD_DEBUG_EVENT:
963 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
964 (unsigned) current_event.dwProcessId,
965 (unsigned) current_event.dwThreadId,
966 "CREATE_THREAD_DEBUG_EVENT"));
1e37c281 967 /* Record the existence of this thread */
8a892701
CF
968 th = child_add_thread (current_event.dwThreadId,
969 current_event.u.CreateThread.hThread);
1e37c281
JM
970 if (info_verbose)
971 printf_unfiltered ("[New %s]\n",
39f77062
KB
972 target_pid_to_str (
973 pid_to_ptid (current_event.dwThreadId)));
450005e7 974 retval = current_event.dwThreadId;
1e37c281
JM
975 break;
976
977 case EXIT_THREAD_DEBUG_EVENT:
978 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
979 (unsigned) current_event.dwProcessId,
980 (unsigned) current_event.dwThreadId,
981 "EXIT_THREAD_DEBUG_EVENT"));
1e37c281 982 child_delete_thread (current_event.dwThreadId);
8a892701 983 th = &dummy_thread_info;
1e37c281
JM
984 break;
985
986 case CREATE_PROCESS_DEBUG_EVENT:
987 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
988 (unsigned) current_event.dwProcessId,
989 (unsigned) current_event.dwThreadId,
990 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 991 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1e37c281
JM
992 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
993
9d3789f7 994 main_thread_id = current_event.dwThreadId;
1e37c281 995 /* Add the main thread */
9d3789f7 996#if 0
450005e7
CF
997 th = child_add_thread (current_event.dwProcessId,
998 current_event.u.CreateProcessInfo.hProcess);
9d3789f7
CF
999#endif
1000 th = child_add_thread (main_thread_id,
8a892701 1001 current_event.u.CreateProcessInfo.hThread);
9d3789f7 1002 retval = ourstatus->value.related_pid = current_event.dwThreadId;
1e37c281
JM
1003 break;
1004
1005 case EXIT_PROCESS_DEBUG_EVENT:
1006 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1007 (unsigned) current_event.dwProcessId,
1008 (unsigned) current_event.dwThreadId,
1009 "EXIT_PROCESS_DEBUG_EVENT"));
1e37c281
JM
1010 ourstatus->kind = TARGET_WAITKIND_EXITED;
1011 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1012 CloseHandle (current_process_handle);
9d3789f7 1013 retval = main_thread_id;
8a892701 1014 break;
1e37c281
JM
1015
1016 case LOAD_DLL_DEBUG_EVENT:
1017 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1018 (unsigned) current_event.dwProcessId,
1019 (unsigned) current_event.dwThreadId,
1020 "LOAD_DLL_DEBUG_EVENT"));
700b351b 1021 CloseHandle (current_event.u.LoadDll.hFile);
8a892701 1022 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1e37c281 1023 registers_changed (); /* mark all regs invalid */
450005e7
CF
1024 ourstatus->kind = TARGET_WAITKIND_LOADED;
1025 ourstatus->value.integer = 0;
9d3789f7 1026 retval = main_thread_id;
1e37c281
JM
1027 break;
1028
1029 case UNLOAD_DLL_DEBUG_EVENT:
1030 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1031 (unsigned) current_event.dwProcessId,
1032 (unsigned) current_event.dwThreadId,
1033 "UNLOAD_DLL_DEBUG_EVENT"));
d3ff4a77
CF
1034 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1035 registers_changed (); /* mark all regs invalid */
1036 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
3bccec63 1037 does not exist yet. */
d3ff4a77 1038 break;
1e37c281
JM
1039
1040 case EXCEPTION_DEBUG_EVENT:
1041 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1042 (unsigned) current_event.dwProcessId,
1043 (unsigned) current_event.dwThreadId,
1044 "EXCEPTION_DEBUG_EVENT"));
02e423b9
CF
1045 if (handle_exception (ourstatus))
1046 retval = current_event.dwThreadId;
1e37c281
JM
1047 break;
1048
8a892701 1049 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1e37c281 1050 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1051 (unsigned) current_event.dwProcessId,
1052 (unsigned) current_event.dwThreadId,
1053 "OUTPUT_DEBUG_STRING_EVENT"));
8e860359 1054 if (handle_output_debug_string (ourstatus))
9d3789f7 1055 retval = main_thread_id;
1e37c281 1056 break;
9d3789f7 1057
1e37c281 1058 default:
29fe111d
CF
1059 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1060 (DWORD) current_event.dwProcessId,
1061 (DWORD) current_event.dwThreadId);
1062 printf_unfiltered (" unknown event code %ld\n",
1e37c281
JM
1063 current_event.dwDebugEventCode);
1064 break;
1065 }
1066
450005e7 1067 if (!retval)
8a892701 1068 CHECK (child_continue (continue_status, -1));
450005e7 1069 else
9d3789f7 1070 {
8e860359 1071 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
39f77062 1072 inferior_ptid = pid_to_ptid (retval);
9d3789f7 1073 }
1e37c281
JM
1074
1075out:
450005e7 1076 return retval;
1e37c281
JM
1077}
1078
1e37c281 1079/* Wait for interesting events to occur in the target process. */
39f77062
KB
1080static ptid_t
1081child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
24e60978 1082{
39f77062
KB
1083 int pid = PIDGET (ptid);
1084
24e60978
SC
1085 /* We loop when we get a non-standard exception rather than return
1086 with a SPURIOUS because resume can try and step or modify things,
3cee93ac 1087 which needs a current_thread->h. But some of these exceptions mark
24e60978
SC
1088 the birth or death of threads, which mean that the current thread
1089 isn't necessarily what you think it is. */
1090
1091 while (1)
450005e7
CF
1092 {
1093 int retval = get_child_debug_event (pid, ourstatus);
1094 if (retval)
39f77062 1095 return pid_to_ptid (retval);
450005e7
CF
1096 else
1097 {
1098 int detach = 0;
3cee93ac 1099
450005e7
CF
1100 if (ui_loop_hook != NULL)
1101 detach = ui_loop_hook (0);
0714f9bf 1102
450005e7
CF
1103 if (detach)
1104 child_kill_inferior ();
1105 }
1106 }
24e60978
SC
1107}
1108
9d3789f7
CF
1109static void
1110do_initial_child_stuff (DWORD pid)
1111{
1112 extern int stop_after_trap;
fa4ba8da 1113 int i;
9d3789f7
CF
1114
1115 last_sig = 0;
1116 event_count = 0;
1117 exception_count = 0;
fa4ba8da
PM
1118 debug_registers_changed = 0;
1119 debug_registers_used = 0;
1120 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1121 dr[i] = 0;
9d3789f7
CF
1122 current_event.dwProcessId = pid;
1123 memset (&current_event, 0, sizeof (current_event));
1124 push_target (&child_ops);
1125 child_init_thread_list ();
1126 child_clear_solibs ();
1127 clear_proceed_status ();
1128 init_wait_for_inferior ();
1129
1130 target_terminal_init ();
1131 target_terminal_inferior ();
1132
1133 while (1)
1134 {
1135 stop_after_trap = 1;
1136 wait_for_inferior ();
1137 if (stop_signal != TARGET_SIGNAL_TRAP)
1138 resume (0, stop_signal);
1139 else
1140 break;
1141 }
1142 stop_after_trap = 0;
1143 return;
1144}
1145
02cc9f49
CV
1146/* Since Windows XP, detaching from a process is supported by Windows.
1147 The following code tries loading the appropriate functions dynamically.
1148 If loading these functions succeeds use them to actually detach from
1149 the inferior process, otherwise behave as usual, pretending that
1150 detach has worked. */
1151static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1152static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1153
1154static int
1155has_detach_ability ()
1156{
1157 static HMODULE kernel32 = NULL;
1158
1159 if (!kernel32)
1160 kernel32 = LoadLibrary ("kernel32.dll");
1161 if (kernel32)
1162 {
1163 if (!DebugSetProcessKillOnExit)
1164 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1165 "DebugSetProcessKillOnExit");
1166 if (!DebugActiveProcessStop)
1167 DebugActiveProcessStop = GetProcAddress (kernel32,
1168 "DebugActiveProcessStop");
1169 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1170 return 1;
1171 }
1172 return 0;
1173}
24e60978 1174
02cc9f49 1175/* Attach to process PID, then initialize for debugging it. */
24e60978 1176static void
fba45db2 1177child_attach (char *args, int from_tty)
24e60978
SC
1178{
1179 BOOL ok;
559e75c0 1180 DWORD pid;
24e60978
SC
1181
1182 if (!args)
1183 error_no_arg ("process-id to attach");
1184
559e75c0 1185 pid = strtoul (args, 0, 0);
9d3789f7 1186 ok = DebugActiveProcess (pid);
24e60978
SC
1187
1188 if (!ok)
1189 error ("Can't attach to process.");
1190
02cc9f49
CV
1191 if (has_detach_ability ())
1192 {
1193 attach_flag = 1;
1194 DebugSetProcessKillOnExit (FALSE);
1195 }
1196
24e60978
SC
1197 if (from_tty)
1198 {
1199 char *exec_file = (char *) get_exec_file (0);
1200
1201 if (exec_file)
1202 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1203 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1204 else
1205 printf_unfiltered ("Attaching to %s\n",
39f77062 1206 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1207
1208 gdb_flush (gdb_stdout);
1209 }
1210
9d3789f7
CF
1211 do_initial_child_stuff (pid);
1212 target_terminal_ours ();
24e60978
SC
1213}
1214
24e60978 1215static void
0a65a603 1216child_detach (char *args, int from_tty)
24e60978 1217{
02cc9f49
CV
1218 int detached = 1;
1219
1220 if (has_detach_ability ())
1221 {
1222 delete_command (NULL, 0);
1223 child_continue (DBG_CONTINUE, -1);
1224 if (!DebugActiveProcessStop (current_event.dwProcessId))
3bccec63 1225 {
02cc9f49
CV
1226 error ("Can't detach process %lu (error %lu)",
1227 current_event.dwProcessId, GetLastError ());
1228 detached = 0;
3bccec63 1229 }
02cc9f49
CV
1230 DebugSetProcessKillOnExit (FALSE);
1231 }
1232 if (detached && from_tty)
24e60978
SC
1233 {
1234 char *exec_file = get_exec_file (0);
1235 if (exec_file == 0)
1236 exec_file = "";
02cc9f49
CV
1237 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1238 current_event.dwProcessId);
24e60978
SC
1239 gdb_flush (gdb_stdout);
1240 }
39f77062 1241 inferior_ptid = null_ptid;
24e60978
SC
1242 unpush_target (&child_ops);
1243}
1244
24e60978
SC
1245/* Print status information about what we're accessing. */
1246
1247static void
0a65a603 1248child_files_info (struct target_ops *ignore)
24e60978
SC
1249{
1250 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1251 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
24e60978
SC
1252}
1253
1254/* ARGSUSED */
1255static void
0a65a603 1256child_open (char *arg, int from_tty)
24e60978
SC
1257{
1258 error ("Use the \"run\" command to start a Unix child process.");
1259}
1260
39f77062 1261/* Start an inferior win32 child process and sets inferior_ptid to its pid.
24e60978
SC
1262 EXEC_FILE is the file to run.
1263 ALLARGS is a string containing the arguments to the program.
1264 ENV is the environment vector to pass. Errors reported with error(). */
1265
24e60978 1266static void
fba45db2 1267child_create_inferior (char *exec_file, char *allargs, char **env)
24e60978 1268{
1750a5ef
SC
1269 char real_path[MAXPATHLEN];
1270 char *winenv;
1271 char *temp;
3a4b77d8 1272 int envlen;
1750a5ef 1273 int i;
24e60978
SC
1274 STARTUPINFO si;
1275 PROCESS_INFORMATION pi;
24e60978
SC
1276 BOOL ret;
1277 DWORD flags;
eb708f2e 1278 char *args;
24e60978
SC
1279
1280 if (!exec_file)
450005e7 1281 error ("No executable specified, use `target exec'.\n");
24e60978
SC
1282
1283 memset (&si, 0, sizeof (si));
1284 si.cb = sizeof (si);
1285
29fe111d 1286 cygwin_conv_to_win32_path (exec_file, real_path);
24e60978 1287
3cee93ac 1288 flags = DEBUG_ONLY_THIS_PROCESS;
24e60978
SC
1289
1290 if (new_group)
1291 flags |= CREATE_NEW_PROCESS_GROUP;
1292
1293 if (new_console)
1294 flags |= CREATE_NEW_CONSOLE;
1295
3d78f532
SC
1296 args = alloca (strlen (real_path) + strlen (allargs) + 2);
1297
1298 strcpy (args, real_path);
eb708f2e 1299
eb708f2e
SC
1300 strcat (args, " ");
1301 strcat (args, allargs);
1302
e88c49c3
DE
1303 /* Prepare the environment vars for CreateProcess. */
1304 {
1305 /* This code use to assume all env vars were file names and would
1306 translate them all to win32 style. That obviously doesn't work in the
2dcfc9c7
DE
1307 general case. The current rule is that we only translate PATH.
1308 We need to handle PATH because we're about to call CreateProcess and
1309 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1310 in both posix and win32 environments. cygwin.dll will change it back
1311 to posix style if necessary. */
e88c49c3
DE
1312
1313 static const char *conv_path_names[] =
3a4b77d8
JM
1314 {
1315 "PATH=",
1316 0
1317 };
e88c49c3
DE
1318
1319 /* CreateProcess takes the environment list as a null terminated set of
1320 strings (i.e. two nulls terminate the list). */
1321
1322 /* Get total size for env strings. */
1323 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1324 {
2dcfc9c7 1325 int j, len;
e88c49c3 1326
2dcfc9c7
DE
1327 for (j = 0; conv_path_names[j]; j++)
1328 {
1329 len = strlen (conv_path_names[j]);
1330 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1331 {
29fe111d 1332 if (cygwin_posix_path_list_p (env[i] + len))
2dcfc9c7 1333 envlen += len
29fe111d 1334 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
2dcfc9c7
DE
1335 else
1336 envlen += strlen (env[i]) + 1;
1337 break;
e88c49c3 1338 }
e88c49c3 1339 }
2dcfc9c7 1340 if (conv_path_names[j] == NULL)
e88c49c3
DE
1341 envlen += strlen (env[i]) + 1;
1342 }
1343
1344 winenv = alloca (envlen + 1);
1345
1346 /* Copy env strings into new buffer. */
3cee93ac 1347 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
e88c49c3 1348 {
2dcfc9c7 1349 int j, len;
e88c49c3 1350
2dcfc9c7
DE
1351 for (j = 0; conv_path_names[j]; j++)
1352 {
1353 len = strlen (conv_path_names[j]);
1354 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1355 {
29fe111d 1356 if (cygwin_posix_path_list_p (env[i] + len))
e88c49c3
DE
1357 {
1358 memcpy (temp, env[i], len);
29fe111d 1359 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
e88c49c3 1360 }
2dcfc9c7
DE
1361 else
1362 strcpy (temp, env[i]);
1363 break;
e88c49c3 1364 }
e88c49c3 1365 }
2dcfc9c7 1366 if (conv_path_names[j] == NULL)
e88c49c3 1367 strcpy (temp, env[i]);
2dcfc9c7 1368
e88c49c3
DE
1369 temp += strlen (temp) + 1;
1370 }
1371
1372 /* Final nil string to terminate new env. */
1373 *temp = 0;
1374 }
1750a5ef 1375
1750a5ef 1376 ret = CreateProcess (0,
3a4b77d8 1377 args, /* command line */
24e60978
SC
1378 NULL, /* Security */
1379 NULL, /* thread */
1380 TRUE, /* inherit handles */
1381 flags, /* start flags */
1750a5ef 1382 winenv,
24e60978
SC
1383 NULL, /* current directory */
1384 &si,
1385 &pi);
1386 if (!ret)
3a4b77d8 1387 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
24e60978 1388
700b351b
CF
1389 CloseHandle (pi.hThread);
1390 CloseHandle (pi.hProcess);
9d3789f7 1391 do_initial_child_stuff (pi.dwProcessId);
d3a09475 1392
8e860359 1393 /* child_continue (DBG_CONTINUE, -1); */
1e37c281 1394 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
24e60978
SC
1395}
1396
1397static void
fba45db2 1398child_mourn_inferior (void)
24e60978 1399{
8a892701 1400 (void) child_continue (DBG_CONTINUE, -1);
fa4ba8da 1401 i386_cleanup_dregs();
24e60978
SC
1402 unpush_target (&child_ops);
1403 generic_mourn_inferior ();
1404}
1405
24e60978
SC
1406/* Send a SIGINT to the process group. This acts just like the user typed a
1407 ^C on the controlling terminal. */
1408
b607efe7 1409static void
fba45db2 1410child_stop (void)
24e60978 1411{
1ef980b9 1412 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1e37c281 1413 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
3a4b77d8 1414 registers_changed (); /* refresh register state */
24e60978
SC
1415}
1416
1417int
eb708f2e 1418child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
0a65a603
AC
1419 int write, struct mem_attrib *mem,
1420 struct target_ops *target)
24e60978
SC
1421{
1422 DWORD done;
1423 if (write)
1424 {
29fe111d
CF
1425 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1426 len, (DWORD) memaddr));
3cee93ac
CF
1427 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1428 len, &done);
1429 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
24e60978
SC
1430 }
1431 else
1432 {
29fe111d
CF
1433 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1434 len, (DWORD) memaddr));
3cee93ac
CF
1435 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1436 &done);
24e60978
SC
1437 }
1438 return done;
1439}
1440
1441void
1442child_kill_inferior (void)
1443{
3cee93ac
CF
1444 CHECK (TerminateProcess (current_process_handle, 0));
1445
b5edcb45
ILT
1446 for (;;)
1447 {
8a892701 1448 if (!child_continue (DBG_CONTINUE, -1))
b5edcb45 1449 break;
3cee93ac 1450 if (!WaitForDebugEvent (&current_event, INFINITE))
b5edcb45 1451 break;
3cee93ac 1452 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
b5edcb45
ILT
1453 break;
1454 }
1455
3cee93ac
CF
1456 CHECK (CloseHandle (current_process_handle));
1457
1458 /* this may fail in an attached process so don't check. */
1459 (void) CloseHandle (current_thread->h);
3a4b77d8 1460 target_mourn_inferior (); /* or just child_mourn_inferior? */
24e60978
SC
1461}
1462
1463void
39f77062 1464child_resume (ptid_t ptid, int step, enum target_signal sig)
24e60978 1465{
3cee93ac 1466 thread_info *th;
8a892701 1467 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
8e860359 1468 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
39f77062 1469 int pid = PIDGET (ptid);
8a892701
CF
1470
1471 last_sig = 0;
24e60978 1472
3cee93ac
CF
1473 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1474 pid, step, sig));
1475
1476 /* Get context for currently selected thread */
1477 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 1478 if (th)
24e60978 1479 {
450005e7
CF
1480 if (step)
1481 {
1482 /* Single step by setting t bit */
1483 child_fetch_inferior_registers (PS_REGNUM);
1484 th->context.EFlags |= FLAG_TRACE_BIT;
1485 }
24e60978 1486
450005e7
CF
1487 if (th->context.ContextFlags)
1488 {
fa4ba8da
PM
1489 if (debug_registers_changed)
1490 {
1491 th->context.Dr0 = dr[0];
1492 th->context.Dr1 = dr[1];
1493 th->context.Dr2 = dr[2];
1494 th->context.Dr3 = dr[3];
1495 /* th->context.Dr6 = dr[6];
1496 FIXME: should we set dr6 also ?? */
1497 th->context.Dr7 = dr[7];
1498 }
450005e7
CF
1499 CHECK (SetThreadContext (th->h, &th->context));
1500 th->context.ContextFlags = 0;
1501 }
24e60978
SC
1502 }
1503
3cee93ac
CF
1504 /* Allow continuing with the same signal that interrupted us.
1505 Otherwise complain. */
24e60978 1506
8a892701 1507 child_continue (continue_status, pid);
24e60978
SC
1508}
1509
1510static void
fba45db2 1511child_prepare_to_store (void)
24e60978
SC
1512{
1513 /* Do nothing, since we can store individual regs */
1514}
1515
1516static int
fba45db2 1517child_can_run (void)
24e60978
SC
1518{
1519 return 1;
1520}
1521
1522static void
0a65a603 1523child_close (int x)
24e60978 1524{
39f77062 1525 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
3bccec63 1526 PIDGET (inferior_ptid)));
24e60978 1527}
1ef980b9 1528
3a4b77d8 1529struct target_ops child_ops;
c719b714 1530
3a4b77d8
JM
1531static void
1532init_child_ops (void)
24e60978 1533{
3a4b77d8
JM
1534 child_ops.to_shortname = "child";
1535 child_ops.to_longname = "Win32 child process";
1536 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1537 child_ops.to_open = child_open;
1538 child_ops.to_close = child_close;
1539 child_ops.to_attach = child_attach;
1540 child_ops.to_detach = child_detach;
1541 child_ops.to_resume = child_resume;
1542 child_ops.to_wait = child_wait;
1543 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1544 child_ops.to_store_registers = child_store_inferior_registers;
1545 child_ops.to_prepare_to_store = child_prepare_to_store;
1546 child_ops.to_xfer_memory = child_xfer_memory;
1547 child_ops.to_files_info = child_files_info;
1548 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1549 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1550 child_ops.to_terminal_init = terminal_init_inferior;
1551 child_ops.to_terminal_inferior = terminal_inferior;
1552 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1553 child_ops.to_terminal_ours = terminal_ours;
1554 child_ops.to_terminal_info = child_terminal_info;
1555 child_ops.to_kill = child_kill_inferior;
1556 child_ops.to_load = 0;
1557 child_ops.to_lookup_symbol = 0;
1558 child_ops.to_create_inferior = child_create_inferior;
1559 child_ops.to_mourn_inferior = child_mourn_inferior;
1560 child_ops.to_can_run = child_can_run;
1561 child_ops.to_notice_signals = 0;
1562 child_ops.to_thread_alive = win32_child_thread_alive;
d3a09475 1563 child_ops.to_pid_to_str = cygwin_pid_to_str;
3a4b77d8
JM
1564 child_ops.to_stop = child_stop;
1565 child_ops.to_stratum = process_stratum;
1566 child_ops.DONT_USE = 0;
1567 child_ops.to_has_all_memory = 1;
1568 child_ops.to_has_memory = 1;
1569 child_ops.to_has_stack = 1;
1570 child_ops.to_has_registers = 1;
1571 child_ops.to_has_execution = 1;
1572 child_ops.to_sections = 0;
1573 child_ops.to_sections_end = 0;
1574 child_ops.to_magic = OPS_MAGIC;
c719b714 1575}
24e60978
SC
1576
1577void
fba45db2 1578_initialize_inftarg (void)
24e60978 1579{
fa58ee11
EZ
1580 struct cmd_list_element *c;
1581
3a4b77d8 1582 init_child_ops ();
1ef980b9 1583
fa58ee11
EZ
1584 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1585 "Load dll library symbols from FILE.");
1586 c->completer = filename_completer;
450005e7
CF
1587
1588 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1589
1590 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
8e860359
CF
1591 (char *) &new_console,
1592 "Set creation of new console when creating child process.",
1593 &setlist),
1594 &showlist);
24e60978 1595
450005e7 1596 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
8e860359
CF
1597 (char *) &new_group,
1598 "Set creation of new group when creating child process.",
1599 &setlist),
1600 &showlist);
24e60978 1601
450005e7 1602 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
8e860359
CF
1603 (char *) &debug_exec,
1604 "Set whether to display execution in child process.",
1605 &setlist),
1606 &showlist);
1ef980b9 1607
450005e7 1608 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
8e860359
CF
1609 (char *) &debug_events,
1610 "Set whether to display kernel events in child process.",
1611 &setlist),
1612 &showlist);
1ef980b9 1613
450005e7 1614 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
8e860359
CF
1615 (char *) &debug_memory,
1616 "Set whether to display memory accesses in child process.",
1617 &setlist),
1618 &showlist);
1ef980b9 1619
450005e7 1620 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
8e860359
CF
1621 (char *) &debug_exceptions,
1622 "Set whether to display kernel exceptions in child process.",
1623 &setlist),
1624 &showlist);
1ef980b9 1625
450005e7
CF
1626 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1627 add_info_alias ("sharedlibrary", "dll", 1);
1628
24e60978
SC
1629 add_target (&child_ops);
1630}
3cee93ac 1631
fa4ba8da
PM
1632/* Hardware watchpoint support, adapted from go32-nat.c code. */
1633
1634/* Pass the address ADDR to the inferior in the I'th debug register.
1635 Here we just store the address in dr array, the registers will be
1636 actually set up when child_continue is called. */
1637void
1638cygwin_set_dr (int i, CORE_ADDR addr)
1639{
1640 if (i < 0 || i > 3)
1641 internal_error (__FILE__, __LINE__,
1642 "Invalid register %d in cygwin_set_dr.\n", i);
1643 dr[i] = (unsigned) addr;
1644 debug_registers_changed = 1;
1645 debug_registers_used = 1;
1646}
1647
1648/* Pass the value VAL to the inferior in the DR7 debug control
1649 register. Here we just store the address in D_REGS, the watchpoint
1650 will be actually set up in child_wait. */
1651void
1652cygwin_set_dr7 (unsigned val)
1653{
1654 dr[7] = val;
1655 debug_registers_changed = 1;
1656 debug_registers_used = 1;
1657}
1658
1659/* Get the value of the DR6 debug status register from the inferior.
1660 Here we just return the value stored in dr[6]
1661 by the last call to thread_rec for current_event.dwThreadId id. */
1662unsigned
1663cygwin_get_dr6 (void)
1664{
1665 return dr[6];
1666}
1667
1668
3cee93ac
CF
1669/* Determine if the thread referenced by "pid" is alive
1670 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1671 it means that the pid has died. Otherwise it is assumed to be alive. */
1672static int
39f77062 1673win32_child_thread_alive (ptid_t ptid)
3cee93ac 1674{
39f77062
KB
1675 int pid = PIDGET (ptid);
1676
3a4b77d8
JM
1677 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1678 FALSE : TRUE;
3cee93ac
CF
1679}
1680
1681/* Convert pid to printable format. */
1682char *
39f77062 1683cygwin_pid_to_str (ptid_t ptid)
3cee93ac
CF
1684{
1685 static char buf[80];
39f77062
KB
1686 int pid = PIDGET (ptid);
1687
29fe111d 1688 if ((DWORD) pid == current_event.dwProcessId)
3cee93ac
CF
1689 sprintf (buf, "process %d", pid);
1690 else
29fe111d 1691 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
3cee93ac
CF
1692 return buf;
1693}
8e860359
CF
1694
1695static int
1696core_dll_symbols_add (char *dll_name, DWORD base_addr)
1697{
1698 struct objfile *objfile;
1699 char *objfile_basename;
1700 const char *dll_basename;
1701
1702 if (!(dll_basename = strrchr (dll_name, '/')))
1703 dll_basename = dll_name;
1704 else
1705 dll_basename++;
1706
1707 ALL_OBJFILES (objfile)
1708 {
1709 objfile_basename = strrchr (objfile->name, '/');
1710
1711 if (objfile_basename &&
1712 strcmp (dll_basename, objfile_basename + 1) == 0)
1713 {
1714 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1715 base_addr, dll_name);
1716 goto out;
1717 }
1718 }
1719
1720 register_loaded_dll (dll_name, base_addr + 0x1000);
02e423b9 1721 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
8e860359
CF
1722
1723out:
1724 return 1;
1725}
1726
1727typedef struct
1728{
1729 struct target_ops *target;
1730 bfd_vma addr;
1731}
1732map_code_section_args;
1733
1734static void
554cb486 1735map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1736{
1737 int old;
1738 int update_coreops;
1739 struct section_table *new_target_sect_ptr;
1740
1741 map_code_section_args *args = (map_code_section_args *) obj;
1742 struct target_ops *target = args->target;
1743 if (sect->flags & SEC_CODE)
1744 {
1745 update_coreops = core_ops.to_sections == target->to_sections;
1746
1747 if (target->to_sections)
1748 {
1749 old = target->to_sections_end - target->to_sections;
1750 target->to_sections = (struct section_table *)
1751 xrealloc ((char *) target->to_sections,
1752 (sizeof (struct section_table)) * (1 + old));
1753 }
1754 else
1755 {
1756 old = 0;
1757 target->to_sections = (struct section_table *)
1758 xmalloc ((sizeof (struct section_table)));
1759 }
1760 target->to_sections_end = target->to_sections + (1 + old);
1761
1762 /* Update the to_sections field in the core_ops structure
3bccec63 1763 if needed. */
8e860359
CF
1764 if (update_coreops)
1765 {
1766 core_ops.to_sections = target->to_sections;
1767 core_ops.to_sections_end = target->to_sections_end;
1768 }
1769 new_target_sect_ptr = target->to_sections + old;
1770 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1771 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1772 bfd_section_size (abfd, sect);;
1773 new_target_sect_ptr->the_bfd_section = sect;
1774 new_target_sect_ptr->bfd = abfd;
1775 }
1776}
1777
1778static int
1779dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1780{
1781 bfd *dll_bfd;
1782 map_code_section_args map_args;
1783 asection *lowest_sect;
1784 char *name;
1785 if (dll_name == NULL || target == NULL)
1786 return 0;
66ed1d85 1787 name = xstrdup (dll_name);
8e860359
CF
1788 dll_bfd = bfd_openr (name, "pei-i386");
1789 if (dll_bfd == NULL)
1790 return 0;
1791
1792 if (bfd_check_format (dll_bfd, bfd_object))
1793 {
1794 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1795 if (lowest_sect == NULL)
1796 return 0;
1797 map_args.target = target;
1798 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1799
554cb486 1800 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
1801 }
1802
1803 return 1;
1804}
1805
1806static void
554cb486 1807core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1808{
1809 struct target_ops *target = (struct target_ops *) obj;
1810
1811 DWORD base_addr;
1812
1813 int dll_name_size;
1814 char *dll_name = NULL;
1815 char *buf = NULL;
1816 struct win32_pstatus *pstatus;
1817 char *p;
1818
1819 if (strncmp (sect->name, ".module", 7))
1820 return;
1821
1822 buf = (char *) xmalloc (sect->_raw_size + 1);
1823 if (!buf)
1824 {
1825 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1826 goto out;
1827 }
1828 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1829 goto out;
1830
1831 pstatus = (struct win32_pstatus *) buf;
1832
1833 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1834 dll_name_size = pstatus->data.module_info.module_name_size;
1835 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1836 goto out;
1837
1838 dll_name = (char *) xmalloc (dll_name_size + 1);
1839 if (!dll_name)
1840 {
1841 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1842 goto out;
1843 }
1844 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1845
1846 while ((p = strchr (dll_name, '\\')))
1847 *p = '/';
1848
1849 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1850 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1851
1852 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1853 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1854
1855out:
1856 if (buf)
b8c9b27d 1857 xfree (buf);
8e860359 1858 if (dll_name)
b8c9b27d 1859 xfree (dll_name);
8e860359
CF
1860 return;
1861}
1862
1863void
0a65a603
AC
1864child_solib_add (char *filename, int from_tty, struct target_ops *target,
1865 int readsyms)
8e860359 1866{
990f9fe3
FF
1867 if (!readsyms)
1868 return;
8e860359
CF
1869 if (core_bfd)
1870 {
1871 child_clear_solibs ();
1872 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1873 }
1874 else
1875 {
1876 if (solib_end && solib_end->name)
d3ff4a77 1877 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
3bccec63 1878 solib_end->load_addr);
8e860359
CF
1879 }
1880}
1881
1882static void
1883fetch_elf_core_registers (char *core_reg_sect,
1884 unsigned core_reg_size,
1885 int which,
1886 CORE_ADDR reg_addr)
1887{
1888 int r;
1889 if (core_reg_size < sizeof (CONTEXT))
1890 {
1891 error ("Core file register section too small (%u bytes).", core_reg_size);
1892 return;
1893 }
1894 for (r = 0; r < NUM_REGS; r++)
1895 supply_register (r, core_reg_sect + mappings[r]);
1896}
1897
1898static struct core_fns win32_elf_core_fns =
1899{
1900 bfd_target_elf_flavour,
1901 default_check_format,
1902 default_core_sniffer,
1903 fetch_elf_core_registers,
1904 NULL
1905};
1906
1907void
0613c401 1908_initialize_core_win32 (void)
8e860359
CF
1909{
1910 add_core_fns (&win32_elf_core_fns);
1911}
2a3d5645
CF
1912
1913void
1914_initialize_check_for_gdb_ini (void)
1915{
1916 char *homedir;
1917 if (inhibit_gdbinit)
1918 return;
1919
1920 homedir = getenv ("HOME");
1921 if (homedir)
1922 {
1923 char *p;
1924 char *oldini = (char *) alloca (strlen (homedir) +
1925 sizeof ("/gdb.ini"));
1926 strcpy (oldini, homedir);
1927 p = strchr (oldini, '\0');
1928 if (p > oldini && p[-1] != '/')
1929 *p++ = '/';
1930 strcpy (p, "gdb.ini");
1931 if (access (oldini, 0) == 0)
1932 {
1933 int len = strlen (oldini);
1934 char *newini = alloca (len + 1);
1935 sprintf (newini, "%.*s.gdbinit", len - (sizeof ("gdb.ini") - 1), oldini);
1936 warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
1937 }
1938 }
1939}