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