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