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