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