Fix for PR gdb/209, PR gdb/156:
[deliverable/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 512 char ppath[MAX_PATH + 1];
3f8ad85b
CF
513 char buf[MAX_PATH + 1];
514 char cwd[MAX_PATH + 1];
515 char *p;
516 WIN32_FIND_DATA w32_fd;
517 HANDLE h = FindFirstFile(name, &w32_fd);
518 size_t len;
519
520 FindClose (h);
521 strcpy (buf, name);
522 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
523 {
524 p = strrchr (buf, '\\');
525 if (p)
526 p[1] = '\0';
527 SetCurrentDirectory (buf);
528 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
529 SetCurrentDirectory (cwd);
530 }
531
532 cygwin_conv_to_posix_path (buf, ppath);
7470a420
CF
533 so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
534 so->loaded = 0;
8e860359 535 so->load_addr = load_addr;
7470a420 536 strcpy (so->name, ppath);
8e860359
CF
537
538 solib_end->next = so;
539 solib_end = so;
540 so->next = NULL;
3f8ad85b
CF
541 len = strlen (ppath);
542 if (len > max_dll_name_len)
543 max_dll_name_len = len;
8e860359
CF
544}
545
c906108c
SS
546/* Wait for child to do something. Return pid of child, or -1 in case
547 of error; store status through argument pointer OURSTATUS. */
c906108c 548static int
554cb486 549handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
c906108c 550{
c5aa993b 551 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
c906108c
SS
552 DWORD dll_name_ptr;
553 DWORD done;
554 char dll_buf[MAX_PATH + 1];
450005e7 555 char *dll_name = NULL;
450005e7 556 char *p;
c906108c 557
c5aa993b 558 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 559
c2d11a7d 560 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
8e860359 561 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 562
c2d11a7d 563 dll_name = dll_buf;
c906108c
SS
564
565 /* Attempt to read the name of the dll that was detected.
566 This is documented to work only when actively debugging
567 a program. It will not work for attached processes. */
568 if (dll_name == NULL || *dll_name == '\0')
569 {
29fe111d 570 DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
c906108c
SS
571 int len = 0;
572 char b[2];
573
574 ReadProcessMemory (current_process_handle,
575 (LPCVOID) event->lpImageName,
576 (char *) &dll_name_ptr,
577 sizeof (dll_name_ptr), &done);
578
579 /* See if we could read the address of a string, and that the
c5aa993b 580 address isn't null. */
c906108c
SS
581
582 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
583 return 1;
584
585 do
586 {
587 ReadProcessMemory (current_process_handle,
588 (LPCVOID) (dll_name_ptr + len * size),
589 &b,
590 size,
591 &done);
592 len++;
593 }
594 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
595
596 dll_name = alloca (len);
597
598 if (event->fUnicode)
599 {
600 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
601 ReadProcessMemory (current_process_handle,
602 (LPCVOID) dll_name_ptr,
603 unicode_dll_name,
604 len * sizeof (WCHAR),
605 &done);
606
607 WideCharToMultiByte (CP_ACP, 0,
608 unicode_dll_name, len,
609 dll_name, len, 0, 0);
610 }
611 else
612 {
613 ReadProcessMemory (current_process_handle,
614 (LPCVOID) dll_name_ptr,
615 dll_name,
616 len,
617 &done);
618 }
619 }
620
621 if (!dll_name)
622 return 1;
623
8e860359 624 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
450005e7
CF
625
626 return 1;
627}
628
629/* Return name of last loaded DLL. */
630char *
9d3789f7 631child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED)
450005e7 632{
8e860359 633 return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
450005e7
CF
634}
635
636/* Clear list of loaded DLLs. */
637void
638child_clear_solibs (void)
639{
640 struct so_stuff *so, *so1 = solib_start.next;
641
642 while ((so = so1) != NULL)
643 {
644 so1 = so->next;
b8c9b27d 645 xfree (so);
450005e7
CF
646 }
647
648 solib_start.next = NULL;
649 solib_end = &solib_start;
650 max_dll_name_len = sizeof ("DLL Name") - 1;
651}
652
653/* Add DLL symbol information. */
02e423b9
CF
654static void
655solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
450005e7
CF
656{
657 struct section_addr_info section_addrs;
658
c906108c
SS
659 /* The symbols in a dll are offset by 0x1000, which is the
660 the offset from 0 of the first byte in an image - because
8a892701 661 of the file header and the section alignment. */
c906108c 662
8e860359 663 if (!name || !name[0])
450005e7
CF
664 return;
665
666 memset (&section_addrs, 0, sizeof (section_addrs));
0aa9cf96 667 section_addrs.other[0].name = ".text";
8e860359 668 section_addrs.other[0].addr = load_addr;
7470a420 669 safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
c906108c 670
450005e7
CF
671 return;
672}
673
674/* Load DLL symbol info. */
675void
7470a420 676dll_symbol_command (char *args, int from_tty)
450005e7 677{
8e860359 678 int n;
450005e7 679 dont_repeat ();
8e860359 680
450005e7
CF
681 if (args == NULL)
682 error ("dll-symbols requires a file name");
683
8e860359
CF
684 n = strlen (args);
685 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
686 {
687 char *newargs = (char *) alloca (n + 4 + 1);
688 strcpy (newargs, args);
689 strcat (newargs, ".dll");
690 args = newargs;
691 }
692
7470a420 693 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
8e860359 694}
450005e7
CF
695
696/* List currently loaded DLLs. */
697void
9d3789f7 698info_dll_command (char *ignore ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
450005e7
CF
699{
700 struct so_stuff *so = &solib_start;
701
702 if (!so->next)
703 return;
704
705 printf ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
706 while ((so = so->next) != NULL)
7c5c87c0 707 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
450005e7
CF
708
709 return;
c906108c
SS
710}
711
712/* Handle DEBUG_STRING output from child process.
713 Cygwin prepends its messages with a "cygwin:". Interpret this as
714 a Cygwin signal. Otherwise just print the string as a warning. */
715static int
716handle_output_debug_string (struct target_waitstatus *ourstatus)
717{
718 char *s;
719 int gotasig = FALSE;
720
721 if (!target_read_string
c5aa993b 722 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
c906108c
SS
723 || !s || !*s)
724 return gotasig;
725
ed9a39eb 726 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
c906108c 727 {
ed9a39eb 728 if (strncmp (s, "cYg", 3) != 0)
29fe111d 729 warning ("%s", s);
c906108c 730 }
ed9a39eb 731 else
c906108c
SS
732 {
733 char *p;
c2d11a7d
JM
734 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
735 gotasig = target_signal_from_host (sig);
7a292a7a
SS
736 ourstatus->value.sig = gotasig;
737 if (gotasig)
c906108c
SS
738 ourstatus->kind = TARGET_WAITKIND_STOPPED;
739 }
740
b8c9b27d 741 xfree (s);
c906108c
SS
742 return gotasig;
743}
744
745static int
450005e7 746handle_exception (struct target_waitstatus *ourstatus)
c906108c 747{
c906108c 748 thread_info *th;
29fe111d 749 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
c906108c 750
29fe111d 751 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 752
c906108c
SS
753 /* Record the context of the current thread */
754 th = thread_rec (current_event.dwThreadId, -1);
755
29fe111d 756 switch (code)
c906108c
SS
757 {
758 case EXCEPTION_ACCESS_VIOLATION:
29fe111d 759 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
8e860359 760 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c 761 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
8a892701 762 last_sig = SIGSEGV;
c906108c 763 break;
0d06e24b
JM
764 case STATUS_FLOAT_UNDERFLOW:
765 case STATUS_FLOAT_DIVIDE_BY_ZERO:
766 case STATUS_FLOAT_OVERFLOW:
767 case STATUS_INTEGER_DIVIDE_BY_ZERO:
29fe111d 768 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
8e860359 769 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
0d06e24b 770 ourstatus->value.sig = TARGET_SIGNAL_FPE;
29fe111d 771 last_sig = SIGFPE;
0d06e24b 772 break;
c906108c 773 case STATUS_STACK_OVERFLOW:
29fe111d 774 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
8e860359 775 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
776 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
777 break;
778 case EXCEPTION_BREAKPOINT:
29fe111d 779 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
8e860359 780 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
781 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
782 break;
783 case DBG_CONTROL_C:
29fe111d 784 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
8e860359 785 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c 786 ourstatus->value.sig = TARGET_SIGNAL_INT;
8a892701 787 last_sig = SIGINT; /* FIXME - should check pass state */
c906108c
SS
788 break;
789 case EXCEPTION_SINGLE_STEP:
29fe111d 790 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
8e860359 791 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
792 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
793 break;
8227c82d 794 case EXCEPTION_ILLEGAL_INSTRUCTION:
29fe111d 795 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
8e860359 796 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
8227c82d 797 ourstatus->value.sig = TARGET_SIGNAL_ILL;
8a892701 798 last_sig = SIGILL;
8227c82d 799 break;
c906108c 800 default:
02e423b9
CF
801 if (current_event.u.Exception.dwFirstChance)
802 return 0;
29fe111d 803 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
c5aa993b 804 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 805 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
c906108c
SS
806 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
807 break;
808 }
809 exception_count++;
810 return 1;
811}
812
813/* Resume all artificially suspended threads if we are continuing
814 execution */
815static BOOL
8a892701 816child_continue (DWORD continue_status, int id)
c906108c
SS
817{
818 int i;
819 thread_info *th;
820 BOOL res;
821
29fe111d 822 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
c906108c 823 current_event.dwProcessId, current_event.dwThreadId));
7a292a7a
SS
824 res = ContinueDebugEvent (current_event.dwProcessId,
825 current_event.dwThreadId,
826 continue_status);
c2d11a7d 827 continue_status = 0;
7a292a7a 828 if (res)
c5aa993b 829 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 830 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
c906108c
SS
831 {
832 for (i = 0; i < th->suspend_count; i++)
833 (void) ResumeThread (th->h);
834 th->suspend_count = 0;
835 }
836
837 return res;
838}
839
8a892701
CF
840/* Get the next event from the child. Return 1 if the event requires
841 handling by WFI (or whatever).
842 */
c2d11a7d 843static int
450005e7 844get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
c2d11a7d
JM
845{
846 BOOL debug_event;
8a892701
CF
847 DWORD continue_status, event_code;
848 thread_info *th = NULL;
849 static thread_info dummy_thread_info;
450005e7 850 int retval = 0;
c2d11a7d 851
9d3789f7
CF
852 last_sig = 0;
853
8a892701 854 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 855 goto out;
c2d11a7d
JM
856
857 event_count++;
858 continue_status = DBG_CONTINUE;
c2d11a7d 859
8a892701 860 event_code = current_event.dwDebugEventCode;
450005e7 861 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
8a892701
CF
862
863 switch (event_code)
c2d11a7d
JM
864 {
865 case CREATE_THREAD_DEBUG_EVENT:
866 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
867 (unsigned) current_event.dwProcessId,
868 (unsigned) current_event.dwThreadId,
869 "CREATE_THREAD_DEBUG_EVENT"));
c2d11a7d 870 /* Record the existence of this thread */
8a892701
CF
871 th = child_add_thread (current_event.dwThreadId,
872 current_event.u.CreateThread.hThread);
c2d11a7d
JM
873 if (info_verbose)
874 printf_unfiltered ("[New %s]\n",
39f77062
KB
875 target_pid_to_str (
876 pid_to_ptid (current_event.dwThreadId)));
450005e7 877 retval = current_event.dwThreadId;
c2d11a7d
JM
878 break;
879
880 case EXIT_THREAD_DEBUG_EVENT:
881 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
882 (unsigned) current_event.dwProcessId,
883 (unsigned) current_event.dwThreadId,
884 "EXIT_THREAD_DEBUG_EVENT"));
c2d11a7d 885 child_delete_thread (current_event.dwThreadId);
8a892701 886 th = &dummy_thread_info;
c2d11a7d
JM
887 break;
888
889 case CREATE_PROCESS_DEBUG_EVENT:
890 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
891 (unsigned) current_event.dwProcessId,
892 (unsigned) current_event.dwThreadId,
893 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 894 CloseHandle (current_event.u.CreateProcessInfo.hFile);
c2d11a7d
JM
895 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
896
9d3789f7 897 main_thread_id = current_event.dwThreadId;
c2d11a7d 898 /* Add the main thread */
9d3789f7 899#if 0
450005e7
CF
900 th = child_add_thread (current_event.dwProcessId,
901 current_event.u.CreateProcessInfo.hProcess);
9d3789f7
CF
902#endif
903 th = child_add_thread (main_thread_id,
8a892701 904 current_event.u.CreateProcessInfo.hThread);
9d3789f7 905 retval = ourstatus->value.related_pid = current_event.dwThreadId;
c2d11a7d
JM
906 break;
907
908 case EXIT_PROCESS_DEBUG_EVENT:
909 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
910 (unsigned) current_event.dwProcessId,
911 (unsigned) current_event.dwThreadId,
912 "EXIT_PROCESS_DEBUG_EVENT"));
c2d11a7d
JM
913 ourstatus->kind = TARGET_WAITKIND_EXITED;
914 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
915 CloseHandle (current_process_handle);
9d3789f7 916 retval = main_thread_id;
8a892701 917 break;
c2d11a7d
JM
918
919 case LOAD_DLL_DEBUG_EVENT:
920 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
921 (unsigned) current_event.dwProcessId,
922 (unsigned) current_event.dwThreadId,
923 "LOAD_DLL_DEBUG_EVENT"));
700b351b 924 CloseHandle (current_event.u.LoadDll.hFile);
8a892701 925 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
c2d11a7d 926 registers_changed (); /* mark all regs invalid */
450005e7
CF
927 ourstatus->kind = TARGET_WAITKIND_LOADED;
928 ourstatus->value.integer = 0;
9d3789f7 929 retval = main_thread_id;
c2d11a7d
JM
930 break;
931
932 case UNLOAD_DLL_DEBUG_EVENT:
933 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
934 (unsigned) current_event.dwProcessId,
935 (unsigned) current_event.dwThreadId,
936 "UNLOAD_DLL_DEBUG_EVENT"));
937 break; /* FIXME: don't know what to do here */
c2d11a7d
JM
938
939 case EXCEPTION_DEBUG_EVENT:
940 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
941 (unsigned) current_event.dwProcessId,
942 (unsigned) current_event.dwThreadId,
943 "EXCEPTION_DEBUG_EVENT"));
02e423b9
CF
944 if (handle_exception (ourstatus))
945 retval = current_event.dwThreadId;
c2d11a7d
JM
946 break;
947
8a892701 948 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
c2d11a7d 949 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
950 (unsigned) current_event.dwProcessId,
951 (unsigned) current_event.dwThreadId,
952 "OUTPUT_DEBUG_STRING_EVENT"));
8e860359 953 if (handle_output_debug_string (ourstatus))
9d3789f7 954 retval = main_thread_id;
c2d11a7d 955 break;
9d3789f7 956
c2d11a7d 957 default:
29fe111d
CF
958 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
959 (DWORD) current_event.dwProcessId,
960 (DWORD) current_event.dwThreadId);
961 printf_unfiltered (" unknown event code %ld\n",
c2d11a7d
JM
962 current_event.dwDebugEventCode);
963 break;
964 }
965
450005e7 966 if (!retval)
8a892701 967 CHECK (child_continue (continue_status, -1));
450005e7 968 else
9d3789f7 969 {
8e860359 970 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
39f77062 971 inferior_ptid = pid_to_ptid (retval);
9d3789f7 972 }
c2d11a7d
JM
973
974out:
450005e7 975 return retval;
c2d11a7d
JM
976}
977
c2d11a7d 978/* Wait for interesting events to occur in the target process. */
39f77062
KB
979static ptid_t
980child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
c906108c 981{
39f77062
KB
982 int pid = PIDGET (ptid);
983
c906108c
SS
984 /* We loop when we get a non-standard exception rather than return
985 with a SPURIOUS because resume can try and step or modify things,
986 which needs a current_thread->h. But some of these exceptions mark
987 the birth or death of threads, which mean that the current thread
988 isn't necessarily what you think it is. */
989
990 while (1)
450005e7
CF
991 {
992 int retval = get_child_debug_event (pid, ourstatus);
993 if (retval)
39f77062 994 return pid_to_ptid (retval);
450005e7
CF
995 else
996 {
997 int detach = 0;
c906108c 998
450005e7
CF
999 if (ui_loop_hook != NULL)
1000 detach = ui_loop_hook (0);
7a292a7a 1001
450005e7
CF
1002 if (detach)
1003 child_kill_inferior ();
1004 }
1005 }
c906108c
SS
1006}
1007
9d3789f7
CF
1008static void
1009do_initial_child_stuff (DWORD pid)
1010{
1011 extern int stop_after_trap;
1012
1013 last_sig = 0;
1014 event_count = 0;
1015 exception_count = 0;
1016 current_event.dwProcessId = pid;
1017 memset (&current_event, 0, sizeof (current_event));
1018 push_target (&child_ops);
1019 child_init_thread_list ();
1020 child_clear_solibs ();
1021 clear_proceed_status ();
1022 init_wait_for_inferior ();
1023
1024 target_terminal_init ();
1025 target_terminal_inferior ();
1026
1027 while (1)
1028 {
1029 stop_after_trap = 1;
1030 wait_for_inferior ();
1031 if (stop_signal != TARGET_SIGNAL_TRAP)
1032 resume (0, stop_signal);
1033 else
1034 break;
1035 }
1036 stop_after_trap = 0;
1037 return;
1038}
1039
02cc9f49
CV
1040/* Since Windows XP, detaching from a process is supported by Windows.
1041 The following code tries loading the appropriate functions dynamically.
1042 If loading these functions succeeds use them to actually detach from
1043 the inferior process, otherwise behave as usual, pretending that
1044 detach has worked. */
1045static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1046static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1047
1048static int
1049has_detach_ability ()
1050{
1051 static HMODULE kernel32 = NULL;
1052
1053 if (!kernel32)
1054 kernel32 = LoadLibrary ("kernel32.dll");
1055 if (kernel32)
1056 {
1057 if (!DebugSetProcessKillOnExit)
1058 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1059 "DebugSetProcessKillOnExit");
1060 if (!DebugActiveProcessStop)
1061 DebugActiveProcessStop = GetProcAddress (kernel32,
1062 "DebugActiveProcessStop");
1063 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1064 return 1;
1065 }
1066 return 0;
1067}
c906108c 1068
02cc9f49 1069/* Attach to process PID, then initialize for debugging it. */
c906108c 1070static void
fba45db2 1071child_attach (char *args, int from_tty)
c906108c
SS
1072{
1073 BOOL ok;
559e75c0 1074 DWORD pid;
c906108c
SS
1075
1076 if (!args)
1077 error_no_arg ("process-id to attach");
1078
559e75c0 1079 pid = strtoul (args, 0, 0);
9d3789f7 1080 ok = DebugActiveProcess (pid);
c906108c
SS
1081
1082 if (!ok)
1083 error ("Can't attach to process.");
1084
02cc9f49
CV
1085 if (has_detach_ability ())
1086 {
1087 attach_flag = 1;
1088 DebugSetProcessKillOnExit (FALSE);
1089 }
1090
c906108c
SS
1091 if (from_tty)
1092 {
1093 char *exec_file = (char *) get_exec_file (0);
1094
1095 if (exec_file)
1096 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1097 target_pid_to_str (pid_to_ptid (pid)));
c906108c
SS
1098 else
1099 printf_unfiltered ("Attaching to %s\n",
39f77062 1100 target_pid_to_str (pid_to_ptid (pid)));
c906108c
SS
1101
1102 gdb_flush (gdb_stdout);
1103 }
1104
9d3789f7
CF
1105 do_initial_child_stuff (pid);
1106 target_terminal_ours ();
c906108c
SS
1107}
1108
1109static void
29fe111d 1110child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
c906108c 1111{
02cc9f49
CV
1112 int detached = 1;
1113
1114 if (has_detach_ability ())
1115 {
1116 delete_command (NULL, 0);
1117 child_continue (DBG_CONTINUE, -1);
1118 if (!DebugActiveProcessStop (current_event.dwProcessId))
1119 {
1120 error ("Can't detach process %lu (error %lu)",
1121 current_event.dwProcessId, GetLastError ());
1122 detached = 0;
1123 }
1124 DebugSetProcessKillOnExit (FALSE);
1125 }
1126 if (detached && from_tty)
c906108c
SS
1127 {
1128 char *exec_file = get_exec_file (0);
1129 if (exec_file == 0)
1130 exec_file = "";
02cc9f49
CV
1131 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1132 current_event.dwProcessId);
c906108c
SS
1133 gdb_flush (gdb_stdout);
1134 }
39f77062 1135 inferior_ptid = null_ptid;
c906108c
SS
1136 unpush_target (&child_ops);
1137}
1138
1139/* Print status information about what we're accessing. */
1140
1141static void
29fe111d 1142child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
c906108c
SS
1143{
1144 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1145 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
c906108c
SS
1146}
1147
1148/* ARGSUSED */
1149static void
29fe111d 1150child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
c906108c
SS
1151{
1152 error ("Use the \"run\" command to start a Unix child process.");
1153}
1154
39f77062 1155/* Start an inferior win32 child process and sets inferior_ptid to its pid.
c906108c
SS
1156 EXEC_FILE is the file to run.
1157 ALLARGS is a string containing the arguments to the program.
1158 ENV is the environment vector to pass. Errors reported with error(). */
1159
1160static void
fba45db2 1161child_create_inferior (char *exec_file, char *allargs, char **env)
c906108c
SS
1162{
1163 char real_path[MAXPATHLEN];
1164 char *winenv;
1165 char *temp;
c5aa993b 1166 int envlen;
c906108c 1167 int i;
c906108c
SS
1168 STARTUPINFO si;
1169 PROCESS_INFORMATION pi;
c906108c
SS
1170 BOOL ret;
1171 DWORD flags;
1172 char *args;
1173
1174 if (!exec_file)
450005e7 1175 error ("No executable specified, use `target exec'.\n");
c906108c
SS
1176
1177 memset (&si, 0, sizeof (si));
1178 si.cb = sizeof (si);
1179
29fe111d 1180 cygwin_conv_to_win32_path (exec_file, real_path);
c906108c
SS
1181
1182 flags = DEBUG_ONLY_THIS_PROCESS;
1183
1184 if (new_group)
1185 flags |= CREATE_NEW_PROCESS_GROUP;
1186
1187 if (new_console)
1188 flags |= CREATE_NEW_CONSOLE;
1189
1190 args = alloca (strlen (real_path) + strlen (allargs) + 2);
1191
1192 strcpy (args, real_path);
1193
1194 strcat (args, " ");
1195 strcat (args, allargs);
1196
1197 /* Prepare the environment vars for CreateProcess. */
1198 {
1199 /* This code use to assume all env vars were file names and would
1200 translate them all to win32 style. That obviously doesn't work in the
1201 general case. The current rule is that we only translate PATH.
1202 We need to handle PATH because we're about to call CreateProcess and
1203 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1204 in both posix and win32 environments. cygwin.dll will change it back
1205 to posix style if necessary. */
1206
1207 static const char *conv_path_names[] =
c5aa993b
JM
1208 {
1209 "PATH=",
1210 0
1211 };
c906108c
SS
1212
1213 /* CreateProcess takes the environment list as a null terminated set of
1214 strings (i.e. two nulls terminate the list). */
1215
1216 /* Get total size for env strings. */
1217 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1218 {
1219 int j, len;
1220
1221 for (j = 0; conv_path_names[j]; j++)
1222 {
1223 len = strlen (conv_path_names[j]);
1224 if (strncmp (conv_path_names[j], env[i], len) == 0)
1225 {
29fe111d 1226 if (cygwin_posix_path_list_p (env[i] + len))
c906108c 1227 envlen += len
29fe111d 1228 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
c906108c
SS
1229 else
1230 envlen += strlen (env[i]) + 1;
1231 break;
1232 }
1233 }
1234 if (conv_path_names[j] == NULL)
1235 envlen += strlen (env[i]) + 1;
1236 }
1237
1238 winenv = alloca (envlen + 1);
1239
1240 /* Copy env strings into new buffer. */
1241 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1242 {
1243 int j, len;
1244
1245 for (j = 0; conv_path_names[j]; j++)
1246 {
1247 len = strlen (conv_path_names[j]);
1248 if (strncmp (conv_path_names[j], env[i], len) == 0)
1249 {
29fe111d 1250 if (cygwin_posix_path_list_p (env[i] + len))
c906108c
SS
1251 {
1252 memcpy (temp, env[i], len);
29fe111d 1253 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
c906108c
SS
1254 }
1255 else
1256 strcpy (temp, env[i]);
1257 break;
1258 }
1259 }
1260 if (conv_path_names[j] == NULL)
1261 strcpy (temp, env[i]);
1262
1263 temp += strlen (temp) + 1;
1264 }
1265
1266 /* Final nil string to terminate new env. */
1267 *temp = 0;
1268 }
1269
1270 ret = CreateProcess (0,
c5aa993b 1271 args, /* command line */
c906108c
SS
1272 NULL, /* Security */
1273 NULL, /* thread */
1274 TRUE, /* inherit handles */
1275 flags, /* start flags */
1276 winenv,
1277 NULL, /* current directory */
1278 &si,
1279 &pi);
1280 if (!ret)
c5aa993b 1281 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
c906108c 1282
700b351b
CF
1283 CloseHandle (pi.hThread);
1284 CloseHandle (pi.hProcess);
9d3789f7 1285 do_initial_child_stuff (pi.dwProcessId);
ed9a39eb 1286
8e860359 1287 /* child_continue (DBG_CONTINUE, -1); */
c2d11a7d 1288 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
c906108c
SS
1289}
1290
1291static void
fba45db2 1292child_mourn_inferior (void)
c906108c 1293{
8a892701 1294 (void) child_continue (DBG_CONTINUE, -1);
c906108c
SS
1295 unpush_target (&child_ops);
1296 generic_mourn_inferior ();
1297}
1298
1299/* Send a SIGINT to the process group. This acts just like the user typed a
1300 ^C on the controlling terminal. */
1301
1302static void
fba45db2 1303child_stop (void)
c906108c
SS
1304{
1305 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
c2d11a7d 1306 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
c5aa993b 1307 registers_changed (); /* refresh register state */
c906108c
SS
1308}
1309
1310int
1311child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
56c40d46 1312 int write, struct mem_attrib *mem ATTRIBUTE_UNUSED,
aea02b6b 1313 struct target_ops *target ATTRIBUTE_UNUSED)
c906108c
SS
1314{
1315 DWORD done;
1316 if (write)
1317 {
29fe111d
CF
1318 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1319 len, (DWORD) memaddr));
c906108c
SS
1320 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1321 len, &done);
1322 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1323 }
1324 else
1325 {
29fe111d
CF
1326 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1327 len, (DWORD) memaddr));
c906108c
SS
1328 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1329 &done);
1330 }
1331 return done;
1332}
1333
1334void
1335child_kill_inferior (void)
1336{
1337 CHECK (TerminateProcess (current_process_handle, 0));
1338
1339 for (;;)
1340 {
8a892701 1341 if (!child_continue (DBG_CONTINUE, -1))
c906108c
SS
1342 break;
1343 if (!WaitForDebugEvent (&current_event, INFINITE))
1344 break;
1345 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1346 break;
1347 }
1348
1349 CHECK (CloseHandle (current_process_handle));
1350
1351 /* this may fail in an attached process so don't check. */
1352 (void) CloseHandle (current_thread->h);
c5aa993b 1353 target_mourn_inferior (); /* or just child_mourn_inferior? */
c906108c
SS
1354}
1355
1356void
39f77062 1357child_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c 1358{
c906108c 1359 thread_info *th;
8a892701 1360 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
8e860359 1361 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
39f77062 1362 int pid = PIDGET (ptid);
8a892701
CF
1363
1364 last_sig = 0;
c906108c
SS
1365
1366 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1367 pid, step, sig));
1368
1369 /* Get context for currently selected thread */
1370 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 1371 if (th)
c906108c 1372 {
450005e7
CF
1373 if (step)
1374 {
1375 /* Single step by setting t bit */
1376 child_fetch_inferior_registers (PS_REGNUM);
1377 th->context.EFlags |= FLAG_TRACE_BIT;
1378 }
c906108c 1379
450005e7
CF
1380 if (th->context.ContextFlags)
1381 {
1382 CHECK (SetThreadContext (th->h, &th->context));
1383 th->context.ContextFlags = 0;
1384 }
c906108c
SS
1385 }
1386
1387 /* Allow continuing with the same signal that interrupted us.
1388 Otherwise complain. */
c906108c 1389
8a892701 1390 child_continue (continue_status, pid);
c906108c
SS
1391}
1392
1393static void
fba45db2 1394child_prepare_to_store (void)
c906108c
SS
1395{
1396 /* Do nothing, since we can store individual regs */
1397}
1398
1399static int
fba45db2 1400child_can_run (void)
c906108c
SS
1401{
1402 return 1;
1403}
1404
1405static void
9d3789f7 1406child_close (int x ATTRIBUTE_UNUSED)
c906108c 1407{
39f77062
KB
1408 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1409 PIDGET (inferior_ptid)));
c906108c
SS
1410}
1411
c5aa993b 1412struct target_ops child_ops;
c906108c 1413
c5aa993b
JM
1414static void
1415init_child_ops (void)
c906108c 1416{
c5aa993b
JM
1417 child_ops.to_shortname = "child";
1418 child_ops.to_longname = "Win32 child process";
1419 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1420 child_ops.to_open = child_open;
1421 child_ops.to_close = child_close;
1422 child_ops.to_attach = child_attach;
1423 child_ops.to_detach = child_detach;
1424 child_ops.to_resume = child_resume;
1425 child_ops.to_wait = child_wait;
1426 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1427 child_ops.to_store_registers = child_store_inferior_registers;
1428 child_ops.to_prepare_to_store = child_prepare_to_store;
1429 child_ops.to_xfer_memory = child_xfer_memory;
1430 child_ops.to_files_info = child_files_info;
1431 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1432 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1433 child_ops.to_terminal_init = terminal_init_inferior;
1434 child_ops.to_terminal_inferior = terminal_inferior;
1435 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1436 child_ops.to_terminal_ours = terminal_ours;
1437 child_ops.to_terminal_info = child_terminal_info;
1438 child_ops.to_kill = child_kill_inferior;
1439 child_ops.to_load = 0;
1440 child_ops.to_lookup_symbol = 0;
1441 child_ops.to_create_inferior = child_create_inferior;
1442 child_ops.to_mourn_inferior = child_mourn_inferior;
1443 child_ops.to_can_run = child_can_run;
1444 child_ops.to_notice_signals = 0;
1445 child_ops.to_thread_alive = win32_child_thread_alive;
ed9a39eb 1446 child_ops.to_pid_to_str = cygwin_pid_to_str;
c5aa993b
JM
1447 child_ops.to_stop = child_stop;
1448 child_ops.to_stratum = process_stratum;
1449 child_ops.DONT_USE = 0;
1450 child_ops.to_has_all_memory = 1;
1451 child_ops.to_has_memory = 1;
1452 child_ops.to_has_stack = 1;
1453 child_ops.to_has_registers = 1;
1454 child_ops.to_has_execution = 1;
1455 child_ops.to_sections = 0;
1456 child_ops.to_sections_end = 0;
1457 child_ops.to_magic = OPS_MAGIC;
c906108c
SS
1458}
1459
1460void
fba45db2 1461_initialize_inftarg (void)
c906108c 1462{
fa58ee11
EZ
1463 struct cmd_list_element *c;
1464
c5aa993b 1465 init_child_ops ();
c906108c 1466
fa58ee11
EZ
1467 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1468 "Load dll library symbols from FILE.");
1469 c->completer = filename_completer;
450005e7
CF
1470
1471 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1472
1473 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
8e860359
CF
1474 (char *) &new_console,
1475 "Set creation of new console when creating child process.",
1476 &setlist),
1477 &showlist);
c906108c 1478
450005e7 1479 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
8e860359
CF
1480 (char *) &new_group,
1481 "Set creation of new group when creating child process.",
1482 &setlist),
1483 &showlist);
c906108c 1484
450005e7 1485 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
8e860359
CF
1486 (char *) &debug_exec,
1487 "Set whether to display execution in child process.",
1488 &setlist),
1489 &showlist);
c906108c 1490
450005e7 1491 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
8e860359
CF
1492 (char *) &debug_events,
1493 "Set whether to display kernel events in child process.",
1494 &setlist),
1495 &showlist);
c906108c 1496
450005e7 1497 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
8e860359
CF
1498 (char *) &debug_memory,
1499 "Set whether to display memory accesses in child process.",
1500 &setlist),
1501 &showlist);
c906108c 1502
450005e7 1503 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
8e860359
CF
1504 (char *) &debug_exceptions,
1505 "Set whether to display kernel exceptions in child process.",
1506 &setlist),
1507 &showlist);
c906108c 1508
450005e7
CF
1509 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1510 add_info_alias ("sharedlibrary", "dll", 1);
1511
c906108c
SS
1512 add_target (&child_ops);
1513}
1514
1515/* Determine if the thread referenced by "pid" is alive
1516 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1517 it means that the pid has died. Otherwise it is assumed to be alive. */
1518static int
39f77062 1519win32_child_thread_alive (ptid_t ptid)
c906108c 1520{
39f77062
KB
1521 int pid = PIDGET (ptid);
1522
c5aa993b
JM
1523 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1524 FALSE : TRUE;
c906108c
SS
1525}
1526
1527/* Convert pid to printable format. */
1528char *
39f77062 1529cygwin_pid_to_str (ptid_t ptid)
c906108c
SS
1530{
1531 static char buf[80];
39f77062
KB
1532 int pid = PIDGET (ptid);
1533
29fe111d 1534 if ((DWORD) pid == current_event.dwProcessId)
c906108c
SS
1535 sprintf (buf, "process %d", pid);
1536 else
29fe111d 1537 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
c906108c
SS
1538 return buf;
1539}
8e860359
CF
1540
1541static int
1542core_dll_symbols_add (char *dll_name, DWORD base_addr)
1543{
1544 struct objfile *objfile;
1545 char *objfile_basename;
1546 const char *dll_basename;
1547
1548 if (!(dll_basename = strrchr (dll_name, '/')))
1549 dll_basename = dll_name;
1550 else
1551 dll_basename++;
1552
1553 ALL_OBJFILES (objfile)
1554 {
1555 objfile_basename = strrchr (objfile->name, '/');
1556
1557 if (objfile_basename &&
1558 strcmp (dll_basename, objfile_basename + 1) == 0)
1559 {
1560 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1561 base_addr, dll_name);
1562 goto out;
1563 }
1564 }
1565
1566 register_loaded_dll (dll_name, base_addr + 0x1000);
02e423b9 1567 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
8e860359
CF
1568
1569out:
1570 return 1;
1571}
1572
1573typedef struct
1574{
1575 struct target_ops *target;
1576 bfd_vma addr;
1577}
1578map_code_section_args;
1579
1580static void
554cb486 1581map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1582{
1583 int old;
1584 int update_coreops;
1585 struct section_table *new_target_sect_ptr;
1586
1587 map_code_section_args *args = (map_code_section_args *) obj;
1588 struct target_ops *target = args->target;
1589 if (sect->flags & SEC_CODE)
1590 {
1591 update_coreops = core_ops.to_sections == target->to_sections;
1592
1593 if (target->to_sections)
1594 {
1595 old = target->to_sections_end - target->to_sections;
1596 target->to_sections = (struct section_table *)
1597 xrealloc ((char *) target->to_sections,
1598 (sizeof (struct section_table)) * (1 + old));
1599 }
1600 else
1601 {
1602 old = 0;
1603 target->to_sections = (struct section_table *)
1604 xmalloc ((sizeof (struct section_table)));
1605 }
1606 target->to_sections_end = target->to_sections + (1 + old);
1607
1608 /* Update the to_sections field in the core_ops structure
1609 if needed. */
1610 if (update_coreops)
1611 {
1612 core_ops.to_sections = target->to_sections;
1613 core_ops.to_sections_end = target->to_sections_end;
1614 }
1615 new_target_sect_ptr = target->to_sections + old;
1616 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1617 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1618 bfd_section_size (abfd, sect);;
1619 new_target_sect_ptr->the_bfd_section = sect;
1620 new_target_sect_ptr->bfd = abfd;
1621 }
1622}
1623
1624static int
1625dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1626{
1627 bfd *dll_bfd;
1628 map_code_section_args map_args;
1629 asection *lowest_sect;
1630 char *name;
1631 if (dll_name == NULL || target == NULL)
1632 return 0;
66ed1d85 1633 name = xstrdup (dll_name);
8e860359
CF
1634 dll_bfd = bfd_openr (name, "pei-i386");
1635 if (dll_bfd == NULL)
1636 return 0;
1637
1638 if (bfd_check_format (dll_bfd, bfd_object))
1639 {
1640 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1641 if (lowest_sect == NULL)
1642 return 0;
1643 map_args.target = target;
1644 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1645
554cb486 1646 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
1647 }
1648
1649 return 1;
1650}
1651
1652static void
554cb486 1653core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1654{
1655 struct target_ops *target = (struct target_ops *) obj;
1656
1657 DWORD base_addr;
1658
1659 int dll_name_size;
1660 char *dll_name = NULL;
1661 char *buf = NULL;
1662 struct win32_pstatus *pstatus;
1663 char *p;
1664
1665 if (strncmp (sect->name, ".module", 7))
1666 return;
1667
1668 buf = (char *) xmalloc (sect->_raw_size + 1);
1669 if (!buf)
1670 {
1671 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1672 goto out;
1673 }
1674 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1675 goto out;
1676
1677 pstatus = (struct win32_pstatus *) buf;
1678
1679 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1680 dll_name_size = pstatus->data.module_info.module_name_size;
1681 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1682 goto out;
1683
1684 dll_name = (char *) xmalloc (dll_name_size + 1);
1685 if (!dll_name)
1686 {
1687 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1688 goto out;
1689 }
1690 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1691
1692 while ((p = strchr (dll_name, '\\')))
1693 *p = '/';
1694
1695 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1696 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1697
1698 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1699 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1700
1701out:
1702 if (buf)
b8c9b27d 1703 xfree (buf);
8e860359 1704 if (dll_name)
b8c9b27d 1705 xfree (dll_name);
8e860359
CF
1706 return;
1707}
1708
1709void
990f9fe3 1710child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty, struct target_ops *target, int readsyms)
8e860359 1711{
990f9fe3
FF
1712 if (!readsyms)
1713 return;
8e860359
CF
1714 if (core_bfd)
1715 {
1716 child_clear_solibs ();
1717 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1718 }
1719 else
1720 {
1721 if (solib_end && solib_end->name)
02e423b9 1722 solib_symbols_add (solib_end->name, from_tty, solib_end->load_addr);
8e860359
CF
1723 }
1724}
1725
1726static void
1727fetch_elf_core_registers (char *core_reg_sect,
1728 unsigned core_reg_size,
1729 int which,
1730 CORE_ADDR reg_addr)
1731{
1732 int r;
1733 if (core_reg_size < sizeof (CONTEXT))
1734 {
1735 error ("Core file register section too small (%u bytes).", core_reg_size);
1736 return;
1737 }
1738 for (r = 0; r < NUM_REGS; r++)
1739 supply_register (r, core_reg_sect + mappings[r]);
1740}
1741
1742static struct core_fns win32_elf_core_fns =
1743{
1744 bfd_target_elf_flavour,
1745 default_check_format,
1746 default_core_sniffer,
1747 fetch_elf_core_registers,
1748 NULL
1749};
1750
1751void
0613c401 1752_initialize_core_win32 (void)
8e860359
CF
1753{
1754 add_core_fns (&win32_elf_core_fns);
1755}
This page took 0.24588 seconds and 4 git commands to generate.