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