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