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