* win32-nat.c (get_child_debug_event): Keep main thread id around even after
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
CommitLineData
24e60978 1/* Target-vector operations for controlling win32 child processes, for GDB.
0a65a603 2
1bac305b 3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
0a65a603
AC
4 Software Foundation, Inc.
5
e6433c28 6 Contributed by Cygnus Solutions, A Red Hat Company.
e88c49c3 7
24e60978
SC
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
3a4b77d8 22 Foundation, Inc., 59 Temple Place - Suite 330,
4e052eda 23 Boston, MA 02111-1307, USA. */
24e60978 24
dfe7f3ac 25/* Originally by Steve Chamberlain, sac@cygnus.com */
24e60978 26
3cee93ac 27/* We assume we're being built with and will be used for cygwin. */
e88c49c3 28
24e60978
SC
29#include "defs.h"
30#include "frame.h" /* required by inferior.h */
31#include "inferior.h"
32#include "target.h"
24e60978
SC
33#include "gdbcore.h"
34#include "command.h"
fa58ee11 35#include "completer.h"
4e052eda 36#include "regcache.h"
2a3d5645 37#include "top.h"
403d9909
CF
38#include <signal.h>
39#include <sys/types.h>
40#include <fcntl.h>
41#include <stdlib.h>
42#include <windows.h>
43#include <imagehlp.h>
44#include <sys/cygwin.h>
cad9cd60 45
24e60978 46#include "buildsym.h"
1ef980b9
SC
47#include "symfile.h"
48#include "objfiles.h"
24e60978 49#include "gdb_string.h"
fdfa3315 50#include "gdbthread.h"
24e60978 51#include "gdbcmd.h"
1750a5ef 52#include <sys/param.h>
1e37c281 53#include <unistd.h>
4646aa9d 54#include "exec.h"
24e60978 55
6c7de422
MK
56#include "i386-tdep.h"
57#include "i387-tdep.h"
58
0714f9bf 59/* The ui's event loop. */
507f3c78 60extern int (*ui_loop_hook) (int signo);
0714f9bf
SS
61
62/* If we're not using the old Cygwin header file set, define the
63 following which never should have been in the generic Win32 API
64 headers in the first place since they were our own invention... */
65#ifndef _GNU_H_WINDOWS_H
9d3789f7 66enum
8e860359
CF
67 {
68 FLAG_TRACE_BIT = 0x100,
69 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
70 };
0714f9bf 71#endif
8e860359
CF
72#include <sys/procfs.h>
73#include <psapi.h>
0714f9bf 74
fa4ba8da
PM
75#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
76 | CONTEXT_EXTENDED_REGISTERS
97da3b20 77
fa4ba8da 78static unsigned dr[8];
87a45c96
CF
79static int debug_registers_changed;
80static int debug_registers_used;
97da3b20 81
3cee93ac
CF
82/* The string sent by cygwin when it processes a signal.
83 FIXME: This should be in a cygwin include file. */
84#define CYGWIN_SIGNAL_STRING "cygwin: signal"
85
29fe111d 86#define CHECK(x) check (x, __FILE__,__LINE__)
dfe7f3ac 87#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
4e52d31c
PM
88#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
89#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
90#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
24e60978
SC
91
92/* Forward declaration */
93extern struct target_ops child_ops;
94
a14ed312 95static void child_stop (void);
39f77062 96static int win32_child_thread_alive (ptid_t);
a14ed312 97void child_kill_inferior (void);
3cee93ac 98
7393af7c
PM
99static enum target_signal last_sig = TARGET_SIGNAL_0;
100/* Set if a signal was received from the debugged process */
101
3cee93ac
CF
102/* Thread information structure used to track information that is
103 not available in gdb's thread structure. */
104typedef struct thread_info_struct
3a4b77d8
JM
105 {
106 struct thread_info_struct *next;
107 DWORD id;
108 HANDLE h;
109 char *name;
110 int suspend_count;
111 CONTEXT context;
1e37c281 112 STACKFRAME sf;
8e860359
CF
113 }
114thread_info;
1e37c281 115
29fe111d 116static thread_info thread_head;
24e60978 117
24e60978
SC
118/* The process and thread handles for the above context. */
119
3cee93ac
CF
120static DEBUG_EVENT current_event; /* The current debug event from
121 WaitForDebugEvent */
122static HANDLE current_process_handle; /* Currently executing process */
123static thread_info *current_thread; /* Info on currently selected thread */
349b409f 124static DWORD main_thread_id; /* Thread ID of the main thread */
24e60978
SC
125
126/* Counts of things. */
127static int exception_count = 0;
128static int event_count = 0;
dfe7f3ac 129static int saw_create;
24e60978
SC
130
131/* User options. */
132static int new_console = 0;
1e37c281 133static int new_group = 1;
dfe7f3ac
CF
134static int debug_exec = 0; /* show execution */
135static int debug_events = 0; /* show events from kernel */
136static int debug_memory = 0; /* show target memory accesses */
1ef980b9 137static int debug_exceptions = 0; /* show target exceptions */
dfe7f3ac
CF
138static int useshell = 0; /* use shell for subprocesses */
139
24e60978 140/* This vector maps GDB's idea of a register's number into an address
3cee93ac 141 in the win32 exception context vector.
24e60978 142
3cee93ac 143 It also contains the bit mask needed to load the register in question.
24e60978
SC
144
145 One day we could read a reg, we could inspect the context we
146 already have loaded, if it doesn't have the bit set that we need,
147 we read that set of registers in using GetThreadContext. If the
148 context already contains what we need, we just unpack it. Then to
149 write a register, first we have to ensure that the context contains
150 the other regs of the group, and then we copy the info in and set
151 out bit. */
152
3cee93ac
CF
153#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
154static const int mappings[] =
24e60978 155{
3a4b77d8
JM
156 context_offset (Eax),
157 context_offset (Ecx),
158 context_offset (Edx),
159 context_offset (Ebx),
160 context_offset (Esp),
161 context_offset (Ebp),
162 context_offset (Esi),
163 context_offset (Edi),
164 context_offset (Eip),
165 context_offset (EFlags),
166 context_offset (SegCs),
167 context_offset (SegSs),
168 context_offset (SegDs),
169 context_offset (SegEs),
170 context_offset (SegFs),
171 context_offset (SegGs),
172 context_offset (FloatSave.RegisterArea[0 * 10]),
173 context_offset (FloatSave.RegisterArea[1 * 10]),
174 context_offset (FloatSave.RegisterArea[2 * 10]),
175 context_offset (FloatSave.RegisterArea[3 * 10]),
176 context_offset (FloatSave.RegisterArea[4 * 10]),
177 context_offset (FloatSave.RegisterArea[5 * 10]),
178 context_offset (FloatSave.RegisterArea[6 * 10]),
179 context_offset (FloatSave.RegisterArea[7 * 10]),
1e37c281
JM
180 context_offset (FloatSave.ControlWord),
181 context_offset (FloatSave.StatusWord),
182 context_offset (FloatSave.TagWord),
183 context_offset (FloatSave.ErrorSelector),
184 context_offset (FloatSave.ErrorOffset),
185 context_offset (FloatSave.DataSelector),
186 context_offset (FloatSave.DataOffset),
d3a09475 187 context_offset (FloatSave.ErrorSelector)
97da3b20 188 /* XMM0-7 */ ,
441532d7
PM
189 context_offset (ExtendedRegisters[10*16]),
190 context_offset (ExtendedRegisters[11*16]),
191 context_offset (ExtendedRegisters[12*16]),
192 context_offset (ExtendedRegisters[13*16]),
193 context_offset (ExtendedRegisters[14*16]),
194 context_offset (ExtendedRegisters[15*16]),
195 context_offset (ExtendedRegisters[16*16]),
196 context_offset (ExtendedRegisters[17*16]),
197 /* MXCSR */
198 context_offset (ExtendedRegisters[24])
24e60978
SC
199};
200
d3a09475
JM
201#undef context_offset
202
24e60978
SC
203/* This vector maps the target's idea of an exception (extracted
204 from the DEBUG_EVENT structure) to GDB's idea. */
205
206struct xlate_exception
207 {
208 int them;
209 enum target_signal us;
210 };
211
24e60978
SC
212static const struct xlate_exception
213 xlate[] =
214{
215 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
9cbf6c0e 216 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
24e60978
SC
217 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
218 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
219 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
7393af7c 220 {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
24e60978
SC
221 {-1, -1}};
222
fa4ba8da
PM
223static void
224check (BOOL ok, const char *file, int line)
225{
226 if (!ok)
dfe7f3ac 227 printf_filtered ("error return %s:%d was %lu\n", file, line,
fa4ba8da
PM
228 GetLastError ());
229}
230
231
3cee93ac
CF
232/* Find a thread record given a thread id.
233 If get_context then also retrieve the context for this
234 thread. */
235static thread_info *
236thread_rec (DWORD id, int get_context)
24e60978 237{
3cee93ac
CF
238 thread_info *th;
239
3a4b77d8 240 for (th = &thread_head; (th = th->next) != NULL;)
3cee93ac
CF
241 if (th->id == id)
242 {
243 if (!th->suspend_count && get_context)
244 {
8a892701 245 if (get_context > 0 && id != current_event.dwThreadId)
3cee93ac
CF
246 th->suspend_count = SuspendThread (th->h) + 1;
247 else if (get_context < 0)
248 th->suspend_count = -1;
249
97da3b20 250 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
3cee93ac 251 GetThreadContext (th->h, &th->context);
fa4ba8da
PM
252 if (id == current_event.dwThreadId)
253 {
254 /* Copy dr values from that thread. */
255 dr[0] = th->context.Dr0;
256 dr[1] = th->context.Dr1;
257 dr[2] = th->context.Dr2;
258 dr[3] = th->context.Dr3;
259 dr[6] = th->context.Dr6;
260 dr[7] = th->context.Dr7;
261 }
3cee93ac
CF
262 }
263 return th;
264 }
265
266 return NULL;
267}
268
269/* Add a thread to the thread list */
270static thread_info *
3a4b77d8 271child_add_thread (DWORD id, HANDLE h)
3cee93ac
CF
272{
273 thread_info *th;
274
275 if ((th = thread_rec (id, FALSE)))
276 return th;
277
278 th = (thread_info *) xmalloc (sizeof (*th));
3a4b77d8 279 memset (th, 0, sizeof (*th));
3cee93ac
CF
280 th->id = id;
281 th->h = h;
282 th->next = thread_head.next;
283 thread_head.next = th;
39f77062 284 add_thread (pid_to_ptid (id));
dfe7f3ac 285 /* Set the debug registers for the new thread in they are used. */
fa4ba8da
PM
286 if (debug_registers_used)
287 {
288 /* Only change the value of the debug registers. */
289 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
290 CHECK (GetThreadContext (th->h, &th->context));
291 th->context.Dr0 = dr[0];
292 th->context.Dr1 = dr[1];
293 th->context.Dr2 = dr[2];
294 th->context.Dr3 = dr[3];
295 /* th->context.Dr6 = dr[6];
296 FIXME: should we set dr6 also ?? */
297 th->context.Dr7 = dr[7];
298 CHECK (SetThreadContext (th->h, &th->context));
299 th->context.ContextFlags = 0;
300 }
3cee93ac 301 return th;
24e60978
SC
302}
303
3cee93ac
CF
304/* Clear out any old thread list and reintialize it to a
305 pristine state. */
24e60978 306static void
fba45db2 307child_init_thread_list (void)
24e60978 308{
3cee93ac
CF
309 thread_info *th = &thread_head;
310
311 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
312 init_thread_list ();
313 while (th->next != NULL)
24e60978 314 {
3cee93ac
CF
315 thread_info *here = th->next;
316 th->next = here->next;
317 (void) CloseHandle (here->h);
b8c9b27d 318 xfree (here);
24e60978 319 }
3cee93ac
CF
320}
321
322/* Delete a thread from the list of threads */
323static void
324child_delete_thread (DWORD id)
325{
326 thread_info *th;
327
328 if (info_verbose)
39f77062
KB
329 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
330 delete_thread (pid_to_ptid (id));
3cee93ac
CF
331
332 for (th = &thread_head;
333 th->next != NULL && th->next->id != id;
334 th = th->next)
335 continue;
336
337 if (th->next != NULL)
24e60978 338 {
3cee93ac
CF
339 thread_info *here = th->next;
340 th->next = here->next;
341 CloseHandle (here->h);
b8c9b27d 342 xfree (here);
24e60978
SC
343 }
344}
345
3cee93ac
CF
346static void
347do_child_fetch_inferior_registers (int r)
24e60978 348{
1e37c281
JM
349 char *context_offset = ((char *) &current_thread->context) + mappings[r];
350 long l;
6c7de422
MK
351
352#define I387_ST0_REGNUM I386_ST0_REGNUM
353
354 if (r == I387_FISEG_REGNUM)
1e37c281 355 {
8e860359 356 l = *((long *) context_offset) & 0xffff;
1e37c281
JM
357 supply_register (r, (char *) &l);
358 }
6c7de422 359 else if (r == I387_FOP_REGNUM)
1e37c281 360 {
8e860359 361 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
1e37c281
JM
362 supply_register (r, (char *) &l);
363 }
364 else if (r >= 0)
d3a09475 365 supply_register (r, context_offset);
3cee93ac 366 else
24e60978
SC
367 {
368 for (r = 0; r < NUM_REGS; r++)
3cee93ac 369 do_child_fetch_inferior_registers (r);
24e60978 370 }
6c7de422
MK
371
372#undef I387_ST0_REGNUM
3cee93ac
CF
373}
374
375static void
376child_fetch_inferior_registers (int r)
377{
39f77062 378 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
3cee93ac
CF
379 do_child_fetch_inferior_registers (r);
380}
381
382static void
383do_child_store_inferior_registers (int r)
384{
385 if (r >= 0)
baa93fa6 386 regcache_collect (r, ((char *) &current_thread->context) + mappings[r]);
24e60978
SC
387 else
388 {
3cee93ac
CF
389 for (r = 0; r < NUM_REGS; r++)
390 do_child_store_inferior_registers (r);
24e60978
SC
391 }
392}
393
3cee93ac
CF
394/* Store a new register value into the current thread context */
395static void
396child_store_inferior_registers (int r)
397{
39f77062 398 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
3cee93ac
CF
399 do_child_store_inferior_registers (r);
400}
24e60978 401
1e37c281
JM
402static int psapi_loaded = 0;
403static HMODULE psapi_module_handle = NULL;
8e860359
CF
404static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
405static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
406static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
1e37c281 407
3bccec63 408int
8e860359 409psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1e37c281
JM
410{
411 DWORD len;
412 MODULEINFO mi;
413 int i;
8e860359
CF
414 HMODULE dh_buf[1];
415 HMODULE *DllHandle = dh_buf;
1e37c281
JM
416 DWORD cbNeeded;
417 BOOL ok;
418
419 if (!psapi_loaded ||
8e860359
CF
420 psapi_EnumProcessModules == NULL ||
421 psapi_GetModuleInformation == NULL ||
422 psapi_GetModuleFileNameExA == NULL)
1e37c281 423 {
8e860359
CF
424 if (psapi_loaded)
425 goto failed;
1e37c281
JM
426 psapi_loaded = 1;
427 psapi_module_handle = LoadLibrary ("psapi.dll");
428 if (!psapi_module_handle)
8e860359
CF
429 {
430 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
431 goto failed;
432 }
433 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
1e37c281
JM
434 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
435 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
8e860359
CF
436 "GetModuleFileNameExA");
437 if (psapi_EnumProcessModules == NULL ||
438 psapi_GetModuleInformation == NULL ||
439 psapi_GetModuleFileNameExA == NULL)
1e37c281
JM
440 goto failed;
441 }
442
443 cbNeeded = 0;
444 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
445 DllHandle,
446 sizeof (HMODULE),
447 &cbNeeded);
1e37c281
JM
448
449 if (!ok || !cbNeeded)
450 goto failed;
451
8e860359 452 DllHandle = (HMODULE *) alloca (cbNeeded);
1e37c281
JM
453 if (!DllHandle)
454 goto failed;
455
456 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
457 DllHandle,
458 cbNeeded,
459 &cbNeeded);
1e37c281
JM
460 if (!ok)
461 goto failed;
462
29fe111d 463 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
1e37c281
JM
464 {
465 if (!(*psapi_GetModuleInformation) (current_process_handle,
8e860359
CF
466 DllHandle[i],
467 &mi,
468 sizeof (mi)))
1e37c281
JM
469 error ("Can't get module info");
470
471 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
8e860359
CF
472 DllHandle[i],
473 dll_name_ret,
474 MAX_PATH);
1e37c281 475 if (len == 0)
5633f842 476 error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
1e37c281
JM
477
478 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
479 return 1;
480 }
481
482failed:
483 dll_name_ret[0] = '\0';
484 return 0;
485}
486
450005e7
CF
487/* Encapsulate the information required in a call to
488 symbol_file_add_args */
8a892701
CF
489struct safe_symbol_file_add_args
490{
491 char *name;
492 int from_tty;
493 struct section_addr_info *addrs;
494 int mainline;
495 int flags;
7c5c87c0 496 struct ui_file *err, *out;
8a892701
CF
497 struct objfile *ret;
498};
499
02e423b9
CF
500/* Maintain a linked list of "so" information. */
501struct so_stuff
502{
d3ff4a77 503 struct so_stuff *next;
02e423b9 504 DWORD load_addr;
5633f842 505 DWORD end_addr;
7470a420 506 int loaded;
d3ff4a77 507 struct objfile *objfile;
7470a420
CF
508 char name[1];
509} solib_start, *solib_end;
02e423b9 510
450005e7
CF
511/* Call symbol_file_add with stderr redirected. We don't care if there
512 are errors. */
8a892701
CF
513static int
514safe_symbol_file_add_stub (void *argv)
515{
516#define p ((struct safe_symbol_file_add_args *)argv)
fefd0a37 517 struct so_stuff *so = &solib_start;
02e423b9
CF
518
519 while ((so = so->next))
7470a420 520 if (so->loaded && strcasecmp (so->name, p->name) == 0)
02e423b9 521 return 0;
8a892701
CF
522 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
523 return !!p->ret;
524#undef p
525}
526
450005e7 527/* Restore gdb's stderr after calling symbol_file_add */
8a892701 528static void
7c5c87c0 529safe_symbol_file_add_cleanup (void *p)
8a892701 530{
8e860359 531#define sp ((struct safe_symbol_file_add_args *)p)
450005e7 532 gdb_flush (gdb_stderr);
7c5c87c0 533 gdb_flush (gdb_stdout);
d3ff4a77 534 ui_file_delete (gdb_stderr);
7c5c87c0 535 ui_file_delete (gdb_stdout);
d3ff4a77 536 gdb_stderr = sp->err;
9d3789f7 537 gdb_stdout = sp->out;
8e860359 538#undef sp
8a892701
CF
539}
540
450005e7 541/* symbol_file_add wrapper that prevents errors from being displayed. */
8a892701
CF
542static struct objfile *
543safe_symbol_file_add (char *name, int from_tty,
544 struct section_addr_info *addrs,
545 int mainline, int flags)
8a892701
CF
546{
547 struct safe_symbol_file_add_args p;
548 struct cleanup *cleanup;
549
7c5c87c0 550 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
8a892701 551
7c5c87c0
CF
552 p.err = gdb_stderr;
553 p.out = gdb_stdout;
450005e7 554 gdb_flush (gdb_stderr);
7c5c87c0 555 gdb_flush (gdb_stdout);
d3ff4a77 556 gdb_stderr = ui_file_new ();
7c5c87c0 557 gdb_stdout = ui_file_new ();
8a892701
CF
558 p.name = name;
559 p.from_tty = from_tty;
560 p.addrs = addrs;
561 p.mainline = mainline;
562 p.flags = flags;
563 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
564
565 do_cleanups (cleanup);
566 return p.ret;
567}
568
450005e7
CF
569/* Remember the maximum DLL length for printing in info dll command. */
570int max_dll_name_len;
571
8e860359
CF
572static void
573register_loaded_dll (const char *name, DWORD load_addr)
574{
575 struct so_stuff *so;
7470a420 576 char ppath[MAX_PATH + 1];
3f8ad85b
CF
577 char buf[MAX_PATH + 1];
578 char cwd[MAX_PATH + 1];
579 char *p;
580 WIN32_FIND_DATA w32_fd;
581 HANDLE h = FindFirstFile(name, &w32_fd);
5633f842 582 MEMORY_BASIC_INFORMATION m;
3f8ad85b
CF
583 size_t len;
584
6badb179
CF
585 if (h == INVALID_HANDLE_VALUE)
586 strcpy (buf, name);
587 else
3f8ad85b 588 {
c914e0cc
CF
589 FindClose (h);
590 strcpy (buf, name);
591 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
592 {
593 p = strrchr (buf, '\\');
594 if (p)
595 p[1] = '\0';
596 SetCurrentDirectory (buf);
597 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
598 SetCurrentDirectory (cwd);
599 }
3f8ad85b
CF
600 }
601
602 cygwin_conv_to_posix_path (buf, ppath);
7470a420
CF
603 so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
604 so->loaded = 0;
8e860359 605 so->load_addr = load_addr;
e325dcec
CF
606 if (VirtualQueryEx (current_process_handle, (void *) load_addr, &m,
607 sizeof (m)))
5633f842
CF
608 so->end_addr = (DWORD) m.AllocationBase + m.RegionSize;
609 else
610 so->end_addr = load_addr + 0x2000; /* completely arbitrary */
611
d3ff4a77
CF
612 so->next = NULL;
613 so->objfile = NULL;
7470a420 614 strcpy (so->name, ppath);
8e860359
CF
615
616 solib_end->next = so;
617 solib_end = so;
3f8ad85b
CF
618 len = strlen (ppath);
619 if (len > max_dll_name_len)
620 max_dll_name_len = len;
8e860359
CF
621}
622
dfe7f3ac
CF
623char *
624get_image_name (HANDLE h, void *address, int unicode)
625{
626 static char buf[(2 * MAX_PATH) + 1];
627 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
628 char *address_ptr;
629 int len = 0;
630 char b[2];
631 DWORD done;
632
633 /* Attempt to read the name of the dll that was detected.
634 This is documented to work only when actively debugging
635 a program. It will not work for attached processes. */
636 if (address == NULL)
637 return NULL;
638
dfe7f3ac
CF
639 /* See if we could read the address of a string, and that the
640 address isn't null. */
9f476a01 641 if (!ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done)
6f17862b 642 || done != sizeof (address_ptr) || !address_ptr)
dfe7f3ac
CF
643 return NULL;
644
645 /* Find the length of the string */
6f17862b
CF
646 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
647 && (b[0] != 0 || b[size - 1] != 0) && done == size)
648 continue;
dfe7f3ac
CF
649
650 if (!unicode)
651 ReadProcessMemory (h, address_ptr, buf, len, &done);
652 else
653 {
654 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
655 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
656 &done);
657
658 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
659 }
660
661 return buf;
662}
663
24e60978
SC
664/* Wait for child to do something. Return pid of child, or -1 in case
665 of error; store status through argument pointer OURSTATUS. */
1750a5ef 666static int
0a65a603 667handle_load_dll (void *dummy)
24e60978 668{
3a4b77d8 669 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
3cee93ac 670 char dll_buf[MAX_PATH + 1];
450005e7 671 char *dll_name = NULL;
450005e7 672 char *p;
3cee93ac 673
3a4b77d8 674 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
3cee93ac 675
1e37c281 676 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
8e860359 677 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
3cee93ac 678
1e37c281 679 dll_name = dll_buf;
24e60978 680
dfe7f3ac
CF
681 if (*dll_name == '\0')
682 dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
3cee93ac
CF
683 if (!dll_name)
684 return 1;
685
8e860359 686 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
450005e7
CF
687
688 return 1;
689}
690
d3ff4a77 691static int
0a65a603 692handle_unload_dll (void *dummy)
d3ff4a77
CF
693{
694 DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
695 struct so_stuff *so;
696
697 for (so = &solib_start; so->next != NULL; so = so->next)
698 if (so->next->load_addr == lpBaseOfDll)
699 {
700 struct so_stuff *sodel = so->next;
701 so->next = sodel->next;
702 if (!so->next)
703 solib_end = so;
704 if (sodel->objfile)
705 free_objfile (sodel->objfile);
706 xfree(sodel);
707 return 1;
708 }
709 error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll);
710
711 return 0;
712}
713
5633f842
CF
714char *
715solib_address (CORE_ADDR address)
716{
717 struct so_stuff *so;
718 for (so = &solib_start; so->next != NULL; so = so->next)
719 if (address >= so->load_addr && address <= so->end_addr)
720 return so->name;
721 return NULL;
722}
723
450005e7
CF
724/* Return name of last loaded DLL. */
725char *
0a65a603 726child_solib_loaded_library_pathname (int pid)
450005e7 727{
8e860359 728 return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
450005e7
CF
729}
730
731/* Clear list of loaded DLLs. */
732void
733child_clear_solibs (void)
734{
735 struct so_stuff *so, *so1 = solib_start.next;
736
737 while ((so = so1) != NULL)
738 {
739 so1 = so->next;
b8c9b27d 740 xfree (so);
450005e7
CF
741 }
742
743 solib_start.next = NULL;
d3ff4a77 744 solib_start.objfile = NULL;
450005e7
CF
745 solib_end = &solib_start;
746 max_dll_name_len = sizeof ("DLL Name") - 1;
747}
295732ea 748
786b8124
CF
749/* Get the loaded address of all sections, given that .text was loaded
750 at text_load. Assumes that all sections are subject to the same
751 relocation offset. Returns NULL if problems occur or if the
752 sections were not relocated. */
753
754static struct section_addr_info *
755get_relocated_section_addrs (bfd *abfd, CORE_ADDR text_load)
756{
757 struct section_addr_info *result = NULL;
758 int section_count = bfd_count_sections (abfd);
759 asection *text_section = bfd_get_section_by_name (abfd, ".text");
760 CORE_ADDR text_vma;
761
762 if (!text_section)
763 {
764 /* Couldn't get the .text section. Weird. */
765 }
766
767 else if (text_load == (text_vma = bfd_get_section_vma (abfd, text_section)))
768 {
769 /* DLL wasn't relocated. */
770 }
771
772 else
773 {
774 /* Figure out all sections' loaded addresses. The offset here is
775 such that taking a bfd_get_section_vma() result and adding
776 offset will give the real load address of the section. */
450005e7 777
786b8124
CF
778 CORE_ADDR offset = text_load - text_vma;
779
780 struct section_table *table_start = NULL;
781 struct section_table *table_end = NULL;
782 struct section_table *iter = NULL;
783
784 build_section_table (abfd, &table_start, &table_end);
785
786 for (iter = table_start; iter < table_end; ++iter)
787 {
788 /* Relocated addresses. */
789 iter->addr += offset;
790 iter->endaddr += offset;
791 }
792
793 result = build_section_addr_info_from_section_table (table_start,
794 table_end);
795
796 xfree (table_start);
797 }
798
799 return result;
800}
295732ea 801
450005e7 802/* Add DLL symbol information. */
d3ff4a77 803static struct objfile *
02e423b9 804solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
450005e7 805{
9f476a01 806 struct section_addr_info *addrs = NULL;
786b8124
CF
807 static struct objfile *result = NULL;
808 bfd *abfd = NULL;
450005e7 809
3cee93ac
CF
810 /* The symbols in a dll are offset by 0x1000, which is the
811 the offset from 0 of the first byte in an image - because
8a892701 812 of the file header and the section alignment. */
3cee93ac 813
8e860359 814 if (!name || !name[0])
d3ff4a77 815 return NULL;
450005e7 816
786b8124
CF
817 abfd = bfd_openr (name, "pei-i386");
818
819 if (!abfd)
820 {
821 /* pei failed - try pe */
822 abfd = bfd_openr (name, "pe-i386");
823 }
824
825 if (abfd)
826 {
827 if (bfd_check_format (abfd, bfd_object))
828 {
9f476a01 829 addrs = get_relocated_section_addrs (abfd, load_addr);
786b8124
CF
830 }
831
832 bfd_close (abfd);
833 }
834
9f476a01 835 if (addrs)
786b8124 836 {
9f476a01
CF
837 result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED);
838 free_section_addr_info (addrs);
786b8124 839 }
786b8124
CF
840 else
841 {
842 /* Fallback on handling just the .text section. */
a39a16c4 843 struct cleanup *my_cleanups;
786b8124 844
9f476a01
CF
845 addrs = alloc_section_addr_info (1);
846 my_cleanups = make_cleanup (xfree, addrs);
847 addrs->other[0].name = ".text";
848 addrs->other[0].addr = load_addr;
786b8124 849
9f476a01 850 result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED);
a39a16c4 851 do_cleanups (my_cleanups);
786b8124
CF
852 }
853
854 return result;
450005e7
CF
855}
856
857/* Load DLL symbol info. */
858void
7470a420 859dll_symbol_command (char *args, int from_tty)
450005e7 860{
8e860359 861 int n;
450005e7 862 dont_repeat ();
8e860359 863
450005e7
CF
864 if (args == NULL)
865 error ("dll-symbols requires a file name");
866
8e860359
CF
867 n = strlen (args);
868 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
869 {
870 char *newargs = (char *) alloca (n + 4 + 1);
871 strcpy (newargs, args);
872 strcat (newargs, ".dll");
873 args = newargs;
874 }
875
7470a420 876 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
8e860359 877}
450005e7
CF
878
879/* List currently loaded DLLs. */
880void
0a65a603 881info_dll_command (char *ignore, int from_tty)
450005e7
CF
882{
883 struct so_stuff *so = &solib_start;
884
885 if (!so->next)
886 return;
887
dfe7f3ac 888 printf_filtered ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
450005e7 889 while ((so = so->next) != NULL)
7c5c87c0 890 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
450005e7
CF
891
892 return;
24e60978
SC
893}
894
3cee93ac
CF
895/* Handle DEBUG_STRING output from child process.
896 Cygwin prepends its messages with a "cygwin:". Interpret this as
897 a Cygwin signal. Otherwise just print the string as a warning. */
898static int
899handle_output_debug_string (struct target_waitstatus *ourstatus)
900{
901 char *s;
902 int gotasig = FALSE;
903
904 if (!target_read_string
3a4b77d8 905 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
3cee93ac
CF
906 || !s || !*s)
907 return gotasig;
908
d3a09475 909 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
3cee93ac 910 {
d3a09475 911 if (strncmp (s, "cYg", 3) != 0)
29fe111d 912 warning ("%s", s);
3cee93ac 913 }
d3a09475 914 else
3cee93ac
CF
915 {
916 char *p;
1e37c281
JM
917 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
918 gotasig = target_signal_from_host (sig);
0714f9bf
SS
919 ourstatus->value.sig = gotasig;
920 if (gotasig)
3cee93ac
CF
921 ourstatus->kind = TARGET_WAITKIND_STOPPED;
922 }
923
b8c9b27d 924 xfree (s);
3cee93ac
CF
925 return gotasig;
926}
24e60978 927
c1748f97
PM
928static int
929display_selector (HANDLE thread, DWORD sel)
930{
931 LDT_ENTRY info;
932 if (GetThreadSelectorEntry (thread, sel, &info))
933 {
934 int base, limit;
935 printf_filtered ("0x%03lx: ", sel);
936 if (!info.HighWord.Bits.Pres)
baa93fa6
CF
937 {
938 puts_filtered ("Segment not present\n");
939 return 0;
940 }
c1748f97
PM
941 base = (info.HighWord.Bits.BaseHi << 24) +
942 (info.HighWord.Bits.BaseMid << 16)
943 + info.BaseLow;
944 limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
945 if (info.HighWord.Bits.Granularity)
caad7706 946 limit = (limit << 12) | 0xfff;
c1748f97
PM
947 printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
948 if (info.HighWord.Bits.Default_Big)
baa93fa6 949 puts_filtered(" 32-bit ");
c1748f97 950 else
baa93fa6 951 puts_filtered(" 16-bit ");
c1748f97
PM
952 switch ((info.HighWord.Bits.Type & 0xf) >> 1)
953 {
954 case 0:
baa93fa6
CF
955 puts_filtered ("Data (Read-Only, Exp-up");
956 break;
c1748f97 957 case 1:
baa93fa6
CF
958 puts_filtered ("Data (Read/Write, Exp-up");
959 break;
c1748f97 960 case 2:
baa93fa6
CF
961 puts_filtered ("Unused segment (");
962 break;
c1748f97 963 case 3:
baa93fa6
CF
964 puts_filtered ("Data (Read/Write, Exp-down");
965 break;
c1748f97 966 case 4:
baa93fa6
CF
967 puts_filtered ("Code (Exec-Only, N.Conf");
968 break;
c1748f97 969 case 5:
baa93fa6 970 puts_filtered ("Code (Exec/Read, N.Conf");
c1748f97
PM
971 break;
972 case 6:
baa93fa6 973 puts_filtered ("Code (Exec-Only, Conf");
c1748f97
PM
974 break;
975 case 7:
baa93fa6 976 puts_filtered ("Code (Exec/Read, Conf");
c1748f97
PM
977 break;
978 default:
979 printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
980 }
981 if ((info.HighWord.Bits.Type & 0x1) == 0)
baa93fa6 982 puts_filtered(", N.Acc");
c1748f97
PM
983 puts_filtered (")\n");
984 if ((info.HighWord.Bits.Type & 0x10) == 0)
985 puts_filtered("System selector ");
986 printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
987 if (info.HighWord.Bits.Granularity)
baa93fa6 988 puts_filtered ("Page granular.\n");
c1748f97
PM
989 else
990 puts_filtered ("Byte granular.\n");
991 return 1;
992 }
993 else
994 {
995 printf_filtered ("Invalid selector 0x%lx.\n",sel);
996 return 0;
997 }
998}
999
1000static void
1001display_selectors (char * args, int from_tty)
1002{
1003 if (!current_thread)
1004 {
1005 puts_filtered ("Impossible to display selectors now.\n");
1006 return;
1007 }
1008 if (!args)
1009 {
1010
1011 puts_filtered ("Selector $cs\n");
1012 display_selector (current_thread->h,
baa93fa6 1013 current_thread->context.SegCs);
c1748f97
PM
1014 puts_filtered ("Selector $ds\n");
1015 display_selector (current_thread->h,
baa93fa6 1016 current_thread->context.SegDs);
c1748f97
PM
1017 puts_filtered ("Selector $es\n");
1018 display_selector (current_thread->h,
baa93fa6 1019 current_thread->context.SegEs);
c1748f97
PM
1020 puts_filtered ("Selector $ss\n");
1021 display_selector (current_thread->h,
baa93fa6 1022 current_thread->context.SegSs);
c1748f97
PM
1023 puts_filtered ("Selector $fs\n");
1024 display_selector (current_thread->h,
1025 current_thread->context.SegFs);
1026 puts_filtered ("Selector $gs\n");
1027 display_selector (current_thread->h,
baa93fa6 1028 current_thread->context.SegGs);
c1748f97
PM
1029 }
1030 else
1031 {
1032 int sel;
1033 sel = parse_and_eval_long (args);
1034 printf_filtered ("Selector \"%s\"\n",args);
1035 display_selector (current_thread->h, sel);
1036 }
1037}
1038
1039static struct cmd_list_element *info_w32_cmdlist = NULL;
1040
1041static void
1042info_w32_command (char *args, int from_tty)
1043{
1044 help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
1045}
1046
1047
7393af7c 1048#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
4e52d31c 1049 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
7393af7c
PM
1050 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1051
36339ecd 1052static int
450005e7 1053handle_exception (struct target_waitstatus *ourstatus)
24e60978 1054{
3cee93ac 1055 thread_info *th;
29fe111d 1056 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
3cee93ac 1057
29fe111d 1058 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 1059
3cee93ac
CF
1060 /* Record the context of the current thread */
1061 th = thread_rec (current_event.dwThreadId, -1);
24e60978 1062
29fe111d 1063 switch (code)
24e60978 1064 {
1ef980b9 1065 case EXCEPTION_ACCESS_VIOLATION:
7393af7c
PM
1066 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1067 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1068 break;
1069 case STATUS_STACK_OVERFLOW:
1070 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1ef980b9 1071 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
7393af7c
PM
1072 break;
1073 case STATUS_FLOAT_DENORMAL_OPERAND:
1074 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1075 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1076 break;
1077 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1078 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1079 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1080 break;
1081 case STATUS_FLOAT_INEXACT_RESULT:
1082 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1083 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1084 break;
1085 case STATUS_FLOAT_INVALID_OPERATION:
1086 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1087 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1088 break;
1089 case STATUS_FLOAT_OVERFLOW:
1090 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1091 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1092 break;
1093 case STATUS_FLOAT_STACK_CHECK:
1094 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1095 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1ef980b9 1096 break;
3b7c8b74 1097 case STATUS_FLOAT_UNDERFLOW:
7393af7c
PM
1098 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1099 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1100 break;
3b7c8b74 1101 case STATUS_FLOAT_DIVIDE_BY_ZERO:
7393af7c
PM
1102 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1103 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1104 break;
3b7c8b74 1105 case STATUS_INTEGER_DIVIDE_BY_ZERO:
7393af7c 1106 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
3b7c8b74 1107 ourstatus->value.sig = TARGET_SIGNAL_FPE;
3b7c8b74 1108 break;
7393af7c
PM
1109 case STATUS_INTEGER_OVERFLOW:
1110 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1111 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1ef980b9
SC
1112 break;
1113 case EXCEPTION_BREAKPOINT:
7393af7c 1114 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1ef980b9
SC
1115 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1116 break;
1117 case DBG_CONTROL_C:
7393af7c 1118 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1ef980b9 1119 ourstatus->value.sig = TARGET_SIGNAL_INT;
5b421780
PM
1120 break;
1121 case DBG_CONTROL_BREAK:
7393af7c 1122 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
5b421780 1123 ourstatus->value.sig = TARGET_SIGNAL_INT;
1ef980b9
SC
1124 break;
1125 case EXCEPTION_SINGLE_STEP:
7393af7c 1126 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1ef980b9
SC
1127 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1128 break;
8227c82d 1129 case EXCEPTION_ILLEGAL_INSTRUCTION:
7393af7c
PM
1130 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1131 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1132 break;
1133 case EXCEPTION_PRIV_INSTRUCTION:
1134 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1135 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1136 break;
1137 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1138 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
8227c82d
CF
1139 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1140 break;
1ef980b9 1141 default:
02e423b9
CF
1142 if (current_event.u.Exception.dwFirstChance)
1143 return 0;
29fe111d 1144 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
3a4b77d8 1145 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 1146 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
24e60978 1147 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1ef980b9 1148 break;
24e60978 1149 }
24e60978 1150 exception_count++;
7393af7c 1151 last_sig = ourstatus->value.sig;
36339ecd 1152 return 1;
24e60978
SC
1153}
1154
3cee93ac
CF
1155/* Resume all artificially suspended threads if we are continuing
1156 execution */
1157static BOOL
8a892701 1158child_continue (DWORD continue_status, int id)
3cee93ac
CF
1159{
1160 int i;
1161 thread_info *th;
1162 BOOL res;
1163
7393af7c
PM
1164 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1165 current_event.dwProcessId, current_event.dwThreadId,
dfe7f3ac 1166 continue_status == DBG_CONTINUE ?
7393af7c 1167 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
0714f9bf
SS
1168 res = ContinueDebugEvent (current_event.dwProcessId,
1169 current_event.dwThreadId,
1170 continue_status);
1e37c281 1171 continue_status = 0;
0714f9bf 1172 if (res)
3a4b77d8 1173 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 1174 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
3cee93ac 1175 {
fa4ba8da 1176
3cee93ac
CF
1177 for (i = 0; i < th->suspend_count; i++)
1178 (void) ResumeThread (th->h);
1179 th->suspend_count = 0;
fa4ba8da
PM
1180 if (debug_registers_changed)
1181 {
1182 /* Only change the value of the debug reisters */
1183 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
1184 th->context.Dr0 = dr[0];
1185 th->context.Dr1 = dr[1];
1186 th->context.Dr2 = dr[2];
1187 th->context.Dr3 = dr[3];
1188 /* th->context.Dr6 = dr[6];
dfe7f3ac 1189 FIXME: should we set dr6 also ?? */
fa4ba8da
PM
1190 th->context.Dr7 = dr[7];
1191 CHECK (SetThreadContext (th->h, &th->context));
1192 th->context.ContextFlags = 0;
1193 }
3cee93ac
CF
1194 }
1195
fa4ba8da 1196 debug_registers_changed = 0;
3cee93ac
CF
1197 return res;
1198}
1199
8a892701
CF
1200/* Get the next event from the child. Return 1 if the event requires
1201 handling by WFI (or whatever).
1202 */
1e37c281 1203static int
0a65a603 1204get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
1e37c281
JM
1205{
1206 BOOL debug_event;
8a892701 1207 DWORD continue_status, event_code;
87a45c96 1208 thread_info *th;
8a892701 1209 static thread_info dummy_thread_info;
450005e7 1210 int retval = 0;
1e37c281 1211
7393af7c 1212 last_sig = TARGET_SIGNAL_0;
9d3789f7 1213
8a892701 1214 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 1215 goto out;
1e37c281
JM
1216
1217 event_count++;
1218 continue_status = DBG_CONTINUE;
1e37c281 1219
8a892701 1220 event_code = current_event.dwDebugEventCode;
450005e7 1221 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
87a45c96 1222 th = NULL;
8a892701
CF
1223
1224 switch (event_code)
1e37c281
JM
1225 {
1226 case CREATE_THREAD_DEBUG_EVENT:
1227 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
1228 (unsigned) current_event.dwProcessId,
1229 (unsigned) current_event.dwThreadId,
1230 "CREATE_THREAD_DEBUG_EVENT"));
dfe7f3ac
CF
1231 if (saw_create != 1)
1232 break;
1e37c281 1233 /* Record the existence of this thread */
8a892701
CF
1234 th = child_add_thread (current_event.dwThreadId,
1235 current_event.u.CreateThread.hThread);
1e37c281
JM
1236 if (info_verbose)
1237 printf_unfiltered ("[New %s]\n",
39f77062
KB
1238 target_pid_to_str (
1239 pid_to_ptid (current_event.dwThreadId)));
450005e7 1240 retval = current_event.dwThreadId;
1e37c281
JM
1241 break;
1242
1243 case EXIT_THREAD_DEBUG_EVENT:
1244 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1245 (unsigned) current_event.dwProcessId,
1246 (unsigned) current_event.dwThreadId,
1247 "EXIT_THREAD_DEBUG_EVENT"));
dfe7f3ac
CF
1248 if (saw_create != 1)
1249 break;
87a45c96
CF
1250 if (current_event.dwThreadId != main_thread_id)
1251 {
1252 child_delete_thread (current_event.dwThreadId);
1253 th = &dummy_thread_info;
1254 }
1e37c281
JM
1255 break;
1256
1257 case CREATE_PROCESS_DEBUG_EVENT:
1258 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1259 (unsigned) current_event.dwProcessId,
1260 (unsigned) current_event.dwThreadId,
1261 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 1262 CloseHandle (current_event.u.CreateProcessInfo.hFile);
dfe7f3ac
CF
1263 if (++saw_create != 1)
1264 {
1265 CloseHandle (current_event.u.CreateProcessInfo.hProcess);
1266 break;
1267 }
1e37c281 1268
dfe7f3ac 1269 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
87a45c96
CF
1270 if (main_thread_id)
1271 child_delete_thread (main_thread_id);
9d3789f7 1272 main_thread_id = current_event.dwThreadId;
1e37c281 1273 /* Add the main thread */
9d3789f7 1274 th = child_add_thread (main_thread_id,
8a892701 1275 current_event.u.CreateProcessInfo.hThread);
9d3789f7 1276 retval = ourstatus->value.related_pid = current_event.dwThreadId;
1e37c281
JM
1277 break;
1278
1279 case EXIT_PROCESS_DEBUG_EVENT:
1280 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1281 (unsigned) current_event.dwProcessId,
1282 (unsigned) current_event.dwThreadId,
1283 "EXIT_PROCESS_DEBUG_EVENT"));
dfe7f3ac
CF
1284 if (saw_create != 1)
1285 break;
1e37c281
JM
1286 ourstatus->kind = TARGET_WAITKIND_EXITED;
1287 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1288 CloseHandle (current_process_handle);
9d3789f7 1289 retval = main_thread_id;
8a892701 1290 break;
1e37c281
JM
1291
1292 case LOAD_DLL_DEBUG_EVENT:
1293 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1294 (unsigned) current_event.dwProcessId,
1295 (unsigned) current_event.dwThreadId,
1296 "LOAD_DLL_DEBUG_EVENT"));
700b351b 1297 CloseHandle (current_event.u.LoadDll.hFile);
dfe7f3ac
CF
1298 if (saw_create != 1)
1299 break;
8a892701 1300 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1e37c281 1301 registers_changed (); /* mark all regs invalid */
450005e7
CF
1302 ourstatus->kind = TARGET_WAITKIND_LOADED;
1303 ourstatus->value.integer = 0;
9d3789f7 1304 retval = main_thread_id;
5633f842 1305 re_enable_breakpoints_in_shlibs ();
1e37c281
JM
1306 break;
1307
1308 case UNLOAD_DLL_DEBUG_EVENT:
1309 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1310 (unsigned) current_event.dwProcessId,
1311 (unsigned) current_event.dwThreadId,
1312 "UNLOAD_DLL_DEBUG_EVENT"));
dfe7f3ac
CF
1313 if (saw_create != 1)
1314 break;
d3ff4a77
CF
1315 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1316 registers_changed (); /* mark all regs invalid */
1317 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
3bccec63 1318 does not exist yet. */
d3ff4a77 1319 break;
1e37c281
JM
1320
1321 case EXCEPTION_DEBUG_EVENT:
1322 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1323 (unsigned) current_event.dwProcessId,
1324 (unsigned) current_event.dwThreadId,
1325 "EXCEPTION_DEBUG_EVENT"));
dfe7f3ac
CF
1326 if (saw_create != 1)
1327 break;
02e423b9
CF
1328 if (handle_exception (ourstatus))
1329 retval = current_event.dwThreadId;
1e37c281
JM
1330 break;
1331
8a892701 1332 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1e37c281 1333 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1334 (unsigned) current_event.dwProcessId,
1335 (unsigned) current_event.dwThreadId,
1336 "OUTPUT_DEBUG_STRING_EVENT"));
dfe7f3ac
CF
1337 if (saw_create != 1)
1338 break;
8e860359 1339 if (handle_output_debug_string (ourstatus))
9d3789f7 1340 retval = main_thread_id;
1e37c281 1341 break;
9d3789f7 1342
1e37c281 1343 default:
dfe7f3ac
CF
1344 if (saw_create != 1)
1345 break;
29fe111d
CF
1346 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1347 (DWORD) current_event.dwProcessId,
1348 (DWORD) current_event.dwThreadId);
1349 printf_unfiltered (" unknown event code %ld\n",
1e37c281
JM
1350 current_event.dwDebugEventCode);
1351 break;
1352 }
1353
dfe7f3ac 1354 if (!retval || saw_create != 1)
8a892701 1355 CHECK (child_continue (continue_status, -1));
450005e7 1356 else
9d3789f7 1357 {
8e860359 1358 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
39f77062 1359 inferior_ptid = pid_to_ptid (retval);
9d3789f7 1360 }
1e37c281
JM
1361
1362out:
450005e7 1363 return retval;
1e37c281
JM
1364}
1365
1e37c281 1366/* Wait for interesting events to occur in the target process. */
39f77062
KB
1367static ptid_t
1368child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
24e60978 1369{
39f77062
KB
1370 int pid = PIDGET (ptid);
1371
24e60978
SC
1372 /* We loop when we get a non-standard exception rather than return
1373 with a SPURIOUS because resume can try and step or modify things,
3cee93ac 1374 which needs a current_thread->h. But some of these exceptions mark
24e60978
SC
1375 the birth or death of threads, which mean that the current thread
1376 isn't necessarily what you think it is. */
1377
1378 while (1)
450005e7
CF
1379 {
1380 int retval = get_child_debug_event (pid, ourstatus);
1381 if (retval)
39f77062 1382 return pid_to_ptid (retval);
450005e7
CF
1383 else
1384 {
1385 int detach = 0;
3cee93ac 1386
450005e7
CF
1387 if (ui_loop_hook != NULL)
1388 detach = ui_loop_hook (0);
0714f9bf 1389
450005e7
CF
1390 if (detach)
1391 child_kill_inferior ();
1392 }
1393 }
24e60978
SC
1394}
1395
9d3789f7
CF
1396static void
1397do_initial_child_stuff (DWORD pid)
1398{
1399 extern int stop_after_trap;
fa4ba8da 1400 int i;
9d3789f7 1401
7393af7c 1402 last_sig = TARGET_SIGNAL_0;
9d3789f7
CF
1403 event_count = 0;
1404 exception_count = 0;
fa4ba8da 1405 debug_registers_changed = 0;
dfe7f3ac 1406 debug_registers_used = 0;
fa4ba8da
PM
1407 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1408 dr[i] = 0;
9d3789f7
CF
1409 current_event.dwProcessId = pid;
1410 memset (&current_event, 0, sizeof (current_event));
1411 push_target (&child_ops);
1412 child_init_thread_list ();
5633f842 1413 disable_breakpoints_in_shlibs (1);
9d3789f7
CF
1414 child_clear_solibs ();
1415 clear_proceed_status ();
1416 init_wait_for_inferior ();
1417
1418 target_terminal_init ();
1419 target_terminal_inferior ();
1420
1421 while (1)
1422 {
1423 stop_after_trap = 1;
1424 wait_for_inferior ();
1425 if (stop_signal != TARGET_SIGNAL_TRAP)
1426 resume (0, stop_signal);
1427 else
1428 break;
1429 }
1430 stop_after_trap = 0;
1431 return;
1432}
1433
02cc9f49
CV
1434/* Since Windows XP, detaching from a process is supported by Windows.
1435 The following code tries loading the appropriate functions dynamically.
1436 If loading these functions succeeds use them to actually detach from
1437 the inferior process, otherwise behave as usual, pretending that
1438 detach has worked. */
1439static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1440static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1441
1442static int
5ae5f592 1443has_detach_ability (void)
02cc9f49
CV
1444{
1445 static HMODULE kernel32 = NULL;
1446
1447 if (!kernel32)
1448 kernel32 = LoadLibrary ("kernel32.dll");
1449 if (kernel32)
1450 {
1451 if (!DebugSetProcessKillOnExit)
1452 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1453 "DebugSetProcessKillOnExit");
1454 if (!DebugActiveProcessStop)
1455 DebugActiveProcessStop = GetProcAddress (kernel32,
1456 "DebugActiveProcessStop");
1457 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1458 return 1;
1459 }
1460 return 0;
1461}
24e60978 1462
616a9dc4
CV
1463/* Try to set or remove a user privilege to the current process. Return -1
1464 if that fails, the previous setting of that privilege otherwise.
1465
1466 This code is copied from the Cygwin source code and rearranged to allow
1467 dynamically loading of the needed symbols from advapi32 which is only
1468 available on NT/2K/XP. */
1469static int
1470set_process_privilege (const char *privilege, BOOL enable)
1471{
1472 static HMODULE advapi32 = NULL;
1473 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
1474 static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
1475 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
1476 DWORD, PTOKEN_PRIVILEGES, PDWORD);
1477
1478 HANDLE token_hdl = NULL;
1479 LUID restore_priv;
1480 TOKEN_PRIVILEGES new_priv, orig_priv;
1481 int ret = -1;
1482 DWORD size;
1483
1484 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1485 return 0;
1486
1487 if (!advapi32)
1488 {
1489 if (!(advapi32 = LoadLibrary ("advapi32.dll")))
1490 goto out;
1491 if (!OpenProcessToken)
1492 OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
1493 if (!LookupPrivilegeValue)
1494 LookupPrivilegeValue = GetProcAddress (advapi32,
1495 "LookupPrivilegeValueA");
1496 if (!AdjustTokenPrivileges)
1497 AdjustTokenPrivileges = GetProcAddress (advapi32,
1498 "AdjustTokenPrivileges");
1499 if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
295732ea 1500 {
616a9dc4
CV
1501 advapi32 = NULL;
1502 goto out;
1503 }
1504 }
295732ea 1505
616a9dc4
CV
1506 if (!OpenProcessToken (GetCurrentProcess (),
1507 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1508 &token_hdl))
1509 goto out;
1510
1511 if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
1512 goto out;
1513
1514 new_priv.PrivilegeCount = 1;
1515 new_priv.Privileges[0].Luid = restore_priv;
1516 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1517
1518 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
295732ea 1519 sizeof orig_priv, &orig_priv, &size))
616a9dc4
CV
1520 goto out;
1521#if 0
1522 /* Disabled, otherwise every `attach' in an unprivileged user session
1523 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1524 child_attach(). */
1525 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1526 be enabled. GetLastError () returns an correct error code, though. */
1527 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1528 goto out;
1529#endif
1530
1531 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1532
1533out:
1534 if (token_hdl)
1535 CloseHandle (token_hdl);
1536
1537 return ret;
1538}
1539
02cc9f49 1540/* Attach to process PID, then initialize for debugging it. */
24e60978 1541static void
fba45db2 1542child_attach (char *args, int from_tty)
24e60978
SC
1543{
1544 BOOL ok;
559e75c0 1545 DWORD pid;
24e60978
SC
1546
1547 if (!args)
1548 error_no_arg ("process-id to attach");
1549
616a9dc4
CV
1550 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1551 {
1552 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1553 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1554 }
1555
baa93fa6
CF
1556 pid = strtoul (args, 0, 0); /* Windows pid */
1557
9d3789f7 1558 ok = DebugActiveProcess (pid);
91a175b3 1559 saw_create = 0;
24e60978
SC
1560
1561 if (!ok)
baa93fa6
CF
1562 {
1563 /* Try fall back to Cygwin pid */
1564 pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1565
1566 if (pid > 0)
1567 ok = DebugActiveProcess (pid);
1568
1569 if (!ok)
caad7706 1570 error ("Can't attach to process.");
baa93fa6 1571 }
24e60978 1572
02cc9f49
CV
1573 if (has_detach_ability ())
1574 {
1575 attach_flag = 1;
1576 DebugSetProcessKillOnExit (FALSE);
1577 }
1578
24e60978
SC
1579 if (from_tty)
1580 {
1581 char *exec_file = (char *) get_exec_file (0);
1582
1583 if (exec_file)
1584 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1585 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1586 else
1587 printf_unfiltered ("Attaching to %s\n",
39f77062 1588 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1589
1590 gdb_flush (gdb_stdout);
1591 }
1592
9d3789f7
CF
1593 do_initial_child_stuff (pid);
1594 target_terminal_ours ();
24e60978
SC
1595}
1596
24e60978 1597static void
0a65a603 1598child_detach (char *args, int from_tty)
24e60978 1599{
02cc9f49
CV
1600 int detached = 1;
1601
1602 if (has_detach_ability ())
1603 {
1604 delete_command (NULL, 0);
1605 child_continue (DBG_CONTINUE, -1);
1606 if (!DebugActiveProcessStop (current_event.dwProcessId))
3bccec63 1607 {
02cc9f49
CV
1608 error ("Can't detach process %lu (error %lu)",
1609 current_event.dwProcessId, GetLastError ());
1610 detached = 0;
3bccec63 1611 }
02cc9f49
CV
1612 DebugSetProcessKillOnExit (FALSE);
1613 }
1614 if (detached && from_tty)
24e60978
SC
1615 {
1616 char *exec_file = get_exec_file (0);
1617 if (exec_file == 0)
1618 exec_file = "";
02cc9f49
CV
1619 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1620 current_event.dwProcessId);
24e60978
SC
1621 gdb_flush (gdb_stdout);
1622 }
39f77062 1623 inferior_ptid = null_ptid;
24e60978
SC
1624 unpush_target (&child_ops);
1625}
1626
24e60978
SC
1627/* Print status information about what we're accessing. */
1628
1629static void
0a65a603 1630child_files_info (struct target_ops *ignore)
24e60978
SC
1631{
1632 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1633 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
24e60978
SC
1634}
1635
24e60978 1636static void
0a65a603 1637child_open (char *arg, int from_tty)
24e60978
SC
1638{
1639 error ("Use the \"run\" command to start a Unix child process.");
1640}
1641
39f77062 1642/* Start an inferior win32 child process and sets inferior_ptid to its pid.
24e60978
SC
1643 EXEC_FILE is the file to run.
1644 ALLARGS is a string containing the arguments to the program.
1645 ENV is the environment vector to pass. Errors reported with error(). */
1646
24e60978 1647static void
fba45db2 1648child_create_inferior (char *exec_file, char *allargs, char **env)
24e60978 1649{
1750a5ef
SC
1650 char *winenv;
1651 char *temp;
3a4b77d8 1652 int envlen;
1750a5ef 1653 int i;
24e60978
SC
1654 STARTUPINFO si;
1655 PROCESS_INFORMATION pi;
24e60978
SC
1656 BOOL ret;
1657 DWORD flags;
eb708f2e 1658 char *args;
dfe7f3ac
CF
1659 char real_path[MAXPATHLEN];
1660 char *toexec;
349b409f
CF
1661 char shell[MAX_PATH + 1]; /* Path to shell */
1662 const char *sh;
2becadee
CF
1663 int tty;
1664 int ostdin, ostdout, ostderr;
24e60978
SC
1665
1666 if (!exec_file)
450005e7 1667 error ("No executable specified, use `target exec'.\n");
24e60978
SC
1668
1669 memset (&si, 0, sizeof (si));
1670 si.cb = sizeof (si);
1671
349b409f 1672 if (!useshell)
dfe7f3ac
CF
1673 {
1674 flags = DEBUG_ONLY_THIS_PROCESS;
1675 cygwin_conv_to_win32_path (exec_file, real_path);
1676 toexec = real_path;
1677 }
1678 else
1679 {
349b409f
CF
1680 char *newallargs;
1681 sh = getenv ("SHELL");
1682 if (!sh)
1683 sh = "/bin/sh";
1684 cygwin_conv_to_win32_path (sh, shell);
1685 newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
1686 + strlen (allargs) + 2);
dfe7f3ac
CF
1687 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1688 allargs = newallargs;
1689 toexec = shell;
1690 flags = DEBUG_PROCESS;
1691 }
eb708f2e 1692
eeb25b8a
PM
1693 if (new_group)
1694 flags |= CREATE_NEW_PROCESS_GROUP;
1695
1696 if (new_console)
1697 flags |= CREATE_NEW_CONSOLE;
1698
dfe7f3ac
CF
1699 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1700 strcpy (args, toexec);
eb708f2e
SC
1701 strcat (args, " ");
1702 strcat (args, allargs);
1703
e88c49c3
DE
1704 /* Prepare the environment vars for CreateProcess. */
1705 {
349b409f 1706 /* This code used to assume all env vars were file names and would
e88c49c3 1707 translate them all to win32 style. That obviously doesn't work in the
2dcfc9c7
DE
1708 general case. The current rule is that we only translate PATH.
1709 We need to handle PATH because we're about to call CreateProcess and
1710 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1711 in both posix and win32 environments. cygwin.dll will change it back
1712 to posix style if necessary. */
e88c49c3
DE
1713
1714 static const char *conv_path_names[] =
3a4b77d8
JM
1715 {
1716 "PATH=",
1717 0
1718 };
e88c49c3
DE
1719
1720 /* CreateProcess takes the environment list as a null terminated set of
1721 strings (i.e. two nulls terminate the list). */
1722
1723 /* Get total size for env strings. */
1724 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1725 {
2dcfc9c7 1726 int j, len;
e88c49c3 1727
2dcfc9c7
DE
1728 for (j = 0; conv_path_names[j]; j++)
1729 {
1730 len = strlen (conv_path_names[j]);
1731 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1732 {
29fe111d 1733 if (cygwin_posix_path_list_p (env[i] + len))
2dcfc9c7 1734 envlen += len
29fe111d 1735 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
2dcfc9c7
DE
1736 else
1737 envlen += strlen (env[i]) + 1;
1738 break;
e88c49c3 1739 }
e88c49c3 1740 }
2dcfc9c7 1741 if (conv_path_names[j] == NULL)
e88c49c3
DE
1742 envlen += strlen (env[i]) + 1;
1743 }
1744
1745 winenv = alloca (envlen + 1);
1746
1747 /* Copy env strings into new buffer. */
3cee93ac 1748 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
e88c49c3 1749 {
2dcfc9c7 1750 int j, len;
e88c49c3 1751
2dcfc9c7
DE
1752 for (j = 0; conv_path_names[j]; j++)
1753 {
1754 len = strlen (conv_path_names[j]);
1755 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1756 {
29fe111d 1757 if (cygwin_posix_path_list_p (env[i] + len))
e88c49c3
DE
1758 {
1759 memcpy (temp, env[i], len);
29fe111d 1760 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
e88c49c3 1761 }
2dcfc9c7
DE
1762 else
1763 strcpy (temp, env[i]);
1764 break;
e88c49c3 1765 }
e88c49c3 1766 }
2dcfc9c7 1767 if (conv_path_names[j] == NULL)
e88c49c3 1768 strcpy (temp, env[i]);
2dcfc9c7 1769
e88c49c3
DE
1770 temp += strlen (temp) + 1;
1771 }
1772
1773 /* Final nil string to terminate new env. */
1774 *temp = 0;
1775 }
1750a5ef 1776
2becadee
CF
1777 if (!inferior_io_terminal)
1778 tty = ostdin = ostdout = ostderr = -1;
1779 else
1780 {
1781 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
1782 if (tty < 0)
1783 {
1784 print_sys_errmsg (inferior_io_terminal, errno);
1785 ostdin = ostdout = ostderr = -1;
1786 }
1787 else
1788 {
1789 ostdin = dup (0);
1790 ostdout = dup (1);
1791 ostderr = dup (2);
1792 dup2 (tty, 0);
1793 dup2 (tty, 1);
1794 dup2 (tty, 2);
1795 }
1796 }
1797
1750a5ef 1798 ret = CreateProcess (0,
3a4b77d8 1799 args, /* command line */
24e60978
SC
1800 NULL, /* Security */
1801 NULL, /* thread */
1802 TRUE, /* inherit handles */
1803 flags, /* start flags */
1750a5ef 1804 winenv,
24e60978
SC
1805 NULL, /* current directory */
1806 &si,
1807 &pi);
2becadee
CF
1808 if (tty >= 0)
1809 {
1810 close (tty);
1811 dup2 (ostdin, 0);
1812 dup2 (ostdout, 1);
1813 dup2 (ostderr, 2);
1814 close (ostdin);
1815 close (ostdout);
1816 close (ostderr);
1817 }
1818
24e60978 1819 if (!ret)
5633f842 1820 error ("Error creating process %s, (error %d)\n", exec_file, (unsigned) GetLastError ());
24e60978 1821
700b351b
CF
1822 CloseHandle (pi.hThread);
1823 CloseHandle (pi.hProcess);
dfe7f3ac
CF
1824
1825 if (useshell && shell[0] != '\0')
1826 saw_create = -1;
1827 else
1828 saw_create = 0;
1829
9d3789f7 1830 do_initial_child_stuff (pi.dwProcessId);
d3a09475 1831
8e860359 1832 /* child_continue (DBG_CONTINUE, -1); */
1e37c281 1833 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
24e60978
SC
1834}
1835
1836static void
fba45db2 1837child_mourn_inferior (void)
24e60978 1838{
8a892701 1839 (void) child_continue (DBG_CONTINUE, -1);
fa4ba8da 1840 i386_cleanup_dregs();
24e60978
SC
1841 unpush_target (&child_ops);
1842 generic_mourn_inferior ();
1843}
1844
24e60978
SC
1845/* Send a SIGINT to the process group. This acts just like the user typed a
1846 ^C on the controlling terminal. */
1847
b607efe7 1848static void
fba45db2 1849child_stop (void)
24e60978 1850{
1ef980b9 1851 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1e37c281 1852 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
3a4b77d8 1853 registers_changed (); /* refresh register state */
24e60978
SC
1854}
1855
1856int
eb708f2e 1857child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
0a65a603
AC
1858 int write, struct mem_attrib *mem,
1859 struct target_ops *target)
24e60978 1860{
6f17862b 1861 DWORD done = 0;
24e60978
SC
1862 if (write)
1863 {
29fe111d
CF
1864 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1865 len, (DWORD) memaddr));
6f17862b
CF
1866 if (!WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1867 len, &done))
1868 done = 0;
3cee93ac 1869 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
24e60978
SC
1870 }
1871 else
1872 {
29fe111d
CF
1873 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1874 len, (DWORD) memaddr));
6f17862b
CF
1875 if (!ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our,
1876 len, &done))
1877 done = 0;
24e60978
SC
1878 }
1879 return done;
1880}
1881
1882void
1883child_kill_inferior (void)
1884{
3cee93ac
CF
1885 CHECK (TerminateProcess (current_process_handle, 0));
1886
b5edcb45
ILT
1887 for (;;)
1888 {
8a892701 1889 if (!child_continue (DBG_CONTINUE, -1))
b5edcb45 1890 break;
3cee93ac 1891 if (!WaitForDebugEvent (&current_event, INFINITE))
b5edcb45 1892 break;
3cee93ac 1893 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
b5edcb45
ILT
1894 break;
1895 }
1896
3cee93ac
CF
1897 CHECK (CloseHandle (current_process_handle));
1898
1899 /* this may fail in an attached process so don't check. */
1900 (void) CloseHandle (current_thread->h);
3a4b77d8 1901 target_mourn_inferior (); /* or just child_mourn_inferior? */
24e60978
SC
1902}
1903
1904void
39f77062 1905child_resume (ptid_t ptid, int step, enum target_signal sig)
24e60978 1906{
3cee93ac 1907 thread_info *th;
7393af7c
PM
1908 DWORD continue_status = DBG_CONTINUE;
1909
39f77062 1910 int pid = PIDGET (ptid);
8a892701 1911
7393af7c
PM
1912 if (sig != TARGET_SIGNAL_0)
1913 {
1914 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1915 {
1916 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1917 }
1918 else if (sig == last_sig)
1919 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1920 else
1921#if 0
1922/* This code does not seem to work, because
1923 the kernel does probably not consider changes in the ExceptionRecord
dfe7f3ac 1924 structure when passing the exception to the inferior.
7393af7c
PM
1925 Note that this seems possible in the exception handler itself. */
1926 {
1927 int i;
1928 for (i = 0; xlate[i].them != -1; i++)
1929 if (xlate[i].us == sig)
1930 {
1931 current_event.u.Exception.ExceptionRecord.ExceptionCode =
1932 xlate[i].them;
1933 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1934 break;
1935 }
1936 if (continue_status == DBG_CONTINUE)
1937 {
1938 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1939 }
1940 }
1941#endif
dfe7f3ac 1942 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
7393af7c
PM
1943 last_sig));
1944 }
1945
1946 last_sig = TARGET_SIGNAL_0;
24e60978 1947
3cee93ac
CF
1948 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1949 pid, step, sig));
1950
1951 /* Get context for currently selected thread */
1952 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 1953 if (th)
24e60978 1954 {
450005e7
CF
1955 if (step)
1956 {
1957 /* Single step by setting t bit */
1958 child_fetch_inferior_registers (PS_REGNUM);
1959 th->context.EFlags |= FLAG_TRACE_BIT;
1960 }
24e60978 1961
450005e7
CF
1962 if (th->context.ContextFlags)
1963 {
caad7706
CF
1964 if (debug_registers_changed)
1965 {
1966 th->context.Dr0 = dr[0];
1967 th->context.Dr1 = dr[1];
1968 th->context.Dr2 = dr[2];
1969 th->context.Dr3 = dr[3];
1970 /* th->context.Dr6 = dr[6];
1971 FIXME: should we set dr6 also ?? */
1972 th->context.Dr7 = dr[7];
1973 }
450005e7
CF
1974 CHECK (SetThreadContext (th->h, &th->context));
1975 th->context.ContextFlags = 0;
1976 }
24e60978
SC
1977 }
1978
3cee93ac
CF
1979 /* Allow continuing with the same signal that interrupted us.
1980 Otherwise complain. */
24e60978 1981
8a892701 1982 child_continue (continue_status, pid);
24e60978
SC
1983}
1984
1985static void
fba45db2 1986child_prepare_to_store (void)
24e60978
SC
1987{
1988 /* Do nothing, since we can store individual regs */
1989}
1990
1991static int
fba45db2 1992child_can_run (void)
24e60978
SC
1993{
1994 return 1;
1995}
1996
1997static void
0a65a603 1998child_close (int x)
24e60978 1999{
39f77062 2000 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
3bccec63 2001 PIDGET (inferior_ptid)));
24e60978 2002}
1ef980b9 2003
3a4b77d8 2004struct target_ops child_ops;
c719b714 2005
3a4b77d8
JM
2006static void
2007init_child_ops (void)
24e60978 2008{
3a4b77d8
JM
2009 child_ops.to_shortname = "child";
2010 child_ops.to_longname = "Win32 child process";
2011 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
2012 child_ops.to_open = child_open;
2013 child_ops.to_close = child_close;
2014 child_ops.to_attach = child_attach;
2015 child_ops.to_detach = child_detach;
2016 child_ops.to_resume = child_resume;
2017 child_ops.to_wait = child_wait;
2018 child_ops.to_fetch_registers = child_fetch_inferior_registers;
2019 child_ops.to_store_registers = child_store_inferior_registers;
2020 child_ops.to_prepare_to_store = child_prepare_to_store;
2021 child_ops.to_xfer_memory = child_xfer_memory;
2022 child_ops.to_files_info = child_files_info;
2023 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
2024 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
2025 child_ops.to_terminal_init = terminal_init_inferior;
2026 child_ops.to_terminal_inferior = terminal_inferior;
2027 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2028 child_ops.to_terminal_ours = terminal_ours;
a790ad35 2029 child_ops.to_terminal_save_ours = terminal_save_ours;
3a4b77d8
JM
2030 child_ops.to_terminal_info = child_terminal_info;
2031 child_ops.to_kill = child_kill_inferior;
3a4b77d8
JM
2032 child_ops.to_create_inferior = child_create_inferior;
2033 child_ops.to_mourn_inferior = child_mourn_inferior;
2034 child_ops.to_can_run = child_can_run;
3a4b77d8 2035 child_ops.to_thread_alive = win32_child_thread_alive;
d3a09475 2036 child_ops.to_pid_to_str = cygwin_pid_to_str;
3a4b77d8
JM
2037 child_ops.to_stop = child_stop;
2038 child_ops.to_stratum = process_stratum;
3a4b77d8
JM
2039 child_ops.to_has_all_memory = 1;
2040 child_ops.to_has_memory = 1;
2041 child_ops.to_has_stack = 1;
2042 child_ops.to_has_registers = 1;
2043 child_ops.to_has_execution = 1;
3a4b77d8 2044 child_ops.to_magic = OPS_MAGIC;
c719b714 2045}
24e60978
SC
2046
2047void
a6b6b089 2048_initialize_win32_nat (void)
24e60978 2049{
fa58ee11
EZ
2050 struct cmd_list_element *c;
2051
3a4b77d8 2052 init_child_ops ();
1ef980b9 2053
fa58ee11
EZ
2054 c = add_com ("dll-symbols", class_files, dll_symbol_command,
2055 "Load dll library symbols from FILE.");
5ba2abeb 2056 set_cmd_completer (c, filename_completer);
450005e7
CF
2057
2058 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
2059
dfe7f3ac
CF
2060 add_show_from_set (add_set_cmd ("shell", class_support, var_boolean,
2061 (char *) &useshell,
2062 "Set use of shell to start subprocess.",
2063 &setlist),
2064 &showlist);
2065
450005e7 2066 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
8e860359
CF
2067 (char *) &new_console,
2068 "Set creation of new console when creating child process.",
2069 &setlist),
2070 &showlist);
24e60978 2071
450005e7 2072 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
8e860359
CF
2073 (char *) &new_group,
2074 "Set creation of new group when creating child process.",
2075 &setlist),
2076 &showlist);
24e60978 2077
450005e7 2078 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
8e860359
CF
2079 (char *) &debug_exec,
2080 "Set whether to display execution in child process.",
2081 &setlist),
2082 &showlist);
1ef980b9 2083
450005e7 2084 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
8e860359
CF
2085 (char *) &debug_events,
2086 "Set whether to display kernel events in child process.",
2087 &setlist),
2088 &showlist);
1ef980b9 2089
450005e7 2090 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
8e860359
CF
2091 (char *) &debug_memory,
2092 "Set whether to display memory accesses in child process.",
2093 &setlist),
2094 &showlist);
1ef980b9 2095
450005e7 2096 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
8e860359
CF
2097 (char *) &debug_exceptions,
2098 "Set whether to display kernel exceptions in child process.",
2099 &setlist),
2100 &showlist);
1ef980b9 2101
450005e7
CF
2102 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
2103 add_info_alias ("sharedlibrary", "dll", 1);
2104
c1748f97 2105 add_prefix_cmd ("w32", class_info, info_w32_command,
baa93fa6
CF
2106 "Print information specific to Win32 debugging.",
2107 &info_w32_cmdlist, "info w32 ", 0, &infolist);
c1748f97
PM
2108
2109 add_cmd ("selector", class_info, display_selectors,
baa93fa6 2110 "Display selectors infos.",
c1748f97
PM
2111 &info_w32_cmdlist);
2112
24e60978
SC
2113 add_target (&child_ops);
2114}
3cee93ac 2115
fa4ba8da
PM
2116/* Hardware watchpoint support, adapted from go32-nat.c code. */
2117
2118/* Pass the address ADDR to the inferior in the I'th debug register.
2119 Here we just store the address in dr array, the registers will be
2120 actually set up when child_continue is called. */
2121void
2122cygwin_set_dr (int i, CORE_ADDR addr)
2123{
2124 if (i < 0 || i > 3)
2125 internal_error (__FILE__, __LINE__,
2126 "Invalid register %d in cygwin_set_dr.\n", i);
2127 dr[i] = (unsigned) addr;
2128 debug_registers_changed = 1;
2129 debug_registers_used = 1;
2130}
2131
2132/* Pass the value VAL to the inferior in the DR7 debug control
2133 register. Here we just store the address in D_REGS, the watchpoint
2134 will be actually set up in child_wait. */
2135void
2136cygwin_set_dr7 (unsigned val)
2137{
2138 dr[7] = val;
2139 debug_registers_changed = 1;
2140 debug_registers_used = 1;
2141}
2142
2143/* Get the value of the DR6 debug status register from the inferior.
2144 Here we just return the value stored in dr[6]
2145 by the last call to thread_rec for current_event.dwThreadId id. */
2146unsigned
2147cygwin_get_dr6 (void)
2148{
2149 return dr[6];
2150}
2151
2152
3cee93ac
CF
2153/* Determine if the thread referenced by "pid" is alive
2154 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2155 it means that the pid has died. Otherwise it is assumed to be alive. */
2156static int
39f77062 2157win32_child_thread_alive (ptid_t ptid)
3cee93ac 2158{
39f77062
KB
2159 int pid = PIDGET (ptid);
2160
3a4b77d8
JM
2161 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
2162 FALSE : TRUE;
3cee93ac
CF
2163}
2164
2165/* Convert pid to printable format. */
2166char *
39f77062 2167cygwin_pid_to_str (ptid_t ptid)
3cee93ac
CF
2168{
2169 static char buf[80];
39f77062
KB
2170 int pid = PIDGET (ptid);
2171
29fe111d 2172 if ((DWORD) pid == current_event.dwProcessId)
b69571f5 2173 sprintf (buf, "process %d", pid);
3cee93ac 2174 else
b69571f5 2175 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
3cee93ac
CF
2176 return buf;
2177}
8e860359
CF
2178
2179static int
2180core_dll_symbols_add (char *dll_name, DWORD base_addr)
2181{
2182 struct objfile *objfile;
2183 char *objfile_basename;
2184 const char *dll_basename;
2185
2186 if (!(dll_basename = strrchr (dll_name, '/')))
2187 dll_basename = dll_name;
2188 else
2189 dll_basename++;
2190
2191 ALL_OBJFILES (objfile)
2192 {
2193 objfile_basename = strrchr (objfile->name, '/');
2194
2195 if (objfile_basename &&
2196 strcmp (dll_basename, objfile_basename + 1) == 0)
2197 {
2198 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2199 base_addr, dll_name);
2200 goto out;
2201 }
2202 }
2203
87a45c96
CF
2204 register_loaded_dll (dll_name, base_addr + 0x1000);
2205 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
8e860359 2206
87a45c96
CF
2207 out:
2208 return 1;
2209 }
8e860359 2210
87a45c96
CF
2211 typedef struct
2212 {
2213 struct target_ops *target;
2214 bfd_vma addr;
2215 } map_code_section_args;
8e860359 2216
87a45c96
CF
2217 static void
2218 map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
2219 {
2220 int old;
2221 int update_coreops;
2222 struct section_table *new_target_sect_ptr;
8e860359 2223
87a45c96
CF
2224 map_code_section_args *args = (map_code_section_args *) obj;
2225 struct target_ops *target = args->target;
2226 if (sect->flags & SEC_CODE)
2227 {
2228 update_coreops = core_ops.to_sections == target->to_sections;
8e860359 2229
87a45c96
CF
2230 if (target->to_sections)
2231 {
2232 old = target->to_sections_end - target->to_sections;
2233 target->to_sections = (struct section_table *)
2234 xrealloc ((char *) target->to_sections,
2235 (sizeof (struct section_table)) * (1 + old));
2236 }
2237 else
2238 {
2239 old = 0;
2240 target->to_sections = (struct section_table *)
2241 xmalloc ((sizeof (struct section_table)));
2242 }
2243 target->to_sections_end = target->to_sections + (1 + old);
8e860359 2244
87a45c96
CF
2245 /* Update the to_sections field in the core_ops structure
2246 if needed. */
2247 if (update_coreops)
2248 {
2249 core_ops.to_sections = target->to_sections;
2250 core_ops.to_sections_end = target->to_sections_end;
2251 }
2252 new_target_sect_ptr = target->to_sections + old;
2253 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
2254 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
2255 bfd_section_size (abfd, sect);;
2256 new_target_sect_ptr->the_bfd_section = sect;
2257 new_target_sect_ptr->bfd = abfd;
2258 }
2259 }
8e860359 2260
87a45c96
CF
2261 static int
2262 dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
8e860359
CF
2263{
2264 bfd *dll_bfd;
2265 map_code_section_args map_args;
2266 asection *lowest_sect;
2267 char *name;
2268 if (dll_name == NULL || target == NULL)
2269 return 0;
66ed1d85 2270 name = xstrdup (dll_name);
8e860359
CF
2271 dll_bfd = bfd_openr (name, "pei-i386");
2272 if (dll_bfd == NULL)
2273 return 0;
2274
2275 if (bfd_check_format (dll_bfd, bfd_object))
2276 {
2277 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
2278 if (lowest_sect == NULL)
2279 return 0;
2280 map_args.target = target;
2281 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
2282
554cb486 2283 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
2284 }
2285
2286 return 1;
2287}
2288
2289static void
554cb486 2290core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
2291{
2292 struct target_ops *target = (struct target_ops *) obj;
2293
2294 DWORD base_addr;
2295
2296 int dll_name_size;
2297 char *dll_name = NULL;
2298 char *buf = NULL;
2299 struct win32_pstatus *pstatus;
2300 char *p;
2301
2302 if (strncmp (sect->name, ".module", 7))
2303 return;
2304
2305 buf = (char *) xmalloc (sect->_raw_size + 1);
2306 if (!buf)
2307 {
2308 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2309 goto out;
2310 }
2311 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
2312 goto out;
2313
2314 pstatus = (struct win32_pstatus *) buf;
2315
2316 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
2317 dll_name_size = pstatus->data.module_info.module_name_size;
2318 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
2319 goto out;
2320
2321 dll_name = (char *) xmalloc (dll_name_size + 1);
2322 if (!dll_name)
2323 {
2324 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2325 goto out;
2326 }
2327 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
2328
2329 while ((p = strchr (dll_name, '\\')))
2330 *p = '/';
2331
2332 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
2333 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
2334
2335 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
2336 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
2337
2338out:
2339 if (buf)
b8c9b27d 2340 xfree (buf);
8e860359 2341 if (dll_name)
b8c9b27d 2342 xfree (dll_name);
8e860359
CF
2343 return;
2344}
2345
2346void
0a65a603
AC
2347child_solib_add (char *filename, int from_tty, struct target_ops *target,
2348 int readsyms)
8e860359 2349{
990f9fe3
FF
2350 if (!readsyms)
2351 return;
8e860359
CF
2352 if (core_bfd)
2353 {
2354 child_clear_solibs ();
2355 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
2356 }
2357 else
2358 {
2359 if (solib_end && solib_end->name)
d3ff4a77 2360 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
3bccec63 2361 solib_end->load_addr);
8e860359
CF
2362 }
2363}
2364
2365static void
2366fetch_elf_core_registers (char *core_reg_sect,
2367 unsigned core_reg_size,
2368 int which,
2369 CORE_ADDR reg_addr)
2370{
2371 int r;
2372 if (core_reg_size < sizeof (CONTEXT))
2373 {
2374 error ("Core file register section too small (%u bytes).", core_reg_size);
2375 return;
2376 }
2377 for (r = 0; r < NUM_REGS; r++)
2378 supply_register (r, core_reg_sect + mappings[r]);
2379}
2380
2381static struct core_fns win32_elf_core_fns =
2382{
2383 bfd_target_elf_flavour,
2384 default_check_format,
2385 default_core_sniffer,
2386 fetch_elf_core_registers,
2387 NULL
2388};
2389
2390void
0613c401 2391_initialize_core_win32 (void)
8e860359
CF
2392{
2393 add_core_fns (&win32_elf_core_fns);
2394}
2a3d5645
CF
2395
2396void
2397_initialize_check_for_gdb_ini (void)
2398{
2399 char *homedir;
2400 if (inhibit_gdbinit)
2401 return;
2402
2403 homedir = getenv ("HOME");
2404 if (homedir)
2405 {
2406 char *p;
2407 char *oldini = (char *) alloca (strlen (homedir) +
2408 sizeof ("/gdb.ini"));
2409 strcpy (oldini, homedir);
2410 p = strchr (oldini, '\0');
2411 if (p > oldini && p[-1] != '/')
2412 *p++ = '/';
2413 strcpy (p, "gdb.ini");
2414 if (access (oldini, 0) == 0)
2415 {
2416 int len = strlen (oldini);
2417 char *newini = alloca (len + 1);
dfe7f3ac 2418 sprintf (newini, "%.*s.gdbinit",
58fa08f0 2419 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2a3d5645
CF
2420 warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
2421 }
2422 }
2423}
This page took 0.725989 seconds and 4 git commands to generate.