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