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