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