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