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